[Conectores mock deterministas, sin tráfico saliente live]

Entorno sandbox

Prueba integraciones contra conectores mock deterministas sin tráfico saliente real al partner. Emite un token de sandbox (`aud=sandbox`) en `auth.knogin.com`, llama a la misma superficie v2026.4 contra `https://sandbox-api.knogin.com` y recibe respuestas idénticas byte a byte en cada replay del mismo payload.

Entorno sandbox

Empezar

El acceso al sandbox se controla mediante el flujo estándar de admin de plataforma. Con el scope `argus:platform:admin` sobre un bearer token, llama a `POST /v1/platform/apps/{client_id}/sandbox-token` para emitir un JWT de sandbox para la app que estás integrando. La respuesta incluye el host del sandbox (`https://sandbox-api.knogin.com`) y la lista de scenarios fijados al token. Apunta tu SDK partner existente al host del sandbox, sustituye el token live por el de sandbox y toda la superficie v2026.4 se enruta a mocks deterministas de forma transparente.

Emisión de tokens

`POST /v1/platform/apps/{client_id}/sandbox-token` acepta un array `scenarios` opcional (fija el sandbox a datos predefinidos concretos, p. ej. `["wallet.high-risk", "entity.sanctioned"]`) y un `ttl_seconds` opcional (acotado al rango inclusivo [60, 86400]; los valores fuera de rango se normalizan antes de firmar). La respuesta incluye el token de sandbox firmado, su `expires_at`, `audience: "sandbox"`, el conjunto de scopes empaquetados en el token, el host del sandbox y los scenarios fijados. El token de sandbox reutiliza el conjunto de claves RS256 del auth_service existente; la cabecera `kid` apunta al mismo JWKS usado para `/oauth/token`, por lo que los SDKs partner ya validan tokens de sandbox sin cambios.

Catálogo de scenarios

Cinco scenarios se publican en el primer release. Fija uno o varios en el campo `scenarios` al emitir el token para que el sandbox devuelva los mismos datos predefinidos en cada replay; omite el campo para la rotación mixta por defecto.

Doble barrera

Argus impone no-leak en ambas direcciones. El host de sandbox (`sandbox-api.knogin.com`) rechaza tokens live: el middleware de routing comprueba el claim `aud` del JWT y rechaza con 403 cuando `aud != "sandbox"`. Los conectores live rechazan tokens de sandbox: cada factory `<provider>_client.py` live comprueba `request.state.sandbox` y lanza 403 si la petición está en scope sandbox. Los tests cubren ambas direcciones, de modo que un token live no puede leer datos mock por accidente y un token de sandbox no puede alcanzar los sistemas live del partner.

Determinismo

Las respuestas del sandbox son deterministas. El mismo payload, lanzado dos veces con los mismos scenarios fijados, devuelve una respuesta idéntica byte a byte. Esto es intencional: los pipelines de CI partner pueden hacer snapshot de las respuestas de sandbox y asertar contra ellas en cada build sin retry-flake. Las respuestas de sandbox también llevan `X-Argus-Sandbox: true` para que las herramientas de debug partner vean de un vistazo que la respuesta es sintética, manteniendo a la vez el `X-Argus-Trace-ID` estándar de G2 para correlación end-to-end con tus propios logs.

Facturación y cuota

Las llamadas al sandbox no consumen tu cuota de conectores partner live y no son facturables. Nunca tocan proveedores OSINT o financieros reales, nunca alcanzan datasets sensibles y nunca entran en los presupuestos de rate-limit que negociaste para producción. Las entradas de auditoría del tráfico sandbox se etiquetan con `secrecy_level=sandbox` para que los operadores puedan filtrar el tráfico sandbox de los reportes de cumplimiento. Usa el sandbox sin límites para tests de integración, ensayos de onboarding partner, grabaciones de demo y CI exploratoria; los presupuestos de producción quedan intactos.

Migración a producción

Cuando tu integración esté lista, cambia la base URL de `https://sandbox-api.knogin.com` a `https://api.knogin.com` y vuelve a emitir un token live mediante el flujo estándar `POST /v1/oauth/token` con tus scopes de producción. La forma en wire, las cabeceras, los status codes y la propagación de trace son idénticos entre sandbox y live, por lo que un cliente validado en sandbox no necesita cambios de comportamiento. La única diferencia en runtime es el claim `aud` del JWT y el host al que apuntas.

Catálogo de scenarios

ID de scenarioEtiquetaDescripción
wallet.high-riskWallet de alto riesgoDevuelve enriquecimiento que indica hits de sanciones, interacción con mixer y transferencias rápidas de gran volumen.
wallet.cleanWallet limpiaDevuelve enriquecimiento que indica actividad de bajo riesgo y sin hits de sanciones.
entity.sanctionedEntidad sancionadaDevuelve enriquecimiento OSINT con coincidencias en listas OFAC, UN y UE.
incident.escalatingIncidente en escaladaDevuelve señales de dispatch y ePCR consistentes con una situación que empeora.
device.offlineDispositivo médico offlineDevuelve telemetría que indica last-seen hace N horas con estado de batería desactualizado.

Emitir un token de sandbox

# Mint a sandbox token (requires argus:platform:admin)
curl -X POST https://auth.knogin.com/v1/platform/apps/app_123/sandbox-token \
  -H "Authorization: Bearer $ADMIN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "scenarios": ["wallet.high-risk", "entity.sanctioned"],
    "ttl_seconds": 3600
  }'

# 200 OK
# {
#   "token": "<sandbox-jwt>",
#   "expires_at": "2026-05-08T13:00:00Z",
#   "audience": "sandbox",
#   "scopes": [
#     "argus:profiles:read",
#     "argus:profiles:write",
#     "argus:jobs:read",
#     "argus:jobs:write"
#   ],
#   "sandbox_host": "https://sandbox-api.knogin.com",
#   "scenarios": ["wallet.high-risk", "entity.sanctioned"]
# }

Listar scenarios de sandbox

# Discover the scenario catalogue (sandbox host only)
curl https://sandbox-api.knogin.com/v1/sandbox/scenarios \
  -H "Authorization: Bearer $SANDBOX_TOKEN"

# 200 OK
# {
#   "scenarios": [
#     { "id": "wallet.high-risk", "label": "High-risk wallet", "description": "..." },
#     { "id": "wallet.clean", "label": "Clean wallet", "description": "..." },
#     { "id": "entity.sanctioned", "label": "Sanctioned entity", "description": "..." },
#     { "id": "incident.escalating", "label": "Escalating incident", "description": "..." },
#     { "id": "device.offline", "label": "Offline medical device", "description": "..." }
#   ]
# }

# A live token against the sandbox host fails closed:
# HTTP/1.1 403 Forbidden
# X-Argus-Sandbox-Reason: live-token-on-sandbox-host

Llamar a la superficie sandbox

# Same v2026.4 surface, sandbox host, sandbox token.
# Two replays of the same payload return a byte-equal response.
curl -X POST https://sandbox-api.knogin.com/v1/jobs \
  -H "Authorization: Bearer $SANDBOX_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "kind": "intelligence.enrich.bulk",
    "payload": { "profile_ids": ["p1", "p2"] }
  }'

# Response carries:
#   X-Argus-Sandbox: true
#   X-Argus-Trace-ID: <32-hex>   (G2 trace propagation, unchanged)

# When ready for production, swap the base URL and re-mint a live token:
curl -X POST https://auth.knogin.com/v1/oauth/token \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "grant_type=client_credentials&client_id=app_123&client_secret=<secret>&scope=argus:jobs:write"

curl -X POST https://api.knogin.com/v1/jobs \
  -H "Authorization: Bearer $LIVE_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "kind": "intelligence.enrich.bulk", "payload": { "profile_ids": ["p1"] } }'

¿Listo para conectar tu integración a través del sandbox?

Abre la referencia API para el contrato público o contacta a Knogin si necesitas un fixture de scenario a medida para tu flujo partner.