{"adoption": {"forks": 113, "observed_at": "2026-08-28T04:05:33.875041+00:00", "stars": 1770}, "canonical_url": "https://ross.abutalabs.com/products/sandwich", "card": {"archived": false, "artifact_type": "library", "description": "🥪  Sandwich is an adaptable and lightweight sealed API library designed for handling API responses and exceptions in Kotlin for Retrofit, Ktor, and Kotlin Multiplatform.", "domain": ["android-tools", "web-development", "developer-tools"], "enriched": true, "function": ["http-client", "error-handling", "serialization"], "health_score": 100, "homepage": "https://skydoves.github.io/sandwich/", "language": "Kotlin", "license": "Apache-2.0", "license_family": "permissive", "maturity": "stable", "member_repos": ["skydoves/sandwich"], "name": "skydoves/sandwich", "platform": ["jvm", "cross-platform"], "pushed_at": "2026-08-25T17:45:47+00:00", "repo": "skydoves/sandwich", "stars": 1770, "tags": ["retrofit", "ktor", "kotlin-multiplatform", "api-response-handling", "sealed-classes", "coroutines", "android"], "topics": ["android", "retrofit", "api", "network", "apiresponse", "datasource", "kotlin", "skydoves"], "urls": [], "use_cases": ["handle retrofit api responses and errors in kotlin", "avoid writing resource wrapper classes for network calls", "handle network exceptions elegantly in android apps", "standardize api response handling across kotlin multiplatform projects", "apply global operators to all network responses", "map api error responses to custom models", "test network response handling with fake factories"], "what_it_is": "Sandwich is a lightweight Kotlin library that provides sealed ApiResponse types for modeling and handling API responses and exceptions from Retrofit, Ktor, and Ktorfit. It offers functional operators, mappers, and global response handling so developers can avoid writing custom Resource/Result wrapper classes.", "when_to_avoid": ["you don't use Retrofit, Ktor, or Ktorfit for networking", "your project already has an established response-handling pattern", "you need a full networking client rather than a response-handling layer", "you're not using Kotlin"], "when_to_choose": ["you use Retrofit, Ktor, or Ktorfit in Kotlin and want consistent response/error handling", "you're tired of writing boilerplate Resource or Result wrapper classes", "you want functional operators and mappers for network responses", "you need shared network response handling in Kotlin Multiplatform", "you want global response handling across your app"]}, "data_as_of": "2026-08-30T08:39:29.467469+00:00", "members": [{"path": "/products/sandwich", "repo": "skydoves/sandwich", "role": "main", "score": 94}], "provenance": {"archived": {"kind": "observed", "observed_at": "2026-08-28T04:05:33.875041+00:00", "source": "github"}, "artifact_type": {"confidence": null, "enriched_at": "2026-08-30T03:26:04.386048+00:00", "kind": "inferred", "prompt_version": 1, "sources": [{"content_hash": "b7224077dd2a2ab5db7f6e0334e92adab7ba70c217ae6466ce1aee4dfec07321", "fetched_at": "2026-08-28T04:05:33.875041+00:00", "kind": "readme", "missing": false, "url": "https://github.com/skydoves/sandwich"}, {"content_hash": "dac3f41321b57e6c65ee83f9375e42c947ca3520bd156a3010408c7014ba1fc1", "fetched_at": "2026-08-29T11:04:22.311126+00:00", "kind": "homepage", "missing": false, "url": "https://skydoves.github.io/sandwich/"}], "taxonomy_version": 1}, "description": {"kind": "observed", "observed_at": "2026-08-28T04:05:33.875041+00:00", "source": "github"}, "domain": {"confidence": null, "enriched_at": "2026-08-30T03:26:04.386048+00:00", "kind": "inferred", "prompt_version": 1, "sources": [{"content_hash": "b7224077dd2a2ab5db7f6e0334e92adab7ba70c217ae6466ce1aee4dfec07321", "fetched_at": "2026-08-28T04:05:33.875041+00:00", "kind": "readme", "missing": false, "url": "https://github.com/skydoves/sandwich"}, {"content_hash": "dac3f41321b57e6c65ee83f9375e42c947ca3520bd156a3010408c7014ba1fc1", "fetched_at": "2026-08-29T11:04:22.311126+00:00", "kind": "homepage", "missing": false, "url": "https://skydoves.github.io/sandwich/"}], "taxonomy_version": 1}, "enriched": {"inputs": [], "kind": "computed", "method": "enrichment_status"}, "function": {"confidence": null, "enriched_at": "2026-08-30T03:26:04.386048+00:00", "kind": "inferred", "prompt_version": 1, "sources": [{"content_hash": "b7224077dd2a2ab5db7f6e0334e92adab7ba70c217ae6466ce1aee4dfec07321", "fetched_at": "2026-08-28T04:05:33.875041+00:00", "kind": "readme", "missing": false, "url": "https://github.com/skydoves/sandwich"}, {"content_hash": "dac3f41321b57e6c65ee83f9375e42c947ca3520bd156a3010408c7014ba1fc1", "fetched_at": "2026-08-29T11:04:22.311126+00:00", "kind": "homepage", "missing": false, "url": "https://skydoves.github.io/sandwich/"}], "taxonomy_version": 1}, "health_score": {"inputs": ["days_since_push", "days_since_release", "archived"], "kind": "computed", "method": "health_v1"}, "homepage": {"kind": "observed", "observed_at": "2026-08-28T04:05:33.875041+00:00", "source": "github"}, "language": {"kind": "observed", "observed_at": "2026-08-28T04:05:33.875041+00:00", "source": "github"}, "license": {"kind": "observed", "observed_at": "2026-08-28T04:05:33.875041+00:00", "source": "github"}, "license_family": {"inputs": ["license"], "kind": "computed", "method": "license_family"}, "maturity": {"confidence": null, "enriched_at": "2026-08-30T03:26:04.386048+00:00", "kind": "inferred", "prompt_version": 1, "sources": [{"content_hash": "b7224077dd2a2ab5db7f6e0334e92adab7ba70c217ae6466ce1aee4dfec07321", "fetched_at": "2026-08-28T04:05:33.875041+00:00", "kind": "readme", "missing": false, "url": "https://github.com/skydoves/sandwich"}, {"content_hash": "dac3f41321b57e6c65ee83f9375e42c947ca3520bd156a3010408c7014ba1fc1", "fetched_at": "2026-08-29T11:04:22.311126+00:00", "kind": "homepage", "missing": false, "url": "https://skydoves.github.io/sandwich/"}], "taxonomy_version": 1}, "member_repos": {"kind": "observed", "observed_at": "2026-08-28T04:05:33.875041+00:00", "source": "github"}, "name": {"kind": "observed", "observed_at": "2026-08-28T04:05:33.875041+00:00", "source": "github"}, "platform": {"confidence": null, "enriched_at": "2026-08-30T03:26:04.386048+00:00", "kind": "inferred", "prompt_version": 1, "sources": [{"content_hash": "b7224077dd2a2ab5db7f6e0334e92adab7ba70c217ae6466ce1aee4dfec07321", "fetched_at": "2026-08-28T04:05:33.875041+00:00", "kind": "readme", "missing": false, "url": "https://github.com/skydoves/sandwich"}, {"content_hash": "dac3f41321b57e6c65ee83f9375e42c947ca3520bd156a3010408c7014ba1fc1", "fetched_at": "2026-08-29T11:04:22.311126+00:00", "kind": "homepage", "missing": false, "url": "https://skydoves.github.io/sandwich/"}], "taxonomy_version": 1}, "pushed_at": {"kind": "observed", "observed_at": "2026-08-28T04:05:33.875041+00:00", "source": "github"}, "repo": {"kind": "observed", "observed_at": "2026-08-28T04:05:33.875041+00:00", "source": "github"}, "stars": {"kind": "observed", "observed_at": "2026-08-28T04:05:33.875041+00:00", "source": "github"}, "tags": {"confidence": null, "enriched_at": "2026-08-30T03:26:04.386048+00:00", "kind": "inferred", "prompt_version": 1, "sources": [{"content_hash": "b7224077dd2a2ab5db7f6e0334e92adab7ba70c217ae6466ce1aee4dfec07321", "fetched_at": "2026-08-28T04:05:33.875041+00:00", "kind": "readme", "missing": false, "url": "https://github.com/skydoves/sandwich"}, {"content_hash": "dac3f41321b57e6c65ee83f9375e42c947ca3520bd156a3010408c7014ba1fc1", "fetched_at": "2026-08-29T11:04:22.311126+00:00", "kind": "homepage", "missing": false, "url": "https://skydoves.github.io/sandwich/"}], "taxonomy_version": 1}, "topics": {"kind": "observed", "observed_at": "2026-08-28T04:05:33.875041+00:00", "source": "github"}, "urls": {"kind": "observed", "observed_at": "2026-08-28T04:05:33.875041+00:00", "source": "github"}, "use_cases": {"confidence": null, "enriched_at": "2026-08-30T03:26:04.386048+00:00", "kind": "inferred", "prompt_version": 1, "sources": [{"content_hash": "b7224077dd2a2ab5db7f6e0334e92adab7ba70c217ae6466ce1aee4dfec07321", "fetched_at": "2026-08-28T04:05:33.875041+00:00", "kind": "readme", "missing": false, "url": "https://github.com/skydoves/sandwich"}, {"content_hash": "dac3f41321b57e6c65ee83f9375e42c947ca3520bd156a3010408c7014ba1fc1", "fetched_at": "2026-08-29T11:04:22.311126+00:00", "kind": "homepage", "missing": false, "url": "https://skydoves.github.io/sandwich/"}], "taxonomy_version": 1}, "what_it_is": {"confidence": null, "enriched_at": "2026-08-30T03:26:04.386048+00:00", "kind": "inferred", "prompt_version": 1, "sources": [{"content_hash": "b7224077dd2a2ab5db7f6e0334e92adab7ba70c217ae6466ce1aee4dfec07321", "fetched_at": "2026-08-28T04:05:33.875041+00:00", "kind": "readme", "missing": false, "url": "https://github.com/skydoves/sandwich"}, {"content_hash": "dac3f41321b57e6c65ee83f9375e42c947ca3520bd156a3010408c7014ba1fc1", "fetched_at": "2026-08-29T11:04:22.311126+00:00", "kind": "homepage", "missing": false, "url": "https://skydoves.github.io/sandwich/"}], "taxonomy_version": 1}, "when_to_avoid": {"confidence": null, "enriched_at": "2026-08-30T03:26:04.386048+00:00", "kind": "inferred", "prompt_version": 1, "sources": [{"content_hash": "b7224077dd2a2ab5db7f6e0334e92adab7ba70c217ae6466ce1aee4dfec07321", "fetched_at": "2026-08-28T04:05:33.875041+00:00", "kind": "readme", "missing": false, "url": "https://github.com/skydoves/sandwich"}, {"content_hash": "dac3f41321b57e6c65ee83f9375e42c947ca3520bd156a3010408c7014ba1fc1", "fetched_at": "2026-08-29T11:04:22.311126+00:00", "kind": "homepage", "missing": false, "url": "https://skydoves.github.io/sandwich/"}], "taxonomy_version": 1}, "when_to_choose": {"confidence": null, "enriched_at": "2026-08-30T03:26:04.386048+00:00", "kind": "inferred", "prompt_version": 1, "sources": [{"content_hash": "b7224077dd2a2ab5db7f6e0334e92adab7ba70c217ae6466ce1aee4dfec07321", "fetched_at": "2026-08-28T04:05:33.875041+00:00", "kind": "readme", "missing": false, "url": "https://github.com/skydoves/sandwich"}, {"content_hash": "dac3f41321b57e6c65ee83f9375e42c947ca3520bd156a3010408c7014ba1fc1", "fetched_at": "2026-08-29T11:04:22.311126+00:00", "kind": "homepage", "missing": false, "url": "https://skydoves.github.io/sandwich/"}], "taxonomy_version": 1}}, "score": {"components": {"activity": 99, "longevity": 100, "rhythm": 83}, "computed_at": "2026-09-03T02:20:16.233290+00:00", "flags": [], "formula": "round(0.45*activity + 0.35*rhythm + 0.20*longevity); archived -> min(score, 10)", "inputs": {"age_days": 2311, "days_push": 8, "days_rel": 38, "gap_med": 67, "n_releases_24m": 12}, "score": 94, "version": 2}, "staleness": {"enrichment_outdated": false, "low_confidence": false, "scrape_days": 9, "stale_scrape": false}}