{"id":"sandbox-environment","title":"Sandbox environment","description":"Issue short-lived sandbox tokens (aud=sandbox) and route the entire v2026.4 surface to deterministic mock connectors at https://sandbox-api.knogin.com. Dual gate prevents leak between sandbox and live.","lastUpdated":"2026-05-08","sections":[{"id":"sandbox-token-issue","title":"POST /v1/platform/apps/{client_id}/sandbox-token · Issue a sandbox token","content":"Route: POST /v1/platform/apps/{client_id}/sandbox-token\nHost: https://auth.knogin.com\nAuth: Bearer token\nAudience: Customer administrators\nStability: Stable\n\nMints a short-lived sandbox token (aud=sandbox) for the requested app. Sandbox tokens route to deterministic mock connectors at https://sandbox-api.knogin.com.\n\nIntegration notes:\n- Requires the `argus:platform:admin` scope to mint sandbox tokens. Sandbox tokens themselves cannot mint further sandbox tokens.\n- `ttl_seconds` is clamped to the inclusive range [60, 86400]; values outside are normalised before signing.\n- Optional `scenarios` array pins the sandbox to specific scenario IDs so the same client_id consistently sees the same canned data.\n- The returned token carries `aud=sandbox`. Use it against the sandbox host `https://sandbox-api.knogin.com`; live hosts reject sandbox tokens with 403.\n- Sandbox tokens carry the issuing tenant's `tenant_id` and `organization_id` so audit and rate-limiting remain tenant-scoped.","codeExamples":[{"language":"bash","code":"curl -X POST https://auth.knogin.com/v1/platform/apps/app_123/sandbox-token \\\n  -H \"Authorization: Bearer <admin-access-token>\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n    \"scenarios\": [\"wallet.high-risk\", \"entity.sanctioned\"],\n    \"ttl_seconds\": 3600\n  }'","description":"Request example"},{"language":"json","code":"{\n  \"token\": \"<sandbox-jwt>\",\n  \"expires_at\": \"2026-05-08T13:00:00Z\",\n  \"audience\": \"sandbox\",\n  \"scopes\": [\"argus:profiles:read\", \"argus:profiles:write\", \"argus:jobs:read\", \"argus:jobs:write\"],\n  \"sandbox_host\": \"https://sandbox-api.knogin.com\",\n  \"scenarios\": [\"wallet.high-risk\", \"entity.sanctioned\"]\n}","description":"Response example"}]},{"id":"sandbox-scenarios-list","title":"GET /v1/sandbox/scenarios · List sandbox scenarios","content":"Route: GET /v1/sandbox/scenarios\nHost: https://sandbox-api.knogin.com\nAuth: Bearer token\nAudience: External integrators\nStability: Stable\n\nReturns the deterministic scenario catalogue (wallet.high-risk, wallet.clean, entity.sanctioned, incident.escalating, device.offline) available on the sandbox host.\n\nIntegration notes:\n- Requires a sandbox token (`aud=sandbox`); a live token returns 403.\n- Hosted on `https://sandbox-api.knogin.com`; calling the same path on the live API host returns 404.\n- Scenario IDs returned by this endpoint are the canonical values accepted by the `scenarios` field on `POST /v1/platform/apps/{client_id}/sandbox-token`.\n- Sandbox responses also carry `X-Argus-Sandbox: true` so partner debugging tools see at a glance that the response is synthetic.","codeExamples":[{"language":"bash","code":"curl https://sandbox-api.knogin.com/v1/sandbox/scenarios \\\n  -H \"Authorization: Bearer <sandbox-token>\"","description":"Request example"},{"language":"json","code":"{\n  \"scenarios\": [\n    {\n      \"id\": \"wallet.high-risk\",\n      \"label\": \"High-risk wallet\",\n      \"description\": \"Returns enrichment indicating sanctions hits, mixer interaction, and high-volume rapid-fire transfers.\"\n    },\n    {\n      \"id\": \"wallet.clean\",\n      \"label\": \"Clean wallet\",\n      \"description\": \"Returns enrichment indicating low-risk activity, no sanctions hits.\"\n    },\n    {\n      \"id\": \"entity.sanctioned\",\n      \"label\": \"Sanctioned entity\",\n      \"description\": \"Returns OSINT enrichment with OFAC/UN/EU sanctions matches.\"\n    },\n    {\n      \"id\": \"incident.escalating\",\n      \"label\": \"Escalating incident\",\n      \"description\": \"Returns dispatch / ePCR signals consistent with a worsening situation.\"\n    },\n    {\n      \"id\": \"device.offline\",\n      \"label\": \"Offline medical device\",\n      \"description\": \"Returns telemetry indicating last-seen N hours ago with stale battery state.\"\n    }\n  ]\n}","description":"Response example"}]}],"relatedTopics":["identity-app-registration","oauth-service-tokens","jwks-token-verification","event-delivery-webhooks","graphql-transport-contract","observability-and-tracing","async-jobs","provenance-and-compliance","discovery-and-governance"],"markdown":"# Sandbox environment\n\nIssue short-lived sandbox tokens (aud=sandbox) and route the entire v2026.4 surface to deterministic mock connectors at https://sandbox-api.knogin.com. Dual gate prevents leak between sandbox and live.\n\n## POST /v1/platform/apps/{client_id}/sandbox-token · Issue a sandbox token\n\nRoute: POST /v1/platform/apps/{client_id}/sandbox-token\nHost: https://auth.knogin.com\nAuth: Bearer token\nAudience: Customer administrators\nStability: Stable\n\nMints a short-lived sandbox token (aud=sandbox) for the requested app. Sandbox tokens route to deterministic mock connectors at https://sandbox-api.knogin.com.\n\nIntegration notes:\n- Requires the `argus:platform:admin` scope to mint sandbox tokens. Sandbox tokens themselves cannot mint further sandbox tokens.\n- `ttl_seconds` is clamped to the inclusive range [60, 86400]; values outside are normalised before signing.\n- Optional `scenarios` array pins the sandbox to specific scenario IDs so the same client_id consistently sees the same canned data.\n- The returned token carries `aud=sandbox`. Use it against the sandbox host `https://sandbox-api.knogin.com`; live hosts reject sandbox tokens with 403.\n- Sandbox tokens carry the issuing tenant's `tenant_id` and `organization_id` so audit and rate-limiting remain tenant-scoped.\n\nRequest example\n\n```bash\ncurl -X POST https://auth.knogin.com/v1/platform/apps/app_123/sandbox-token \\\n  -H \"Authorization: Bearer <admin-access-token>\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n    \"scenarios\": [\"wallet.high-risk\", \"entity.sanctioned\"],\n    \"ttl_seconds\": 3600\n  }'\n```\n\nResponse example\n\n```json\n{\n  \"token\": \"<sandbox-jwt>\",\n  \"expires_at\": \"2026-05-08T13:00:00Z\",\n  \"audience\": \"sandbox\",\n  \"scopes\": [\"argus:profiles:read\", \"argus:profiles:write\", \"argus:jobs:read\", \"argus:jobs:write\"],\n  \"sandbox_host\": \"https://sandbox-api.knogin.com\",\n  \"scenarios\": [\"wallet.high-risk\", \"entity.sanctioned\"]\n}\n```\n\n## GET /v1/sandbox/scenarios · List sandbox scenarios\n\nRoute: GET /v1/sandbox/scenarios\nHost: https://sandbox-api.knogin.com\nAuth: Bearer token\nAudience: External integrators\nStability: Stable\n\nReturns the deterministic scenario catalogue (wallet.high-risk, wallet.clean, entity.sanctioned, incident.escalating, device.offline) available on the sandbox host.\n\nIntegration notes:\n- Requires a sandbox token (`aud=sandbox`); a live token returns 403.\n- Hosted on `https://sandbox-api.knogin.com`; calling the same path on the live API host returns 404.\n- Scenario IDs returned by this endpoint are the canonical values accepted by the `scenarios` field on `POST /v1/platform/apps/{client_id}/sandbox-token`.\n- Sandbox responses also carry `X-Argus-Sandbox: true` so partner debugging tools see at a glance that the response is synthetic.\n\nRequest example\n\n```bash\ncurl https://sandbox-api.knogin.com/v1/sandbox/scenarios \\\n  -H \"Authorization: Bearer <sandbox-token>\"\n```\n\nResponse example\n\n```json\n{\n  \"scenarios\": [\n    {\n      \"id\": \"wallet.high-risk\",\n      \"label\": \"High-risk wallet\",\n      \"description\": \"Returns enrichment indicating sanctions hits, mixer interaction, and high-volume rapid-fire transfers.\"\n    },\n    {\n      \"id\": \"wallet.clean\",\n      \"label\": \"Clean wallet\",\n      \"description\": \"Returns enrichment indicating low-risk activity, no sanctions hits.\"\n    },\n    {\n      \"id\": \"entity.sanctioned\",\n      \"label\": \"Sanctioned entity\",\n      \"description\": \"Returns OSINT enrichment with OFAC/UN/EU sanctions matches.\"\n    },\n    {\n      \"id\": \"incident.escalating\",\n      \"label\": \"Escalating incident\",\n      \"description\": \"Returns dispatch / ePCR signals consistent with a worsening situation.\"\n    },\n    {\n      \"id\": \"device.offline\",\n      \"label\": \"Offline medical device\",\n      \"description\": \"Returns telemetry indicating last-seen N hours ago with stale battery state.\"\n    }\n  ]\n}\n```\n\n## Related Topics\n\n- [Identity and app registration](https://knogin.com/api/docs/identity-app-registration)\n- [OAuth and service tokens](https://knogin.com/api/docs/oauth-service-tokens)\n- [JWKS and token verification](https://knogin.com/api/docs/jwks-token-verification)\n- [Event delivery and webhooks](https://knogin.com/api/docs/event-delivery-webhooks)\n- [GraphQL transport contract](https://knogin.com/api/docs/graphql-transport-contract)\n- [Observability and tracing](https://knogin.com/api/docs/observability-and-tracing)\n- [Async jobs](https://knogin.com/api/docs/async-jobs)\n- [Provenance and compliance](https://knogin.com/api/docs/provenance-and-compliance)\n- [Discovery and governance](https://knogin.com/api/docs/discovery-and-governance)","metadata":{"readingTime":"4 min","difficulty":"intermediate","tags":["integrations","api","oauth","webhooks","graphql"]}}