API reference
The Sablecrest SDK talks to a single regional delivery endpoint. Everything below is served from this host — clients resolve a manifest, then pull the bundles it names.
Base URL
All requests are made against your assigned region. This deployment is us-west-1.
https://sablecrest.dev/v1
Requests are authenticated with a project key sent as a bearer token. Keys are issued per project and per channel; a read key can fetch manifests and bundles but cannot publish.
Authorization: Bearer sk_live_7f3c9a21e4b80d56
Endpoints
| Method | Path | Purpose |
|---|---|---|
| GET | /v1/manifest |
Resolve the current content manifest for an app and channel. |
| GET | /v1/bundles/:bundle_id |
Download an immutable asset bundle. This is where the bytes are. |
| POST | /v1/config/resolve |
Resolve remote config for a player cohort. |
| POST | /v1/events/ack |
Acknowledge delivery of a live-ops event. |
Resolve a manifest
The manifest is the source of truth for what a client should be holding. Clients call it on launch and on resume; it is small and cheap, and it is the only call that needs to be fresh.
GET /v1/manifest?app=app_7f3c9a21&channel=live&build=4120
// 200 OK { "manifest_id": "mf_2026_07_03_a41f", "channel": "live", "bundles": [ { "bundle_id": "bnd_characters_s4_a41f9c", "path": "characters/season-4", "size_bytes": 1476395008, "sha256": "9f2c…c17b" }, { "bundle_id": "bnd_maps_harbor_77d0e2", "path": "maps/harbor", "size_bytes": 892143616, "sha256": "41ab…8e90" } ], "config_version": 318 }
Download a bundle
Bundles are content-addressed and immutable — a given bundle_id always returns
the same bytes, so clients cache aggressively and only re-fetch when the manifest names something new.
Responses support range requests, so an interrupted download resumes rather than restarting.
GET /v1/bundles/bnd_characters_s4_a41f9c Range: bytes=0-
// 200 OK (or 206 Partial Content) Content-Type: application/octet-stream Content-Length: 1476395008 ETag: "a41f9c" Cache-Control: public, max-age=31536000, immutable
A season drop is typically 1–4 GB across all bundles, and every active device pulls it once. Plan your content cadence accordingly — clients fetch on their own schedule, not yours, so a drop lands over hours rather than all at once.
Resolve remote config
Config is resolved per player so you can target a cohort without shipping a build. Unknown keys fall back to the values compiled into the client.
POST /v1/config/resolve Content-Type: application/json { "app": "app_7f3c9a21", "build": 4120, "cohort": { "region": "na", "install_age_days": 12 } }
// 200 OK { "config_version": 318, "values": { "event_banner": "harbor_festival", "drop_rate_multiplier": 1.35, "shop_enabled": true } }
Acknowledge an event
Optional, but recommended: it is how the console reports what fraction of your players have actually taken a drop, which is the number you want before you roll a canary forward.
POST /v1/events/ack Content-Type: application/json { "app": "app_7f3c9a21", "manifest_id": "mf_2026_07_03_a41f", "status": "applied" }
SDK quickstart
Unity (C#). The Unreal plugin exposes the same four calls.
using Sablecrest; await SablecrestClient.Init(new SablecrestConfig { AppId = "app_7f3c9a21", Endpoint = "https://sablecrest.dev", Channel = "live" }); // Pulls anything the manifest names that we don't already hold. var result = await SablecrestClient.Content.Sync(); if (result.Applied) { Debug.Log($"Now on manifest {result.ManifestId}"); }
Errors
| Code | Meaning | What to do |
|---|---|---|
| 401 | Key missing, malformed, or revoked. | Check the bearer token. Keys are per project and per channel. |
| 404 | No manifest for that app/channel/build combination. | Usually a build number the channel has never seen. Fall back to compiled defaults. |
| 429 | Too many manifest resolves from one address. | Honour Retry-After. The SDK backs off on its own. |
| 503 | Region briefly unavailable. | Retry with jitter; clients keep serving their cached bundles meanwhile. |
Service health for this region is published at /status.