Sandbox only. Gated on PHOSRA_ENV==sandbox — returns 404 on dev, staging, and
production. Production §8.3.2 consent semantics are unchanged.
Mints a §8.3.2-shaped test consent row with app_ref = your
RFC 9421 caller DID, so a
cold self-registered platform can satisfy the consent-first gate on
POST /enforcement-endpoints with no
OCSS_CONSENT_ATTESTATION_APPS roster edit and no live counterparty.
With no child_ref, the census auto-provisions the sandbox self-serve test child and targets
it. A supplied child_ref must already exist — the door never fabricates a caller-named child.
The response gives you the target_ref to pass straight into the bind call.
Worked example
ts
import { signRequest } from "@openchildsafety/ocss"const BASE = "https://phosra-api-sandbox-production.up.railway.app/api/v1"const seed = new Uint8Array(Buffer.from(process.env.OCSS_SANDBOX_TEST_SEED_B64URL!, "base64url"))const keyID = process.env.OCSS_SANDBOX_KEY_ID!const targetURI = BASE + "/sandbox/consent-attestations"const body = { band: "13_15", consent_scope: "collection_parental_authority" } // both optional; these are the defaultsconst bodyText = JSON.stringify(body)const headers = signRequest({ method: "POST", targetURI, body: new TextEncoder().encode(bodyText), keyID, seed, created: Math.floor(Date.now() / 1000) })headers["Content-Type"] = "application/json"const res = await fetch(targetURI, { method: "POST", headers, body: bodyText })const consent = await res.json()console.log(res.status, consent.target_ref) // pass target_ref to POST /enforcement-endpoints
Example synthetic sandbox 201 response:
json
{ "ok": true, "app_ref": "did:ocss:loopline", "target_ref": "child:5ba0d00c-0000-4000-8000-0000000000c1", "standing_ref": "consent:attestation:sbx-consent:did:ocss:loopline:child:5ba0d00c-0000-4000-8000-0000000000c1", "idempotency_key": "sbx-consent:did:ocss:loopline:child:5ba0d00c-0000-4000-8000-0000000000c1", "band": "13_15", "consent_scope": "collection_parental_authority", "expiry": "2027-07-06T05:26:40Z", "note": "sandbox-only test consent; pass audience_did=<this DID> and child_ref=<target_ref> to POST /api/v1/enforcement-endpoints to complete the consent-first mint"}
The call is idempotent on (app_ref, target_ref) — re-minting returns the same
standing_ref. Next: bind the endpoint.
This standing_ref satisfies the consent-first precondition for POST /enforcement-endpoints
(endpoint binding) — that is its only job. It does not satisfy a signed rule write
(POST /policies/{id}/rules): the sandbox mint stores no signed consent envelope, so the census's
writer-tier resolver fails closed and the rule write returns 403 standing_failure. For a rule
write, obtain a standing via the §8.3.2 consent-ingest lane (a real signed consent_attestation),
not this sandbox mint. The two consent surfaces are not interchangeable.