The base URL
Nothing you do in the sandbox touches a real family or production data. When you are ready for
production, swap the base URL for
https://prodapi.phosra.com and add a phosra_live_… key —
the request shapes are identical.What’s already seeded
| Thing | Value | Use it for |
|---|---|---|
| Demo family | Mia, Leo, Ava (children) | The connect ceremony shares these three profiles |
| Reference provider (configured) | did:ocss:loopline | Run the full OAuth connect flow end-to-end |
| Reference provider (unconfigured) | did:ocss:courier | Test the 404 provider connect config not available branch |
| Trust List entries | 130+ on the signed Trust List (grows as parties self-register) | Verify signatures and accreditation tiers |
| Reference platforms | 22 (nextdns, controld, apple, …) | Discovery by capability and category |
Read the signed Trust List
The Trust List is the source of truth for who is accredited. It is served at a well-known path
and the entire document is Ed25519-signed by the sandbox root key — verify the signature
before you trust any entry inside it.Real response (200):The top-level object wraps a signed document:
The
entries count is a live, growing number — every self-registration (below) adds an entry,
so expect a value at or above the one shown here. Verify the signature and each entry’s tier
rather than asserting on the total.{ "document": "…", "key_id": "…", "alg": "ed25519", "sig": "…" }.
Parse document (itself JSON) to read the entries array — each entry carries a did, an
entity name, its published jwks signing keys, and an accreditation tier. The
@ocss/ts SDK verifies the signature and resolves keys for you.Fields & errors — GET /.well-known/ocss/trust-list
Fields & errors — GET /.well-known/ocss/trust-list
No parameters, no auth. Returns the signed Trust List document.Top-level response fields (200)
Fields on each entry (inside the parsed
| Field | Type | Description |
|---|---|---|
document | string | The Trust List as a JSON string — parse it to get { version, entries: [...] }. Signed as-is; verify before parsing. |
key_id | string | The signing key id, root-sandbox-2026-06 in the sandbox. |
alg | string | Signature algorithm, ed25519. |
sig | string | Base64url Ed25519 signature over document. |
document.entries)| Field | Type | Description |
|---|---|---|
did | string | The party’s DID. |
entity | string | Human-readable entity name. |
jwks | object | The party’s published signing_keys (and payload_keys), for verifying its envelopes. |
tier | string | Accreditation tier: provisional, verified, or accredited. |
status | string | active while the entry is valid. |
valid_through | string (RFC 3339) | When the entry expires. |
Self-register a provisional DID
You do not need anyone’s approval to start testing signed flows. Post your DID and a raw
Ed25519 public key (base64url, unpadded) to Then register:Real response (200):You are now on the sandbox Trust List. The
POST /api/v1/advisors/self-register, and the
census adds you to the sandbox Trust List at the provisional tier.First, mint a keypair and extract the raw 32-byte public key:key_id (did#kid) is what you sign your requests
with; the census publishes your public key so counterparties can verify you.provisional is enough to test the full signed flow in the sandbox. Moving to verified or
accredited — the tiers that carry weight in production — is a governance step, not an API call.
See Production accreditation.Fields & errors — POST /api/v1/advisors/self-register
Fields & errors — POST /api/v1/advisors/self-register
Request body (
Response fields (200)
Errors
application/json)| Field | Type | Required | Description |
|---|---|---|---|
did | string | yes | Your chosen DID, e.g. did:ocss:dx-demo. |
public_key_b64url | string | yes | Raw 32-byte Ed25519 public key, base64url, unpadded. |
roles | string[] | no | Roles to claim, e.g. ["provider"]. |
key_id / kid | string | no | Optional key id; defaults to the current YYYY-MM (e.g. 2026-07). |
| Field | Type | Description |
|---|---|---|
advisor_id | string (UUID) | Your Trust List record id. |
did | string | Echoes your DID. |
key_id | string | Fully-qualified signing key id, did#kid. |
kid | string | The short key id, e.g. 2026-07. |
published_key_x | string | The public key the census published for you (base64url). |
trust_tier | string | provisional for a self-registration. |
| Status | message | When it happens |
|---|---|---|
400 | did is required | did is missing from the body. |
400 | public_key_b64url is required | The key field is missing. |
400 | invalid_public_key_b64url: must decode to 32 bytes, got N | The key is not a valid 32-byte Ed25519 key (wrong length or bad encoding). |
The sandbox host
Everything partner-facing points at one host — the same base URL used throughout these guides. It’s open, seeded, and requires no key:| Host | Backs |
|---|---|
https://phosra-api-sandbox-production.up.railway.app | The live openchildsafety.com walkthrough — the base URL used throughout these guides |
Now build something
Connect a platform
Run the OAuth connect ceremony against the seeded reference provider.
Set up a family & kids
Build a family and an active policy in one call.
Quickstart
Zero to an enforced policy in under five minutes.