{"openapi":"3.1.0","info":{"title":"TrustChain API","version":"1.0","description":"For organisations' own systems: draft credentials and batches for people to approve, invite people to link their wallets, ask for proofs, and hear about it all by webhook. Clients never approve, sign or revoke: people do, in the consoles.\n\nThis server is **testnet**.","contact":{"name":"TrustChain developer support","url":"https://sandbox-api.ssi-trustchain.com/docs"}},"servers":[{"url":"https://sandbox-api.ssi-trustchain.com/api/v1","description":"testnet"}],"tags":[{"name":"Access"},{"name":"Issuing"},{"name":"Batches"},{"name":"Connections"},{"name":"Proofs"},{"name":"Webhooks"},{"name":"Sandbox","description":"Testnet only."},{"name":"Status"}],"paths":{"/health":{"get":{"tags":["Status"],"summary":"Is the API up","security":[],"responses":{"200":{"description":"Up.","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"const":"ok"},"network":{"enum":["testnet","mainnet"]},"api_version":{"type":"string"},"time":{"type":"string","format":"date-time"},"block_height":{"type":"integer"}}}}}}}}},"/openapi.json":{"get":{"tags":["Status"],"summary":"This description (OpenAPI 3.1)","security":[],"responses":{"200":{"description":"The description.","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/status":{"get":{"tags":["Status"],"summary":"Each part of the service, and uptime","security":[],"responses":{"200":{"description":"Status.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Status"}}}}}}},"/oauth/token":{"post":{"tags":["Access"],"summary":"Get an access token (OAuth 2.0 client credentials)","security":[],"description":"Sign a short JWT (EdDSA, Ed25519) with your client's private key: iss and sub your client ID, aud `https://sandbox-api.ssi-trustchain.com/api/v1/oauth/token`, exp at most 5 minutes ahead, and a jti never used before (RFC 7523, private_key_jwt). On testnet a client ID and secret also work. Tokens last 15 minutes: reuse them.","requestBody":{"required":true,"content":{"application/x-www-form-urlencoded":{"schema":{"$ref":"#/components/schemas/TokenRequest"}},"application/json":{"schema":{"$ref":"#/components/schemas/TokenRequest"}}}},"responses":{"200":{"description":"A token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Token"}}}},"400":{"description":"Bad request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OAuthError"}}}},"401":{"description":"Unknown client, bad assertion or secret.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OAuthError"}}}},"403":{"description":"Not from an allowed address.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OAuthError"}}}},"429":{"description":"Too many attempts from this address.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OAuthError"}}}}}}},"/me":{"get":{"security":[{"bearer":[]}],"tags":["Access"],"summary":"Who this token is","responses":{"200":{"description":"The client.","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"The request is malformed.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"No token, or it expired.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Missing scope, or not from an allowed address.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Over the rate limit; see Retry-After.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/templates":{"get":{"security":[{"bearer":["templates:read"]}],"tags":["Issuing"],"summary":"Credential templates you can draft","responses":{"200":{"description":"Templates.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Template"}}}}}}},"400":{"description":"The request is malformed.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"No token, or it expired.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Missing scope, or not from an allowed address.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Over the rate limit; see Retry-After.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/credentials":{"post":{"security":[{"bearer":["credentials:draft"]}],"tags":["Issuing"],"summary":"Draft a credential for people to approve","parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DraftRequest"}}}},"responses":{"201":{"description":"Drafted and waiting for approval.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Request"}}}},"400":{"description":"The request is malformed.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"No token, or it expired.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Missing scope, or not from an allowed address.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Not drafted (the detail says why).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Over the rate limit; see Retry-After.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/requests":{"get":{"security":[{"bearer":["requests:read"]}],"tags":["Issuing"],"summary":"Your drafts and what became of them","parameters":[{"name":"status","in":"query","schema":{"enum":["draft","in_approval","issued","rejected"]}},{"name":"reference","in":"query","schema":{"type":"string"}},{"name":"limit","in":"query","schema":{"type":"integer","maximum":200}},{"name":"after","in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":"A page.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Request"}},"next":{"type":["string","null"]}}}}}},"400":{"description":"The request is malformed.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"No token, or it expired.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Missing scope, or not from an allowed address.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Over the rate limit; see Retry-After.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/requests/{id}":{"get":{"security":[{"bearer":["requests:read"]}],"tags":["Issuing"],"summary":"One draft","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","pattern":"^REQ-\\d+$"},"example":"REQ-0042"}],"responses":{"200":{"description":"The draft.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Request"}}}},"400":{"description":"The request is malformed.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"No token, or it expired.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Missing scope, or not from an allowed address.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Not yours, or no such draft.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Over the rate limit; see Retry-After.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/batches":{"post":{"security":[{"bearer":["batches:write"]}],"tags":["Batches"],"summary":"Upload a batch (JSON, or CSV with ?template=&name=&reference=)","parameters":[{"$ref":"#/components/parameters/IdempotencyKey"},{"name":"template","in":"query","schema":{"type":"string"}},{"name":"name","in":"query","schema":{"type":"string"}},{"name":"reference","in":"query","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BatchUpload"}},"text/csv":{"schema":{"type":"string","description":"Header: holder_ref (or connection), reference, then one column per template detail."}}}},"responses":{"202":{"description":"Checked. Waiting for approval, or needs fixing.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Batch"}}}},"400":{"description":"The request is malformed.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"No token, or it expired.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Missing scope, or not from an allowed address.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"413":{"description":"Larger than 8 MB.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Not accepted.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Over the rate limit; see Retry-After.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"get":{"security":[{"bearer":["batches:read"]}],"tags":["Batches"],"summary":"Your latest batches","responses":{"200":{"description":"Batches.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Batch"}}}}}}},"400":{"description":"The request is malformed.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"No token, or it expired.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Missing scope, or not from an allowed address.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Over the rate limit; see Retry-After.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/batches/{id}":{"get":{"security":[{"bearer":["batches:read"]}],"tags":["Batches"],"summary":"One batch, with progress","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","pattern":"^BT-\\d+$"},"example":"BT-0007"}],"responses":{"200":{"description":"The batch.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Batch"}}}},"400":{"description":"The request is malformed.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"No token, or it expired.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Missing scope, or not from an allowed address.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"No such batch.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Over the rate limit; see Retry-After.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/batches/{id}/results":{"get":{"security":[{"bearer":["batches:read"]}],"tags":["Batches"],"summary":"Each row: its credential, or why it failed","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","pattern":"^BT-\\d+$"},"example":"BT-0007"},{"name":"after","in":"query","schema":{"type":"integer"}},{"name":"limit","in":"query","schema":{"type":"integer","maximum":1000}}],"responses":{"200":{"description":"A page of rows.","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"The request is malformed.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"No token, or it expired.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Missing scope, or not from an allowed address.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Over the rate limit; see Retry-After.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/batches/{id}/cancel":{"post":{"security":[{"bearer":["batches:write"]}],"tags":["Batches"],"summary":"Withdraw a batch you uploaded, before it is approved","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","pattern":"^BT-\\d+$"},"example":"BT-0007"}],"responses":{"200":{"description":"Cancelled.","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"The request is malformed.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"No token, or it expired.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Missing scope, or not from an allowed address.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Too late, or not yours.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Over the rate limit; see Retry-After.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/connections":{"post":{"security":[{"bearer":["connections:write"]}],"tags":["Connections"],"summary":"Invite a person to link their wallet to your record","parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["reference"],"properties":{"reference":{"type":"string","pattern":"^[A-Za-z0-9._:-]{1,64}$"},"purpose":{"type":"string","maxLength":120}}}}}},"responses":{"201":{"description":"Send `url` to the person yourself.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Connection"}}}},"400":{"description":"The request is malformed.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"No token, or it expired.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Missing scope, or not from an allowed address.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Not made.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Over the rate limit; see Retry-After.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"get":{"security":[{"bearer":["connections:write"]}],"tags":["Connections"],"summary":"Your invitations","parameters":[{"name":"reference","in":"query","schema":{"type":"string"}},{"name":"status","in":"query","schema":{"enum":["pending","accepted","declined","expired"]}}],"responses":{"200":{"description":"Invitations.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Connection"}}}}}}},"400":{"description":"The request is malformed.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"No token, or it expired.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Missing scope, or not from an allowed address.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Over the rate limit; see Retry-After.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/connections/{id}":{"get":{"security":[{"bearer":["connections:write"]}],"tags":["Connections"],"summary":"One invitation","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","pattern":"^CN-\\d+$"},"example":"CN-0012"}],"responses":{"200":{"description":"The invitation.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Connection"}}}},"400":{"description":"The request is malformed.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"No token, or it expired.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Missing scope, or not from an allowed address.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"No such invitation.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Over the rate limit; see Retry-After.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/proof-templates":{"get":{"security":[{"bearer":["proofs:write"]}],"tags":["Proofs"],"summary":"Your network-reviewed proof templates","responses":{"200":{"description":"Templates.","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"The request is malformed.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"No token, or it expired.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Missing scope, or not from an allowed address.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Over the rate limit; see Retry-After.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/proof-requests":{"post":{"security":[{"bearer":["proofs:write"]}],"tags":["Proofs"],"summary":"Ask a person for proof","parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["template"],"properties":{"template":{"type":"string"}}}}}},"responses":{"201":{"description":"Show `wallet_url` as a QR code, or send it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProofRequest"}}}},"400":{"description":"The request is malformed.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"No token, or it expired.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Missing scope, or not from an allowed address.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Not asked.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Over the rate limit; see Retry-After.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"get":{"security":[{"bearer":["proofs:read"]}],"tags":["Proofs"],"summary":"Your latest proof requests","parameters":[{"name":"status","in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":"Requests.","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"The request is malformed.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"No token, or it expired.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Missing scope, or not from an allowed address.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Over the rate limit; see Retry-After.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/proof-requests/{id}":{"get":{"security":[{"bearer":["proofs:read"]}],"tags":["Proofs"],"summary":"A result. What the person chose to reveal is included for 24 hours, then deleted.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","pattern":"^PR-\\d+$"},"example":"PR-00042"}],"responses":{"200":{"description":"The result.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProofRequest"}}}},"400":{"description":"The request is malformed.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"No token, or it expired.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Missing scope, or not from an allowed address.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"No such request.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Over the rate limit; see Retry-After.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/proof-requests/{id}/recheck":{"post":{"security":[{"bearer":["proofs:write"]}],"tags":["Proofs"],"summary":"Check a result again against today's ledger (free)","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","pattern":"^PR-\\d+$"},"example":"PR-00042"}],"responses":{"200":{"description":"Re-checked; a new receipt.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProofRequest"}}}},"400":{"description":"The request is malformed.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"No token, or it expired.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Missing scope, or not from an allowed address.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Not re-checked.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Over the rate limit; see Retry-After.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/proof-requests/{id}/cancel":{"post":{"security":[{"bearer":["proofs:write"]}],"tags":["Proofs"],"summary":"Withdraw a request nobody answered","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","pattern":"^PR-\\d+$"},"example":"PR-00042"}],"responses":{"200":{"description":"Withdrawn.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProofRequest"}}}},"400":{"description":"The request is malformed.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"No token, or it expired.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Missing scope, or not from an allowed address.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Already answered.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Over the rate limit; see Retry-After.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/webhooks":{"get":{"security":[{"bearer":["webhooks:manage"]}],"tags":["Webhooks"],"summary":"Your endpoints","responses":{"200":{"description":"Endpoints.","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"The request is malformed.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"No token, or it expired.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Missing scope, or not from an allowed address.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Over the rate limit; see Retry-After.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"post":{"security":[{"bearer":["webhooks:manage"]}],"tags":["Webhooks"],"summary":"Add an endpoint (public HTTPS only)","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["url","events"],"properties":{"url":{"type":"string","format":"uri"},"events":{"type":"array","items":{"enum":["request.submitted","request.approved","request.rejected","credential.signed","credential.revoked","connection.accepted","connection.declined","batch.validated","batch.completed","proof.completed","ping"]}}}}}}},"responses":{"201":{"description":"Added. `signing_secret` is shown only once.","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"The request is malformed.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"No token, or it expired.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Missing scope, or not from an allowed address.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Not added.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Over the rate limit; see Retry-After.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/webhooks/{id}/test":{"post":{"security":[{"bearer":["webhooks:manage"]}],"tags":["Webhooks"],"summary":"Send a test message","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","pattern":"^WH-\\d+$"},"example":"WH-0003"}],"responses":{"202":{"description":"On its way.","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"The request is malformed.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"No token, or it expired.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Missing scope, or not from an allowed address.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Over the rate limit; see Retry-After.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/sandbox/wallets":{"post":{"security":[{"bearer":[]}],"tags":["Sandbox"],"summary":"Make a test wallet (testnet only)","responses":{"201":{"description":"A test wallet.","content":{"application/json":{"schema":{"type":"object","properties":{"holder_ref":{"type":"string"},"wallet_secret":{"type":"string"}}}}}},"400":{"description":"The request is malformed.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"No token, or it expired.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Missing scope, or not from an allowed address.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Over the rate limit; see Retry-After.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/sandbox/proof-requests/{id}/decline":{"post":{"security":[{"bearer":["proofs:write"]}],"tags":["Sandbox"],"summary":"A test wallet declines your request (testnet only)","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","pattern":"^PR-\\d+$"},"example":"PR-00042"}],"responses":{"200":{"description":"Declined.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProofRequest"}}}},"400":{"description":"The request is malformed.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"No token, or it expired.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Missing scope, or not from an allowed address.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Over the rate limit; see Retry-After.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}}},"webhooks":{"request.submitted":{"post":{"summary":"request.submitted","description":"Signed: check the TrustChain-Signature header (t=<seconds>,v1=<hex HMAC-SHA256 of \"t.body\">) with your endpoint secret, and refuse anything older than 5 minutes. Answer 2xx within 10 seconds; failures are retried for a day.","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Event"}}}},"responses":{"200":{"description":"Received."}}}},"request.approved":{"post":{"summary":"request.approved","description":"Signed: check the TrustChain-Signature header (t=<seconds>,v1=<hex HMAC-SHA256 of \"t.body\">) with your endpoint secret, and refuse anything older than 5 minutes. Answer 2xx within 10 seconds; failures are retried for a day.","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Event"}}}},"responses":{"200":{"description":"Received."}}}},"request.rejected":{"post":{"summary":"request.rejected","description":"Signed: check the TrustChain-Signature header (t=<seconds>,v1=<hex HMAC-SHA256 of \"t.body\">) with your endpoint secret, and refuse anything older than 5 minutes. Answer 2xx within 10 seconds; failures are retried for a day.","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Event"}}}},"responses":{"200":{"description":"Received."}}}},"credential.signed":{"post":{"summary":"credential.signed","description":"Signed: check the TrustChain-Signature header (t=<seconds>,v1=<hex HMAC-SHA256 of \"t.body\">) with your endpoint secret, and refuse anything older than 5 minutes. Answer 2xx within 10 seconds; failures are retried for a day.","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Event"}}}},"responses":{"200":{"description":"Received."}}}},"credential.revoked":{"post":{"summary":"credential.revoked","description":"Signed: check the TrustChain-Signature header (t=<seconds>,v1=<hex HMAC-SHA256 of \"t.body\">) with your endpoint secret, and refuse anything older than 5 minutes. Answer 2xx within 10 seconds; failures are retried for a day.","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Event"}}}},"responses":{"200":{"description":"Received."}}}},"connection.accepted":{"post":{"summary":"connection.accepted","description":"Signed: check the TrustChain-Signature header (t=<seconds>,v1=<hex HMAC-SHA256 of \"t.body\">) with your endpoint secret, and refuse anything older than 5 minutes. Answer 2xx within 10 seconds; failures are retried for a day.","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Event"}}}},"responses":{"200":{"description":"Received."}}}},"connection.declined":{"post":{"summary":"connection.declined","description":"Signed: check the TrustChain-Signature header (t=<seconds>,v1=<hex HMAC-SHA256 of \"t.body\">) with your endpoint secret, and refuse anything older than 5 minutes. Answer 2xx within 10 seconds; failures are retried for a day.","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Event"}}}},"responses":{"200":{"description":"Received."}}}},"batch.validated":{"post":{"summary":"batch.validated","description":"Signed: check the TrustChain-Signature header (t=<seconds>,v1=<hex HMAC-SHA256 of \"t.body\">) with your endpoint secret, and refuse anything older than 5 minutes. Answer 2xx within 10 seconds; failures are retried for a day.","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Event"}}}},"responses":{"200":{"description":"Received."}}}},"batch.completed":{"post":{"summary":"batch.completed","description":"Signed: check the TrustChain-Signature header (t=<seconds>,v1=<hex HMAC-SHA256 of \"t.body\">) with your endpoint secret, and refuse anything older than 5 minutes. Answer 2xx within 10 seconds; failures are retried for a day.","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Event"}}}},"responses":{"200":{"description":"Received."}}}},"proof.completed":{"post":{"summary":"proof.completed","description":"Signed: check the TrustChain-Signature header (t=<seconds>,v1=<hex HMAC-SHA256 of \"t.body\">) with your endpoint secret, and refuse anything older than 5 minutes. Answer 2xx within 10 seconds; failures are retried for a day.","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Event"}}}},"responses":{"200":{"description":"Received."}}}},"ping":{"post":{"summary":"ping","description":"Signed: check the TrustChain-Signature header (t=<seconds>,v1=<hex HMAC-SHA256 of \"t.body\">) with your endpoint secret, and refuse anything older than 5 minutes. Answer 2xx within 10 seconds; failures are retried for a day.","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Event"}}}},"responses":{"200":{"description":"Received."}}}}},"components":{"securitySchemes":{"bearer":{"type":"oauth2","flows":{"clientCredentials":{"tokenUrl":"https://sandbox-api.ssi-trustchain.com/api/v1/oauth/token","scopes":{"templates:read":"Read credential templates","credentials:draft":"Draft credentials for people to approve","requests:read":"Read the status of drafts and signed credentials","connections:write":"Invite people to link their wallet","batches:write":"Upload batches for people to approve","batches:read":"Read batch progress and results","proofs:write":"Ask people for proof, from approved templates","proofs:read":"Read proof results","webhooks:manage":"Manage webhook endpoints"}}}}},"parameters":{"IdempotencyKey":{"name":"Idempotency-Key","in":"header","required":true,"description":"Unique per request (8 to 100 letters, digits, - or _). A retry with the same key and body gets the first answer (header Idempotent-Replayed: true); kept 24 hours.","schema":{"type":"string","pattern":"^[\\w-]{8,100}$"}}},"schemas":{"Problem":{"type":"object","description":"RFC 9457 problem details.","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"required_scope":{"type":"string"}}},"OAuthError":{"type":"object","properties":{"error":{"type":"string"},"error_description":{"type":"string"}}},"TokenRequest":{"type":"object","required":["grant_type"],"properties":{"grant_type":{"const":"client_credentials"},"client_assertion_type":{"const":"urn:ietf:params:oauth:client-assertion-type:jwt-bearer"},"client_assertion":{"type":"string"},"client_id":{"type":"string","description":"Testnet secrets only."},"client_secret":{"type":"string","description":"Testnet only."}}},"Token":{"type":"object","properties":{"access_token":{"type":"string"},"token_type":{"const":"Bearer"},"expires_in":{"const":900},"scope":{"type":"string"}}},"Template":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"category":{"type":"string"},"claims":{"type":"array","items":{"type":"string"}},"approvals_needed":{"type":"integer"},"journey":{"type":"boolean"},"drafting_by_api":{"type":"boolean"}}},"DraftRequest":{"type":"object","required":["template","holder_ref","claims"],"properties":{"template":{"type":"string"},"holder_ref":{"type":"string","pattern":"^HX-\\d+$"},"reference":{"type":"string","pattern":"^[A-Za-z0-9._:-]{1,64}$","description":"Your record number. Never a name or ID number."},"claims":{"type":"object","additionalProperties":{"type":"string"}},"submit":{"type":"boolean","default":true}}},"Request":{"type":"object","properties":{"request":{"type":"string"},"reference":{"type":["string","null"]},"template":{"type":"string"},"holder_ref":{"type":"string"},"status":{"enum":["draft","in_approval","issued","rejected"]},"approvals":{"type":"integer"},"credential_id":{"type":["string","null"]},"rejection_reason":{"type":["string","null"]}}},"BatchUpload":{"type":"object","required":["name","template","rows"],"properties":{"name":{"type":"string"},"template":{"type":"string"},"reference":{"type":"string"},"rows":{"type":"array","maxItems":10000,"items":{"type":"object","properties":{"holder_ref":{"type":"string"},"connection":{"type":"string"},"reference":{"type":"string"},"claims":{"type":"object","additionalProperties":{"type":"string"}}}}}}},"Batch":{"type":"object","properties":{"batch":{"type":"string"},"status":{"enum":["needs_fixing","awaiting_approval","signing","completed","rejected","cancelled","expired"]},"total":{"type":"integer"},"invalid":{"type":"integer"},"errors":{"type":"array","items":{"type":"object","properties":{"row":{"type":"integer"},"field":{"type":"string"},"message":{"type":"string"}}}},"signed":{"type":"integer"},"failed":{"type":"integer"},"progress":{"type":"integer"}}},"Connection":{"type":"object","properties":{"connection":{"type":"string"},"reference":{"type":"string"},"status":{"enum":["pending","accepted","declined","expired"]},"holder_ref":{"type":["string","null"]},"url":{"type":"string","description":"Only when made."},"expires_at":{"type":"string"}}},"ProofRequest":{"type":"object","properties":{"request":{"type":"string"},"status":{"type":"string"},"wallet_url":{"type":"string"},"outcome":{"enum":["verified","not_verified","declined",null]},"receipt":{"type":["string","null"]},"checks":{"type":"array","items":{"type":"object"}},"revealed":{"type":"array","items":{"type":"object"},"description":"GET only, for 24 hours."}}},"Event":{"type":"object","properties":{"id":{"type":"string"},"type":{"enum":["request.submitted","request.approved","request.rejected","credential.signed","credential.revoked","connection.accepted","connection.declined","batch.validated","batch.completed","proof.completed","ping"]},"created_at":{"type":"string"},"network":{"enum":["testnet","mainnet"]},"organisation":{"type":"string"},"data":{"type":"object"}}},"Status":{"type":"object","properties":{"status":{"enum":["operational","degraded","outage"]},"network":{"type":"string"},"components":{"type":"array","items":{"type":"object"}},"uptime":{"type":"object"}}}}},"x-rate-limits":{"testnet":300,"mainnet":1200}}