API reference

The ZadQ API is plain HTTPS with JSON bodies at https://api.zadq.net. This page is generated at build time from the service's OpenAPI contract, so every operation, parameter and schema below is the contract itself, rendered.

The verification path is free and public: it needs no account and no credential. Every integration keeps working when no verdict is available — the answer is unknown, and what to do with it stays the caller's decision.

Quickstart

Each operation in the reference carries a ready-to-run curl example; the three calls below are the ones most integrations start with. Values in angle brackets are placeholders to replace with your own.

1. Read the substrate status. Public, no credential: whether the identity substrate behind the verdicts is ok, degraded or unknown, and when a standing read last succeeded.

curl -sS "https://api.zadq.net/v0/status" -H "Accept: application/json"

2. Verify a seller endpoint. The free verification path: the current signed verdict for an x402 endpoint, or an explicit no-signal outcome. No account, no credential, never charged.

curl -sS "https://api.zadq.net/v0/verifications?chain=base&payTo=<wallet-address>&resourceUrl=<endpoint-url>" \
  -H "Accept: application/json"

Signatures verify locally against the published keys at https://api.zadq.net/v0/verification-keys.

3. Prove the wallet for a payTo write. The dashboard runs under an account: the responsible person signs in with a passkey at https://zadq.app, and that session carries every read and write of the account. The wallet that controls a payTo address is bound to the account and signs only the writes that touch that address (registering an endpoint on it, acknowledging the terms, rotating to a new wallet). For those, request a challenge for the address, sign it with the wallet and redeem the signature for a short-lived session credential, which rides as a bearer beside the passkey session. On its own it opens nothing: the wallet is never a login.

curl -sS -X POST "https://api.zadq.net/v0/auth/challenge" \
  -H "Content-Type: application/json" \
  -d '{"chain":"base","address":"<wallet-address>"}'

curl -sS -X POST "https://api.zadq.net/v0/auth/session" \
  -H "Content-Type: application/json" \
  -d '{"chain":"base","address":"<wallet-address>","nonce":"<challenge-nonce>","signature":"<wallet-signature>"}'

The exact request and response bodies of every call are in the reference below (AuthChallengeRequest, AuthSessionRequest, Verdict). The reference renders the service's v0 contract. The account's routes are not part of it yet; the calls a runtime makes are listed on the agent operators page.

Overview

FieldValue
ContractSeller-Verification Service API
Version0.1.0
SpecificationOpenAPI 3.0.3

v0 seller-verification API: seller intake, admission state, attestation issuance metadata, and the free verification path.

The free verification path is never charged for, to anyone, ever.

Graceful degradation: consumers must treat an unreachable service or an absent verdict as "no signal", never as a failure of their own flow.

MintID unreachable at start-up (ZADQ-407): a deployment whose MintID ids are discovered at start-up (never production, where they are configuration) serves while MintID does not answer. /healthz stays 200 and names mintid: discovering; the free path and every route that reads this service's own records are served; the routes that reach MintID synchronously — the issuer's KYC sessions (POST /v0/sellers, the kyc/sessions, kyc/result and consent-withdrawal routes of /v0 and /v1), the attestations and credential offers it issues, the agent mints, renewals and revocations (/v0 agent routes, POST /v1/enrolments/{id}/offer and /mint, POST /v1/agents/{id}/renewals and /stop) — answer 503 mintid_unavailable with Retry-After: 60 (the /v1 envelope's error, the /v0 problem's title), nothing recorded. Discovery is retried in the background; mintid: ready once it succeeds, and the same routes answer as usual.

Authentication

Operations name the schemes they accept; an operation marked as public takes no credential at all.

walletSession

HTTP header Authorization: Bearer <credential>.

Session bearer from POST /v0/auth/session (wallet-proven payTo). Since ZADQ-287 the wallet is no longer a login: a wallet session alone may register the account's first passkey and nothing else (403 passkey required); inside a passkey session it is the signature every write touching that payTo re-signs with (ADR-0015).

passkeySession

API key in the cookie __Host-passkey_session.

The passkey session (ZADQ-287; platform API v1 §4): set after a WebAuthn registration or sign-in, same site, HttpOnly, Secure, short lived (30 minutes idle) and renewed on use, at most 12 hours. On a development host (localhost) the cookie is named passkey_session and is not Secure.

runtimeCredential

HTTP header Authorization: Bearer <credential>.

The runtime credential (the contract's runtime_token; ZADQ-289, issued at claim by ZADQ-288): Authorization: Bearer <runtime_token>, scoped to one enrolment and, once registered, to that agent's runtime for its present approvals; random, hashed at rest, revocable. 401 runtime_token_invalid when unknown, revoked or expired.

Other operations

POST /v0/auth/challenge

Wallet signature, step 1 — challenge for a payTo address

Returns a one-time message for the payment wallet to sign (EVM personal_sign or Solana message signing). Since ZADQ-287 the wallet signature is the binding of a payTo (ADR-0015), not a login: the dashboard's session is the passkey (/v1/auth/passkeys). No personal data. Challenges expire after 5 minutes.

Authentication: none — this operation is public.

Request body

application/json — required

Schema: AuthChallengeRequest

PropertyTypeRequiredDescriptionValues
chainChainyes
addressstringyes

Responses

201 — Challenge issued.

Content type application/json.

Schema: AuthChallenge

PropertyTypeRequiredDescriptionValues
noncestringyes
messagestringyesExact text to sign, byte for byte.
expiresAtstring (date-time)yes

default — RFC 9457 problem details.

Content type application/problem+json.

Schema: Problem

PropertyTypeRequiredDescriptionValues
typestringno
titlestringno
statusintegerno
detailstringno
instancestringno

Example

curl -sS -X POST "<base-url>/v0/auth/challenge" \
  -H "Content-Type: application/json" \
  -d @request-body.json

POST /v0/auth/session

Wallet signature, step 2 — redeem the signed challenge for the payTo's bearer

Verifies the wallet signature over the challenge message and returns a bearer credential bound to {chain, address} (12 h). Send it as Authorization: Bearer <bearer> on the operations that write a payTo (ADR-0015): the wallet proves control of the address, it is not the dashboard's login and carries no account or personal data — the session is the passkey (/v1/auth/passkeys, platform API v1 §4). The challenge and this redemption are served by the service on every host that reaches it (the API host; the app host's /v0/* once its path behaviour is on), and the bearer is a header, so a payTo write under the passkey session sends both the cookie and the bearer (platform API v1.3 §5.9). With the passkey release switch on (ZADQ-287): a wallet whose account has no passkey yet gets the migration bearer, which may register the account's first passkey and nothing else; a wallet whose account has a passkey gets a bearer only inside that account's passkey session (the re-signature of a payTo write) — without it, 403 "wallet login retired".

Authentication: none — this operation is public.

Request body

application/json — required

Schema: AuthSessionRequest

PropertyTypeRequiredDescriptionValues
chainChainyes
addressstringyes
noncestringyes
signaturestringyesEVM — 0x-hex r||s||v from personal_sign; Solana — base58 (or hex) 64-byte signature.

Responses

201 — Session issued.

Content type application/json.

Schema: AuthSession

PropertyTypeRequiredDescriptionValues
bearerstringyesOpaque session credential for the Authorization header.
expiresAtstring (date-time)yes
chainChainyes
addressstringyes

default — RFC 9457 problem details.

Content type application/problem+json.

Schema: Problem

PropertyTypeRequiredDescriptionValues
typestringno
titlestringno
statusintegerno
detailstringno
instancestringno

Example

curl -sS -X POST "<base-url>/v0/auth/session" \
  -H "Content-Type: application/json" \
  -d @request-body.json

GET /healthz

Liveness probe

200 whenever the process serves, MintID reachable or not (the load balancer's health check); mintid says whether the MintID ids are known (ZADQ-407).

Authentication: none — this operation is public.

Responses

200 — Service is up.

Content type application/json.

Schema: Health

PropertyTypeRequiredDescriptionValues
statusstringyes"ok"
versionstringno
mintidstringnoThe readiness of this deployment's MintID ids (ZADQ-407): discovering while MintID was unreachable at start-up and the ids are retried in the background (the MintID-dependent routes answer 503 mintid_unavailable), ready otherwise. The probe answers 200 either way."discovering", "ready"

Example

curl -sS "<base-url>/healthz"

GET /v0/status

Substrate status (public)

What an explorer or a seller can check before asking: whether the identity substrate behind the verdicts is ok, degraded or unknown, when a standing read last succeeded, and the cadence promise. Read from the verifier's own status contract when wired (source: verifier); otherwise inferred from the cadence — degraded only after three consecutive cycles in which every attestation was withheld, never from a single unknown (source: cadence). No credentials, no identifiers, nothing personal (ZADQ-70). While the substrate is degraded every integration keeps working: verdicts read no_signal, badges read unknown, nothing blocks.

Authentication: none — this operation is public.

Responses

200 — The substrate's state as this service sees it.

Content type application/json.

Schema: SubstrateStatus

PropertyTypeRequiredDescriptionValues
substratestringyes"ok", "degraded", "unknown"
sourcestringyesWhere the state comes from — the verifier's status read, or this service's cadence accounting."verifier", "cadence"
reasonstringnoWhy the substrate is not ok, in the verifier's standing vocabulary (for example height_stale, root_expired, state_unavailable). Absent when ok.
checkedAtstring (date-time)yes
lastSuccessfulStandingReadstring (date-time)noThe last time a standing read answered with a known status. Absent before the first.
cadenceobjectyes
cadence.recheckEveryHoursintegeryesThe published cadence promise.
cadence.lastCycleAtstring (date-time)no
cadence.checkedintegernoAttestations the last cycle asked the verifier about.
cadence.withheldintegernoOf those, how many came back with an unknown standing.

Example

curl -sS "<base-url>/v0/status"

POST /v0/interest

Register interest (public web form target)

The target of the native HTML form on the public web's register-interest page (ZADQ-103): a vendor or an agent operator says which side of the trust perimeter it is on, optionally the x402 resource URL it sells at or the size band of its fleet, and nothing else. No contact data is accepted or stored here — the person sends their address through the mailbox from the page the browser is sent back to. Submissions are counted by side for the funnel; the optional details are cleared after twelve months, the count stays.

Answers with a redirect to the public web in every case, so a browser without scripts lands on a page: the "received" page (with the side as the fragment) on success, the "not received" page when the input is invalid, when the client is over its rate limit (a few submissions per client per ten minutes, and a global bound), or when storage fails. The page reached always shows the mailbox route, so nothing a person can do depends on this service being up. The field named website is a trap for automated submitters: when it carries a value the submission is dropped and the browser still lands on the "received" page.

Authentication: none — this operation is public.

Request body

application/x-www-form-urlencoded — required

Schema: InterestForm

PropertyTypeRequiredDescriptionValues
sidestringyesWhich side of the trust perimeter the person stands on."vendor", "agent_operator"
resource_urlstring (uri)noThe x402 resource URL a vendor sells at (optional, vendors).
agent_count_bandstringnoThe size band of an operator's fleet (optional, agent operators)."up_to_10", "up_to_100", "more_than_100"
sourcestringnoThe page family the form was reached from (optional; a hidden field rendered at build time, ZADQ-160). An unknown value is dropped, not refused."home", "seller", "agent", "plans", "industries", "trust_about", "docs", "blog", "legal", "metrics"
websitestringnoTrap field for automated submitters; a person leaves it empty.

Responses

303 — The browser is sent back to the public web.

Example

curl -sS -X POST "<base-url>/v0/interest" \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d @request-body.json

POST /v0/sellers

Seller intake (onboarding flow 1)

Registers a seller's x402 identifiers and segment declaration and opens a KYC session at the issuer-side KYC boundary. No identity data is accepted here. Requires a wallet session for the intake payTo address (401/403 otherwise): control of the address is proven from the first minute. 409 when the endpoint (chain, payTo, resource URL) is already registered: the problem's instance is the existing record's route (/v0/sellers/{sellerId}), the returning customer's way back. 501 kyb_not_available when the operator type is organisation: there is no business verification (KYB) in this phase — an organisation is declared by its responsible person, not verified, and the issuer answers 501 on this deployment; nothing is recorded, the same endpoint can register later (ZADQ-192). A person acting for a company registers as person and declares the company (PUT /v1/organisation). biometric_consent: {version} is required (ZADQ-331): the consent to the face comparison the person gave on ZadQ's page before the verification link opens — 409 biometric_consent_required when absent, 409 biometric_consent_version_stale (the current label in the detail) when it is not the deployment's label; refused, nothing is registered and nothing reaches the issuer. Accepted, the consent is recorded with the session the intake opened.

Authentication: walletSession.

Request body

application/json — required

Schema: SellerIntake

PropertyTypeRequiredDescriptionValues
payToPayToyes
resourceUrlstring (uri)yes
operatorTypestringyes"person", "organisation"
segmentSegmentDeclarationyes
kycSandboxHintKycSandboxHintno
biometric_consentBiometricConsentGivenno

Responses

201 — Seller registered; KYC session opened.

Content type application/json.

Schema: Seller

PropertyTypeRequiredDescriptionValues
idstringyes
payToPayToyes
resourceUrlstring (uri)yes
operatorTypestringyes"person", "organisation"
statestringyeskyc_expired: the proofing session ran past its deadline without an outcome; a new session can be opened (POST …/kyc/sessions). withdrawn: consent to the service withdrawn — terminal."pending_kyc", "kyc_expired", "admitted", "rejected", "withdrawn"
billingstringyesBilling state at the operator's billing provider (ZADQ-54): none until the provider's signed checkout.session.completed lands, active afterwards; back to none on customer.subscription.deleted. Opening a checkout session records nothing (ZADQ-221). The service holds no legal or payment data."none", "active"
billingTierstringnoThe schedule tier, by name, as the provider's completed event carried it from the session's metadata. Absent until billing is active (ZADQ-221)."attested_vendor", "regulated_compliance"
billingCadencestringnoHow the minimum is billed, as the provider's completed event carried it from the session's metadata (ZADQ-230). Absent until billing is active; a record active before cadences existed reads annual."monthly", "annual"
kycSessionIdstringnoOpaque session handle at the KYC boundary. Not identity data.
kycKycHandoffno
credentialCredentialStateno
depositDepositno
renewalall of KycHandoffnoThe pending re-verification session, while one is open (ZADQ-91): the person completes it on handoffUrl; the approved session in kyc keeps backing the attestation meanwhile.
attestationAttestationno
createdAtstring (date-time)yes

default — RFC 9457 problem details.

Content type application/problem+json.

Schema: Problem

PropertyTypeRequiredDescriptionValues
typestringno
titlestringno
statusintegerno
detailstringno
instancestringno

Example

curl -sS -X POST "<base-url>/v0/sellers" \
  -H "Authorization: Bearer <session-credential>" \
  -H "Content-Type: application/json" \
  -d @request-body.json

GET /v0/sellers/{sellerId}

Seller state (admission, attestation, billing)

Wallet-bound since ZADQ-130: the record (KYC hand-off, billing, credential) is the seller's own, so the read requires the wallet session of this seller's payTo (401 without a session, 403 for another wallet). The free path is the verdict (GET /v0/sellers/{sellerId}/verdict) and GET /v0/verifications.

Authentication: walletSession.

Parameters

NameInRequiredTypeDescription
sellerIdpathyesstring

Responses

200 — Current seller state.

Content type application/json.

Schema: Seller

PropertyTypeRequiredDescriptionValues
idstringyes
payToPayToyes
resourceUrlstring (uri)yes
operatorTypestringyes"person", "organisation"
statestringyeskyc_expired: the proofing session ran past its deadline without an outcome; a new session can be opened (POST …/kyc/sessions). withdrawn: consent to the service withdrawn — terminal."pending_kyc", "kyc_expired", "admitted", "rejected", "withdrawn"
billingstringyesBilling state at the operator's billing provider (ZADQ-54): none until the provider's signed checkout.session.completed lands, active afterwards; back to none on customer.subscription.deleted. Opening a checkout session records nothing (ZADQ-221). The service holds no legal or payment data."none", "active"
billingTierstringnoThe schedule tier, by name, as the provider's completed event carried it from the session's metadata. Absent until billing is active (ZADQ-221)."attested_vendor", "regulated_compliance"
billingCadencestringnoHow the minimum is billed, as the provider's completed event carried it from the session's metadata (ZADQ-230). Absent until billing is active; a record active before cadences existed reads annual."monthly", "annual"
kycSessionIdstringnoOpaque session handle at the KYC boundary. Not identity data.
kycKycHandoffno
credentialCredentialStateno
depositDepositno
renewalall of KycHandoffnoThe pending re-verification session, while one is open (ZADQ-91): the person completes it on handoffUrl; the approved session in kyc keeps backing the attestation meanwhile.
attestationAttestationno
createdAtstring (date-time)yes

default — RFC 9457 problem details.

Content type application/problem+json.

Schema: Problem

PropertyTypeRequiredDescriptionValues
typestringno
titlestringno
statusintegerno
detailstringno
instancestringno

Example

curl -sS "<base-url>/v0/sellers/<sellerId>" \
  -H "Authorization: Bearer <session-credential>"

GET /v0/sellers/{sellerId}/billing

The vendor's billing lines and usage statement (ZADQ-470)

Platform API v1.3.31 (ZADQ-470; Platform Decision 10's vendor lines, built on Marc's decision of 2026-11-07). What the operator group of this seller record is billed beside its tier, for the seller dashboard's billing screen: the tier and cadence of the group's billing; the entry fee — paid once per operator group at the tier's checkout (Attested Vendor €400, Regulated / Compliance €1,500, net, not credited), and what a checkout of each tier would charge now (a higher tier charges the difference — confirmed by Marc on 2026-11-08, v1.3.32; a lower one nothing); the endpoints — the group's admitted endpoint records against the tier's included ones (3 / 10) and the additional-endpoint item on the subscription (its quantity and one endpoint's price for the period); and the usage fee's monthly statements — the meter's closes (0.75 % of each covered settlement received, capped at USD 0.40, converted at the ECB rule, credited against the minimum), shown whether or not the fee is invoiced (usage_fee.invoicing: off until the counsel items of Platform Decision 15, Marc's gate; v1.3.32: on, each billable month is invoiced at the close on a monthly invoice of its own, every cadence, its id the statement's invoice_ref). Amounts in minor units, net (the provider adds the VAT). Requires the wallet session of this seller's payTo (401/403), as the operator's endpoints read.

Authentication: walletSession.

Parameters

NameInRequiredTypeDescription
sellerIdpathyesstring

Responses

200 — The vendor's billing lines.

Content type application/json.

Schema: VendorBilling

PropertyTypeRequiredDescriptionValues
seller_idstringyesThe seller record asked about.
billing_seller_idstring, nullablenoThe operator group's seller record whose billing is active (the oldest); null when none.
billingstringyesThe group's billing state."none", "active"
tierstring, nullableno"attested_vendor", "regulated_compliance"
cadencestring, nullableno"monthly", "annual"
entry_feeVendorEntryFeeyes
endpointsVendorEndpointsyes
usage_feeVendorUsageFeeyes

default — RFC 9457 problem details.

Content type application/problem+json.

Schema: Problem

PropertyTypeRequiredDescriptionValues
typestringno
titlestringno
statusintegerno
detailstringno
instancestringno

Example

curl -sS "<base-url>/v0/sellers/<sellerId>/billing" \
  -H "Authorization: Bearer <session-credential>"

GET /v0/sellers/{sellerId}/endpoints

The endpoints of this seller's operator

Every endpoint the same accountable operator registered on its approved verification (ZADQ-53). Requires the wallet session of this seller's payTo (401/403): the grouping is never a public read, so an operator's endpoints stay uncorrelatable to third parties.

Authentication: walletSession.

Parameters

NameInRequiredTypeDescription
sellerIdpathyesstring

Responses

200 — The operator's endpoints, oldest first.

Content type application/json.

Schema: OperatorEndpoints

PropertyTypeRequiredDescriptionValues
endpointsarray of EndpointSummaryyes

default — RFC 9457 problem details.

Content type application/problem+json.

Schema: Problem

PropertyTypeRequiredDescriptionValues
typestringno
titlestringno
statusintegerno
detailstringno
instancestringno

Example

curl -sS "<base-url>/v0/sellers/<sellerId>/endpoints" \
  -H "Authorization: Bearer <session-credential>"

POST /v0/sellers/{sellerId}/endpoints

Add an endpoint on the operator's approved verification

Registers a further endpoint of the accountable operator behind this admitted seller, reusing its approved session inside the reuse window (ZADQ-53): no new KYC, the new seller reads admitted at once and can be attested. Requires the wallet session of this seller's payTo (401/403). When the new endpoint's payTo differs, proof must carry a signed auth challenge for the new address (POST /v0/auth/challenge for it, sign the message): control of every address is proven. 409 unless admitted with an open window (re-verify first), or when the endpoint already exists.

Authentication: walletSession.

Parameters

NameInRequiredTypeDescription
sellerIdpathyesstring

Request body

application/json — required

Schema: EndpointAddition

PropertyTypeRequiredDescriptionValues
resourceUrlstring (uri)yes
payToPayTono
proofAddressProofno

Responses

201 — The new seller, admitted on the shared verification.

Content type application/json.

Schema: Seller

PropertyTypeRequiredDescriptionValues
idstringyes
payToPayToyes
resourceUrlstring (uri)yes
operatorTypestringyes"person", "organisation"
statestringyeskyc_expired: the proofing session ran past its deadline without an outcome; a new session can be opened (POST …/kyc/sessions). withdrawn: consent to the service withdrawn — terminal."pending_kyc", "kyc_expired", "admitted", "rejected", "withdrawn"
billingstringyesBilling state at the operator's billing provider (ZADQ-54): none until the provider's signed checkout.session.completed lands, active afterwards; back to none on customer.subscription.deleted. Opening a checkout session records nothing (ZADQ-221). The service holds no legal or payment data."none", "active"
billingTierstringnoThe schedule tier, by name, as the provider's completed event carried it from the session's metadata. Absent until billing is active (ZADQ-221)."attested_vendor", "regulated_compliance"
billingCadencestringnoHow the minimum is billed, as the provider's completed event carried it from the session's metadata (ZADQ-230). Absent until billing is active; a record active before cadences existed reads annual."monthly", "annual"
kycSessionIdstringnoOpaque session handle at the KYC boundary. Not identity data.
kycKycHandoffno
credentialCredentialStateno
depositDepositno
renewalall of KycHandoffnoThe pending re-verification session, while one is open (ZADQ-91): the person completes it on handoffUrl; the approved session in kyc keeps backing the attestation meanwhile.
attestationAttestationno
createdAtstring (date-time)yes

default — RFC 9457 problem details.

Content type application/problem+json.

Schema: Problem

PropertyTypeRequiredDescriptionValues
typestringno
titlestringno
statusintegerno
detailstringno
instancestringno

Example

curl -sS -X POST "<base-url>/v0/sellers/<sellerId>/endpoints" \
  -H "Authorization: Bearer <session-credential>" \
  -H "Content-Type: application/json" \
  -d @request-body.json

POST /v0/sellers/{sellerId}/wallet

Rotate the payment wallet behind an attested endpoint

Changes this admitted seller's payTo address inside the approved session's reuse window (ZADQ-53): the attestation bound to the old identifiers is revoked upstream and a new one is issued for the new ones on the same verification — no new KYC. Requires the wallet session of the current payTo (401/403) and proof: a signed auth challenge for the new address. 409 unless admitted with an open window and acknowledged terms, or when the endpoint already exists.

Authentication: walletSession.

Parameters

NameInRequiredTypeDescription
sellerIdpathyesstring

Request body

application/json — required

Schema: WalletRotation

PropertyTypeRequiredDescriptionValues
payToPayToyes
proofAddressProofyes

Responses

200 — The seller on its new address, with the new attestation.

Content type application/json.

Schema: Seller

PropertyTypeRequiredDescriptionValues
idstringyes
payToPayToyes
resourceUrlstring (uri)yes
operatorTypestringyes"person", "organisation"
statestringyeskyc_expired: the proofing session ran past its deadline without an outcome; a new session can be opened (POST …/kyc/sessions). withdrawn: consent to the service withdrawn — terminal."pending_kyc", "kyc_expired", "admitted", "rejected", "withdrawn"
billingstringyesBilling state at the operator's billing provider (ZADQ-54): none until the provider's signed checkout.session.completed lands, active afterwards; back to none on customer.subscription.deleted. Opening a checkout session records nothing (ZADQ-221). The service holds no legal or payment data."none", "active"
billingTierstringnoThe schedule tier, by name, as the provider's completed event carried it from the session's metadata. Absent until billing is active (ZADQ-221)."attested_vendor", "regulated_compliance"
billingCadencestringnoHow the minimum is billed, as the provider's completed event carried it from the session's metadata (ZADQ-230). Absent until billing is active; a record active before cadences existed reads annual."monthly", "annual"
kycSessionIdstringnoOpaque session handle at the KYC boundary. Not identity data.
kycKycHandoffno
credentialCredentialStateno
depositDepositno
renewalall of KycHandoffnoThe pending re-verification session, while one is open (ZADQ-91): the person completes it on handoffUrl; the approved session in kyc keeps backing the attestation meanwhile.
attestationAttestationno
createdAtstring (date-time)yes

default — RFC 9457 problem details.

Content type application/problem+json.

Schema: Problem

PropertyTypeRequiredDescriptionValues
typestringno
titlestringno
statusintegerno
detailstringno
instancestringno

Example

curl -sS -X POST "<base-url>/v0/sellers/<sellerId>/wallet" \
  -H "Authorization: Bearer <session-credential>" \
  -H "Content-Type: application/json" \
  -d @request-body.json

POST /v0/sellers/{sellerId}/billing/checkout

Set up billing on the operator's hosted checkout

Opens the operator's hosted checkout page for this admitted seller, keyed by the seller id and the chosen tier only (ZADQ-54). The person enters legal and billing data there — none of it enters this service, which keeps the billing state, the tier name and an opaque customer reference. Opening the session records nothing (ZADQ-221): the record keeps billing: none and no tier until the provider's signed checkout.session.completed lands on POST /v0/billing/events, which sets active and the tier the session was opened for; a session the person abandons leaves the record as it was. Calling again opens a fresh session (the dashboard's "resume"). Requires the wallet session of the seller's payTo (401/403); 409 unless admitted, or while billing is already active. Manual bank transfer for the first contracts is agreed with us directly, outside the service.

v1.3.31 (ZADQ-470), where the deployment prices the vendor lines: the one session carries the tier's subscription, the entry fee due as a one-off line (once per operator group; a higher tier's checkout charges the difference) and, when the operator group holds more admitted endpoint records than the tier includes (3 / 10), the additional endpoints as a recurring line, quantity the endpoints above the quota. 409 while the operator's billing is active on another of its endpoint records (one billing per operator); 400 when endpoints above the quota have no price for the cadence chosen.

Authentication: walletSession.

Parameters

NameInRequiredTypeDescription
sellerIdpathyesstring

Request body

application/json — required

Schema: BillingCheckout

PropertyTypeRequiredDescriptionValues
tierstringyesThe schedule tier, by name. Amounts are on the checkout page and in the operator agreement."attested_vendor", "regulated_compliance"
cadencestringnoHow the tier's minimum is billed: monthly or annually (ZADQ-230). The cadence rides on the session's metadata like the tier and lands on the record with the provider's completed event. 400 when this deployment has no price for the cadence requested."monthly", "annual"

Responses

201 — The hosted checkout to open, and the seller's billing state.

Content type application/json.

Schema: BillingHandoff

PropertyTypeRequiredDescriptionValues
urlstring (uri)yesThe hosted checkout page — open it as-is.
billingstringyesThe record's billing state as the session opens — none, since opening a session records nothing (ZADQ-221). It moves to active with the provider's signed completed event, never here."none", "active"

default — RFC 9457 problem details.

Content type application/problem+json.

Schema: Problem

PropertyTypeRequiredDescriptionValues
typestringno
titlestringno
statusintegerno
detailstringno
instancestringno

Example

curl -sS -X POST "<base-url>/v0/sellers/<sellerId>/billing/checkout" \
  -H "Authorization: Bearer <session-credential>" \
  -H "Content-Type: application/json" \
  -d @request-body.json

POST /v0/billing/events

Billing provider event (signed)

Inbound event from the operator's billing provider, signed with the webhook secret (Stripe-Signature: t=<unix>,v1=<hmac-sha256>), applied once per event id. checkout.session.completed moves billing to active; checkout.session.expired and customer.subscription.deleted to none; anything else is acknowledged and ignored. The payload is read for its id, type, seller reference and customer reference only. 401 on a bad or stale signature.

Authentication: none — this operation is public.

Parameters

NameInRequiredTypeDescription
Stripe-Signatureheaderyesstring

Request body

application/json — required

Type: object.

Responses

200 — Acknowledged; whether the event changed a state.

Content type application/json.

Schema: BillingEventReceipt

PropertyTypeRequiredDescriptionValues
appliedbooleanyes

default — RFC 9457 problem details.

Content type application/problem+json.

Schema: Problem

PropertyTypeRequiredDescriptionValues
typestringno
titlestringno
statusintegerno
detailstringno
instancestringno

Example

curl -sS -X POST "<base-url>/v0/billing/events" \
  -H "Stripe-Signature: <Stripe-Signature>" \
  -H "Content-Type: application/json" \
  -d @request-body.json

POST /v0/sellers/{sellerId}/deposit/kyb

Guarantee deposit — open the holder's hosted verification

Opens the deposit holder's hosted verification of the vendor and returns the URL the person opens; the holder sends the person back to the dashboard afterwards. This service keeps the session id and its state only — no document or identity datum passes through it. By the wallet that owns payTo. 409 until the operator has linked the vendor's account at the holder, once the verification is validated, or while the deposit is being returned; 501 when no deposit holder is configured on this deployment.

Authentication: walletSession.

Parameters

NameInRequiredTypeDescription
sellerIdpathyesstring

Responses

201 — The hosted verification is open.

Content type application/json.

Schema: DepositKybHandoff

PropertyTypeRequiredDescriptionValues
urlstring (uri)yesThe holder's hosted verification page.

default — RFC 9457 problem details.

Content type application/problem+json.

Schema: Problem

PropertyTypeRequiredDescriptionValues
typestringno
titlestringno
statusintegerno
detailstringno
instancestringno

Example

curl -sS -X POST "<base-url>/v0/sellers/<sellerId>/deposit/kyb" \
  -H "Authorization: Bearer <session-credential>"

POST /v0/sellers/{sellerId}/deposit/pay-in

Guarantee deposit — bank-wire instructions for the missing part

Registers a bank-wire pay-in into the vendor's own wallet at the holder for the part of the level still missing, and relays the holder's collection details once: shown to the vendor, never stored. By the wallet that owns payTo. 409 before the verification is validated, while the level is met, or while the deposit is being returned; 501 when no deposit holder is configured.

Authentication: walletSession.

Parameters

NameInRequiredTypeDescription
sellerIdpathyesstring

Responses

201 — The pay-in is registered; wire with these details.

Content type application/json.

Schema: DepositPayInInstructions

PropertyTypeRequiredDescriptionValues
collectionAccountstringyesThe holder's collection account to wire to.
bankNamestringyes
bankCodestringyes
wireReferencestringyesMust travel with the wire so the holder credits the right wallet.
amountMinorinteger (int64)yes
currencystringyes

default — RFC 9457 problem details.

Content type application/problem+json.

Schema: Problem

PropertyTypeRequiredDescriptionValues
typestringno
titlestringno
statusintegerno
detailstringno
instancestringno

Example

curl -sS -X POST "<base-url>/v0/sellers/<sellerId>/deposit/pay-in" \
  -H "Authorization: Bearer <session-credential>"

GET /v0/deposit/hooks/{hookToken}

Deposit holder hook (a signal, never a fact)

The holder's notification: an unsigned GET naming an event type and a resource id, guarded by a secret path segment compared in constant time. Answered 200 at once whatever the event; a known event is a prompt to read the resource back from the holder — nothing in the query is trusted or recorded as a fact. Unknown events are acknowledged and ignored; a wrong path segment is 404.

Authentication: none — this operation is public.

Parameters

NameInRequiredTypeDescription
hookTokenpathyesstring
EventTypequerynostring
RessourceIdquerynostring
Datequerynostring

Responses

200 — Acknowledged.

default — RFC 9457 problem details.

Content type application/problem+json.

Schema: Problem

PropertyTypeRequiredDescriptionValues
typestringno
titlestringno
statusintegerno
detailstringno
instancestringno

Example

curl -sS "<base-url>/v0/deposit/hooks/<hookToken>"

POST /v0/sellers/{sellerId}/credential/offer

Hand out the v1 credential offer, once

Creates the v1 credential offer for this admitted seller from its approved verification (ZADQ-83) and hands it out exactly once, over the wallet session of the seller's payTo (401/403). The offer is a one-shot pre-authorized code the seller's own middleware redeems at once with the holder library, in the seller's own infrastructure: this service never stores or logs it, never sees the credential, a key or a proof — the dashboard shows state, never secrets. The code and the credential it yields expire exactly with the verification (no grace); past the window the issuer answers 409 and the seller re-verifies. 409 while a credential is already held or a re-verification is pending; 501 when the substrate offers no v1 credential rail.

Authentication: walletSession.

Parameters

NameInRequiredTypeDescription
sellerIdpathyesstring

Responses

201 — The offer, handed out once, and when it expires.

Content type application/json.

Schema: CredentialOfferHandoff

PropertyTypeRequiredDescriptionValues
offerobjectyesThe credential offer object, as the issuer returned it — opaque, one-shot; redeem it at once.
expiresAtstring (date-time)yesWhen the code and the credential it yields expire — the verification's own expiry at the latest. No grace.
credentialCredentialStateyes

default — RFC 9457 problem details.

Content type application/problem+json.

Schema: Problem

PropertyTypeRequiredDescriptionValues
typestringno
titlestringno
statusintegerno
detailstringno
instancestringno

Example

curl -sS -X POST "<base-url>/v0/sellers/<sellerId>/credential/offer" \
  -H "Authorization: Bearer <session-credential>"

POST /v0/sellers/{sellerId}/credential

Report the credential's state from the seller's infrastructure

The seller's middleware reports what it did with the offer: held (optionally with an opaque reference of the seller's choosing, and with the presentationUrl its holder answers this service's challenges at — that URL puts the seller on the v1 verdict path: on the cadence this service forwards its verifier's 10-second challenge there, byte for byte, and the verifier's decision on the holder's envelope governs the positive claim, ZADQ-84) or self_revoked (the holder revoked its own credential through the network's privacy relay; it stops presenting it at once and, within the network's published bound — 245 s from the moment the revocation is recorded — the credential presents nowhere, including any copy taken before; revoked is accepted as the older spelling of the same report; the presentation URL is cleared). Without a presentation URL the seller keeps the v0 standing path. Wallet session of the seller's payTo required (401/403). Nothing secret travels here; the reference is never a key, a code or a proof. presentationUrl must be an absolute https URL (http only to a loopback host, local development).

A self_revoked report is recorded as the state change on the seller's own record and nothing else: no event, no time, no log line, no notification — the reference, the hand-out time and the presentation URL are cleared. The consequence lands at the next verdict cadence, never at this moment: the v0 attestation is retired (statusReason: self_revoked) and the public verdict reads revoked from then on. The way back is a new verification (re-verify), which yields a fresh offer; another offer on the same verification answers 409.

Authentication: walletSession.

Parameters

NameInRequiredTypeDescription
sellerIdpathyesstring

Request body

application/json — required

Schema: CredentialReport

PropertyTypeRequiredDescriptionValues
statestringyesheld, or self_revoked (revoked is the older spelling of the same report)."held", "self_revoked", "revoked"
credentialRefstringnoAn opaque reference of the seller's choosing for the credential it holds. Never a key.
presentationUrlstring (uri)noWhere the seller's holder answers this service's challenges (ZADQ-84): POST of the issued challenge as the verifier returned it ({request, signature_hex}), 200 with the envelope ({proof_hex, issuer_id, status_root, claimed_predicates}); any other status means the holder cannot present this time. Only with held; kept when omitted on a later report.

Responses

200 — The seller with the reported credential state.

Content type application/json.

Schema: Seller

PropertyTypeRequiredDescriptionValues
idstringyes
payToPayToyes
resourceUrlstring (uri)yes
operatorTypestringyes"person", "organisation"
statestringyeskyc_expired: the proofing session ran past its deadline without an outcome; a new session can be opened (POST …/kyc/sessions). withdrawn: consent to the service withdrawn — terminal."pending_kyc", "kyc_expired", "admitted", "rejected", "withdrawn"
billingstringyesBilling state at the operator's billing provider (ZADQ-54): none until the provider's signed checkout.session.completed lands, active afterwards; back to none on customer.subscription.deleted. Opening a checkout session records nothing (ZADQ-221). The service holds no legal or payment data."none", "active"
billingTierstringnoThe schedule tier, by name, as the provider's completed event carried it from the session's metadata. Absent until billing is active (ZADQ-221)."attested_vendor", "regulated_compliance"
billingCadencestringnoHow the minimum is billed, as the provider's completed event carried it from the session's metadata (ZADQ-230). Absent until billing is active; a record active before cadences existed reads annual."monthly", "annual"
kycSessionIdstringnoOpaque session handle at the KYC boundary. Not identity data.
kycKycHandoffno
credentialCredentialStateno
depositDepositno
renewalall of KycHandoffnoThe pending re-verification session, while one is open (ZADQ-91): the person completes it on handoffUrl; the approved session in kyc keeps backing the attestation meanwhile.
attestationAttestationno
createdAtstring (date-time)yes

default — RFC 9457 problem details.

Content type application/problem+json.

Schema: Problem

PropertyTypeRequiredDescriptionValues
typestringno
titlestringno
statusintegerno
detailstringno
instancestringno

Example

curl -sS -X POST "<base-url>/v0/sellers/<sellerId>/credential" \
  -H "Authorization: Bearer <session-credential>" \
  -H "Content-Type: application/json" \
  -d @request-body.json

POST /v0/sellers/{sellerId}/kyc/sessions

Start the identity verification again, or re-verify before the reuse window ends

Opens a new KYC session at the boundary. From kyc_expired: start again (the seller reads pending_kyc with the new handoff). From admitted: a re-verification that renews the approved session (ZADQ-91) — the seller stays admitted, its attestation keeps its standing, and the pending renewal is returned in renewal; once approved, the renewal is bound upstream to the attestation, which keeps its reference, and a rekyc_overdue suspension is lifted at the next root. 409 from any other state or while a renewal is pending. Requires the wallet session of the seller's payTo address (401/403 otherwise). Either way a new verification session opens, so the body carries the consent to the face comparison, {biometric_consent: {version}} (ZADQ-331): 409 biometric_consent_required without it, 409 biometric_consent_version_stale with another label than the deployment's — checked after the wallet and before the state, and nothing reaches the issuer when refused; accepted, the consent is recorded with the session opened.

Authentication: walletSession.

Parameters

NameInRequiredTypeDescription
sellerIdpathyesstring

Request body

application/json

Schema: KycSessionRestart

PropertyTypeRequiredDescriptionValues
biometric_consentBiometricConsentGivenno

Responses

201 — New session opened; the seller reads pending_kyc again.

Content type application/json.

Schema: Seller

PropertyTypeRequiredDescriptionValues
idstringyes
payToPayToyes
resourceUrlstring (uri)yes
operatorTypestringyes"person", "organisation"
statestringyeskyc_expired: the proofing session ran past its deadline without an outcome; a new session can be opened (POST …/kyc/sessions). withdrawn: consent to the service withdrawn — terminal."pending_kyc", "kyc_expired", "admitted", "rejected", "withdrawn"
billingstringyesBilling state at the operator's billing provider (ZADQ-54): none until the provider's signed checkout.session.completed lands, active afterwards; back to none on customer.subscription.deleted. Opening a checkout session records nothing (ZADQ-221). The service holds no legal or payment data."none", "active"
billingTierstringnoThe schedule tier, by name, as the provider's completed event carried it from the session's metadata. Absent until billing is active (ZADQ-221)."attested_vendor", "regulated_compliance"
billingCadencestringnoHow the minimum is billed, as the provider's completed event carried it from the session's metadata (ZADQ-230). Absent until billing is active; a record active before cadences existed reads annual."monthly", "annual"
kycSessionIdstringnoOpaque session handle at the KYC boundary. Not identity data.
kycKycHandoffno
credentialCredentialStateno
depositDepositno
renewalall of KycHandoffnoThe pending re-verification session, while one is open (ZADQ-91): the person completes it on handoffUrl; the approved session in kyc keeps backing the attestation meanwhile.
attestationAttestationno
createdAtstring (date-time)yes

default — RFC 9457 problem details.

Content type application/problem+json.

Schema: Problem

PropertyTypeRequiredDescriptionValues
typestringno
titlestringno
statusintegerno
detailstringno
instancestringno

Example

curl -sS -X POST "<base-url>/v0/sellers/<sellerId>/kyc/sessions" \
  -H "Authorization: Bearer <session-credential>" \
  -H "Content-Type: application/json" \
  -d @request-body.json

POST /v0/sellers/{sellerId}/biometric-consent

Record the consent to the face comparison on the seller's pending session (ZADQ-331)

For a seller whose pending session (or pending re-verification) has no consent recorded: the consent to the face comparison, {version} the label of the text shown. 409 biometric_consent_required / biometric_consent_version_stale (checked after the wallet, before anything else; nothing reaches the issuer); 409 "invalid state" unless a session or a renewal is pending. Accepted, the consent is recorded for that session and the seller is returned with its link. Wallet session of the seller's payTo (401/403).

Authentication: walletSession.

Parameters

NameInRequiredTypeDescription
sellerIdpathyesstring

Request body

application/json — required

Schema: BiometricConsentGiven

PropertyTypeRequiredDescriptionValues
versionstringyesThe consent text's version label (e.g. 2026-10.2).

Responses

200 — The seller, with its link.

Content type application/json.

Schema: Seller

PropertyTypeRequiredDescriptionValues
idstringyes
payToPayToyes
resourceUrlstring (uri)yes
operatorTypestringyes"person", "organisation"
statestringyeskyc_expired: the proofing session ran past its deadline without an outcome; a new session can be opened (POST …/kyc/sessions). withdrawn: consent to the service withdrawn — terminal."pending_kyc", "kyc_expired", "admitted", "rejected", "withdrawn"
billingstringyesBilling state at the operator's billing provider (ZADQ-54): none until the provider's signed checkout.session.completed lands, active afterwards; back to none on customer.subscription.deleted. Opening a checkout session records nothing (ZADQ-221). The service holds no legal or payment data."none", "active"
billingTierstringnoThe schedule tier, by name, as the provider's completed event carried it from the session's metadata. Absent until billing is active (ZADQ-221)."attested_vendor", "regulated_compliance"
billingCadencestringnoHow the minimum is billed, as the provider's completed event carried it from the session's metadata (ZADQ-230). Absent until billing is active; a record active before cadences existed reads annual."monthly", "annual"
kycSessionIdstringnoOpaque session handle at the KYC boundary. Not identity data.
kycKycHandoffno
credentialCredentialStateno
depositDepositno
renewalall of KycHandoffnoThe pending re-verification session, while one is open (ZADQ-91): the person completes it on handoffUrl; the approved session in kyc keeps backing the attestation meanwhile.
attestationAttestationno
createdAtstring (date-time)yes

default — RFC 9457 problem details.

Content type application/problem+json.

Schema: Problem

PropertyTypeRequiredDescriptionValues
typestringno
titlestringno
statusintegerno
detailstringno
instancestringno

Example

curl -sS -X POST "<base-url>/v0/sellers/<sellerId>/biometric-consent" \
  -H "Authorization: Bearer <session-credential>" \
  -H "Content-Type: application/json" \
  -d @request-body.json

POST /v0/sellers/{sellerId}/consent/withdraw

Withdraw consent to the service (terminal)

The accountable party withdraws its consent to the service (ZADQ-91). The boundary records it on the approved session; every attestation it backs is revoked upstream with reason consent_withdrawn — an issuer revocation, effective everywhere within the network's published bound, 185 s from the root that drops it —, the verdict reads revoked, and the seller is withdrawn — terminal (a new intake is a new session). Consent given to the identity provider itself is withdrawn at the provider and has no status effect here. Requires the wallet session of the seller's payTo address (401/403); 409 unless admitted; 501 when the substrate cannot record it (raised with the operator; nothing changes).

Authentication: walletSession.

Parameters

NameInRequiredTypeDescription
sellerIdpathyesstring

Responses

200 — Consent withdrawn; the seller is terminal.

Content type application/json.

Schema: Seller

PropertyTypeRequiredDescriptionValues
idstringyes
payToPayToyes
resourceUrlstring (uri)yes
operatorTypestringyes"person", "organisation"
statestringyeskyc_expired: the proofing session ran past its deadline without an outcome; a new session can be opened (POST …/kyc/sessions). withdrawn: consent to the service withdrawn — terminal."pending_kyc", "kyc_expired", "admitted", "rejected", "withdrawn"
billingstringyesBilling state at the operator's billing provider (ZADQ-54): none until the provider's signed checkout.session.completed lands, active afterwards; back to none on customer.subscription.deleted. Opening a checkout session records nothing (ZADQ-221). The service holds no legal or payment data."none", "active"
billingTierstringnoThe schedule tier, by name, as the provider's completed event carried it from the session's metadata. Absent until billing is active (ZADQ-221)."attested_vendor", "regulated_compliance"
billingCadencestringnoHow the minimum is billed, as the provider's completed event carried it from the session's metadata (ZADQ-230). Absent until billing is active; a record active before cadences existed reads annual."monthly", "annual"
kycSessionIdstringnoOpaque session handle at the KYC boundary. Not identity data.
kycKycHandoffno
credentialCredentialStateno
depositDepositno
renewalall of KycHandoffnoThe pending re-verification session, while one is open (ZADQ-91): the person completes it on handoffUrl; the approved session in kyc keeps backing the attestation meanwhile.
attestationAttestationno
createdAtstring (date-time)yes

default — RFC 9457 problem details.

Content type application/problem+json.

Schema: Problem

PropertyTypeRequiredDescriptionValues
typestringno
titlestringno
statusintegerno
detailstringno
instancestringno

Example

curl -sS -X POST "<base-url>/v0/sellers/<sellerId>/consent/withdraw" \
  -H "Authorization: Bearer <session-credential>"

GET /v0/terms

The terms-acknowledgement document in force (free path)

The versioned document a seller signs with its payment wallet before the first issuance (ZADQ-55): the version, its SHA-256, where the full Terms of Service are published, and the text itself — which carries the related-party disclosure at contract time. Public and cacheable, so anyone can check what an attested seller acknowledged.

Authentication: none — this operation is public.

Responses

200 — The current document.

Content type application/json.

Schema: TermsDocument

PropertyTypeRequiredDescriptionValues
versionstringyesVersion name of the acknowledgement document.
sha256stringyesHex SHA-256 of text.
urlstring (uri)yesWhere the full Terms of Service are published.
textstringyesThe acknowledgement text the wallet signs for.

default — RFC 9457 problem details.

Content type application/problem+json.

Schema: Problem

PropertyTypeRequiredDescriptionValues
typestringno
titlestringno
statusintegerno
detailstringno
instancestringno

Example

curl -sS "<base-url>/v0/terms"

GET /v0/sellers/{sellerId}/terms

Terms acknowledgement state of a seller, and the message to sign

Whether the seller's wallet has acknowledged the current terms version, and — if not — the exact message to sign, with the signing time the service will verify it against (messageSignedAt; submit it back unchanged within fifteen minutes). Requires the wallet session of the seller's payTo address (401/403).

Authentication: walletSession.

Parameters

NameInRequiredTypeDescription
sellerIdpathyesstring

Responses

200 — Acknowledgement state.

Content type application/json.

Schema: SellerTerms

PropertyTypeRequiredDescriptionValues
currentTermsDocumentyes
acknowledgedbooleanyesWhether the current version is acknowledged by this seller.
acknowledgedVersionstringno
signedAtstring (date-time)noWhen the current version was signed, if it was.
messagestringyesThe exact text to sign for the current version.
messageSignedAtstring (date-time)yesThe signing time embedded in message; submit it back as signedAt.

default — RFC 9457 problem details.

Content type application/problem+json.

Schema: Problem

PropertyTypeRequiredDescriptionValues
typestringno
titlestringno
statusintegerno
detailstringno
instancestringno

Example

curl -sS "<base-url>/v0/sellers/<sellerId>/terms" \
  -H "Authorization: Bearer <session-credential>"

POST /v0/sellers/{sellerId}/terms

Acknowledge the current terms with the seller's wallet

Records the wallet signature over the acknowledgement message for the current version (same challenge mechanism as the login, a different message). Stored against the seller: version, SHA-256, signature, signing time — no mailbox, no account, no identity data. Issuance requires an acknowledgement of the current version (409 terms not acknowledged otherwise). 401 on a signature that does not verify for the seller's payTo; 409 when the version or hash is not the current one; 400 when the signing time is outside the accepted window. A second acknowledgement of the same version changes nothing.

Authentication: walletSession.

Parameters

NameInRequiredTypeDescription
sellerIdpathyesstring

Request body

application/json — required

Schema: TermsAcknowledgement

PropertyTypeRequiredDescriptionValues
versionstringyes
sha256stringyes
signedAtstring (date-time)yes
signaturestringyesWallet signature over the message (hex for EVM, base58 or hex for Solana).

Responses

201 — Acknowledged.

Content type application/json.

Schema: SellerTerms

PropertyTypeRequiredDescriptionValues
currentTermsDocumentyes
acknowledgedbooleanyesWhether the current version is acknowledged by this seller.
acknowledgedVersionstringno
signedAtstring (date-time)noWhen the current version was signed, if it was.
messagestringyesThe exact text to sign for the current version.
messageSignedAtstring (date-time)yesThe signing time embedded in message; submit it back as signedAt.

default — RFC 9457 problem details.

Content type application/problem+json.

Schema: Problem

PropertyTypeRequiredDescriptionValues
typestringno
titlestringno
statusintegerno
detailstringno
instancestringno

Example

curl -sS -X POST "<base-url>/v0/sellers/<sellerId>/terms" \
  -H "Authorization: Bearer <session-credential>" \
  -H "Content-Type: application/json" \
  -d @request-body.json

GET /v0/sellers/{sellerId}/webhooks

The seller's own receivers (secrets never shown again)

Authentication: walletSession.

Parameters

NameInRequiredTypeDescription
sellerIdpathyesstring

Responses

200 — The seller's receivers.

Content type application/json.

Schema: SellerWebhooks

PropertyTypeRequiredDescriptionValues
webhooksarray of Webhookyes

default — RFC 9457 problem details.

Content type application/problem+json.

Schema: Problem

PropertyTypeRequiredDescriptionValues
typestringno
titlestringno
statusintegerno
detailstringno
instancestringno

Example

curl -sS "<base-url>/v0/sellers/<sellerId>/webhooks" \
  -H "Authorization: Bearer <session-credential>"

POST /v0/sellers/{sellerId}/webhooks

Register a receiver for the seller's own events

Owner-bound (ZADQ-51): the wallet session must prove the seller's payTo (401/403). The per-subscription secret is returned once; https is required except for loopback receivers (local development). Events and signing: see the webhooks note at the top of this document. 409 receiver already registered when the URL is already registered for this seller (remove it first; a new secret is shown once).

Authentication: walletSession.

Parameters

NameInRequiredTypeDescription
sellerIdpathyesstring

Request body

application/json — required

Schema: WebhookRegistration

PropertyTypeRequiredDescriptionValues
urlstring (uri)yes

Responses

201 — Receiver registered; secret shown once.

Content type application/json.

Schema: Webhook

PropertyTypeRequiredDescriptionValues
idstringyes
urlstring (uri)yes
secretstringnoHex signing secret for X-Signature. Returned once at registration.
createdAtstring (date-time)yes

default — RFC 9457 problem details.

Content type application/problem+json.

Schema: Problem

PropertyTypeRequiredDescriptionValues
typestringno
titlestringno
statusintegerno
detailstringno
instancestringno

Example

curl -sS -X POST "<base-url>/v0/sellers/<sellerId>/webhooks" \
  -H "Authorization: Bearer <session-credential>" \
  -H "Content-Type: application/json" \
  -d @request-body.json

DELETE /v0/sellers/{sellerId}/webhooks/{webhookId}

Remove one of the seller's receivers

Authentication: walletSession.

Parameters

NameInRequiredTypeDescription
sellerIdpathyesstring
webhookIdpathyesstring

Responses

204 — Receiver removed.

default — RFC 9457 problem details.

Content type application/problem+json.

Schema: Problem

PropertyTypeRequiredDescriptionValues
typestringno
titlestringno
statusintegerno
detailstringno
instancestringno

Example

curl -sS -X DELETE "<base-url>/v0/sellers/<sellerId>/webhooks/<webhookId>" \
  -H "Authorization: Bearer <session-credential>"

GET /v0/sellers/{sellerId}/events

What changed — the seller's recent events, newest first

The append-only event stream of the seller (intake, KYC outcomes and expiry, issuance, status changes, consent withdrawal), for the dashboard's "what changed" list (ZADQ-51). Wallet-bound; metadata only, never identity data.

Authentication: walletSession.

Parameters

NameInRequiredTypeDescription
sellerIdpathyesstring
limitquerynointeger

Responses

200 — Recent events.

Content type application/json.

Schema: SellerEvents

PropertyTypeRequiredDescriptionValues
eventsarray of SellerEventyes

default — RFC 9457 problem details.

Content type application/problem+json.

Schema: Problem

PropertyTypeRequiredDescriptionValues
typestringno
titlestringno
statusintegerno
detailstringno
instancestringno

Example

curl -sS "<base-url>/v0/sellers/<sellerId>/events" \
  -H "Authorization: Bearer <session-credential>"

POST /v0/sellers/{sellerId}/kyc/result

KYC outcome callback (issuer-side boundary → this service)

Callback endpoint for the KYC boundary. Carries outcome metadata only — never identity data. HMAC-authenticated: X-Signature: sha256=<hex> over the raw body with the shared callback secret and X-Signature-Key (first 8 bytes of the secret's SHA-256, hex); 401 otherwise. Local fake mode without a secret leaves it open for the smoke.

Authentication: none — this operation is public.

Parameters

NameInRequiredTypeDescription
sellerIdpathyesstring

Request body

application/json — required

Schema: KycResult

PropertyTypeRequiredDescriptionValues
sessionIdstringyes
outcomestringyes"approved", "rejected"
assuranceLevelstringnoAssurance grade met by the proofing process (e.g. "G").

Responses

200 — Admission state updated.

Content type application/json.

Schema: Seller

PropertyTypeRequiredDescriptionValues
idstringyes
payToPayToyes
resourceUrlstring (uri)yes
operatorTypestringyes"person", "organisation"
statestringyeskyc_expired: the proofing session ran past its deadline without an outcome; a new session can be opened (POST …/kyc/sessions). withdrawn: consent to the service withdrawn — terminal."pending_kyc", "kyc_expired", "admitted", "rejected", "withdrawn"
billingstringyesBilling state at the operator's billing provider (ZADQ-54): none until the provider's signed checkout.session.completed lands, active afterwards; back to none on customer.subscription.deleted. Opening a checkout session records nothing (ZADQ-221). The service holds no legal or payment data."none", "active"
billingTierstringnoThe schedule tier, by name, as the provider's completed event carried it from the session's metadata. Absent until billing is active (ZADQ-221)."attested_vendor", "regulated_compliance"
billingCadencestringnoHow the minimum is billed, as the provider's completed event carried it from the session's metadata (ZADQ-230). Absent until billing is active; a record active before cadences existed reads annual."monthly", "annual"
kycSessionIdstringnoOpaque session handle at the KYC boundary. Not identity data.
kycKycHandoffno
credentialCredentialStateno
depositDepositno
renewalall of KycHandoffnoThe pending re-verification session, while one is open (ZADQ-91): the person completes it on handoffUrl; the approved session in kyc keeps backing the attestation meanwhile.
attestationAttestationno
createdAtstring (date-time)yes

default — RFC 9457 problem details.

Content type application/problem+json.

Schema: Problem

PropertyTypeRequiredDescriptionValues
typestringno
titlestringno
statusintegerno
detailstringno
instancestringno

Example

curl -sS -X POST "<base-url>/v0/sellers/<sellerId>/kyc/result" \
  -H "Content-Type: application/json" \
  -d @request-body.json

POST /v0/sellers/{sellerId}/attestations

Issue the seller-side attestation (flow 2)

Orchestrates issuance for an admitted seller via the issuer path and records attestation metadata. Fails for non-admitted sellers. Requires a wallet session for the seller's payTo address.

Authentication: walletSession.

Parameters

NameInRequiredTypeDescription
sellerIdpathyesstring

Responses

201 — Attestation issued.

Content type application/json.

Schema: Attestation

PropertyTypeRequiredDescriptionValues
idstringyes
sellerIdstringyes
assuranceLevelstringyes
statusstringyes"active", "suspended", "revoked"
statusReasonstringnoWhy a non-active status was set — never silent. rekyc_overdue: the reuse window ended; restored under the same reference by a bound re-verification. consent_withdrawn: terminal. self_revoked: the holder revoked its own credential and the attestation was retired at the next verdict cadence — terminal for this attestation; a new verification yields a new one. Absent for operator changes and while active."rekyc_overdue", "consent_withdrawn", "self_revoked"
freshnessBandstringnoFreshness band of the backing session, as the issuer reports it."F4", "F3", "F2", "F1"
issuedAtstring (date-time)yes
updatedAtstring (date-time)yes

default — RFC 9457 problem details.

Content type application/problem+json.

Schema: Problem

PropertyTypeRequiredDescriptionValues
typestringno
titlestringno
statusintegerno
detailstringno
instancestringno

Example

curl -sS -X POST "<base-url>/v0/sellers/<sellerId>/attestations" \
  -H "Authorization: Bearer <session-credential>"

GET /v0/sellers/{sellerId}/attestations/{attestationId}/receipt

The issuer's signed receipt of the attestation (for X-PAYMENT-IDENTITY)

The issuer-signed receipt of the issuance, byte-shaped as the attestation-ref/v0 payload of the payment-identity companion header (ZADQ-92): the seller's middleware puts it on X-PAYMENT-IDENTITY beside X-PAYMENT, and a receiver may verify the issuer's Ed25519 signature locally against the issuer's registered status key. It is proof of issuance, never of standing: standing is the verdict's (GET /v0/verifications). Requires the wallet session of the seller's payTo address (401/403). 404 when no receipt is stored (local fakes, attestations recorded before receipts were kept).

Authentication: walletSession.

Parameters

NameInRequiredTypeDescription
sellerIdpathyesstring
attestationIdpathyesstring

Responses

200 — The receipt.

Content type application/json.

Schema: AttestationReceipt

PropertyTypeRequiredDescriptionValues
attestation_refstringyes32-byte opaque reference, hex.
issuer_idstringyes
chainstringyes
pay_tostringyes
resource_urlstringyes
assurance_gradeintegeryes
issued_at_unixintegeryes
signaturestringyesEd25519 by the issuer's registered status signing key, hex (64 bytes).

default — RFC 9457 problem details.

Content type application/problem+json.

Schema: Problem

PropertyTypeRequiredDescriptionValues
typestringno
titlestringno
statusintegerno
detailstringno
instancestringno

Example

curl -sS "<base-url>/v0/sellers/<sellerId>/attestations/<attestationId>/receipt" \
  -H "Authorization: Bearer <session-credential>"

POST /v0/attestations/{attestationId}/status

Status-mirror update (network status cycle → this service)

Applies a status change originating in the standard network status machinery. The service never revokes by its own say-so (seed §3.1 flow 4); this endpoint mirrors upstream state. HMAC-authenticated like the KYC callback (X-Signature, X-Signature-Key).

Authentication: none — this operation is public.

Parameters

NameInRequiredTypeDescription
attestationIdpathyesstring

Request body

application/json — required

Schema: AttestationStatusUpdate

PropertyTypeRequiredDescriptionValues
statusstringyes"active", "suspended", "revoked"

Responses

200 — Mirrored status applied.

Content type application/json.

Schema: Attestation

PropertyTypeRequiredDescriptionValues
idstringyes
sellerIdstringyes
assuranceLevelstringyes
statusstringyes"active", "suspended", "revoked"
statusReasonstringnoWhy a non-active status was set — never silent. rekyc_overdue: the reuse window ended; restored under the same reference by a bound re-verification. consent_withdrawn: terminal. self_revoked: the holder revoked its own credential and the attestation was retired at the next verdict cadence — terminal for this attestation; a new verification yields a new one. Absent for operator changes and while active."rekyc_overdue", "consent_withdrawn", "self_revoked"
freshnessBandstringnoFreshness band of the backing session, as the issuer reports it."F4", "F3", "F2", "F1"
issuedAtstring (date-time)yes
updatedAtstring (date-time)yes

default — RFC 9457 problem details.

Content type application/problem+json.

Schema: Problem

PropertyTypeRequiredDescriptionValues
typestringno
titlestringno
statusintegerno
detailstringno
instancestringno

Example

curl -sS -X POST "<base-url>/v0/attestations/<attestationId>/status" \
  -H "Content-Type: application/json" \
  -d @request-body.json

GET /v0/verification-keys

Verdict-verification public keys (free path)

The Ed25519 public keys verdict signatures are checked against. Free, unauthenticated, cacheable. keyId matches Verdict.keyId (first 8 bytes of the key's SHA-256, hex). Consumers without the key keep working: a signature they cannot check is "unverifiable", never an error.

Authentication: none — this operation is public.

Responses

200 — Current verification keys.

Content type application/json.

Schema: VerificationKeys

PropertyTypeRequiredDescriptionValues
keysarray of VerificationKeyyes

Example

curl -sS "<base-url>/v0/verification-keys"

GET /v0/metrics

Published metrics (free path)

The published metric series (ZADQ-106): sellers attested, 90-day retention, verifications served, independent registered verifiers, anchor-service revenue — computed from this service's own records, counts only, monthly, complete months only. Free, unauthenticated, cacheable. Every series carries relatedParty: true and its period: the operator runs a related-party pilot and nothing measured on it counts as independent adoption. A series the records hold no source for says so (available: false) rather than carrying a figure. Registry-based or aggregate throughout — no per-verification record exists — and nothing personal, no identifier of any kind.

Authentication: none — this operation is public.

Responses

200 — The current report.

Content type application/json.

Schema: MetricsReport

PropertyTypeRequiredDescriptionValues
schemastringyesThe wire shape's name (published-metrics/v1).
computedAtstring (date-time)yes
asOfstring (date)yesThe cut-off — the last day of the last complete month (UTC). Partial months are never published.
periodMetricsPeriodno
cadenceobjectyes
cadence.publicationstringyesmonthly.
cadence.snapshotstringyesquarterly, aligned to the two-consecutive-quarters clock.
relatedPartybooleanyesAlways true — the operator's position is a property of the dataset.
operatorMetricsOperatoryes
seriesarray of MetricsSeriesyes
contextNotestringyes

Example

curl -sS "<base-url>/v0/metrics"

GET /v0/verifications

Free verification path (explorers, buyers)

Returns the current signed verdict for an x402 endpoint, or a no-signal outcome. Free of charge, no authentication, ever.

Authentication: none — this operation is public.

Parameters

NameInRequiredTypeDescription
chainqueryyesChain
payToqueryyesstring
resourceUrlqueryyesstring

Responses

200 — Verdict (or explicit no-signal outcome).

Content type application/json.

Schema: Verdict

PropertyTypeRequiredDescriptionValues
outcomestringyes"human_backed", "revoked", "stale", "no_signal"
subjectobjectyes
subject.chainChainyes
subject.payTostringyes
subject.resourceUrlstringyes
assuranceLevelstringno
verifiedAtstring (date-time)no
recheckEveryHoursintegeryes
signaturestringnoEd25519 over the canonical verdict payload, base64.
keyIdstringno
reasonstringnoWhy the outcome is not human_backed: the standing read's reason code (closed vocabulary), or suspended when the witnessed status is suspended. Absent on human_backed; absent on revoked too. The policy reason of a suspension (rekyc_overdue) is the seller's own record, never part of the public verdict. On the v1 path (ZADQ-84) a verifier-side condition of the presentation decision is carried with the same code (issuer_not_active, status_root_stale, height_stale) or as state_unavailable; a presentation the verifier refused on the holder's side withholds the positive claim with no reason — the decision's exact code is the seller's own record (credential.lastPresentation). The freshness half of "human-backed" (grade ≥ 2 and freshness ≥ F1) is the issuer's state on both rails (ZADQ-182): the issuer computes the band and suspends rekyc_overdue when the reuse window ends; ZadQ mirrors that state and never asks a presentation about recency (a presentation proves the grade threshold, expiry and non-revocation only). The verdict carries neither the band nor a date; the band is the seller's own record (freshnessBand)."state_unavailable", "issuer_unknown", "issuer_not_active", "status_root_stale", "height_stale", "witness_unavailable", "witness_malformed", "witness_invalid", "witness_root_mismatch", "bond_insufficient", "suspended"
extensionsVerdictExtensionsno

default — RFC 9457 problem details.

Content type application/problem+json.

Schema: Problem

PropertyTypeRequiredDescriptionValues
typestringno
titlestringno
statusintegerno
detailstringno
instancestringno

Example

curl -sS "<base-url>/v0/verifications?chain=<chain>&payTo=<payTo>&resourceUrl=<resourceUrl>"

POST /v0/webhooks

Register an explorer receiver for verdict.updated

Free and unauthenticated — the payload is the public verdict. The per-subscription secret is returned once; https is required except for loopback receivers (local development).

Authentication: none — this operation is public.

Request body

application/json — required

Schema: WebhookRegistration

PropertyTypeRequiredDescriptionValues
urlstring (uri)yes

Responses

201 — Subscription created; secret shown once.

Content type application/json.

Schema: Webhook

PropertyTypeRequiredDescriptionValues
idstringyes
urlstring (uri)yes
secretstringnoHex signing secret for X-Signature. Returned once at registration.
createdAtstring (date-time)yes

default — RFC 9457 problem details.

Content type application/problem+json.

Schema: Problem

PropertyTypeRequiredDescriptionValues
typestringno
titlestringno
statusintegerno
detailstringno
instancestringno

Example

curl -sS -X POST "<base-url>/v0/webhooks" \
  -H "Content-Type: application/json" \
  -d @request-body.json

DELETE /v0/webhooks/{webhookId}

Remove a receiver

Authentication: none — this operation is public.

Parameters

NameInRequiredTypeDescription
webhookIdpathyesstring

Responses

204 — Subscription removed.

default — RFC 9457 problem details.

Content type application/problem+json.

Schema: Problem

PropertyTypeRequiredDescriptionValues
typestringno
titlestringno
statusintegerno
detailstringno
instancestringno

Example

curl -sS -X DELETE "<base-url>/v0/webhooks/<webhookId>"

GET /v0/sellers/{sellerId}/verdict

Latest verdict for a seller (dashboard view)

Authentication: none — this operation is public.

Parameters

NameInRequiredTypeDescription
sellerIdpathyesstring

Responses

200 — Latest verdict.

Content type application/json.

Schema: Verdict

PropertyTypeRequiredDescriptionValues
outcomestringyes"human_backed", "revoked", "stale", "no_signal"
subjectobjectyes
subject.chainChainyes
subject.payTostringyes
subject.resourceUrlstringyes
assuranceLevelstringno
verifiedAtstring (date-time)no
recheckEveryHoursintegeryes
signaturestringnoEd25519 over the canonical verdict payload, base64.
keyIdstringno
reasonstringnoWhy the outcome is not human_backed: the standing read's reason code (closed vocabulary), or suspended when the witnessed status is suspended. Absent on human_backed; absent on revoked too. The policy reason of a suspension (rekyc_overdue) is the seller's own record, never part of the public verdict. On the v1 path (ZADQ-84) a verifier-side condition of the presentation decision is carried with the same code (issuer_not_active, status_root_stale, height_stale) or as state_unavailable; a presentation the verifier refused on the holder's side withholds the positive claim with no reason — the decision's exact code is the seller's own record (credential.lastPresentation). The freshness half of "human-backed" (grade ≥ 2 and freshness ≥ F1) is the issuer's state on both rails (ZADQ-182): the issuer computes the band and suspends rekyc_overdue when the reuse window ends; ZadQ mirrors that state and never asks a presentation about recency (a presentation proves the grade threshold, expiry and non-revocation only). The verdict carries neither the band nor a date; the band is the seller's own record (freshnessBand)."state_unavailable", "issuer_unknown", "issuer_not_active", "status_root_stale", "height_stale", "witness_unavailable", "witness_malformed", "witness_invalid", "witness_root_mismatch", "bond_insufficient", "suspended"
extensionsVerdictExtensionsno

default — RFC 9457 problem details.

Content type application/problem+json.

Schema: Problem

PropertyTypeRequiredDescriptionValues
typestringno
titlestringno
statusintegerno
detailstringno
instancestringno

Example

curl -sS "<base-url>/v0/sellers/<sellerId>/verdict"

GET /v0/agent-scopes

The delegation vocabulary an agent is minted with

The scope vocabulary v2 (mintid.scope-vocabulary.v2) an agent's delegation draws from — the content carried on chain, read under its pinned content hash (contentSha256: SHA-256 over the RFC 8785 canonical JSON of the content), never hard-coded. Only values whose status is active are served: scopes lists the enumerated ones (actions, mintid: categories); axes gives, per axis (action, counterparty, category, geo), the enumerated values and the forms or namespaces with their canonical patterns — a value is valid only in its canonical form. A gated value (agent.delegate) is never served, and an offer naming it is refused (400, code scope_value_gated). units are the value units of the per-transaction limit with their minor-unit exponent. The dashboard builds the "Mint an agent" form from it. 503 when the content does not match its pin (fail closed: no offer is validated against it); 501 when the substrate supplies no vocabulary. Wallet session required (401).

Authentication: walletSession.

Responses

200 — The vocabulary and the hash it was read under.

Content type application/json.

Schema: ScopeVocabulary

PropertyTypeRequiredDescriptionValues
contentSha256stringyesSHA-256 (hex) of the RFC 8785 canonical JSON of the vocabulary content it was read under.
versionstringno
scopesarray of stringyesThe enumerated active values as an offer writes them (actions, mintid: categories).
axesarray of ScopeAxisno
unitsarray of ScopeValueUnitno
custodyClassesarray of stringyesKey-custody class codes, lowest rank first.

default — RFC 9457 problem details.

Content type application/problem+json.

Schema: Problem

PropertyTypeRequiredDescriptionValues
typestringno
titlestringno
statusintegerno
detailstringno
instancestringno

Example

curl -sS "<base-url>/v0/agent-scopes" \
  -H "Authorization: Bearer <session-credential>"

GET /v0/agent-bundles

The bundle catalogue ZadQ mints bounded agents from

ZadQ's bounded-agent bundle catalogue (ZADQ-173): the named, bounded scopes an operator mints agent credentials from — for each bundle the actions every agent of it is granted, the categories and regions the operator may choose from at mint (and the defaults), the counterparty forms, the per-transaction caps by unit in minor units, the lease bounds and the minimum backing grade; always private-only and software-custodied. The catalogue is ZadQ's own content in the format the network's issuer validates; digest is the SHA-256 of its canonical form and is what the issuer serves beside the catalogue once configured with it. price is ZadQ's price line for the bundle (the issuer echoes it in offers; it never reaches a policy). The dashboard builds the "Mint an agent" form from this read. servedByIssuer says whether the network's issuer serves this catalogue (servedCatalogue names the one it serves, when read): when it does, an agent sold under a bundle is minted in the issuer's bundle form; when it does not, ZadQ mints the same agent on raw-scope terms derived from the bundle's definition and records its price line itself — either way the operator chooses a ZadQ bundle and never sees the issuer's catalogue codes. Wallet session required (401).

Authentication: walletSession.

Responses

200 — The catalogue, its digest and ZadQ's price per bundle.

Content type application/json.

Schema: AgentBundleCatalogue

PropertyTypeRequiredDescriptionValues
versionstringyes<namespace>.agent-bundles[.<name>].v<N>; ZadQ's namespace is zadq.
vocabularystringyes
digeststringyesLowercase hex SHA-256 of the catalogue's canonical form.
bundlesarray of AgentBundleyes
servedByIssuerbooleanyesWhether the network's issuer serves this catalogue (same id and digest). False also when its catalogue could not be read.
servedCataloguestringnoThe id of the catalogue the issuer serves, when read.

default — RFC 9457 problem details.

Content type application/problem+json.

Schema: Problem

PropertyTypeRequiredDescriptionValues
typestringno
titlestringno
statusintegerno
detailstringno
instancestringno

Example

curl -sS "<base-url>/v0/agent-bundles" \
  -H "Authorization: Bearer <session-credential>"

POST /v1/auth/passkeys/register/options

Passkey registration, step 1 — creation options

WebAuthn creation options for a discoverable passkey with user verification required; the PRF extension is requested and its support recorded on registration. Three callers: with a passkey session, the person adds a passkey; with the wallet session's bearer alone (POST /v0/auth/session), the migration step — the wallet account's first passkey, the one thing a wallet-only session may do (only the account's first-enrolled wallet may do it; 403 passkey_required names that); with no session and new_account, a new account and its owner person are created when the registration finishes. 401 session_required with neither (or a wallet whose account already has a passkey: the wallet is no longer a login).

Authentication: none or passkeySession or walletSession.

Request body

application/json

Schema: PasskeyRegisterOptionsRequest

PropertyTypeRequiredDescriptionValues
new_accountobjectnoWith no session, the account the registration creates. kind (default organisation, so a v1.2 front still works) and country seed the customer record (ZADQ-307 §2.2); the kind may change until the first payment.
new_account.namestringyesThe organisation's label in the dashboard.
new_account.kindNewAccountKindno
new_account.countrystringnoISO 3166-1 alpha-2, the country of registration.
new_account.referralall of ReferralParamsnov1.3.14 (§5.16): the door the sign-up came through — the landing URL's parameters. Checked here (404 referral_unknown, 409 referral_closed; 501 not_available while the door is off) and recorded in the account's transaction at the finish (account_referred).
consentsall of ConsentsUpdatenoThe consents given at Create your account (ZADQ-307 §2.3), recorded in the account's own transaction when the registration finishes. Checked here: 409 terms_changed for a stale Terms version or hash, 400 business_use_required for business_use: false. Only with new_account.
labelstringnoThe passkey's label (e.g. the device).

Responses

200 — Creation options, as navigator.credentials.create takes them.

Content type application/json.

Schema: PasskeyCeremonyOptions

PropertyTypeRequiredDescriptionValues
publicKeyobjectyesWebAuthn PublicKeyCredentialCreationOptions or RequestOptions (JSON, base64url binaries).

default — A /v1 refusal — {"error", "detail"} (platform API v1 §5).

Content type application/json.

Schema: V1Error

PropertyTypeRequiredDescriptionValues
errorstringyessession_required · passkey_required · last_passkey · ceremony_invalid · attestation_invalid · assertion_invalid · email_operational_invalid · body_invalid · origin_refused · not_found · not_available · internal · runtime_token_invalid · approval_not_pending · result_already_taken · declaration_invalid · request_invalid · cursor_invalid · rate_limited · offer_refused:<issuer code> (ZADQ-289) · kyc_current · kyc_required · entry_fee_due · reverification_required · invalid_state · sandbox_hint_not_available · invalid_sandbox_hint · issuer_unavailable (ZADQ-316) · kyc_grade_below_bundle (ZADQ-321) · person_invalid · profile_invalid · profile_incomplete · kind_locked · terms_changed · business_use_required · reauth_required (ZADQ-307) · account_blocked (ZADQ-311) · custody_version_conflict · last_wrap · passkey_not_on_account (ZADQ-293) · wraps_required (ZADQ-293, v1.3.2) · origin_invalid · key_invalid · private_key_refused · origin_in_use · key_reused · evidence_required · obligations_not_published · obligations_changed (ZADQ-362, v1.3.13) · mintid_unavailable (503, ZADQ-407: MintID unreachable since the start-up and the ids not discovered yet; nothing recorded, retry later)
detailstringyes
custody_versioninteger (int64)no409 custody_version_conflict (§5.8, v1.3.2) — the stored version, to read and retry on.
fieldsobjectnoThe refused fields by path (400 person_invalid, profile_invalid).
missingarray of stringnoThe field paths a payment still needs (409 profile_incomplete).

Example

curl -sS -X POST "<base-url>/v1/auth/passkeys/register/options" \
  --cookie "__Host-passkey_session=<api-key>" \
  -H "Content-Type: application/json" \
  -d @request-body.json

POST /v1/auth/passkeys/register

Passkey registration, step 2 — the authenticator's answer

Verifies the registration answer against the ceremony the same caller began (the same passkey session, the same wallet session, or none) and stores the passkey. A registration signs the person in: the passkey session cookie is set and its expiry returned. 400 attestation_invalid when the answer does not verify; 409 ceremony_invalid when it names no live ceremony of this caller.

Authentication: none or passkeySession or walletSession.

Request body

application/json — required

Schema: PasskeyRegisterRequest

PropertyTypeRequiredDescriptionValues
attestationobjectyesThe PublicKeyCredential the browser answered (toJSON form).

Responses

201 — Passkey stored; session cookie set.

Content type application/json.

Schema: PasskeyRegistered

PropertyTypeRequiredDescriptionValues
passkey_idstringyes
prf_supportedbooleanyes
session_expires_atstring (date-time)yes

default — A /v1 refusal — {"error", "detail"} (platform API v1 §5).

Content type application/json.

Schema: V1Error

PropertyTypeRequiredDescriptionValues
errorstringyessession_required · passkey_required · last_passkey · ceremony_invalid · attestation_invalid · assertion_invalid · email_operational_invalid · body_invalid · origin_refused · not_found · not_available · internal · runtime_token_invalid · approval_not_pending · result_already_taken · declaration_invalid · request_invalid · cursor_invalid · rate_limited · offer_refused:<issuer code> (ZADQ-289) · kyc_current · kyc_required · entry_fee_due · reverification_required · invalid_state · sandbox_hint_not_available · invalid_sandbox_hint · issuer_unavailable (ZADQ-316) · kyc_grade_below_bundle (ZADQ-321) · person_invalid · profile_invalid · profile_incomplete · kind_locked · terms_changed · business_use_required · reauth_required (ZADQ-307) · account_blocked (ZADQ-311) · custody_version_conflict · last_wrap · passkey_not_on_account (ZADQ-293) · wraps_required (ZADQ-293, v1.3.2) · origin_invalid · key_invalid · private_key_refused · origin_in_use · key_reused · evidence_required · obligations_not_published · obligations_changed (ZADQ-362, v1.3.13) · mintid_unavailable (503, ZADQ-407: MintID unreachable since the start-up and the ids not discovered yet; nothing recorded, retry later)
detailstringyes
custody_versioninteger (int64)no409 custody_version_conflict (§5.8, v1.3.2) — the stored version, to read and retry on.
fieldsobjectnoThe refused fields by path (400 person_invalid, profile_invalid).
missingarray of stringnoThe field paths a payment still needs (409 profile_incomplete).

Example

curl -sS -X POST "<base-url>/v1/auth/passkeys/register" \
  --cookie "__Host-passkey_session=<api-key>" \
  -H "Content-Type: application/json" \
  -d @request-body.json

POST /v1/auth/passkeys/login/options

Passkey sign-in, step 1 — request options

WebAuthn request options for a discoverable sign-in (no account is named), user verification required. The same options serve a fresh assertion where a decision asks for one (an approval).

Authentication: none — this operation is public.

Responses

200 — Request options, as navigator.credentials.get takes them.

Content type application/json.

Schema: PasskeyCeremonyOptions

PropertyTypeRequiredDescriptionValues
publicKeyobjectyesWebAuthn PublicKeyCredentialCreationOptions or RequestOptions (JSON, base64url binaries).

default — A /v1 refusal — {"error", "detail"} (platform API v1 §5).

Content type application/json.

Schema: V1Error

PropertyTypeRequiredDescriptionValues
errorstringyessession_required · passkey_required · last_passkey · ceremony_invalid · attestation_invalid · assertion_invalid · email_operational_invalid · body_invalid · origin_refused · not_found · not_available · internal · runtime_token_invalid · approval_not_pending · result_already_taken · declaration_invalid · request_invalid · cursor_invalid · rate_limited · offer_refused:<issuer code> (ZADQ-289) · kyc_current · kyc_required · entry_fee_due · reverification_required · invalid_state · sandbox_hint_not_available · invalid_sandbox_hint · issuer_unavailable (ZADQ-316) · kyc_grade_below_bundle (ZADQ-321) · person_invalid · profile_invalid · profile_incomplete · kind_locked · terms_changed · business_use_required · reauth_required (ZADQ-307) · account_blocked (ZADQ-311) · custody_version_conflict · last_wrap · passkey_not_on_account (ZADQ-293) · wraps_required (ZADQ-293, v1.3.2) · origin_invalid · key_invalid · private_key_refused · origin_in_use · key_reused · evidence_required · obligations_not_published · obligations_changed (ZADQ-362, v1.3.13) · mintid_unavailable (503, ZADQ-407: MintID unreachable since the start-up and the ids not discovered yet; nothing recorded, retry later)
detailstringyes
custody_versioninteger (int64)no409 custody_version_conflict (§5.8, v1.3.2) — the stored version, to read and retry on.
fieldsobjectnoThe refused fields by path (400 person_invalid, profile_invalid).
missingarray of stringnoThe field paths a payment still needs (409 profile_incomplete).

Example

curl -sS -X POST "<base-url>/v1/auth/passkeys/login/options"

POST /v1/auth/passkeys/login

Passkey sign-in, step 2 — the assertion

Verifies the assertion and opens the passkey session: a cookie, same site, HttpOnly, short lived and renewed on use. 401 assertion_invalid when it does not verify.

Authentication: none — this operation is public.

Request body

application/json — required

Schema: PasskeyLoginRequest

PropertyTypeRequiredDescriptionValues
assertionobjectyesThe PublicKeyCredential the browser answered (toJSON form).

Responses

200 — Signed in; session cookie set.

Content type application/json.

Schema: PasskeySessionOpened

PropertyTypeRequiredDescriptionValues
session_expires_atstring (date-time)yes

default — A /v1 refusal — {"error", "detail"} (platform API v1 §5).

Content type application/json.

Schema: V1Error

PropertyTypeRequiredDescriptionValues
errorstringyessession_required · passkey_required · last_passkey · ceremony_invalid · attestation_invalid · assertion_invalid · email_operational_invalid · body_invalid · origin_refused · not_found · not_available · internal · runtime_token_invalid · approval_not_pending · result_already_taken · declaration_invalid · request_invalid · cursor_invalid · rate_limited · offer_refused:<issuer code> (ZADQ-289) · kyc_current · kyc_required · entry_fee_due · reverification_required · invalid_state · sandbox_hint_not_available · invalid_sandbox_hint · issuer_unavailable (ZADQ-316) · kyc_grade_below_bundle (ZADQ-321) · person_invalid · profile_invalid · profile_incomplete · kind_locked · terms_changed · business_use_required · reauth_required (ZADQ-307) · account_blocked (ZADQ-311) · custody_version_conflict · last_wrap · passkey_not_on_account (ZADQ-293) · wraps_required (ZADQ-293, v1.3.2) · origin_invalid · key_invalid · private_key_refused · origin_in_use · key_reused · evidence_required · obligations_not_published · obligations_changed (ZADQ-362, v1.3.13) · mintid_unavailable (503, ZADQ-407: MintID unreachable since the start-up and the ids not discovered yet; nothing recorded, retry later)
detailstringyes
custody_versioninteger (int64)no409 custody_version_conflict (§5.8, v1.3.2) — the stored version, to read and retry on.
fieldsobjectnoThe refused fields by path (400 person_invalid, profile_invalid).
missingarray of stringnoThe field paths a payment still needs (409 profile_incomplete).

Example

curl -sS -X POST "<base-url>/v1/auth/passkeys/login" \
  -H "Content-Type: application/json" \
  -d @request-body.json

POST /v1/auth/logout

Sign out — the passkey session ends

Authentication: none — this operation is public.

Responses

204 — Session ended (or none was open); cookie cleared.

default — A /v1 refusal — {"error", "detail"} (platform API v1 §5).

Content type application/json.

Schema: V1Error

PropertyTypeRequiredDescriptionValues
errorstringyessession_required · passkey_required · last_passkey · ceremony_invalid · attestation_invalid · assertion_invalid · email_operational_invalid · body_invalid · origin_refused · not_found · not_available · internal · runtime_token_invalid · approval_not_pending · result_already_taken · declaration_invalid · request_invalid · cursor_invalid · rate_limited · offer_refused:<issuer code> (ZADQ-289) · kyc_current · kyc_required · entry_fee_due · reverification_required · invalid_state · sandbox_hint_not_available · invalid_sandbox_hint · issuer_unavailable (ZADQ-316) · kyc_grade_below_bundle (ZADQ-321) · person_invalid · profile_invalid · profile_incomplete · kind_locked · terms_changed · business_use_required · reauth_required (ZADQ-307) · account_blocked (ZADQ-311) · custody_version_conflict · last_wrap · passkey_not_on_account (ZADQ-293) · wraps_required (ZADQ-293, v1.3.2) · origin_invalid · key_invalid · private_key_refused · origin_in_use · key_reused · evidence_required · obligations_not_published · obligations_changed (ZADQ-362, v1.3.13) · mintid_unavailable (503, ZADQ-407: MintID unreachable since the start-up and the ids not discovered yet; nothing recorded, retry later)
detailstringyes
custody_versioninteger (int64)no409 custody_version_conflict (§5.8, v1.3.2) — the stored version, to read and retry on.
fieldsobjectnoThe refused fields by path (400 person_invalid, profile_invalid).
missingarray of stringnoThe field paths a payment still needs (409 profile_incomplete).

Example

curl -sS -X POST "<base-url>/v1/auth/logout"

GET /v1/me

The account, its owner person, passkeys, payTo bindings and products

The signed-in person's account. person.kyc holds the issuer's session handle and the facts the issuer's operator API returns for it (state, grade, reuse window) — never KYC data. Products: the vendor's state is read from the account's vendor records; the agent-operator product's from its activation once it exists (ZADQ-290: plan, seats.plan = the plan's seats capped by the issuer's 10 per person), else from the agent-operator records with null plans. seats.used counts the live agents plus the enrolments holding a seat (created, claimed, or approved and waiting on their price line); the hourly counter the agent credentials offered in the last hour against ZadQ's allowance of 4. biometric_consent (ZADQ-331): the consent text's label the deployment requires now and the last consent given, so the page never shows an outdated text. 401 session_required; 403 passkey_required with a wallet session alone.

Authentication: passkeySession.

Responses

200 — The account.

Content type application/json.

Schema: Me

PropertyTypeRequiredDescriptionValues
accountMeAccountyes
personMePersonyes
passkeysarray of MePasskeyyes
payto_bindingsarray of MePaytoBindingyes
productsMeProductsyes
biometric_consentMeBiometricConsentyes

default — A /v1 refusal — {"error", "detail"} (platform API v1 §5).

Content type application/json.

Schema: V1Error

PropertyTypeRequiredDescriptionValues
errorstringyessession_required · passkey_required · last_passkey · ceremony_invalid · attestation_invalid · assertion_invalid · email_operational_invalid · body_invalid · origin_refused · not_found · not_available · internal · runtime_token_invalid · approval_not_pending · result_already_taken · declaration_invalid · request_invalid · cursor_invalid · rate_limited · offer_refused:<issuer code> (ZADQ-289) · kyc_current · kyc_required · entry_fee_due · reverification_required · invalid_state · sandbox_hint_not_available · invalid_sandbox_hint · issuer_unavailable (ZADQ-316) · kyc_grade_below_bundle (ZADQ-321) · person_invalid · profile_invalid · profile_incomplete · kind_locked · terms_changed · business_use_required · reauth_required (ZADQ-307) · account_blocked (ZADQ-311) · custody_version_conflict · last_wrap · passkey_not_on_account (ZADQ-293) · wraps_required (ZADQ-293, v1.3.2) · origin_invalid · key_invalid · private_key_refused · origin_in_use · key_reused · evidence_required · obligations_not_published · obligations_changed (ZADQ-362, v1.3.13) · mintid_unavailable (503, ZADQ-407: MintID unreachable since the start-up and the ids not discovered yet; nothing recorded, retry later)
detailstringyes
custody_versioninteger (int64)no409 custody_version_conflict (§5.8, v1.3.2) — the stored version, to read and retry on.
fieldsobjectnoThe refused fields by path (400 person_invalid, profile_invalid).
missingarray of stringnoThe field paths a payment still needs (409 profile_incomplete).

Example

curl -sS "<base-url>/v1/me" \
  --cookie "__Host-passkey_session=<api-key>"

PATCH /v1/me/person

Set the person's operational e-mail

The operational e-mail is the one contact field ZadQ keeps: the address it writes to about the account. Optional at migration, required before a product is activated. Never KYC data; null clears it. 400 email_operational_invalid.

Authentication: passkeySession.

Request body

application/json — required

Schema: MePersonUpdate

PropertyTypeRequiredDescriptionValues
given_namestring, nullableno
family_namestring, nullableno
email_operationalstring, nullableno
preferred_languagestringno

Responses

200 — The person.

Content type application/json.

Schema: MePerson

PropertyTypeRequiredDescriptionValues
idstringyes
given_namestring, nullableyes
family_namestring, nullableyes
email_operationalstring, nullableyesThe operational contact address; never KYC data.
preferred_languagestringyesISO 639-1, from the service's supported set (en, es, ca, et, de, fr, it, pt, nl); en by default.
kycMeKycyes

default — A /v1 refusal — {"error", "detail"} (platform API v1 §5).

Content type application/json.

Schema: V1Error

PropertyTypeRequiredDescriptionValues
errorstringyessession_required · passkey_required · last_passkey · ceremony_invalid · attestation_invalid · assertion_invalid · email_operational_invalid · body_invalid · origin_refused · not_found · not_available · internal · runtime_token_invalid · approval_not_pending · result_already_taken · declaration_invalid · request_invalid · cursor_invalid · rate_limited · offer_refused:<issuer code> (ZADQ-289) · kyc_current · kyc_required · entry_fee_due · reverification_required · invalid_state · sandbox_hint_not_available · invalid_sandbox_hint · issuer_unavailable (ZADQ-316) · kyc_grade_below_bundle (ZADQ-321) · person_invalid · profile_invalid · profile_incomplete · kind_locked · terms_changed · business_use_required · reauth_required (ZADQ-307) · account_blocked (ZADQ-311) · custody_version_conflict · last_wrap · passkey_not_on_account (ZADQ-293) · wraps_required (ZADQ-293, v1.3.2) · origin_invalid · key_invalid · private_key_refused · origin_in_use · key_reused · evidence_required · obligations_not_published · obligations_changed (ZADQ-362, v1.3.13) · mintid_unavailable (503, ZADQ-407: MintID unreachable since the start-up and the ids not discovered yet; nothing recorded, retry later)
detailstringyes
custody_versioninteger (int64)no409 custody_version_conflict (§5.8, v1.3.2) — the stored version, to read and retry on.
fieldsobjectnoThe refused fields by path (400 person_invalid, profile_invalid).
missingarray of stringnoThe field paths a payment still needs (409 profile_incomplete).

Example

curl -sS -X PATCH "<base-url>/v1/me/person" \
  --cookie "__Host-passkey_session=<api-key>" \
  -H "Content-Type: application/json" \
  -d @request-body.json

DELETE /v1/me/passkeys/{passkeyId}

Remove a passkey (never the last one)

Removes one of the person's passkeys and ends the sessions it opened. 409 last_passkey for the last one: an account never falls back to the wallet as a login. 404 not_found for a passkey that is not the person's. 409 last_wrap for the passkey that carries the last wrap of a live browser credential (§5.8; revoke the credential first). A wrap the passkey carries that is not the last goes in the same step (ZADQ-293, v1.3.2): one custody_version step, rotation_due set, custody_wrap_removed written.

Authentication: passkeySession.

Parameters

NameInRequiredTypeDescription
passkeyIdpathyesstring

Responses

204 — Removed.

default — A /v1 refusal — {"error", "detail"} (platform API v1 §5).

Content type application/json.

Schema: V1Error

PropertyTypeRequiredDescriptionValues
errorstringyessession_required · passkey_required · last_passkey · ceremony_invalid · attestation_invalid · assertion_invalid · email_operational_invalid · body_invalid · origin_refused · not_found · not_available · internal · runtime_token_invalid · approval_not_pending · result_already_taken · declaration_invalid · request_invalid · cursor_invalid · rate_limited · offer_refused:<issuer code> (ZADQ-289) · kyc_current · kyc_required · entry_fee_due · reverification_required · invalid_state · sandbox_hint_not_available · invalid_sandbox_hint · issuer_unavailable (ZADQ-316) · kyc_grade_below_bundle (ZADQ-321) · person_invalid · profile_invalid · profile_incomplete · kind_locked · terms_changed · business_use_required · reauth_required (ZADQ-307) · account_blocked (ZADQ-311) · custody_version_conflict · last_wrap · passkey_not_on_account (ZADQ-293) · wraps_required (ZADQ-293, v1.3.2) · origin_invalid · key_invalid · private_key_refused · origin_in_use · key_reused · evidence_required · obligations_not_published · obligations_changed (ZADQ-362, v1.3.13) · mintid_unavailable (503, ZADQ-407: MintID unreachable since the start-up and the ids not discovered yet; nothing recorded, retry later)
detailstringyes
custody_versioninteger (int64)no409 custody_version_conflict (§5.8, v1.3.2) — the stored version, to read and retry on.
fieldsobjectnoThe refused fields by path (400 person_invalid, profile_invalid).
missingarray of stringnoThe field paths a payment still needs (409 profile_incomplete).

Example

curl -sS -X DELETE "<base-url>/v1/me/passkeys/<passkeyId>" \
  --cookie "__Host-passkey_session=<api-key>"

GET /v1/organisation

The account's organisation (or the sole trader's trade), as declared

The customer record the responsible person DECLARES (Marc, 2026-10-18): the legal name, trade name, legal form, business-register number, country, EU VAT number, national tax number, registered address and invoicing e-mail of the organisation or sole trader the verified person contracts for. No documented KYB: no register check, no power-to-represent check, no beneficial owners — VIES on the VAT number is the one check performed. complete and missing are computed: the fields a payment still needs (409 profile_incomplete on the checkout routes until then). Before the first PUT the answer is the skeleton: the account's kind and country, the legal name prefilled from the account's name, no address, complete: false. 401 session_required. 409 account_blocked once the account is blocked by an erasure request or the contract's end (ZADQ-311): the record is kept for the retention periods only and is not served — the same on PUT, on /v1/me/consents, on PATCH /v1/me/person, on the export and at the payment gate (where 409 profile_incomplete answers).

Authentication: passkeySession.

Responses

200 — The declared record.

Content type application/json.

Schema: Organisation

PropertyTypeRequiredDescriptionValues
kindAccountKindyes
legal_namestring, nullableyesRequired to save; for a sole trader the trading name or the person's own name, as on their tax registration.
trade_namestring, nullableyes
legal_formstring, nullableyes
registration_numberstring, nullableyesThe national business-register number as declared (EE registry code, ES Registro Mercantil entry, DE HRB, FR SIREN…).
countrystring, nullableyesISO 3166-1 alpha-2, the country of registration.
vat_idall of OrganisationVatIdyes
tax_idall of OrganisationTaxIdyes
registered_addressall of OrganisationAddressyes
invoice_emailstring, nullableyesThe invoicing address; the operational e-mail is used when absent.
completebooleanyes
missingarray of stringyesThe field paths a payment still needs, e.g. registered_address.line1, tax_id.

default — A /v1 refusal — {"error", "detail"} (platform API v1 §5).

Content type application/json.

Schema: V1Error

PropertyTypeRequiredDescriptionValues
errorstringyessession_required · passkey_required · last_passkey · ceremony_invalid · attestation_invalid · assertion_invalid · email_operational_invalid · body_invalid · origin_refused · not_found · not_available · internal · runtime_token_invalid · approval_not_pending · result_already_taken · declaration_invalid · request_invalid · cursor_invalid · rate_limited · offer_refused:<issuer code> (ZADQ-289) · kyc_current · kyc_required · entry_fee_due · reverification_required · invalid_state · sandbox_hint_not_available · invalid_sandbox_hint · issuer_unavailable (ZADQ-316) · kyc_grade_below_bundle (ZADQ-321) · person_invalid · profile_invalid · profile_incomplete · kind_locked · terms_changed · business_use_required · reauth_required (ZADQ-307) · account_blocked (ZADQ-311) · custody_version_conflict · last_wrap · passkey_not_on_account (ZADQ-293) · wraps_required (ZADQ-293, v1.3.2) · origin_invalid · key_invalid · private_key_refused · origin_in_use · key_reused · evidence_required · obligations_not_published · obligations_changed (ZADQ-362, v1.3.13) · mintid_unavailable (503, ZADQ-407: MintID unreachable since the start-up and the ids not discovered yet; nothing recorded, retry later)
detailstringyes
custody_versioninteger (int64)no409 custody_version_conflict (§5.8, v1.3.2) — the stored version, to read and retry on.
fieldsobjectnoThe refused fields by path (400 person_invalid, profile_invalid).
missingarray of stringnoThe field paths a payment still needs (409 profile_incomplete).

Example

curl -sS "<base-url>/v1/organisation" \
  --cookie "__Host-passkey_session=<api-key>"

PUT /v1/organisation

Declare (or replace) the organisation record

The full object minus the computed fields. Strings are trimmed; unknown fields answer 400 body_invalid. legal_name and country identify the record; the rest may arrive over several saves (what a payment still needs is missing). vat_id is checked against VIES on write with the operating entity's number as the requester, the consultation kept as evidence: valid | invalid (refused, 400 profile_invalid with fields.vat_id = vat_id_invalid) | unchecked (a prefix outside VIES) | unavailable (no answer; stored and retried every VIES_RETRY_EVERY). tax_id with scheme es_nif is checked for format and control character (checksum). kind may change until the first payment: 409 kind_locked after. 400 profile_invalid with fields: {<path>: required | too_long | invalid | checksum | vat_id_invalid} — paths, never values.

Authentication: passkeySession.

Request body

application/json — required

Schema: OrganisationUpdate

PropertyTypeRequiredDescriptionValues
kindAccountKindno
legal_namestringyes
trade_namestring, nullableno
legal_formstring, nullableno
registration_numberstring, nullableno
countrystringyes
vat_idstring, nullablenoThe EU VAT number with its ISO prefix; checked against VIES on write. On PUT the record's own shape {value, status?, checked_at?} is accepted too — the contract's "object minus the computed fields" (zadq.app sends it); the computed fields are ignored.
tax_idall of OrganisationTaxIdno
registered_addressall of OrganisationAddressno
invoice_emailstring, nullableno

Responses

200 — The record as saved, with complete and missing.

Content type application/json.

Schema: Organisation

PropertyTypeRequiredDescriptionValues
kindAccountKindyes
legal_namestring, nullableyesRequired to save; for a sole trader the trading name or the person's own name, as on their tax registration.
trade_namestring, nullableyes
legal_formstring, nullableyes
registration_numberstring, nullableyesThe national business-register number as declared (EE registry code, ES Registro Mercantil entry, DE HRB, FR SIREN…).
countrystring, nullableyesISO 3166-1 alpha-2, the country of registration.
vat_idall of OrganisationVatIdyes
tax_idall of OrganisationTaxIdyes
registered_addressall of OrganisationAddressyes
invoice_emailstring, nullableyesThe invoicing address; the operational e-mail is used when absent.
completebooleanyes
missingarray of stringyesThe field paths a payment still needs, e.g. registered_address.line1, tax_id.

default — A /v1 refusal — {"error", "detail"} (platform API v1 §5).

Content type application/json.

Schema: V1Error

PropertyTypeRequiredDescriptionValues
errorstringyessession_required · passkey_required · last_passkey · ceremony_invalid · attestation_invalid · assertion_invalid · email_operational_invalid · body_invalid · origin_refused · not_found · not_available · internal · runtime_token_invalid · approval_not_pending · result_already_taken · declaration_invalid · request_invalid · cursor_invalid · rate_limited · offer_refused:<issuer code> (ZADQ-289) · kyc_current · kyc_required · entry_fee_due · reverification_required · invalid_state · sandbox_hint_not_available · invalid_sandbox_hint · issuer_unavailable (ZADQ-316) · kyc_grade_below_bundle (ZADQ-321) · person_invalid · profile_invalid · profile_incomplete · kind_locked · terms_changed · business_use_required · reauth_required (ZADQ-307) · account_blocked (ZADQ-311) · custody_version_conflict · last_wrap · passkey_not_on_account (ZADQ-293) · wraps_required (ZADQ-293, v1.3.2) · origin_invalid · key_invalid · private_key_refused · origin_in_use · key_reused · evidence_required · obligations_not_published · obligations_changed (ZADQ-362, v1.3.13) · mintid_unavailable (503, ZADQ-407: MintID unreachable since the start-up and the ids not discovered yet; nothing recorded, retry later)
detailstringyes
custody_versioninteger (int64)no409 custody_version_conflict (§5.8, v1.3.2) — the stored version, to read and retry on.
fieldsobjectnoThe refused fields by path (400 person_invalid, profile_invalid).
missingarray of stringnoThe field paths a payment still needs (409 profile_incomplete).

Example

curl -sS -X PUT "<base-url>/v1/organisation" \
  --cookie "__Host-passkey_session=<api-key>" \
  -H "Content-Type: application/json" \
  -d @request-body.json

GET /v1/me/consents

The consents record — the current view of the append-only log

The Terms version accepted (version, SHA-256, time), the Privacy Policy version shown (information, never a consent), the business-use declaration's time, the marketing choice. Each is the latest entry of the account's append-only consents log — the evidence of the electronic acceptance (who, what, version, hash, time), never edited. Absent items read null.

Authentication: passkeySession.

Responses

200 — The current view.

Content type application/json.

Schema: Consents

PropertyTypeRequiredDescriptionValues
termsobject, nullableyes
terms.versionstringyes
terms.sha256stringyes
terms.accepted_atstring (date-time)yes
privacy_noticeobject, nullableyesThe Privacy Policy version shown — information, never a consent.
privacy_notice.versionstringyes
privacy_notice.shown_atstring (date-time)yes
business_useobject, nullableyes
business_use.atstring (date-time)yes
marketingobjectyes
marketing.opt_inbooleanyes
marketing.atstring (date-time), nullableyes

default — A /v1 refusal — {"error", "detail"} (platform API v1 §5).

Content type application/json.

Schema: V1Error

PropertyTypeRequiredDescriptionValues
errorstringyessession_required · passkey_required · last_passkey · ceremony_invalid · attestation_invalid · assertion_invalid · email_operational_invalid · body_invalid · origin_refused · not_found · not_available · internal · runtime_token_invalid · approval_not_pending · result_already_taken · declaration_invalid · request_invalid · cursor_invalid · rate_limited · offer_refused:<issuer code> (ZADQ-289) · kyc_current · kyc_required · entry_fee_due · reverification_required · invalid_state · sandbox_hint_not_available · invalid_sandbox_hint · issuer_unavailable (ZADQ-316) · kyc_grade_below_bundle (ZADQ-321) · person_invalid · profile_invalid · profile_incomplete · kind_locked · terms_changed · business_use_required · reauth_required (ZADQ-307) · account_blocked (ZADQ-311) · custody_version_conflict · last_wrap · passkey_not_on_account (ZADQ-293) · wraps_required (ZADQ-293, v1.3.2) · origin_invalid · key_invalid · private_key_refused · origin_in_use · key_reused · evidence_required · obligations_not_published · obligations_changed (ZADQ-362, v1.3.13) · mintid_unavailable (503, ZADQ-407: MintID unreachable since the start-up and the ids not discovered yet; nothing recorded, retry later)
detailstringyes
custody_versioninteger (int64)no409 custody_version_conflict (§5.8, v1.3.2) — the stored version, to read and retry on.
fieldsobjectnoThe refused fields by path (400 person_invalid, profile_invalid).
missingarray of stringnoThe field paths a payment still needs (409 profile_incomplete).

Example

curl -sS "<base-url>/v1/me/consents" \
  --cookie "__Host-passkey_session=<api-key>"

POST /v1/me/consents

Accept a Terms version, record the Privacy Policy shown, declare business use, set the marketing choice

Any of terms {version, sha256}, privacy_notice {version}, business_use: true, marketing: <bool>; each appends to the log. No fresh passkey assertion is required. 409 terms_changed when the Terms version or hash is not the published one (re-read /v1/legal/current and ask again); 400 business_use_required for business_use: false; 400 body_invalid for an unpublished Privacy Policy version or an empty body.

Authentication: passkeySession.

Request body

application/json — required

Schema: ConsentsUpdate

PropertyTypeRequiredDescriptionValues
termsobjectno
terms.versionstringyes
terms.sha256stringyes
privacy_noticeobjectno
privacy_notice.versionstringyes
business_usebooleannoThe declaration "I act for my business or profession"; false is refused (400 business_use_required).
marketingbooleanno

Responses

200 — The current view after the append.

Content type application/json.

Schema: Consents

PropertyTypeRequiredDescriptionValues
termsobject, nullableyes
terms.versionstringyes
terms.sha256stringyes
terms.accepted_atstring (date-time)yes
privacy_noticeobject, nullableyesThe Privacy Policy version shown — information, never a consent.
privacy_notice.versionstringyes
privacy_notice.shown_atstring (date-time)yes
business_useobject, nullableyes
business_use.atstring (date-time)yes
marketingobjectyes
marketing.opt_inbooleanyes
marketing.atstring (date-time), nullableyes

default — A /v1 refusal — {"error", "detail"} (platform API v1 §5).

Content type application/json.

Schema: V1Error

PropertyTypeRequiredDescriptionValues
errorstringyessession_required · passkey_required · last_passkey · ceremony_invalid · attestation_invalid · assertion_invalid · email_operational_invalid · body_invalid · origin_refused · not_found · not_available · internal · runtime_token_invalid · approval_not_pending · result_already_taken · declaration_invalid · request_invalid · cursor_invalid · rate_limited · offer_refused:<issuer code> (ZADQ-289) · kyc_current · kyc_required · entry_fee_due · reverification_required · invalid_state · sandbox_hint_not_available · invalid_sandbox_hint · issuer_unavailable (ZADQ-316) · kyc_grade_below_bundle (ZADQ-321) · person_invalid · profile_invalid · profile_incomplete · kind_locked · terms_changed · business_use_required · reauth_required (ZADQ-307) · account_blocked (ZADQ-311) · custody_version_conflict · last_wrap · passkey_not_on_account (ZADQ-293) · wraps_required (ZADQ-293, v1.3.2) · origin_invalid · key_invalid · private_key_refused · origin_in_use · key_reused · evidence_required · obligations_not_published · obligations_changed (ZADQ-362, v1.3.13) · mintid_unavailable (503, ZADQ-407: MintID unreachable since the start-up and the ids not discovered yet; nothing recorded, retry later)
detailstringyes
custody_versioninteger (int64)no409 custody_version_conflict (§5.8, v1.3.2) — the stored version, to read and retry on.
fieldsobjectnoThe refused fields by path (400 person_invalid, profile_invalid).
missingarray of stringnoThe field paths a payment still needs (409 profile_incomplete).

Example

curl -sS -X POST "<base-url>/v1/me/consents" \
  --cookie "__Host-passkey_session=<api-key>" \
  -H "Content-Type: application/json" \
  -d @request-body.json

GET /v1/legal/current

The Terms and the Privacy Policy versions in force (no session)

What Create your account shows and sends back: the current Terms version with its SHA-256 and url, the current Privacy Policy version with its url. The versions are published by the operator (the console); 404 not_found while none is. The version in force is the latest whose effective_at has passed — computed on read against the clock (ZADQ-313): a published version that applies later is on /v1/legal/upcoming until then.

Authentication: none — this operation is public.

Responses

200 — The versions in force.

Content type application/json.

Schema: LegalCurrent

PropertyTypeRequiredDescriptionValues
termsobjectyes
terms.versionstringyes
terms.sha256stringyes
terms.urlstringyes
terms.effective_atstring (date-time)yes
privacyobjectyes
privacy.versionstringyes
privacy.urlstringyes
privacy.effective_atstring (date-time)yes

default — A /v1 refusal — {"error", "detail"} (platform API v1 §5).

Content type application/json.

Schema: V1Error

PropertyTypeRequiredDescriptionValues
errorstringyessession_required · passkey_required · last_passkey · ceremony_invalid · attestation_invalid · assertion_invalid · email_operational_invalid · body_invalid · origin_refused · not_found · not_available · internal · runtime_token_invalid · approval_not_pending · result_already_taken · declaration_invalid · request_invalid · cursor_invalid · rate_limited · offer_refused:<issuer code> (ZADQ-289) · kyc_current · kyc_required · entry_fee_due · reverification_required · invalid_state · sandbox_hint_not_available · invalid_sandbox_hint · issuer_unavailable (ZADQ-316) · kyc_grade_below_bundle (ZADQ-321) · person_invalid · profile_invalid · profile_incomplete · kind_locked · terms_changed · business_use_required · reauth_required (ZADQ-307) · account_blocked (ZADQ-311) · custody_version_conflict · last_wrap · passkey_not_on_account (ZADQ-293) · wraps_required (ZADQ-293, v1.3.2) · origin_invalid · key_invalid · private_key_refused · origin_in_use · key_reused · evidence_required · obligations_not_published · obligations_changed (ZADQ-362, v1.3.13) · mintid_unavailable (503, ZADQ-407: MintID unreachable since the start-up and the ids not discovered yet; nothing recorded, retry later)
detailstringyes
custody_versioninteger (int64)no409 custody_version_conflict (§5.8, v1.3.2) — the stored version, to read and retry on.
fieldsobjectnoThe refused fields by path (400 person_invalid, profile_invalid).
missingarray of stringnoThe field paths a payment still needs (409 profile_incomplete).

Example

curl -sS "<base-url>/v1/legal/current"

GET /v1/legal/upcoming

The Terms and Privacy Policy versions published and not yet in force (no session)

Every version published with a later effective_at, the soonest first (empty lists when none). A Terms change applies at least 30 calendar days after its publication (Terms clause 20) unless the change is required by law (reason: required_by_law); a Privacy Policy change announced ahead applies at the date given. At effective_at the version becomes the one /v1/legal/current answers, by the clock — no job. A Terms version can be accepted before it applies (POST /v1/me/consents with its version and SHA-256).

Authentication: none — this operation is public.

Responses

200 — The versions to come.

Content type application/json.

Schema: LegalUpcoming

PropertyTypeRequiredDescriptionValues
termsarray of LegalUpcomingTermsyes
privacyarray of LegalUpcomingPrivacyyes

default — A /v1 refusal — {"error", "detail"} (platform API v1 §5).

Content type application/json.

Schema: V1Error

PropertyTypeRequiredDescriptionValues
errorstringyessession_required · passkey_required · last_passkey · ceremony_invalid · attestation_invalid · assertion_invalid · email_operational_invalid · body_invalid · origin_refused · not_found · not_available · internal · runtime_token_invalid · approval_not_pending · result_already_taken · declaration_invalid · request_invalid · cursor_invalid · rate_limited · offer_refused:<issuer code> (ZADQ-289) · kyc_current · kyc_required · entry_fee_due · reverification_required · invalid_state · sandbox_hint_not_available · invalid_sandbox_hint · issuer_unavailable (ZADQ-316) · kyc_grade_below_bundle (ZADQ-321) · person_invalid · profile_invalid · profile_incomplete · kind_locked · terms_changed · business_use_required · reauth_required (ZADQ-307) · account_blocked (ZADQ-311) · custody_version_conflict · last_wrap · passkey_not_on_account (ZADQ-293) · wraps_required (ZADQ-293, v1.3.2) · origin_invalid · key_invalid · private_key_refused · origin_in_use · key_reused · evidence_required · obligations_not_published · obligations_changed (ZADQ-362, v1.3.13) · mintid_unavailable (503, ZADQ-407: MintID unreachable since the start-up and the ids not discovered yet; nothing recorded, retry later)
detailstringyes
custody_versioninteger (int64)no409 custody_version_conflict (§5.8, v1.3.2) — the stored version, to read and retry on.
fieldsobjectnoThe refused fields by path (400 person_invalid, profile_invalid).
missingarray of stringnoThe field paths a payment still needs (409 profile_incomplete).

Example

curl -sS "<base-url>/v1/legal/upcoming"

GET /v1/me/notices

The change notices of the account — the Terms or Privacy Policy versions it is told about (ZADQ-313)

One notice per account per version, opened when the operator publishes a version that changes a previous one (for the Privacy Policy: one announced before it applies), and e-mailed to the Responsible Person's operational e-mail. A Terms notice carries the version's SHA-256 and whether the account has accepted it (this version or a later one); it clears on the acceptance (POST /v1/me/consents with terms {version, sha256}). A Privacy Policy notice clears when dismissed (POST /v1/me/notices/{id}/seen). state=open (default) lists the notices still asking for something; state=all lists every one. At effective_at the Terms version applies whether or not the account accepted it; clause 20 gives the account the right to terminate without penalty within the notice period.

Authentication: passkeySession.

Parameters

NameInRequiredTypeDescription
statequerynostringValues: "open", "all".

Responses

200 — The notices, the soonest effective first.

Content type application/json.

Schema: ChangeNotices

PropertyTypeRequiredDescriptionValues
noticesarray of ChangeNoticeyes

default — A /v1 refusal — {"error", "detail"} (platform API v1 §5).

Content type application/json.

Schema: V1Error

PropertyTypeRequiredDescriptionValues
errorstringyessession_required · passkey_required · last_passkey · ceremony_invalid · attestation_invalid · assertion_invalid · email_operational_invalid · body_invalid · origin_refused · not_found · not_available · internal · runtime_token_invalid · approval_not_pending · result_already_taken · declaration_invalid · request_invalid · cursor_invalid · rate_limited · offer_refused:<issuer code> (ZADQ-289) · kyc_current · kyc_required · entry_fee_due · reverification_required · invalid_state · sandbox_hint_not_available · invalid_sandbox_hint · issuer_unavailable (ZADQ-316) · kyc_grade_below_bundle (ZADQ-321) · person_invalid · profile_invalid · profile_incomplete · kind_locked · terms_changed · business_use_required · reauth_required (ZADQ-307) · account_blocked (ZADQ-311) · custody_version_conflict · last_wrap · passkey_not_on_account (ZADQ-293) · wraps_required (ZADQ-293, v1.3.2) · origin_invalid · key_invalid · private_key_refused · origin_in_use · key_reused · evidence_required · obligations_not_published · obligations_changed (ZADQ-362, v1.3.13) · mintid_unavailable (503, ZADQ-407: MintID unreachable since the start-up and the ids not discovered yet; nothing recorded, retry later)
detailstringyes
custody_versioninteger (int64)no409 custody_version_conflict (§5.8, v1.3.2) — the stored version, to read and retry on.
fieldsobjectnoThe refused fields by path (400 person_invalid, profile_invalid).
missingarray of stringnoThe field paths a payment still needs (409 profile_incomplete).

Example

curl -sS "<base-url>/v1/me/notices" \
  --cookie "__Host-passkey_session=<api-key>"

POST /v1/me/notices/{id}/seen

Dismiss a Privacy Policy change notice (ZADQ-313)

Records the notice as seen (the first dismissal's time is kept; a repeat answers the same). 409 invalid_state for a Terms notice — it clears on the acceptance of the version; 404 not_found for an unknown notice or another account's.

Authentication: passkeySession.

Parameters

NameInRequiredTypeDescription
idpathyesstring

Responses

200 — The notice, dismissed.

Content type application/json.

Schema: ChangeNotice

PropertyTypeRequiredDescriptionValues
idstringyes
kindstringyes"terms", "privacy"
versionstringyes
urlstringyes
effective_atstring (date-time)yes
in_forcebooleanyesThe version applies already.
openbooleanyesThe notice still asks for something — the acceptance, or reading it.
sha256string, nullableyesThe Terms version's SHA-256, to accept it with (null for the Privacy Policy).
required_by_lawbooleanyes
acceptedboolean, nullableyes
seen_atstring (date-time), nullableyes
mailed_atstring (date-time), nullableyes

default — A /v1 refusal — {"error", "detail"} (platform API v1 §5).

Content type application/json.

Schema: V1Error

PropertyTypeRequiredDescriptionValues
errorstringyessession_required · passkey_required · last_passkey · ceremony_invalid · attestation_invalid · assertion_invalid · email_operational_invalid · body_invalid · origin_refused · not_found · not_available · internal · runtime_token_invalid · approval_not_pending · result_already_taken · declaration_invalid · request_invalid · cursor_invalid · rate_limited · offer_refused:<issuer code> (ZADQ-289) · kyc_current · kyc_required · entry_fee_due · reverification_required · invalid_state · sandbox_hint_not_available · invalid_sandbox_hint · issuer_unavailable (ZADQ-316) · kyc_grade_below_bundle (ZADQ-321) · person_invalid · profile_invalid · profile_incomplete · kind_locked · terms_changed · business_use_required · reauth_required (ZADQ-307) · account_blocked (ZADQ-311) · custody_version_conflict · last_wrap · passkey_not_on_account (ZADQ-293) · wraps_required (ZADQ-293, v1.3.2) · origin_invalid · key_invalid · private_key_refused · origin_in_use · key_reused · evidence_required · obligations_not_published · obligations_changed (ZADQ-362, v1.3.13) · mintid_unavailable (503, ZADQ-407: MintID unreachable since the start-up and the ids not discovered yet; nothing recorded, retry later)
detailstringyes
custody_versioninteger (int64)no409 custody_version_conflict (§5.8, v1.3.2) — the stored version, to read and retry on.
fieldsobjectnoThe refused fields by path (400 person_invalid, profile_invalid).
missingarray of stringnoThe field paths a payment still needs (409 profile_incomplete).

Example

curl -sS -X POST "<base-url>/v1/me/notices/<id>/seen" \
  --cookie "__Host-passkey_session=<api-key>"

GET /v1/legal/terms/{version}

The exact text of a published Terms version (the accepted version, for download)

Authentication: passkeySession.

Parameters

NameInRequiredTypeDescription
versionpathyesstring

Responses

200 — The version, its SHA-256 and its text.

Content type application/json.

Schema: LegalTermsText

PropertyTypeRequiredDescriptionValues
versionstringyes
sha256stringyes
textstringyes

default — A /v1 refusal — {"error", "detail"} (platform API v1 §5).

Content type application/json.

Schema: V1Error

PropertyTypeRequiredDescriptionValues
errorstringyessession_required · passkey_required · last_passkey · ceremony_invalid · attestation_invalid · assertion_invalid · email_operational_invalid · body_invalid · origin_refused · not_found · not_available · internal · runtime_token_invalid · approval_not_pending · result_already_taken · declaration_invalid · request_invalid · cursor_invalid · rate_limited · offer_refused:<issuer code> (ZADQ-289) · kyc_current · kyc_required · entry_fee_due · reverification_required · invalid_state · sandbox_hint_not_available · invalid_sandbox_hint · issuer_unavailable (ZADQ-316) · kyc_grade_below_bundle (ZADQ-321) · person_invalid · profile_invalid · profile_incomplete · kind_locked · terms_changed · business_use_required · reauth_required (ZADQ-307) · account_blocked (ZADQ-311) · custody_version_conflict · last_wrap · passkey_not_on_account (ZADQ-293) · wraps_required (ZADQ-293, v1.3.2) · origin_invalid · key_invalid · private_key_refused · origin_in_use · key_reused · evidence_required · obligations_not_published · obligations_changed (ZADQ-362, v1.3.13) · mintid_unavailable (503, ZADQ-407: MintID unreachable since the start-up and the ids not discovered yet; nothing recorded, retry later)
detailstringyes
custody_versioninteger (int64)no409 custody_version_conflict (§5.8, v1.3.2) — the stored version, to read and retry on.
fieldsobjectnoThe refused fields by path (400 person_invalid, profile_invalid).
missingarray of stringnoThe field paths a payment still needs (409 profile_incomplete).

Example

curl -sS "<base-url>/v1/legal/terms/<version>" \
  --cookie "__Host-passkey_session=<api-key>"

GET /v1/me/export

The account's data export (Art. 15, Art. 20) — JSON

The account, the person, the declared organisation, the consents (current view and log, and biometric_consents: every consent to the face comparison — version, time, the KYC session it opened, the record; kept after a withdrawal, ZADQ-331), the passkeys (ids, labels, dates), the payTo bindings, the product records, the price lines (the invoice facts: kind, amount, state, time — no provider reference), the VIES evidence, the activity log, the erasure state, and the controller's identity. Requires a passkey sign-in within the reauth window (5 minutes by default): 403 reauth_required otherwise — the session stays valid; sign in again with the passkey and retry. The export is recorded as an activity event (data_exported). 409 account_blocked after an erasure request (ZADQ-311): download before asking for the erasure; afterwards the request goes by e-mail.

Authentication: passkeySession.

Responses

200 — The export (application/json; Content-Disposition attachment).

Content type application/json.

Type: object.

default — A /v1 refusal — {"error", "detail"} (platform API v1 §5).

Content type application/json.

Schema: V1Error

PropertyTypeRequiredDescriptionValues
errorstringyessession_required · passkey_required · last_passkey · ceremony_invalid · attestation_invalid · assertion_invalid · email_operational_invalid · body_invalid · origin_refused · not_found · not_available · internal · runtime_token_invalid · approval_not_pending · result_already_taken · declaration_invalid · request_invalid · cursor_invalid · rate_limited · offer_refused:<issuer code> (ZADQ-289) · kyc_current · kyc_required · entry_fee_due · reverification_required · invalid_state · sandbox_hint_not_available · invalid_sandbox_hint · issuer_unavailable (ZADQ-316) · kyc_grade_below_bundle (ZADQ-321) · person_invalid · profile_invalid · profile_incomplete · kind_locked · terms_changed · business_use_required · reauth_required (ZADQ-307) · account_blocked (ZADQ-311) · custody_version_conflict · last_wrap · passkey_not_on_account (ZADQ-293) · wraps_required (ZADQ-293, v1.3.2) · origin_invalid · key_invalid · private_key_refused · origin_in_use · key_reused · evidence_required · obligations_not_published · obligations_changed (ZADQ-362, v1.3.13) · mintid_unavailable (503, ZADQ-407: MintID unreachable since the start-up and the ids not discovered yet; nothing recorded, retry later)
detailstringyes
custody_versioninteger (int64)no409 custody_version_conflict (§5.8, v1.3.2) — the stored version, to read and retry on.
fieldsobjectnoThe refused fields by path (400 person_invalid, profile_invalid).
missingarray of stringnoThe field paths a payment still needs (409 profile_incomplete).

Example

curl -sS "<base-url>/v1/me/export" \
  --cookie "__Host-passkey_session=<api-key>"

POST /v1/me/erasure-request

Request the erasure of the account's data

Records the data-subject's request (once; a repeat answers the first), blocks the record for the retention jobs (ZADQ-311: the account closes at the end of the current billing period, what accounting and tax law require is kept blocked for those purposes only, the rest is erased per period), and withdraws now what the existing cascades can: every admitted vendor record (its attestations revoked, consent withdrawn), every live agent-operator record's consent at the issuer (its agents brought along). The person is answered by e-mail (ZADQ-313). Requires a passkey sign-in within the reauth window: 403 reauth_required otherwise. As built by ZADQ-311: the retention job sets every live subscription of the account's billing Customers to end at its current period's end and closes the account at the latest of those ends (at once when nothing is billed periodically); /v1/me reads account.blocked_at and account.closes_at. At the close the sessions end and the passkeys are deleted.

Authentication: passkeySession.

Responses

202 — The request is recorded.

Content type application/json.

Schema: ErasureState

PropertyTypeRequiredDescriptionValues
statestringyes"requested"
atstring (date-time)yes

default — A /v1 refusal — {"error", "detail"} (platform API v1 §5).

Content type application/json.

Schema: V1Error

PropertyTypeRequiredDescriptionValues
errorstringyessession_required · passkey_required · last_passkey · ceremony_invalid · attestation_invalid · assertion_invalid · email_operational_invalid · body_invalid · origin_refused · not_found · not_available · internal · runtime_token_invalid · approval_not_pending · result_already_taken · declaration_invalid · request_invalid · cursor_invalid · rate_limited · offer_refused:<issuer code> (ZADQ-289) · kyc_current · kyc_required · entry_fee_due · reverification_required · invalid_state · sandbox_hint_not_available · invalid_sandbox_hint · issuer_unavailable (ZADQ-316) · kyc_grade_below_bundle (ZADQ-321) · person_invalid · profile_invalid · profile_incomplete · kind_locked · terms_changed · business_use_required · reauth_required (ZADQ-307) · account_blocked (ZADQ-311) · custody_version_conflict · last_wrap · passkey_not_on_account (ZADQ-293) · wraps_required (ZADQ-293, v1.3.2) · origin_invalid · key_invalid · private_key_refused · origin_in_use · key_reused · evidence_required · obligations_not_published · obligations_changed (ZADQ-362, v1.3.13) · mintid_unavailable (503, ZADQ-407: MintID unreachable since the start-up and the ids not discovered yet; nothing recorded, retry later)
detailstringyes
custody_versioninteger (int64)no409 custody_version_conflict (§5.8, v1.3.2) — the stored version, to read and retry on.
fieldsobjectnoThe refused fields by path (400 person_invalid, profile_invalid).
missingarray of stringnoThe field paths a payment still needs (409 profile_incomplete).

Example

curl -sS -X POST "<base-url>/v1/me/erasure-request" \
  --cookie "__Host-passkey_session=<api-key>"

GET /v1/sellers

The account's seller records (the vendor product), under the passkey session

The sellers bound to the account through its payto_bindings (ZADQ-287), oldest first, as the v0 seller routes already serve them (platform API v1.3 §5.9, ZADQ-324): the endpoint, its admission state, whether the current terms version is acknowledged, the billing state and tier, the attestation, the v1 credential's state (with the last cadence presentation's outcome) and the dashboard verdict. No new data: the record's detail, its KYC hand-off, deposit and events stay on GET /v0/sellers/{sellerId} and its sub-routes, which the passkey session also reads (on the app host once its /v0/* path behaviour is on; infra/web). Writes touching a payTo keep the wallet bearer (ADR-0015). A pending seller's admission state is refreshed from the KYC boundary on the read, as GET /v0/sellers/{id} does. 401 session_required.

Authentication: passkeySession.

Responses

200 — The account's sellers.

Content type application/json.

Schema: PlatformSellerList

PropertyTypeRequiredDescriptionValues
sellersarray of PlatformSelleryes

default — A /v1 refusal — {"error", "detail"} (platform API v1 §5).

Content type application/json.

Schema: V1Error

PropertyTypeRequiredDescriptionValues
errorstringyessession_required · passkey_required · last_passkey · ceremony_invalid · attestation_invalid · assertion_invalid · email_operational_invalid · body_invalid · origin_refused · not_found · not_available · internal · runtime_token_invalid · approval_not_pending · result_already_taken · declaration_invalid · request_invalid · cursor_invalid · rate_limited · offer_refused:<issuer code> (ZADQ-289) · kyc_current · kyc_required · entry_fee_due · reverification_required · invalid_state · sandbox_hint_not_available · invalid_sandbox_hint · issuer_unavailable (ZADQ-316) · kyc_grade_below_bundle (ZADQ-321) · person_invalid · profile_invalid · profile_incomplete · kind_locked · terms_changed · business_use_required · reauth_required (ZADQ-307) · account_blocked (ZADQ-311) · custody_version_conflict · last_wrap · passkey_not_on_account (ZADQ-293) · wraps_required (ZADQ-293, v1.3.2) · origin_invalid · key_invalid · private_key_refused · origin_in_use · key_reused · evidence_required · obligations_not_published · obligations_changed (ZADQ-362, v1.3.13) · mintid_unavailable (503, ZADQ-407: MintID unreachable since the start-up and the ids not discovered yet; nothing recorded, retry later)
detailstringyes
custody_versioninteger (int64)no409 custody_version_conflict (§5.8, v1.3.2) — the stored version, to read and retry on.
fieldsobjectnoThe refused fields by path (400 person_invalid, profile_invalid).
missingarray of stringnoThe field paths a payment still needs (409 profile_incomplete).

Example

curl -sS "<base-url>/v1/sellers" \
  --cookie "__Host-passkey_session=<api-key>"

GET /v1/approvals

The approvals inbox

The account's approval requests, newest first (at most 200), in one state with ?state=. Kinds: delegate (an enrolment a runtime claimed), present (a verifier's declaration a runtime brings) and renew (an agent's renewal). A pending request past its expiry reads expired. 401 session_required.

Authentication: passkeySession.

Parameters

NameInRequiredTypeDescription
statequerynostringValues: "pending", "approved", "declined", "expired", "failed".

Responses

200 — The inbox.

Content type application/json.

Schema: ApprovalList

PropertyTypeRequiredDescriptionValues
approvalsarray of ApprovalSummaryyes

default — A /v1 refusal — {"error", "detail"} (platform API v1 §5).

Content type application/json.

Schema: V1Error

PropertyTypeRequiredDescriptionValues
errorstringyessession_required · passkey_required · last_passkey · ceremony_invalid · attestation_invalid · assertion_invalid · email_operational_invalid · body_invalid · origin_refused · not_found · not_available · internal · runtime_token_invalid · approval_not_pending · result_already_taken · declaration_invalid · request_invalid · cursor_invalid · rate_limited · offer_refused:<issuer code> (ZADQ-289) · kyc_current · kyc_required · entry_fee_due · reverification_required · invalid_state · sandbox_hint_not_available · invalid_sandbox_hint · issuer_unavailable (ZADQ-316) · kyc_grade_below_bundle (ZADQ-321) · person_invalid · profile_invalid · profile_incomplete · kind_locked · terms_changed · business_use_required · reauth_required (ZADQ-307) · account_blocked (ZADQ-311) · custody_version_conflict · last_wrap · passkey_not_on_account (ZADQ-293) · wraps_required (ZADQ-293, v1.3.2) · origin_invalid · key_invalid · private_key_refused · origin_in_use · key_reused · evidence_required · obligations_not_published · obligations_changed (ZADQ-362, v1.3.13) · mintid_unavailable (503, ZADQ-407: MintID unreachable since the start-up and the ids not discovered yet; nothing recorded, retry later)
detailstringyes
custody_versioninteger (int64)no409 custody_version_conflict (§5.8, v1.3.2) — the stored version, to read and retry on.
fieldsobjectnoThe refused fields by path (400 person_invalid, profile_invalid).
missingarray of stringnoThe field paths a payment still needs (409 profile_incomplete).

Example

curl -sS "<base-url>/v1/approvals" \
  --cookie "__Host-passkey_session=<api-key>"

POST /v1/approvals

A runtime asks the person to prove something (kind present only)

Under the runtime credential (Authorization: Bearer <runtime_token>). The request carries the verifier's declaration — profile, origin, challenge endpoint, claim policy, issuer policy — never a challenge (an unknown field is refused). The challenge endpoint is https (http on loopback only) on the verifier origin's host or a subdomain of it. from is the credential's enrolment or agent and its runtime. expires_in_s defaults to 600 (30 to 3600). 400 declaration_invalid · body_invalid; 401 runtime_token_invalid; 429 rate_limited past 20 pending requests of one runtime credential. principal_mode (ZADQ-294): runtime (the operator's runtime holds the person's credential and posts the result) or browser (the person's browser does); absent, the mode of the runtime credential's enrolment. Browser-mode present approvals are closed on every deployment (BROWSER_PRESENT=off) until MintID publishes @mintid-net/holder 0.1.1 — the proof does not fit the ten-second window on slow devices yet: 409 mode_not_available.

Authentication: runtimeCredential.

Request body

application/json — required

Schema: PresentApprovalRequest

PropertyTypeRequiredDescriptionValues
kindstringyes"present"
purposestringyes
declarationPresentDeclarationyes
expires_in_sintegerno
principal_modePrincipalModeno

Responses

202 — Pending in the person's inbox.

Content type application/json.

Schema: PresentApprovalCreated

PropertyTypeRequiredDescriptionValues
idstringyes
stateApprovalStateyes
expires_atstring (date-time)yes

default — A /v1 refusal — {"error", "detail"} (platform API v1 §5).

Content type application/json.

Schema: V1Error

PropertyTypeRequiredDescriptionValues
errorstringyessession_required · passkey_required · last_passkey · ceremony_invalid · attestation_invalid · assertion_invalid · email_operational_invalid · body_invalid · origin_refused · not_found · not_available · internal · runtime_token_invalid · approval_not_pending · result_already_taken · declaration_invalid · request_invalid · cursor_invalid · rate_limited · offer_refused:<issuer code> (ZADQ-289) · kyc_current · kyc_required · entry_fee_due · reverification_required · invalid_state · sandbox_hint_not_available · invalid_sandbox_hint · issuer_unavailable (ZADQ-316) · kyc_grade_below_bundle (ZADQ-321) · person_invalid · profile_invalid · profile_incomplete · kind_locked · terms_changed · business_use_required · reauth_required (ZADQ-307) · account_blocked (ZADQ-311) · custody_version_conflict · last_wrap · passkey_not_on_account (ZADQ-293) · wraps_required (ZADQ-293, v1.3.2) · origin_invalid · key_invalid · private_key_refused · origin_in_use · key_reused · evidence_required · obligations_not_published · obligations_changed (ZADQ-362, v1.3.13) · mintid_unavailable (503, ZADQ-407: MintID unreachable since the start-up and the ids not discovered yet; nothing recorded, retry later)
detailstringyes
custody_versioninteger (int64)no409 custody_version_conflict (§5.8, v1.3.2) — the stored version, to read and retry on.
fieldsobjectnoThe refused fields by path (400 person_invalid, profile_invalid).
missingarray of stringnoThe field paths a payment still needs (409 profile_incomplete).

Example

curl -sS -X POST "<base-url>/v1/approvals" \
  -H "Authorization: Bearer <session-credential>" \
  -H "Content-Type: application/json" \
  -d @request-body.json

GET /v1/approvals/{approvalId}

One approval (the dashboard) or the runtime's long-poll

Under the passkey session: the approval with what it carries (delegate, present or renew), decided_at once closed, failure for failed, and for a present approval result_taken once its result was delivered.

Under the runtime credential (Authorization: Bearer <runtime_token>), within its scope: the long-poll. ?wait= (0 to 30 seconds; about 1 while a person is deciding) holds the answer until the state changes, or, for an approved present approval, until the holder's result arrives: 200 {state, failure?, result?} with the result {session_id, request, envelope} delivered once and deleted; 204 on every poll after delivery. A declined or expired approval answers its state and nothing else.

Authentication: passkeySession or runtimeCredential.

Parameters

NameInRequiredTypeDescription
approvalIdpathyesstringThe approval's handle (apr_…).
waitquerynointegerLong-poll seconds (runtime credential only), 0 to 30.

Responses

200 — The approval (dashboard) or the poll's answer (runtime).

Content type application/json.

One of:

204 — Runtime only — the result was delivered; nothing more.

default — A /v1 refusal — {"error", "detail"} (platform API v1 §5).

Content type application/json.

Schema: V1Error

PropertyTypeRequiredDescriptionValues
errorstringyessession_required · passkey_required · last_passkey · ceremony_invalid · attestation_invalid · assertion_invalid · email_operational_invalid · body_invalid · origin_refused · not_found · not_available · internal · runtime_token_invalid · approval_not_pending · result_already_taken · declaration_invalid · request_invalid · cursor_invalid · rate_limited · offer_refused:<issuer code> (ZADQ-289) · kyc_current · kyc_required · entry_fee_due · reverification_required · invalid_state · sandbox_hint_not_available · invalid_sandbox_hint · issuer_unavailable (ZADQ-316) · kyc_grade_below_bundle (ZADQ-321) · person_invalid · profile_invalid · profile_incomplete · kind_locked · terms_changed · business_use_required · reauth_required (ZADQ-307) · account_blocked (ZADQ-311) · custody_version_conflict · last_wrap · passkey_not_on_account (ZADQ-293) · wraps_required (ZADQ-293, v1.3.2) · origin_invalid · key_invalid · private_key_refused · origin_in_use · key_reused · evidence_required · obligations_not_published · obligations_changed (ZADQ-362, v1.3.13) · mintid_unavailable (503, ZADQ-407: MintID unreachable since the start-up and the ids not discovered yet; nothing recorded, retry later)
detailstringyes
custody_versioninteger (int64)no409 custody_version_conflict (§5.8, v1.3.2) — the stored version, to read and retry on.
fieldsobjectnoThe refused fields by path (400 person_invalid, profile_invalid).
missingarray of stringnoThe field paths a payment still needs (409 profile_incomplete).

Example

curl -sS "<base-url>/v1/approvals/<approvalId>" \
  --cookie "__Host-passkey_session=<api-key>"

POST /v1/approvals/{approvalId}/approve

Approve — the passkey session plus a fresh WebAuthn assertion

The body carries a fresh assertion of the session's own person, answered to the request options of POST /v1/auth/passkeys/login/options (taken once; it opens no session). Approving a delegate records the decision and hands it to the enrolment's next step (the offer); if that step is refused the approval reads failed and the route answers 422 offer_refused:<issuer code>. For a browser-mode delegate or renew (principal_mode: browser, ZADQ-294) whose price line settles at once, the answer carries the issuer's agent offer once — the operator's price line stripped, Cache-Control: no-store, never stored or logged — for the browser's credential step inside a fresh issuer challenge; the approval reads approved and the enrolment waits for the browser's material (POST /v1/enrolments/{id}/mint). A browser-mode present approval is closed while BROWSER_PRESENT is off (409 mode_not_available, until @mintid-net/holder 0.1.1). 400 body_invalid without an assertion; 401 assertion_invalid; 409 ceremony_invalid · approval_not_pending; 404 not_found.

Authentication: passkeySession.

Parameters

NameInRequiredTypeDescription
approvalIdpathyesstringThe approval's handle (apr_…).

Request body

application/json — required

Schema: ApproveRequest

PropertyTypeRequiredDescriptionValues
assertionobjectyesThe PublicKeyCredential the browser answered to the login options (toJSON form).

Responses

200 — Approved.

Content type application/json.

Schema: ApprovalDecided

PropertyTypeRequiredDescriptionValues
stateApprovalStateyes
offerobjectnoBrowser-mode delegate or renew only (ZADQ-294), once: the issuer's agent offer for the browser's credential step — {credential_offer, mint_challenge, expires_at, scope, bundle}, the operator's price line stripped. Never stored or logged.
offer_expires_atstring (date-time)no

default — A /v1 refusal — {"error", "detail"} (platform API v1 §5).

Content type application/json.

Schema: V1Error

PropertyTypeRequiredDescriptionValues
errorstringyessession_required · passkey_required · last_passkey · ceremony_invalid · attestation_invalid · assertion_invalid · email_operational_invalid · body_invalid · origin_refused · not_found · not_available · internal · runtime_token_invalid · approval_not_pending · result_already_taken · declaration_invalid · request_invalid · cursor_invalid · rate_limited · offer_refused:<issuer code> (ZADQ-289) · kyc_current · kyc_required · entry_fee_due · reverification_required · invalid_state · sandbox_hint_not_available · invalid_sandbox_hint · issuer_unavailable (ZADQ-316) · kyc_grade_below_bundle (ZADQ-321) · person_invalid · profile_invalid · profile_incomplete · kind_locked · terms_changed · business_use_required · reauth_required (ZADQ-307) · account_blocked (ZADQ-311) · custody_version_conflict · last_wrap · passkey_not_on_account (ZADQ-293) · wraps_required (ZADQ-293, v1.3.2) · origin_invalid · key_invalid · private_key_refused · origin_in_use · key_reused · evidence_required · obligations_not_published · obligations_changed (ZADQ-362, v1.3.13) · mintid_unavailable (503, ZADQ-407: MintID unreachable since the start-up and the ids not discovered yet; nothing recorded, retry later)
detailstringyes
custody_versioninteger (int64)no409 custody_version_conflict (§5.8, v1.3.2) — the stored version, to read and retry on.
fieldsobjectnoThe refused fields by path (400 person_invalid, profile_invalid).
missingarray of stringnoThe field paths a payment still needs (409 profile_incomplete).

Example

curl -sS -X POST "<base-url>/v1/approvals/<approvalId>/approve" \
  --cookie "__Host-passkey_session=<api-key>" \
  -H "Content-Type: application/json" \
  -d @request-body.json

POST /v1/approvals/{approvalId}/decline

Decline — nothing is delivered

Closes a pending approval as declined. A declined present request delivers nothing to the runtime. 409 approval_not_pending; 404 not_found.

Authentication: passkeySession.

Parameters

NameInRequiredTypeDescription
approvalIdpathyesstringThe approval's handle (apr_…).

Request body

application/json

Type: object.

Responses

200 — Declined.

Content type application/json.

Schema: ApprovalDecided

PropertyTypeRequiredDescriptionValues
stateApprovalStateyes
offerobjectnoBrowser-mode delegate or renew only (ZADQ-294), once: the issuer's agent offer for the browser's credential step — {credential_offer, mint_challenge, expires_at, scope, bundle}, the operator's price line stripped. Never stored or logged.
offer_expires_atstring (date-time)no

default — A /v1 refusal — {"error", "detail"} (platform API v1 §5).

Content type application/json.

Schema: V1Error

PropertyTypeRequiredDescriptionValues
errorstringyessession_required · passkey_required · last_passkey · ceremony_invalid · attestation_invalid · assertion_invalid · email_operational_invalid · body_invalid · origin_refused · not_found · not_available · internal · runtime_token_invalid · approval_not_pending · result_already_taken · declaration_invalid · request_invalid · cursor_invalid · rate_limited · offer_refused:<issuer code> (ZADQ-289) · kyc_current · kyc_required · entry_fee_due · reverification_required · invalid_state · sandbox_hint_not_available · invalid_sandbox_hint · issuer_unavailable (ZADQ-316) · kyc_grade_below_bundle (ZADQ-321) · person_invalid · profile_invalid · profile_incomplete · kind_locked · terms_changed · business_use_required · reauth_required (ZADQ-307) · account_blocked (ZADQ-311) · custody_version_conflict · last_wrap · passkey_not_on_account (ZADQ-293) · wraps_required (ZADQ-293, v1.3.2) · origin_invalid · key_invalid · private_key_refused · origin_in_use · key_reused · evidence_required · obligations_not_published · obligations_changed (ZADQ-362, v1.3.13) · mintid_unavailable (503, ZADQ-407: MintID unreachable since the start-up and the ids not discovered yet; nothing recorded, retry later)
detailstringyes
custody_versioninteger (int64)no409 custody_version_conflict (§5.8, v1.3.2) — the stored version, to read and retry on.
fieldsobjectnoThe refused fields by path (400 person_invalid, profile_invalid).
missingarray of stringnoThe field paths a payment still needs (409 profile_incomplete).

Example

curl -sS -X POST "<base-url>/v1/approvals/<approvalId>/decline" \
  --cookie "__Host-passkey_session=<api-key>" \
  -H "Content-Type: application/json" \
  -d @request-body.json

POST /v1/approvals/{approvalId}/result

The holder's runtime posts a present result, once

After the person approved a present request, the holder fetches the challenge from the declared endpoint, presents at once and posts {session_id, request, envelope} here — in stage 1 the operator's runtime under its runtime credential; in stage 2 the browser under the passkey session. Accepted once (202), held encrypted until the operator's poll takes it, deleted on delivery. A result not taken within two minutes is deleted and the approval reads failed(result_not_taken). Instead of a result the holder may post {failure: <code>} (ZADQ-294; closed: window_lapsed, challenge_unreachable, the holder's refusal codes challenge_unsigned, challenge_key_unknown, challenge_origin_mismatch, challenge_profile_mismatch, challenge_expired, challenge_replayed, policy_unsatisfiable, credential_revoked, module_trapped, and person_cancelled): the approval reads failed(<code>). 202 {state}: approved (the result held) or failed. The poster must be the side that holds the person's holder for the approval (principal_mode): a browser on a runtime-mode approval, or a runtime on a browser-mode one, answers 409 mode_not_available, as does every browser post while BROWSER_PRESENT is off. 400 request_invalid · reason_invalid · body_invalid (not a present approval); 409 approval_not_pending · result_already_taken.

Authentication: runtimeCredential or passkeySession.

Parameters

NameInRequiredTypeDescription
approvalIdpathyesstringThe approval's handle (apr_…).

Request body

application/json — required

One of:

Responses

202 — Held until the operator's poll takes it, or failed.

Content type application/json.

Schema: ApprovalDecided

PropertyTypeRequiredDescriptionValues
stateApprovalStateyes
offerobjectnoBrowser-mode delegate or renew only (ZADQ-294), once: the issuer's agent offer for the browser's credential step — {credential_offer, mint_challenge, expires_at, scope, bundle}, the operator's price line stripped. Never stored or logged.
offer_expires_atstring (date-time)no

default — A /v1 refusal — {"error", "detail"} (platform API v1 §5).

Content type application/json.

Schema: V1Error

PropertyTypeRequiredDescriptionValues
errorstringyessession_required · passkey_required · last_passkey · ceremony_invalid · attestation_invalid · assertion_invalid · email_operational_invalid · body_invalid · origin_refused · not_found · not_available · internal · runtime_token_invalid · approval_not_pending · result_already_taken · declaration_invalid · request_invalid · cursor_invalid · rate_limited · offer_refused:<issuer code> (ZADQ-289) · kyc_current · kyc_required · entry_fee_due · reverification_required · invalid_state · sandbox_hint_not_available · invalid_sandbox_hint · issuer_unavailable (ZADQ-316) · kyc_grade_below_bundle (ZADQ-321) · person_invalid · profile_invalid · profile_incomplete · kind_locked · terms_changed · business_use_required · reauth_required (ZADQ-307) · account_blocked (ZADQ-311) · custody_version_conflict · last_wrap · passkey_not_on_account (ZADQ-293) · wraps_required (ZADQ-293, v1.3.2) · origin_invalid · key_invalid · private_key_refused · origin_in_use · key_reused · evidence_required · obligations_not_published · obligations_changed (ZADQ-362, v1.3.13) · mintid_unavailable (503, ZADQ-407: MintID unreachable since the start-up and the ids not discovered yet; nothing recorded, retry later)
detailstringyes
custody_versioninteger (int64)no409 custody_version_conflict (§5.8, v1.3.2) — the stored version, to read and retry on.
fieldsobjectnoThe refused fields by path (400 person_invalid, profile_invalid).
missingarray of stringnoThe field paths a payment still needs (409 profile_incomplete).

Example

curl -sS -X POST "<base-url>/v1/approvals/<approvalId>/result" \
  -H "Authorization: Bearer <session-credential>" \
  -H "Content-Type: application/json" \
  -d @request-body.json

GET /v1/activity

The activity log — reason codes, never a value

The account's events, newest first, 50 a page; next_cursor while more remain. Each event: the time, the kind, the state and reason code where they apply, at most one reference (an enrolment, an agent or an approval) and the actor. Never a value: no seller id, limit, credential id, envelope, pseudonym or decision record. 400 cursor_invalid.

Authentication: passkeySession.

Parameters

NameInRequiredTypeDescription
cursorquerynostring

Responses

200 — A page of events.

Content type application/json.

Schema: ActivityPage

PropertyTypeRequiredDescriptionValues
eventsarray of ActivityEventyes
next_cursorstringno

default — A /v1 refusal — {"error", "detail"} (platform API v1 §5).

Content type application/json.

Schema: V1Error

PropertyTypeRequiredDescriptionValues
errorstringyessession_required · passkey_required · last_passkey · ceremony_invalid · attestation_invalid · assertion_invalid · email_operational_invalid · body_invalid · origin_refused · not_found · not_available · internal · runtime_token_invalid · approval_not_pending · result_already_taken · declaration_invalid · request_invalid · cursor_invalid · rate_limited · offer_refused:<issuer code> (ZADQ-289) · kyc_current · kyc_required · entry_fee_due · reverification_required · invalid_state · sandbox_hint_not_available · invalid_sandbox_hint · issuer_unavailable (ZADQ-316) · kyc_grade_below_bundle (ZADQ-321) · person_invalid · profile_invalid · profile_incomplete · kind_locked · terms_changed · business_use_required · reauth_required (ZADQ-307) · account_blocked (ZADQ-311) · custody_version_conflict · last_wrap · passkey_not_on_account (ZADQ-293) · wraps_required (ZADQ-293, v1.3.2) · origin_invalid · key_invalid · private_key_refused · origin_in_use · key_reused · evidence_required · obligations_not_published · obligations_changed (ZADQ-362, v1.3.13) · mintid_unavailable (503, ZADQ-407: MintID unreachable since the start-up and the ids not discovered yet; nothing recorded, retry later)
detailstringyes
custody_versioninteger (int64)no409 custody_version_conflict (§5.8, v1.3.2) — the stored version, to read and retry on.
fieldsobjectnoThe refused fields by path (400 person_invalid, profile_invalid).
missingarray of stringnoThe field paths a payment still needs (409 profile_incomplete).

Example

curl -sS "<base-url>/v1/activity" \
  --cookie "__Host-passkey_session=<api-key>"

GET /v1/enrolments

The account's enrolments (dashboard) or a runtime's own (runtime credential)

Under the passkey session: the account's enrolments, newest first (at most 200), kind enrol and the renewals (renewal) the person asked for. Under the runtime credential: the enrolments it covers — its own and the renewals of its agent (how a runtime learns that a renewal was asked: it then polls that enrolment as a first mint). Due enrolments are closed before the read.

Authentication: passkeySession or runtimeCredential.

Responses

200 — The enrolments.

Content type application/json.

Schema: EnrolmentList

PropertyTypeRequiredDescriptionValues
enrolmentsarray of EnrolmentSummaryyes

default — A /v1 refusal — {"error", "detail"} (platform API v1 §5).

Content type application/json.

Schema: V1Error

PropertyTypeRequiredDescriptionValues
errorstringyessession_required · passkey_required · last_passkey · ceremony_invalid · attestation_invalid · assertion_invalid · email_operational_invalid · body_invalid · origin_refused · not_found · not_available · internal · runtime_token_invalid · approval_not_pending · result_already_taken · declaration_invalid · request_invalid · cursor_invalid · rate_limited · offer_refused:<issuer code> (ZADQ-289) · kyc_current · kyc_required · entry_fee_due · reverification_required · invalid_state · sandbox_hint_not_available · invalid_sandbox_hint · issuer_unavailable (ZADQ-316) · kyc_grade_below_bundle (ZADQ-321) · person_invalid · profile_invalid · profile_incomplete · kind_locked · terms_changed · business_use_required · reauth_required (ZADQ-307) · account_blocked (ZADQ-311) · custody_version_conflict · last_wrap · passkey_not_on_account (ZADQ-293) · wraps_required (ZADQ-293, v1.3.2) · origin_invalid · key_invalid · private_key_refused · origin_in_use · key_reused · evidence_required · obligations_not_published · obligations_changed (ZADQ-362, v1.3.13) · mintid_unavailable (503, ZADQ-407: MintID unreachable since the start-up and the ids not discovered yet; nothing recorded, retry later)
detailstringyes
custody_versioninteger (int64)no409 custody_version_conflict (§5.8, v1.3.2) — the stored version, to read and retry on.
fieldsobjectnoThe refused fields by path (400 person_invalid, profile_invalid).
missingarray of stringnoThe field paths a payment still needs (409 profile_incomplete).

Example

curl -sS "<base-url>/v1/enrolments" \
  --cookie "__Host-passkey_session=<api-key>"

POST /v1/enrolments

Create an enrolment — a one-time code for the agent's runtime

The bundle and its params are checked against the catalogue the issuer serves (read and cached), before anything is stored; the lease defaults to the bundle's (ZadQ's catalogue) or 30 days, at most 90. principal_mode: browser (ZADQ-294) is accepted only while the account's identity credential is held in a browser (the custody store, GET /v1/custody/browser state: held), else 409 mode_not_available. The code (8 characters, Crockford base32) is shown once and kept as a keyed hash; claimable for 24 hours, once. The Idempotency-Key header is required: the same key and body answer the same enrolment (with a fresh code while it is unclaimed), 409 idempotency_conflict with another body, 409 enrolment_not_claimable once claimed. 400 bundle_unknown · bundle_params_invalid · body_invalid; 409 kyc_required · kyc_grade_below_bundle (ZADQ-321: the served catalogue's assurance_grade_min of the bundle is above the person's grade — refused here, before any line opens, with both grades in the detail; a record without a grade goes through) · product_inactive (no activation, or the product pending or suspended) · credential_not_held (ZADQ-424, runtime mode: the person is verified and the fee recorded, but the identity credential is not held yet — the detail names the two ways to hold it, keep it in this browser or in the operator's runtime) · entry_fee_due · seats_exhausted · person_cap_reached; 503 catalogue_unavailable.

Authentication: passkeySession.

Parameters

NameInRequiredTypeDescription
Idempotency-Keyheadernostring

Request body

application/json — required

Schema: EnrolmentRequest

PropertyTypeRequiredDescriptionValues
namestringyesThe agent's name in the runtime, e.g. trip-planner/concierge_agent.
bundlestringnoA bundle of the issuer's served catalogue (GET /v1/catalogue); required unless referral_id presets it.
referral_idstringnov1.3.14 (§5.16) — the first bounded agent preset from one of the account's referrals: the bundle (when left out; else it must be the referral's) and the refusing service's origin as a counterparty (added when left out). 404 referral_unknown; 409 referral_closed; 400 bundle_params_invalid for another bundle.
bundle_paramsEnrolmentBundleParamsyes
lease_secondsintegerno
principal_modestringyes"runtime", "browser"

Responses

201 — The enrolment and its code (shown once).

Content type application/json.

Schema: EnrolmentCreated

PropertyTypeRequiredDescriptionValues
idstringyes
codestringyesThe one-time code (8 characters), shown once.
claim_urlstringyesThe app's origin with the code in the fragment (<origin>/claim#<code>), for the QR code.
expires_atstring (date-time)yes

default — A /v1 refusal — {"error", "detail"} (platform API v1 §5).

Content type application/json.

Schema: V1Error

PropertyTypeRequiredDescriptionValues
errorstringyessession_required · passkey_required · last_passkey · ceremony_invalid · attestation_invalid · assertion_invalid · email_operational_invalid · body_invalid · origin_refused · not_found · not_available · internal · runtime_token_invalid · approval_not_pending · result_already_taken · declaration_invalid · request_invalid · cursor_invalid · rate_limited · offer_refused:<issuer code> (ZADQ-289) · kyc_current · kyc_required · entry_fee_due · reverification_required · invalid_state · sandbox_hint_not_available · invalid_sandbox_hint · issuer_unavailable (ZADQ-316) · kyc_grade_below_bundle (ZADQ-321) · person_invalid · profile_invalid · profile_incomplete · kind_locked · terms_changed · business_use_required · reauth_required (ZADQ-307) · account_blocked (ZADQ-311) · custody_version_conflict · last_wrap · passkey_not_on_account (ZADQ-293) · wraps_required (ZADQ-293, v1.3.2) · origin_invalid · key_invalid · private_key_refused · origin_in_use · key_reused · evidence_required · obligations_not_published · obligations_changed (ZADQ-362, v1.3.13) · mintid_unavailable (503, ZADQ-407: MintID unreachable since the start-up and the ids not discovered yet; nothing recorded, retry later)
detailstringyes
custody_versioninteger (int64)no409 custody_version_conflict (§5.8, v1.3.2) — the stored version, to read and retry on.
fieldsobjectnoThe refused fields by path (400 person_invalid, profile_invalid).
missingarray of stringnoThe field paths a payment still needs (409 profile_incomplete).

Example

curl -sS -X POST "<base-url>/v1/enrolments" \
  --cookie "__Host-passkey_session=<api-key>" \
  -H "Content-Type: application/json" \
  -d @request-body.json

POST /v1/enrolments/claim

The runtime claims a code (no session; throttled per IP)

The runtime posts the code and its descriptor; it receives the runtime credential (shown once) scoped to the enrolment, and a delegate approval lands in the person's inbox. expires_at is when that approval expires. The same code again from the same runtime (kind and instance_ref) answers the same enrolment with a new runtime credential (the earlier one revoked); after failed(token_expired) it starts a new approval. key_attestation is accepted and not used (ZadQ sends the issuer no attestation evidence). 409 enrolment_not_claimable (unknown, expired or spent code, or another runtime); 400 body_invalid; 429 rate_limited.

Authentication: none — this operation is public.

Request body

application/json — required

Schema: EnrolmentClaimRequest

PropertyTypeRequiredDescriptionValues
codestringyes
runtimeEnrolmentRuntimeyes
key_attestationobjectnoAccepted, not used, not kept (ZadQ sends the issuer no attestation evidence).

Responses

200 — Claimed.

Content type application/json.

Schema: EnrolmentClaimed

PropertyTypeRequiredDescriptionValues
enrolment_idstringyes
runtime_tokenstringyesThe runtime credential (rt1_…), shown once; sent as Authorization: Bearer on the runtime routes.
expires_atstring (date-time)yesWhen the delegate approval expires (keep polling until then).

default — A /v1 refusal — {"error", "detail"} (platform API v1 §5).

Content type application/json.

Schema: V1Error

PropertyTypeRequiredDescriptionValues
errorstringyessession_required · passkey_required · last_passkey · ceremony_invalid · attestation_invalid · assertion_invalid · email_operational_invalid · body_invalid · origin_refused · not_found · not_available · internal · runtime_token_invalid · approval_not_pending · result_already_taken · declaration_invalid · request_invalid · cursor_invalid · rate_limited · offer_refused:<issuer code> (ZADQ-289) · kyc_current · kyc_required · entry_fee_due · reverification_required · invalid_state · sandbox_hint_not_available · invalid_sandbox_hint · issuer_unavailable (ZADQ-316) · kyc_grade_below_bundle (ZADQ-321) · person_invalid · profile_invalid · profile_incomplete · kind_locked · terms_changed · business_use_required · reauth_required (ZADQ-307) · account_blocked (ZADQ-311) · custody_version_conflict · last_wrap · passkey_not_on_account (ZADQ-293) · wraps_required (ZADQ-293, v1.3.2) · origin_invalid · key_invalid · private_key_refused · origin_in_use · key_reused · evidence_required · obligations_not_published · obligations_changed (ZADQ-362, v1.3.13) · mintid_unavailable (503, ZADQ-407: MintID unreachable since the start-up and the ids not discovered yet; nothing recorded, retry later)
detailstringyes
custody_versioninteger (int64)no409 custody_version_conflict (§5.8, v1.3.2) — the stored version, to read and retry on.
fieldsobjectnoThe refused fields by path (400 person_invalid, profile_invalid).
missingarray of stringnoThe field paths a payment still needs (409 profile_incomplete).

Example

curl -sS -X POST "<base-url>/v1/enrolments/claim" \
  -H "Content-Type: application/json" \
  -d @request-body.json

GET /v1/enrolments/{enrolmentId}

One enrolment (dashboard) or the runtime's long-poll

Under the passkey session: the enrolment. Under the runtime credential, within its scope: the long-poll. ?wait= (0 to 30 seconds) holds the answer while the enrolment is created or claimed; 200 {state, failure?, agent_id?, mint?} with the mint material delivered once (the enrolment then reads minting) and deleted; 204 on every poll after delivery. In runtime mode the material is the issuer's agent offer itself — credential_offer, mint_challenge, expires_at, scope, bundle — with the operator's price line stripped; the runtime redeems it with the published agent client and the person's holder it runs. In browser mode (ZADQ-294) the material is the split mint's MintMaterial the person's browser posted (MintID's stage-2 interface v1.1 §1, to_json()), and the runtime completes it with AgentClient.complete_issuance; the poll waits while the offer is with the browser. Material not taken before its expiry (the offer's in runtime mode, the material's expires_at in browser mode) ends in failed(token_expired). Under the passkey session offer_ready says a browser-mode offer waits to be collected (POST …/offer).

Authentication: passkeySession or runtimeCredential.

Parameters

NameInRequiredTypeDescription
enrolmentIdpathyesstring
waitquerynointegerLong-poll seconds (runtime credential only), 0 to 30.

Responses

200 — The enrolment (dashboard) or the poll's answer (runtime).

Content type application/json.

One of:

204 — Runtime only — the material was delivered; nothing more.

default — A /v1 refusal — {"error", "detail"} (platform API v1 §5).

Content type application/json.

Schema: V1Error

PropertyTypeRequiredDescriptionValues
errorstringyessession_required · passkey_required · last_passkey · ceremony_invalid · attestation_invalid · assertion_invalid · email_operational_invalid · body_invalid · origin_refused · not_found · not_available · internal · runtime_token_invalid · approval_not_pending · result_already_taken · declaration_invalid · request_invalid · cursor_invalid · rate_limited · offer_refused:<issuer code> (ZADQ-289) · kyc_current · kyc_required · entry_fee_due · reverification_required · invalid_state · sandbox_hint_not_available · invalid_sandbox_hint · issuer_unavailable (ZADQ-316) · kyc_grade_below_bundle (ZADQ-321) · person_invalid · profile_invalid · profile_incomplete · kind_locked · terms_changed · business_use_required · reauth_required (ZADQ-307) · account_blocked (ZADQ-311) · custody_version_conflict · last_wrap · passkey_not_on_account (ZADQ-293) · wraps_required (ZADQ-293, v1.3.2) · origin_invalid · key_invalid · private_key_refused · origin_in_use · key_reused · evidence_required · obligations_not_published · obligations_changed (ZADQ-362, v1.3.13) · mintid_unavailable (503, ZADQ-407: MintID unreachable since the start-up and the ids not discovered yet; nothing recorded, retry later)
detailstringyes
custody_versioninteger (int64)no409 custody_version_conflict (§5.8, v1.3.2) — the stored version, to read and retry on.
fieldsobjectnoThe refused fields by path (400 person_invalid, profile_invalid).
missingarray of stringnoThe field paths a payment still needs (409 profile_incomplete).

Example

curl -sS "<base-url>/v1/enrolments/<enrolmentId>" \
  --cookie "__Host-passkey_session=<api-key>"

POST /v1/enrolments/{enrolmentId}/cancel

Cancel an enrolment (created, claimed, or approved before the material is taken)

The pending approval reads failed(enrolment_cancelled), the price line void (open) or credited (recorded), the runtime credential is revoked. 409 enrolment_not_pending from minting on.

Authentication: passkeySession.

Parameters

NameInRequiredTypeDescription
enrolmentIdpathyesstring

Responses

200 — Cancelled.

Content type application/json.

Schema: EnrolmentStateAnswer

PropertyTypeRequiredDescriptionValues
statestringyes

default — A /v1 refusal — {"error", "detail"} (platform API v1 §5).

Content type application/json.

Schema: V1Error

PropertyTypeRequiredDescriptionValues
errorstringyessession_required · passkey_required · last_passkey · ceremony_invalid · attestation_invalid · assertion_invalid · email_operational_invalid · body_invalid · origin_refused · not_found · not_available · internal · runtime_token_invalid · approval_not_pending · result_already_taken · declaration_invalid · request_invalid · cursor_invalid · rate_limited · offer_refused:<issuer code> (ZADQ-289) · kyc_current · kyc_required · entry_fee_due · reverification_required · invalid_state · sandbox_hint_not_available · invalid_sandbox_hint · issuer_unavailable (ZADQ-316) · kyc_grade_below_bundle (ZADQ-321) · person_invalid · profile_invalid · profile_incomplete · kind_locked · terms_changed · business_use_required · reauth_required (ZADQ-307) · account_blocked (ZADQ-311) · custody_version_conflict · last_wrap · passkey_not_on_account (ZADQ-293) · wraps_required (ZADQ-293, v1.3.2) · origin_invalid · key_invalid · private_key_refused · origin_in_use · key_reused · evidence_required · obligations_not_published · obligations_changed (ZADQ-362, v1.3.13) · mintid_unavailable (503, ZADQ-407: MintID unreachable since the start-up and the ids not discovered yet; nothing recorded, retry later)
detailstringyes
custody_versioninteger (int64)no409 custody_version_conflict (§5.8, v1.3.2) — the stored version, to read and retry on.
fieldsobjectnoThe refused fields by path (400 person_invalid, profile_invalid).
missingarray of stringnoThe field paths a payment still needs (409 profile_incomplete).

Example

curl -sS -X POST "<base-url>/v1/enrolments/<enrolmentId>/cancel" \
  --cookie "__Host-passkey_session=<api-key>"

POST /v1/enrolments/{enrolmentId}/registered

The runtime reports the credential born in it

Under the runtime credential, on a minting enrolment: the credential id the holder received (the issuer never returns it to the operator), its expiry, optionally the scope endpoint, the control hook {url, secret_ref} (the shared secret ZadQ signs a kill with, kept sealed; https on a public address) and usable: true once the agent's scope is anchored (also on a later call). The agent reads registered (or usable), the runtime credential extends to it. Idempotent on (enrolment, credential id); another credential id is 409 enrolment_not_pending. A renewal's report moves the same agent to its new credential.

Authentication: runtimeCredential.

Parameters

NameInRequiredTypeDescription
enrolmentIdpathyesstring

Request body

application/json — required

Schema: EnrolmentRegisteredRequest

PropertyTypeRequiredDescriptionValues
credential_idstringyesThe issuer's handle of the credential (64 hex), as the holder received it.
expires_atstring (date-time)yes
scope_endpointstringno
control_hookEnrolmentControlHookno
usablebooleannoThe agent's scope is anchored (it can present its delegation); also on a later call.

Responses

200 — Registered.

Content type application/json.

Schema: EnrolmentRegistered

PropertyTypeRequiredDescriptionValues
agent_idstringyes

default — A /v1 refusal — {"error", "detail"} (platform API v1 §5).

Content type application/json.

Schema: V1Error

PropertyTypeRequiredDescriptionValues
errorstringyessession_required · passkey_required · last_passkey · ceremony_invalid · attestation_invalid · assertion_invalid · email_operational_invalid · body_invalid · origin_refused · not_found · not_available · internal · runtime_token_invalid · approval_not_pending · result_already_taken · declaration_invalid · request_invalid · cursor_invalid · rate_limited · offer_refused:<issuer code> (ZADQ-289) · kyc_current · kyc_required · entry_fee_due · reverification_required · invalid_state · sandbox_hint_not_available · invalid_sandbox_hint · issuer_unavailable (ZADQ-316) · kyc_grade_below_bundle (ZADQ-321) · person_invalid · profile_invalid · profile_incomplete · kind_locked · terms_changed · business_use_required · reauth_required (ZADQ-307) · account_blocked (ZADQ-311) · custody_version_conflict · last_wrap · passkey_not_on_account (ZADQ-293) · wraps_required (ZADQ-293, v1.3.2) · origin_invalid · key_invalid · private_key_refused · origin_in_use · key_reused · evidence_required · obligations_not_published · obligations_changed (ZADQ-362, v1.3.13) · mintid_unavailable (503, ZADQ-407: MintID unreachable since the start-up and the ids not discovered yet; nothing recorded, retry later)
detailstringyes
custody_versioninteger (int64)no409 custody_version_conflict (§5.8, v1.3.2) — the stored version, to read and retry on.
fieldsobjectnoThe refused fields by path (400 person_invalid, profile_invalid).
missingarray of stringnoThe field paths a payment still needs (409 profile_incomplete).

Example

curl -sS -X POST "<base-url>/v1/enrolments/<enrolmentId>/registered" \
  -H "Authorization: Bearer <session-credential>" \
  -H "Content-Type: application/json" \
  -d @request-body.json

POST /v1/enrolments/{enrolmentId}/failed

The runtime reports that the mint did not happen

From claimed, approved or minting: failed(reason_code) — a reason code (lowercase words, an optional :-qualified issuer code; anything else reads unspecified). The approval fails, the price line is credited. 409 enrolment_not_pending.

Authentication: runtimeCredential.

Parameters

NameInRequiredTypeDescription
enrolmentIdpathyesstring

Request body

application/json — required

Schema: EnrolmentFailedRequest

PropertyTypeRequiredDescriptionValues
reason_codestringyes

Responses

200 — Failed.

Content type application/json.

Schema: EnrolmentStateAnswer

PropertyTypeRequiredDescriptionValues
statestringyes

default — A /v1 refusal — {"error", "detail"} (platform API v1 §5).

Content type application/json.

Schema: V1Error

PropertyTypeRequiredDescriptionValues
errorstringyessession_required · passkey_required · last_passkey · ceremony_invalid · attestation_invalid · assertion_invalid · email_operational_invalid · body_invalid · origin_refused · not_found · not_available · internal · runtime_token_invalid · approval_not_pending · result_already_taken · declaration_invalid · request_invalid · cursor_invalid · rate_limited · offer_refused:<issuer code> (ZADQ-289) · kyc_current · kyc_required · entry_fee_due · reverification_required · invalid_state · sandbox_hint_not_available · invalid_sandbox_hint · issuer_unavailable (ZADQ-316) · kyc_grade_below_bundle (ZADQ-321) · person_invalid · profile_invalid · profile_incomplete · kind_locked · terms_changed · business_use_required · reauth_required (ZADQ-307) · account_blocked (ZADQ-311) · custody_version_conflict · last_wrap · passkey_not_on_account (ZADQ-293) · wraps_required (ZADQ-293, v1.3.2) · origin_invalid · key_invalid · private_key_refused · origin_in_use · key_reused · evidence_required · obligations_not_published · obligations_changed (ZADQ-362, v1.3.13) · mintid_unavailable (503, ZADQ-407: MintID unreachable since the start-up and the ids not discovered yet; nothing recorded, retry later)
detailstringyes
custody_versioninteger (int64)no409 custody_version_conflict (§5.8, v1.3.2) — the stored version, to read and retry on.
fieldsobjectnoThe refused fields by path (400 person_invalid, profile_invalid).
missingarray of stringnoThe field paths a payment still needs (409 profile_incomplete).

Example

curl -sS -X POST "<base-url>/v1/enrolments/<enrolmentId>/failed" \
  -H "Authorization: Bearer <session-credential>" \
  -H "Content-Type: application/json" \
  -d @request-body.json

POST /v1/enrolments/{enrolmentId}/offer

The person's browser collects a browser-mode offer, once

Browser mode (ZADQ-294). When the enrolment's price line settled after the approval (the console's mark, a hosted checkout), the issuer's agent offer was asked for then and is held sealed for the person's browser: this answers it once (Cache-Control: no-store), the operator's price line stripped, and deletes it; the enrolment then waits for the browser's material (POST …/mint). When the line settled at the approval, the approve answer carried the offer and nothing is held here. 409 enrolment_not_pending (no offer waits: runtime mode, already collected, or past its expiry); 404 not_found.

Authentication: passkeySession.

Parameters

NameInRequiredTypeDescription
enrolmentIdpathyesstring

Responses

200 — The offer, once.

Content type application/json.

Schema: BrowserOffer

PropertyTypeRequiredDescriptionValues
offerobjectyesThe issuer's agent offer, the operator's price line stripped (the runtime-mode material shape).
expires_atstring (date-time)yes

default — A /v1 refusal — {"error", "detail"} (platform API v1 §5).

Content type application/json.

Schema: V1Error

PropertyTypeRequiredDescriptionValues
errorstringyessession_required · passkey_required · last_passkey · ceremony_invalid · attestation_invalid · assertion_invalid · email_operational_invalid · body_invalid · origin_refused · not_found · not_available · internal · runtime_token_invalid · approval_not_pending · result_already_taken · declaration_invalid · request_invalid · cursor_invalid · rate_limited · offer_refused:<issuer code> (ZADQ-289) · kyc_current · kyc_required · entry_fee_due · reverification_required · invalid_state · sandbox_hint_not_available · invalid_sandbox_hint · issuer_unavailable (ZADQ-316) · kyc_grade_below_bundle (ZADQ-321) · person_invalid · profile_invalid · profile_incomplete · kind_locked · terms_changed · business_use_required · reauth_required (ZADQ-307) · account_blocked (ZADQ-311) · custody_version_conflict · last_wrap · passkey_not_on_account (ZADQ-293) · wraps_required (ZADQ-293, v1.3.2) · origin_invalid · key_invalid · private_key_refused · origin_in_use · key_reused · evidence_required · obligations_not_published · obligations_changed (ZADQ-362, v1.3.13) · mintid_unavailable (503, ZADQ-407: MintID unreachable since the start-up and the ids not discovered yet; nothing recorded, retry later)
detailstringyes
custody_versioninteger (int64)no409 custody_version_conflict (§5.8, v1.3.2) — the stored version, to read and retry on.
fieldsobjectnoThe refused fields by path (400 person_invalid, profile_invalid).
missingarray of stringnoThe field paths a payment still needs (409 profile_incomplete).

Example

curl -sS -X POST "<base-url>/v1/enrolments/<enrolmentId>/offer" \
  --cookie "__Host-passkey_session=<api-key>"

POST /v1/enrolments/{enrolmentId}/mint

The person's browser posts the credential step's material, once

Browser mode (ZADQ-294), under the passkey session, on the account's own enrolment once its offer reached the browser: {mint: MintMaterial} — MintMaterial.to_json() of mintToken(offer, holder), MintID's stage-2 interface v1.1 §1 — or {failure: <code>} instead. The material is checked (unknown fields refused; v 1; credential_configuration_id mintid_agent_v1 or mintid_agent_v2; c_nonce 64 hex; expires_at in the future and within ten minutes; issuer_url the configured issuer; bundle_id, when present, the enrolment's bundle; renews_credential_id only on a renewal), held sealed until the runtime's poll takes it once ({state: "minting", mint}), deleted on delivery, never logged; past its expires_at untaken the enrolment fails token_expired and its price line is credited. A failure code (window_lapsed, token_refused, issuer_unavailable, credential_revoked, credential_expired, custody_unavailable, module_trapped, person_cancelled) fails the enrolment the same way. 202 {state}: approved (held) or failed. 400 material_invalid · reason_invalid · body_invalid; 409 enrolment_not_pending (runtime mode, not approved, the offer not handed yet, or a material already posted); 404 not_found.

Authentication: passkeySession.

Parameters

NameInRequiredTypeDescription
enrolmentIdpathyesstring

Request body

application/json — required

Schema: EnrolmentMintRequest

PropertyTypeRequiredDescriptionValues
mintMintMaterialno
failurestringnoA code of the closed vocabulary instead of a material.

Responses

202 — Held for the runtime's poll, or failed.

Content type application/json.

Schema: EnrolmentStateAnswer

PropertyTypeRequiredDescriptionValues
statestringyes

default — A /v1 refusal — {"error", "detail"} (platform API v1 §5).

Content type application/json.

Schema: V1Error

PropertyTypeRequiredDescriptionValues
errorstringyessession_required · passkey_required · last_passkey · ceremony_invalid · attestation_invalid · assertion_invalid · email_operational_invalid · body_invalid · origin_refused · not_found · not_available · internal · runtime_token_invalid · approval_not_pending · result_already_taken · declaration_invalid · request_invalid · cursor_invalid · rate_limited · offer_refused:<issuer code> (ZADQ-289) · kyc_current · kyc_required · entry_fee_due · reverification_required · invalid_state · sandbox_hint_not_available · invalid_sandbox_hint · issuer_unavailable (ZADQ-316) · kyc_grade_below_bundle (ZADQ-321) · person_invalid · profile_invalid · profile_incomplete · kind_locked · terms_changed · business_use_required · reauth_required (ZADQ-307) · account_blocked (ZADQ-311) · custody_version_conflict · last_wrap · passkey_not_on_account (ZADQ-293) · wraps_required (ZADQ-293, v1.3.2) · origin_invalid · key_invalid · private_key_refused · origin_in_use · key_reused · evidence_required · obligations_not_published · obligations_changed (ZADQ-362, v1.3.13) · mintid_unavailable (503, ZADQ-407: MintID unreachable since the start-up and the ids not discovered yet; nothing recorded, retry later)
detailstringyes
custody_versioninteger (int64)no409 custody_version_conflict (§5.8, v1.3.2) — the stored version, to read and retry on.
fieldsobjectnoThe refused fields by path (400 person_invalid, profile_invalid).
missingarray of stringnoThe field paths a payment still needs (409 profile_incomplete).

Example

curl -sS -X POST "<base-url>/v1/enrolments/<enrolmentId>/mint" \
  --cookie "__Host-passkey_session=<api-key>" \
  -H "Content-Type: application/json" \
  -d @request-body.json

GET /v1/agents

The account's agents enrolled through the platform

The agents the runtimes reported registered, newest first. State: registered; usable once the runtime reported the scope anchored; expiring within the lease-reminder lead (14 days by default) of the lease end; revoked; expired. Agents minted from the earlier mint form stay on the v0 agents view. Beside ZadQ's state, the issuer's own as the reconciliation last read it (issuer_state, issuer_reason, reconciled_at; ZADQ-296) — an agent whose registered report was lost appears here once the reconciliation recovered it.

Authentication: passkeySession.

Responses

200 — The agents.

Content type application/json.

Schema: PlatformAgentList

PropertyTypeRequiredDescriptionValues
agentsarray of PlatformAgentyes

default — A /v1 refusal — {"error", "detail"} (platform API v1 §5).

Content type application/json.

Schema: V1Error

PropertyTypeRequiredDescriptionValues
errorstringyessession_required · passkey_required · last_passkey · ceremony_invalid · attestation_invalid · assertion_invalid · email_operational_invalid · body_invalid · origin_refused · not_found · not_available · internal · runtime_token_invalid · approval_not_pending · result_already_taken · declaration_invalid · request_invalid · cursor_invalid · rate_limited · offer_refused:<issuer code> (ZADQ-289) · kyc_current · kyc_required · entry_fee_due · reverification_required · invalid_state · sandbox_hint_not_available · invalid_sandbox_hint · issuer_unavailable (ZADQ-316) · kyc_grade_below_bundle (ZADQ-321) · person_invalid · profile_invalid · profile_incomplete · kind_locked · terms_changed · business_use_required · reauth_required (ZADQ-307) · account_blocked (ZADQ-311) · custody_version_conflict · last_wrap · passkey_not_on_account (ZADQ-293) · wraps_required (ZADQ-293, v1.3.2) · origin_invalid · key_invalid · private_key_refused · origin_in_use · key_reused · evidence_required · obligations_not_published · obligations_changed (ZADQ-362, v1.3.13) · mintid_unavailable (503, ZADQ-407: MintID unreachable since the start-up and the ids not discovered yet; nothing recorded, retry later)
detailstringyes
custody_versioninteger (int64)no409 custody_version_conflict (§5.8, v1.3.2) — the stored version, to read and retry on.
fieldsobjectnoThe refused fields by path (400 person_invalid, profile_invalid).
missingarray of stringnoThe field paths a payment still needs (409 profile_incomplete).

Example

curl -sS "<base-url>/v1/agents" \
  --cookie "__Host-passkey_session=<api-key>"

POST /v1/agents/{agentId}/stop

Stop — the issuer's revocation through ZadQ

No custody needed. The agent reads revoked; its runtime credentials end; an open renewal is cancelled. A revoked agent answers as it is; 409 agent_not_live for an expired one.

Authentication: passkeySession.

Parameters

NameInRequiredTypeDescription
agentIdpathyesstring

Responses

200 — Revoked.

Content type application/json.

Schema: EnrolmentStateAnswer

PropertyTypeRequiredDescriptionValues
statestringyes

default — A /v1 refusal — {"error", "detail"} (platform API v1 §5).

Content type application/json.

Schema: V1Error

PropertyTypeRequiredDescriptionValues
errorstringyessession_required · passkey_required · last_passkey · ceremony_invalid · attestation_invalid · assertion_invalid · email_operational_invalid · body_invalid · origin_refused · not_found · not_available · internal · runtime_token_invalid · approval_not_pending · result_already_taken · declaration_invalid · request_invalid · cursor_invalid · rate_limited · offer_refused:<issuer code> (ZADQ-289) · kyc_current · kyc_required · entry_fee_due · reverification_required · invalid_state · sandbox_hint_not_available · invalid_sandbox_hint · issuer_unavailable (ZADQ-316) · kyc_grade_below_bundle (ZADQ-321) · person_invalid · profile_invalid · profile_incomplete · kind_locked · terms_changed · business_use_required · reauth_required (ZADQ-307) · account_blocked (ZADQ-311) · custody_version_conflict · last_wrap · passkey_not_on_account (ZADQ-293) · wraps_required (ZADQ-293, v1.3.2) · origin_invalid · key_invalid · private_key_refused · origin_in_use · key_reused · evidence_required · obligations_not_published · obligations_changed (ZADQ-362, v1.3.13) · mintid_unavailable (503, ZADQ-407: MintID unreachable since the start-up and the ids not discovered yet; nothing recorded, retry later)
detailstringyes
custody_versioninteger (int64)no409 custody_version_conflict (§5.8, v1.3.2) — the stored version, to read and retry on.
fieldsobjectnoThe refused fields by path (400 person_invalid, profile_invalid).
missingarray of stringnoThe field paths a payment still needs (409 profile_incomplete).

Example

curl -sS -X POST "<base-url>/v1/agents/<agentId>/stop" \
  --cookie "__Host-passkey_session=<api-key>"

POST /v1/agents/{agentId}/renewals

Renew — a renew approval, then the same machine

Opens a renewal (an enrolment of kind renewal for the agent's runtime) and a renew approval in the inbox; an open renewal answers its approval again. On approval the issuer's renew offer becomes the material; the runtime completes it as in §5.4 and reports the new credential. 409 agent_not_live · kyc_required · product_inactive · credential_not_held (ZADQ-424) · entry_fee_due.

Authentication: passkeySession.

Parameters

NameInRequiredTypeDescription
agentIdpathyesstring

Responses

202 — The renew approval is pending.

Content type application/json.

Schema: AgentRenewalRequested

PropertyTypeRequiredDescriptionValues
approval_idstringyes

default — A /v1 refusal — {"error", "detail"} (platform API v1 §5).

Content type application/json.

Schema: V1Error

PropertyTypeRequiredDescriptionValues
errorstringyessession_required · passkey_required · last_passkey · ceremony_invalid · attestation_invalid · assertion_invalid · email_operational_invalid · body_invalid · origin_refused · not_found · not_available · internal · runtime_token_invalid · approval_not_pending · result_already_taken · declaration_invalid · request_invalid · cursor_invalid · rate_limited · offer_refused:<issuer code> (ZADQ-289) · kyc_current · kyc_required · entry_fee_due · reverification_required · invalid_state · sandbox_hint_not_available · invalid_sandbox_hint · issuer_unavailable (ZADQ-316) · kyc_grade_below_bundle (ZADQ-321) · person_invalid · profile_invalid · profile_incomplete · kind_locked · terms_changed · business_use_required · reauth_required (ZADQ-307) · account_blocked (ZADQ-311) · custody_version_conflict · last_wrap · passkey_not_on_account (ZADQ-293) · wraps_required (ZADQ-293, v1.3.2) · origin_invalid · key_invalid · private_key_refused · origin_in_use · key_reused · evidence_required · obligations_not_published · obligations_changed (ZADQ-362, v1.3.13) · mintid_unavailable (503, ZADQ-407: MintID unreachable since the start-up and the ids not discovered yet; nothing recorded, retry later)
detailstringyes
custody_versioninteger (int64)no409 custody_version_conflict (§5.8, v1.3.2) — the stored version, to read and retry on.
fieldsobjectnoThe refused fields by path (400 person_invalid, profile_invalid).
missingarray of stringnoThe field paths a payment still needs (409 profile_incomplete).

Example

curl -sS -X POST "<base-url>/v1/agents/<agentId>/renewals" \
  --cookie "__Host-passkey_session=<api-key>"

POST /v1/agents/{agentId}/kill

Kill — only through the runtime's registered control hook

A signed POST to the control hook the runtime registered (the agent's self-revocation needs the agent's custody, which is the runtime's): 202 once the runtime accepted it. 409 control_hook_missing without one (Stop is the way then); 502 control_hook_failed when the hook does not answer 2xx; 409 agent_not_live.

Authentication: passkeySession.

Parameters

NameInRequiredTypeDescription
agentIdpathyesstring

Responses

202 — The runtime accepted the kill.

default — A /v1 refusal — {"error", "detail"} (platform API v1 §5).

Content type application/json.

Schema: V1Error

PropertyTypeRequiredDescriptionValues
errorstringyessession_required · passkey_required · last_passkey · ceremony_invalid · attestation_invalid · assertion_invalid · email_operational_invalid · body_invalid · origin_refused · not_found · not_available · internal · runtime_token_invalid · approval_not_pending · result_already_taken · declaration_invalid · request_invalid · cursor_invalid · rate_limited · offer_refused:<issuer code> (ZADQ-289) · kyc_current · kyc_required · entry_fee_due · reverification_required · invalid_state · sandbox_hint_not_available · invalid_sandbox_hint · issuer_unavailable (ZADQ-316) · kyc_grade_below_bundle (ZADQ-321) · person_invalid · profile_invalid · profile_incomplete · kind_locked · terms_changed · business_use_required · reauth_required (ZADQ-307) · account_blocked (ZADQ-311) · custody_version_conflict · last_wrap · passkey_not_on_account (ZADQ-293) · wraps_required (ZADQ-293, v1.3.2) · origin_invalid · key_invalid · private_key_refused · origin_in_use · key_reused · evidence_required · obligations_not_published · obligations_changed (ZADQ-362, v1.3.13) · mintid_unavailable (503, ZADQ-407: MintID unreachable since the start-up and the ids not discovered yet; nothing recorded, retry later)
detailstringyes
custody_versioninteger (int64)no409 custody_version_conflict (§5.8, v1.3.2) — the stored version, to read and retry on.
fieldsobjectnoThe refused fields by path (400 person_invalid, profile_invalid).
missingarray of stringnoThe field paths a payment still needs (409 profile_incomplete).

Example

curl -sS -X POST "<base-url>/v1/agents/<agentId>/kill" \
  --cookie "__Host-passkey_session=<api-key>"

GET /v1/catalogue

The bundles the issuer serves (prices stripped) and ZadQ's plans (no amounts)

The issuer's served bundle catalogue, read through ZadQ (cached ten minutes), each bundle with the keys the enrolment form needs — never its price — and the agent-operator product's plans: id, seats, label. Amounts are never here: they live on the billing provider's checkout page. 503 catalogue_unavailable when the issuer's catalogue was never read. v1.3.30 (ZADQ-472): the plans are the principal plans the deployment offers (kind: principal) and enterprise (kind: contact, its seats the most an Enterprise contract holds today — the issuer's cap per person): sold by contact, activated by ZadQ once agreed, never an amount and never self-serve. No earlier plan and no periods remain.

Authentication: passkeySession.

Responses

200 — The catalogue and the plans.

Content type application/json.

Schema: PlatformCatalogue

PropertyTypeRequiredDescriptionValues
bundlesarray of CatalogueBundleyes
plansarray of CataloguePlanyes

default — A /v1 refusal — {"error", "detail"} (platform API v1 §5).

Content type application/json.

Schema: V1Error

PropertyTypeRequiredDescriptionValues
errorstringyessession_required · passkey_required · last_passkey · ceremony_invalid · attestation_invalid · assertion_invalid · email_operational_invalid · body_invalid · origin_refused · not_found · not_available · internal · runtime_token_invalid · approval_not_pending · result_already_taken · declaration_invalid · request_invalid · cursor_invalid · rate_limited · offer_refused:<issuer code> (ZADQ-289) · kyc_current · kyc_required · entry_fee_due · reverification_required · invalid_state · sandbox_hint_not_available · invalid_sandbox_hint · issuer_unavailable (ZADQ-316) · kyc_grade_below_bundle (ZADQ-321) · person_invalid · profile_invalid · profile_incomplete · kind_locked · terms_changed · business_use_required · reauth_required (ZADQ-307) · account_blocked (ZADQ-311) · custody_version_conflict · last_wrap · passkey_not_on_account (ZADQ-293) · wraps_required (ZADQ-293, v1.3.2) · origin_invalid · key_invalid · private_key_refused · origin_in_use · key_reused · evidence_required · obligations_not_published · obligations_changed (ZADQ-362, v1.3.13) · mintid_unavailable (503, ZADQ-407: MintID unreachable since the start-up and the ids not discovered yet; nothing recorded, retry later)
detailstringyes
custody_versioninteger (int64)no409 custody_version_conflict (§5.8, v1.3.2) — the stored version, to read and retry on.
fieldsobjectnoThe refused fields by path (400 person_invalid, profile_invalid).
missingarray of stringnoThe field paths a payment still needs (409 profile_incomplete).

Example

curl -sS "<base-url>/v1/catalogue" \
  --cookie "__Host-passkey_session=<api-key>"

POST /v1/products/agent-operator/activate

Activate the agent-operator product with a principal plan

v1.3.30 (ZADQ-472) — the plans an account chooses itself are the principal plans, personal and premium (§5.16; period month or year, yearly when left out): the activation opens in pending_payment with its plan_line, paid before the identity check (POST /v1/price-lines/{id}/pay), then pending_kyc until the responsible person is verified at the plan's grade, then active (product_activated). enterprise is sold by contact and activated by ZadQ from the operator console once agreed (§5.20): 409 plan_by_contact. Any other id: 400 plan_unknown. An account that runs an Enterprise contract, or an earlier plan with a collected fee or seats, answers 409 plan_not_switchable; an earlier plan's activation with nothing collected moves to the principal plan chosen. entry_fee reads null (no entry fee is sold).

v1.3.17 (ZADQ-387, §5.16): Personal → Premium once paid is the switch on either settlement — on the provider, paying the switch line opens a new subscription of Premium's whole price with the credit of the unused period as a one-off credit on the checkout, and the old subscription is cancelled when the new one's checkout completes. A plan closed after its identity check ended refused or withdrawn is chosen again once its refund is paid back (a new period, paid before a new identity check); while the refund is still being paid back, 409 plan_closed.

Authentication: passkeySession.

Request body

application/json — required

Schema: ActivateAgentOperator

PropertyTypeRequiredDescriptionValues
planstringyesA principal plan's id (personal, premium — v1.3.16; plus is retired). v1.3.30 — enterprise answers 409 plan_by_contact (the console activates it, §5.20).
periodstringnov1.3.14 (§5.16) — the principal plan's billing period, in advance (default year; on a switch, the current one)."month", "year"

Responses

200 — The activation.

Content type application/json.

Schema: AgentOperatorActivation

PropertyTypeRequiredDescriptionValues
statestringyes"pending_payment", "pending_kyc", "pending_entry_fee", "active", "suspended", "closed"
periodstring, nullablenov1.3.14 — the principal plan's period."month", "year"
plan_lineall of PriceLinenov1.3.14 — the principal plan's seat line for the period (pay it with POST /v1/price-lines/{id}/pay).
planstringyes
settlementstringno"console", "stripe"
entry_feeall of PriceLineyesv1.3.30 (ZADQ-472) — always null; no entry fee is sold (kept in the shape for the client app).
plan_switchall of PlanSwitchnov1.3.16 — the switch Personal → Premium waiting on its line; null otherwise.

default — A /v1 refusal — {"error", "detail"} (platform API v1 §5).

Content type application/json.

Schema: V1Error

PropertyTypeRequiredDescriptionValues
errorstringyessession_required · passkey_required · last_passkey · ceremony_invalid · attestation_invalid · assertion_invalid · email_operational_invalid · body_invalid · origin_refused · not_found · not_available · internal · runtime_token_invalid · approval_not_pending · result_already_taken · declaration_invalid · request_invalid · cursor_invalid · rate_limited · offer_refused:<issuer code> (ZADQ-289) · kyc_current · kyc_required · entry_fee_due · reverification_required · invalid_state · sandbox_hint_not_available · invalid_sandbox_hint · issuer_unavailable (ZADQ-316) · kyc_grade_below_bundle (ZADQ-321) · person_invalid · profile_invalid · profile_incomplete · kind_locked · terms_changed · business_use_required · reauth_required (ZADQ-307) · account_blocked (ZADQ-311) · custody_version_conflict · last_wrap · passkey_not_on_account (ZADQ-293) · wraps_required (ZADQ-293, v1.3.2) · origin_invalid · key_invalid · private_key_refused · origin_in_use · key_reused · evidence_required · obligations_not_published · obligations_changed (ZADQ-362, v1.3.13) · mintid_unavailable (503, ZADQ-407: MintID unreachable since the start-up and the ids not discovered yet; nothing recorded, retry later)
detailstringyes
custody_versioninteger (int64)no409 custody_version_conflict (§5.8, v1.3.2) — the stored version, to read and retry on.
fieldsobjectnoThe refused fields by path (400 person_invalid, profile_invalid).
missingarray of stringnoThe field paths a payment still needs (409 profile_incomplete).

Example

curl -sS -X POST "<base-url>/v1/products/agent-operator/activate" \
  --cookie "__Host-passkey_session=<api-key>" \
  -H "Content-Type: application/json" \
  -d @request-body.json

POST /v1/products/agent-operator/steps

Open a plan step (§5.16, v1.3.16; no step is offered since v1.3.25)

v1.3.16 (ZADQ-382): the route that opens a plan step (kind agent_extra or grade_a3_option; period month or year, the plan's when left out) for one period, in advance, paid as every line (POST /v1/price-lines/{id}/pay). v1.3.25 (ZADQ-451; Marc, 2026-11-06): a step the deployment's price table does not price is not offered, and no deployment prices one — this route answers 409 line_not_offered on every plan (Personal, Premium, an Enterprise contract), and GET /v1/plans lists no step. Both plans include A3 when a relying party requires it (grade_included: 3). v1.3.27 (ZADQ-451; Marc, 2026-11-07 — the caps as decided): Personal includes 1 bounded agent (seats_max: 1) and the 2nd answers 409 plan_cap_reached on POST /v1/enrolments (the switch to Premium the way on); Premium includes 5 and the 6th answers 409 seats_exhausted (beyond Premium, Enterprise by contact — v1.3.30, §5.20).

Authentication: passkeySession.

Request body

application/json — required

Schema: PlanStepOpen

PropertyTypeRequiredDescriptionValues
kindstringyes"agent_extra", "grade_a3_option"
periodstringnoBilled in advance; the plan's period when left out."month", "year"

Responses

200 — The step's line already standing, as it is.

Content type application/json.

Schema: PriceLine

PropertyTypeRequiredDescriptionValues
idstringyes
periodstring, nullablenov1.3.14 (§5.16) — the period a principal plan's seat line pays; its amount is the plan's whole price for it. v1.3.15 (§5.17) — the period a managed environment's line pays, in advance."month", "year"
environmentstring, nullablenov1.3.15 (§5.17) — a managed environment's environment; null on every other line."production", "test"
kindPriceLineKindyes
amount_minorinteger (int64), nullableyesv1.3.18 (ZADQ-389) — negative on a principal_enrolled line opened since (the month's rebate set off on the invoice; not payable).
unitstring, nullableyes
statePriceLineStateyes
refPriceLineRefyes
settlementstringyes"console", "stripe"
channelstringyesHow the line is collected (ZADQ-324, derived at read time, never stored): invoice on the console settlement (a manual invoice) and for a provider customer whose subscription collects by invoice; card otherwise (the hosted checkout). The dashboard shows "Pay" for card, "on your invoice" for invoice."card", "invoice"
quantityinteger, nullablenoSeats (seat), lease days (lease_year); v1.3.16 — the month's count of principals enrolled (principal_enrolled); v1.3.18 — on a rebate credit, the rebates settled in the month.
bundlestring, nullableno
vat_treatmentstring, nullablenov1.3.16 (ZADQ-382) — how the amount stands to VAT, on the lines opened since (null on the lines before). v1.3.29 (ZADQ-469) — every amount is net, ex-VAT: a line opens exclusive (the billing provider adds the VAT at checkout and on the invoice) or reverse_charge (the same net, no VAT, for a business whose customer record holds a valid VAT number of another member state). included is a legacy value: it is never opened now and stays only on lines opened before v1.3.29."included", "reverse_charge", "exclusive"
covers_untilstring (date-time), nullablenov1.3.16 — the end of the period a step's line (agent_extra, grade_a3_option) pays, from its settlement; null until settled and on every other line. No step is offered since v1.3.25.
credit_minorinteger (int64), nullablenov1.3.16 — on a switch's seat line (Personal → Premium), the credit of the unused period; amount_minor is the new period's price less it.
free_quantityinteger, nullablenov1.3.16 — on a principal_enrolled line, the free volume applied to the month's count; null on a rebate credit (v1.3.18).
billing_monthstring (date), nullablenov1.3.16 — on a principal_enrolled line, the month counted (its first day); v1.3.18 — the rebate statement's month.
retained_minorinteger (int64), nullablenov1.3.17 (ZADQ-387) — on a plan_refund line, the cost of the identity check performed at the person's request, retained; amount_minor is what is paid back. v1.3.29 (ZADQ-469) — net, ex-VAT, on a line exclusive or reverse_charge: the provider's refund pays back amount_minor plus its share of the VAT the payment collected (a legacy included line keeps the amounts it was opened with).
refund_reasonstring, nullablenov1.3.17 — on a plan_refund line, why the plan closed (ZadQ's own code; nothing of the issuer's reason); v1.3.34 (ZADQ-472) — enterprise_replaces_paid_plan, the paid plan replaced by an Enterprise contract (its unused period paid back by hand)."identity_check_refused", "identity_check_withdrawn", "enterprise_replaces_paid_plan"
created_atstring (date-time)yes

201 — The step's line opened.

Content type application/json.

Schema: PriceLine

PropertyTypeRequiredDescriptionValues
idstringyes
periodstring, nullablenov1.3.14 (§5.16) — the period a principal plan's seat line pays; its amount is the plan's whole price for it. v1.3.15 (§5.17) — the period a managed environment's line pays, in advance."month", "year"
environmentstring, nullablenov1.3.15 (§5.17) — a managed environment's environment; null on every other line."production", "test"
kindPriceLineKindyes
amount_minorinteger (int64), nullableyesv1.3.18 (ZADQ-389) — negative on a principal_enrolled line opened since (the month's rebate set off on the invoice; not payable).
unitstring, nullableyes
statePriceLineStateyes
refPriceLineRefyes
settlementstringyes"console", "stripe"
channelstringyesHow the line is collected (ZADQ-324, derived at read time, never stored): invoice on the console settlement (a manual invoice) and for a provider customer whose subscription collects by invoice; card otherwise (the hosted checkout). The dashboard shows "Pay" for card, "on your invoice" for invoice."card", "invoice"
quantityinteger, nullablenoSeats (seat), lease days (lease_year); v1.3.16 — the month's count of principals enrolled (principal_enrolled); v1.3.18 — on a rebate credit, the rebates settled in the month.
bundlestring, nullableno
vat_treatmentstring, nullablenov1.3.16 (ZADQ-382) — how the amount stands to VAT, on the lines opened since (null on the lines before). v1.3.29 (ZADQ-469) — every amount is net, ex-VAT: a line opens exclusive (the billing provider adds the VAT at checkout and on the invoice) or reverse_charge (the same net, no VAT, for a business whose customer record holds a valid VAT number of another member state). included is a legacy value: it is never opened now and stays only on lines opened before v1.3.29."included", "reverse_charge", "exclusive"
covers_untilstring (date-time), nullablenov1.3.16 — the end of the period a step's line (agent_extra, grade_a3_option) pays, from its settlement; null until settled and on every other line. No step is offered since v1.3.25.
credit_minorinteger (int64), nullablenov1.3.16 — on a switch's seat line (Personal → Premium), the credit of the unused period; amount_minor is the new period's price less it.
free_quantityinteger, nullablenov1.3.16 — on a principal_enrolled line, the free volume applied to the month's count; null on a rebate credit (v1.3.18).
billing_monthstring (date), nullablenov1.3.16 — on a principal_enrolled line, the month counted (its first day); v1.3.18 — the rebate statement's month.
retained_minorinteger (int64), nullablenov1.3.17 (ZADQ-387) — on a plan_refund line, the cost of the identity check performed at the person's request, retained; amount_minor is what is paid back. v1.3.29 (ZADQ-469) — net, ex-VAT, on a line exclusive or reverse_charge: the provider's refund pays back amount_minor plus its share of the VAT the payment collected (a legacy included line keeps the amounts it was opened with).
refund_reasonstring, nullablenov1.3.17 — on a plan_refund line, why the plan closed (ZadQ's own code; nothing of the issuer's reason); v1.3.34 (ZADQ-472) — enterprise_replaces_paid_plan, the paid plan replaced by an Enterprise contract (its unused period paid back by hand)."identity_check_refused", "identity_check_withdrawn", "enterprise_replaces_paid_plan"
created_atstring (date-time)yes

default — A /v1 refusal — {"error", "detail"} (platform API v1 §5).

Content type application/json.

Schema: V1Error

PropertyTypeRequiredDescriptionValues
errorstringyessession_required · passkey_required · last_passkey · ceremony_invalid · attestation_invalid · assertion_invalid · email_operational_invalid · body_invalid · origin_refused · not_found · not_available · internal · runtime_token_invalid · approval_not_pending · result_already_taken · declaration_invalid · request_invalid · cursor_invalid · rate_limited · offer_refused:<issuer code> (ZADQ-289) · kyc_current · kyc_required · entry_fee_due · reverification_required · invalid_state · sandbox_hint_not_available · invalid_sandbox_hint · issuer_unavailable (ZADQ-316) · kyc_grade_below_bundle (ZADQ-321) · person_invalid · profile_invalid · profile_incomplete · kind_locked · terms_changed · business_use_required · reauth_required (ZADQ-307) · account_blocked (ZADQ-311) · custody_version_conflict · last_wrap · passkey_not_on_account (ZADQ-293) · wraps_required (ZADQ-293, v1.3.2) · origin_invalid · key_invalid · private_key_refused · origin_in_use · key_reused · evidence_required · obligations_not_published · obligations_changed (ZADQ-362, v1.3.13) · mintid_unavailable (503, ZADQ-407: MintID unreachable since the start-up and the ids not discovered yet; nothing recorded, retry later)
detailstringyes
custody_versioninteger (int64)no409 custody_version_conflict (§5.8, v1.3.2) — the stored version, to read and retry on.
fieldsobjectnoThe refused fields by path (400 person_invalid, profile_invalid).
missingarray of stringnoThe field paths a payment still needs (409 profile_incomplete).

Example

curl -sS -X POST "<base-url>/v1/products/agent-operator/steps" \
  --cookie "__Host-passkey_session=<api-key>" \
  -H "Content-Type: application/json" \
  -d @request-body.json

GET /v1/price-lines

The account's price lines, newest first

Kinds entry | seat | bundle_mint | lease_year | usage; states open | authorised | captured | invoiced | failed | credited | void (failed: the billing provider refused an authorisation — payable again). ref names what the line belongs to (an enrolment or an agent), as the activity log does; the provider's own reference is never shown. amount_minor and unit are the amount the line carries (the bundle's price, the lease priced at settlement), or null when it lives on the provider's price (the entry fee, the seats).

Authentication: passkeySession.

Responses

200 — The lines.

Content type application/json.

Schema: PriceLineList

PropertyTypeRequiredDescriptionValues
linesarray of PriceLineyes

default — A /v1 refusal — {"error", "detail"} (platform API v1 §5).

Content type application/json.

Schema: V1Error

PropertyTypeRequiredDescriptionValues
errorstringyessession_required · passkey_required · last_passkey · ceremony_invalid · attestation_invalid · assertion_invalid · email_operational_invalid · body_invalid · origin_refused · not_found · not_available · internal · runtime_token_invalid · approval_not_pending · result_already_taken · declaration_invalid · request_invalid · cursor_invalid · rate_limited · offer_refused:<issuer code> (ZADQ-289) · kyc_current · kyc_required · entry_fee_due · reverification_required · invalid_state · sandbox_hint_not_available · invalid_sandbox_hint · issuer_unavailable (ZADQ-316) · kyc_grade_below_bundle (ZADQ-321) · person_invalid · profile_invalid · profile_incomplete · kind_locked · terms_changed · business_use_required · reauth_required (ZADQ-307) · account_blocked (ZADQ-311) · custody_version_conflict · last_wrap · passkey_not_on_account (ZADQ-293) · wraps_required (ZADQ-293, v1.3.2) · origin_invalid · key_invalid · private_key_refused · origin_in_use · key_reused · evidence_required · obligations_not_published · obligations_changed (ZADQ-362, v1.3.13) · mintid_unavailable (503, ZADQ-407: MintID unreachable since the start-up and the ids not discovered yet; nothing recorded, retry later)
detailstringyes
custody_versioninteger (int64)no409 custody_version_conflict (§5.8, v1.3.2) — the stored version, to read and retry on.
fieldsobjectnoThe refused fields by path (400 person_invalid, profile_invalid).
missingarray of stringnoThe field paths a payment still needs (409 profile_incomplete).

Example

curl -sS "<base-url>/v1/price-lines" \
  --cookie "__Host-passkey_session=<api-key>"

POST /v1/price-lines/{priceLineId}/pay

Pay a price line — a hosted checkout URL, or the line's state

The entry fee or the seats while the subscription does not exist: the billing provider's hosted checkout (the plan's seats as a licensed quantity and the entry fee when due). A bundle or lease line whose approval waits on it: a card customer's hosted checkout (authorised on completion, captured when the agent is registered, released if the enrolment fails); an invoiced customer's line goes on the open invoice ({state: "invoiced"}). On the console path the answer is the line's state (open until the operator console marks it invoiced). The body names the dashboard's account page the hosted checkout comes back to (return_to, default agent-operator): the way back is <app>/#/account/<page>?billing=done|cancelled (ZADQ-319). The account's customer record must be complete first (ZADQ-307): 409 profile_incomplete with missing otherwise; the hosted page is opened for the account's provider Customer made from the record and asks for neither the address nor the tax id. 400 body_invalid (an unknown page); 404 price_line_not_found; 409 price_line_not_payable (the line is not open or failed: already authorised, captured, invoiced, credited or void — ZADQ-324) · price_line_not_due (an open line not payable yet: its approval has not come, the subscription already carries it, the usage fee) · kyc_required · profile_incomplete; 502 billing_provider_failed. v1.3.17 (ZADQ-387): a plan_refund line is paid back to the person, never paid — 409 price_line_not_payable; a switch's seat line on the provider opens the switch's hosted checkout (Premium's whole price, the credit as a one-off credit on the checkout).

Authentication: passkeySession.

Parameters

NameInRequiredTypeDescription
priceLineIdpathyesstring

Request body

application/json

Schema: PriceLinePay

PropertyTypeRequiredDescriptionValues
return_tostringnoThe dashboard's account page the hosted checkout returns to (account, verification, agent-operator (default), enrolments, approvals, agents, billing, activity)."account", "verification", "agent-operator", "enrolments", "approvals", "agents", "billing", "activity"

Responses

200 — A checkout URL or the state.

Content type application/json.

Schema: PriceLinePayment

PropertyTypeRequiredDescriptionValues
checkout_urlstringnoThe billing provider's hosted checkout page.
statePriceLineStateno

default — A /v1 refusal — {"error", "detail"} (platform API v1 §5).

Content type application/json.

Schema: V1Error

PropertyTypeRequiredDescriptionValues
errorstringyessession_required · passkey_required · last_passkey · ceremony_invalid · attestation_invalid · assertion_invalid · email_operational_invalid · body_invalid · origin_refused · not_found · not_available · internal · runtime_token_invalid · approval_not_pending · result_already_taken · declaration_invalid · request_invalid · cursor_invalid · rate_limited · offer_refused:<issuer code> (ZADQ-289) · kyc_current · kyc_required · entry_fee_due · reverification_required · invalid_state · sandbox_hint_not_available · invalid_sandbox_hint · issuer_unavailable (ZADQ-316) · kyc_grade_below_bundle (ZADQ-321) · person_invalid · profile_invalid · profile_incomplete · kind_locked · terms_changed · business_use_required · reauth_required (ZADQ-307) · account_blocked (ZADQ-311) · custody_version_conflict · last_wrap · passkey_not_on_account (ZADQ-293) · wraps_required (ZADQ-293, v1.3.2) · origin_invalid · key_invalid · private_key_refused · origin_in_use · key_reused · evidence_required · obligations_not_published · obligations_changed (ZADQ-362, v1.3.13) · mintid_unavailable (503, ZADQ-407: MintID unreachable since the start-up and the ids not discovered yet; nothing recorded, retry later)
detailstringyes
custody_versioninteger (int64)no409 custody_version_conflict (§5.8, v1.3.2) — the stored version, to read and retry on.
fieldsobjectnoThe refused fields by path (400 person_invalid, profile_invalid).
missingarray of stringnoThe field paths a payment still needs (409 profile_incomplete).

Example

curl -sS -X POST "<base-url>/v1/price-lines/<priceLineId>/pay" \
  --cookie "__Host-passkey_session=<api-key>" \
  -H "Content-Type: application/json" \
  -d @request-body.json

POST /v1/kyc/sessions

Open the responsible person's KYC session (platform API v1 §5.2)

The responsible person's verification at the issuer, operator type person, on the agent-operator machinery: the account's own record — no wallet, owned by the account from creation — opens a session at the KYC boundary. 201 {session_id, state: "pending", handoff_url, expires_at}. When the account already has a record: a pending session is returned as it is (200); an approved one with its window open answers 409 kyc_current; an expired one, or one whose principal credential its holder revoked, opens a new session on the same record (201); after a rejection or a withdrawal a new record is opened (201).

sandbox (<outcome>[:<option>…], e.g. approved:g2) picks the session's outcome on a staging instance whose issuer runs MintID's sandbox KYC driver, and nowhere else: 400 sandbox_hint_not_available elsewhere, 400 invalid_sandbox_hint when malformed or naming an identity option (this service carries no identity data, not even synthetic). ZadQ keeps the session handle and the window — never identity data.

biometric_consent: {version} is required (ZADQ-331; GDPR Art. 9(2)(a)): the person's explicit consent to the face comparison, given on ZadQ's page by the button whose label is the consent, before the verification link is opened; version is the label of the text shown. Absent (an empty body included): 409 biometric_consent_required; another label than the deployment's (GET /v1/me → biometric_consent.version_required): 409 biometric_consent_version_stale, the current label in the detail. Checked after the body's own 400s and before anything else — when refused nothing reaches the issuer and nothing is recorded. Accepted, the consent is recorded (version, time, the session handed out) and the activity log gains biometric_consent_given, whenever a session is handed out to be opened — a new one (201) or the pending one returned as it is (200); not on 409 kyc_current. "Not now" on the page is the absence of this call.

Authentication: passkeySession.

Request body

application/json

Schema: KycSessionCreate

PropertyTypeRequiredDescriptionValues
sandboxstringnoStaging only: the sandbox KYC driver's outcome grammar without its sandbox: prefix (<outcome>[:<option>…], e.g. approved:g2, rejected, expired). Identity options are refused.
biometric_consentBiometricConsentGivenno

Responses

200 — The account's pending session, as it is.

Content type application/json.

Schema: KycSession

PropertyTypeRequiredDescriptionValues
session_idstringyesThe issuer's KYC session handle (opaque).
statestringyes"pending", "approved", "rejected", "expired", "withdrawn"
handoff_urlstring, nullablenoWhere the person completes the verification at the issuer's provider; while pending, and only once a consent to the face comparison is recorded for this session (ZADQ-331) — absent (null) otherwise, with biometric_consent_required: true.
biometric_consent_requiredbooleannoWhile pending (ZADQ-331): true when no consent to the face comparison is recorded for this session (one opened before the rule) — the link is withheld until POST /v1/kyc/sessions/{id}/biometric-consent records one.
expires_atstring (date-time)noThe proofing deadline of a pending session.
gradeinteger, nullableyesThe issuer's assurance grade the approval was recorded at (ZADQ-321); null while not approved or where the boundary named none.
reusable_untilstring (date-time), nullableyesThe end of an approved session's reuse window; the principal credential expires exactly with it.
credentialKycCredentialyes

201 — A new session, pending.

Content type application/json.

Schema: KycSession

PropertyTypeRequiredDescriptionValues
session_idstringyesThe issuer's KYC session handle (opaque).
statestringyes"pending", "approved", "rejected", "expired", "withdrawn"
handoff_urlstring, nullablenoWhere the person completes the verification at the issuer's provider; while pending, and only once a consent to the face comparison is recorded for this session (ZADQ-331) — absent (null) otherwise, with biometric_consent_required: true.
biometric_consent_requiredbooleannoWhile pending (ZADQ-331): true when no consent to the face comparison is recorded for this session (one opened before the rule) — the link is withheld until POST /v1/kyc/sessions/{id}/biometric-consent records one.
expires_atstring (date-time)noThe proofing deadline of a pending session.
gradeinteger, nullableyesThe issuer's assurance grade the approval was recorded at (ZADQ-321); null while not approved or where the boundary named none.
reusable_untilstring (date-time), nullableyesThe end of an approved session's reuse window; the principal credential expires exactly with it.
credentialKycCredentialyes

default — A /v1 refusal — {"error", "detail"} (platform API v1 §5).

Content type application/json.

Schema: V1Error

PropertyTypeRequiredDescriptionValues
errorstringyessession_required · passkey_required · last_passkey · ceremony_invalid · attestation_invalid · assertion_invalid · email_operational_invalid · body_invalid · origin_refused · not_found · not_available · internal · runtime_token_invalid · approval_not_pending · result_already_taken · declaration_invalid · request_invalid · cursor_invalid · rate_limited · offer_refused:<issuer code> (ZADQ-289) · kyc_current · kyc_required · entry_fee_due · reverification_required · invalid_state · sandbox_hint_not_available · invalid_sandbox_hint · issuer_unavailable (ZADQ-316) · kyc_grade_below_bundle (ZADQ-321) · person_invalid · profile_invalid · profile_incomplete · kind_locked · terms_changed · business_use_required · reauth_required (ZADQ-307) · account_blocked (ZADQ-311) · custody_version_conflict · last_wrap · passkey_not_on_account (ZADQ-293) · wraps_required (ZADQ-293, v1.3.2) · origin_invalid · key_invalid · private_key_refused · origin_in_use · key_reused · evidence_required · obligations_not_published · obligations_changed (ZADQ-362, v1.3.13) · mintid_unavailable (503, ZADQ-407: MintID unreachable since the start-up and the ids not discovered yet; nothing recorded, retry later)
detailstringyes
custody_versioninteger (int64)no409 custody_version_conflict (§5.8, v1.3.2) — the stored version, to read and retry on.
fieldsobjectnoThe refused fields by path (400 person_invalid, profile_invalid).
missingarray of stringnoThe field paths a payment still needs (409 profile_incomplete).

Example

curl -sS -X POST "<base-url>/v1/kyc/sessions" \
  --cookie "__Host-passkey_session=<api-key>" \
  -H "Content-Type: application/json" \
  -d @request-body.json

GET /v1/kyc/sessions/{kycSessionId}

The responsible person's KYC session, brought up to date

The session's state after the boundary is read: pending (with handoff_url and expires_at), approved (with reusable_until, the end of the reuse window — the principal credential expires exactly with it), rejected, expired (the proofing deadline passed or the window closed: verify again with POST /v1/kyc/sessions) or withdrawn. credential is the principal credential's state in the operator's runtime. grade is the issuer's assurance grade the approval was recorded at (1..4; ZADQ-321), null while not approved or where the boundary named none. 404 not_found unless the session is the current session of one of the account's records.

Authentication: passkeySession.

Parameters

NameInRequiredTypeDescription
kycSessionIdpathyesstringThe issuer's KYC session handle (opaque), as session_id names it.

Responses

200 — The session.

Content type application/json.

Schema: KycSession

PropertyTypeRequiredDescriptionValues
session_idstringyesThe issuer's KYC session handle (opaque).
statestringyes"pending", "approved", "rejected", "expired", "withdrawn"
handoff_urlstring, nullablenoWhere the person completes the verification at the issuer's provider; while pending, and only once a consent to the face comparison is recorded for this session (ZADQ-331) — absent (null) otherwise, with biometric_consent_required: true.
biometric_consent_requiredbooleannoWhile pending (ZADQ-331): true when no consent to the face comparison is recorded for this session (one opened before the rule) — the link is withheld until POST /v1/kyc/sessions/{id}/biometric-consent records one.
expires_atstring (date-time)noThe proofing deadline of a pending session.
gradeinteger, nullableyesThe issuer's assurance grade the approval was recorded at (ZADQ-321); null while not approved or where the boundary named none.
reusable_untilstring (date-time), nullableyesThe end of an approved session's reuse window; the principal credential expires exactly with it.
credentialKycCredentialyes

default — A /v1 refusal — {"error", "detail"} (platform API v1 §5).

Content type application/json.

Schema: V1Error

PropertyTypeRequiredDescriptionValues
errorstringyessession_required · passkey_required · last_passkey · ceremony_invalid · attestation_invalid · assertion_invalid · email_operational_invalid · body_invalid · origin_refused · not_found · not_available · internal · runtime_token_invalid · approval_not_pending · result_already_taken · declaration_invalid · request_invalid · cursor_invalid · rate_limited · offer_refused:<issuer code> (ZADQ-289) · kyc_current · kyc_required · entry_fee_due · reverification_required · invalid_state · sandbox_hint_not_available · invalid_sandbox_hint · issuer_unavailable (ZADQ-316) · kyc_grade_below_bundle (ZADQ-321) · person_invalid · profile_invalid · profile_incomplete · kind_locked · terms_changed · business_use_required · reauth_required (ZADQ-307) · account_blocked (ZADQ-311) · custody_version_conflict · last_wrap · passkey_not_on_account (ZADQ-293) · wraps_required (ZADQ-293, v1.3.2) · origin_invalid · key_invalid · private_key_refused · origin_in_use · key_reused · evidence_required · obligations_not_published · obligations_changed (ZADQ-362, v1.3.13) · mintid_unavailable (503, ZADQ-407: MintID unreachable since the start-up and the ids not discovered yet; nothing recorded, retry later)
detailstringyes
custody_versioninteger (int64)no409 custody_version_conflict (§5.8, v1.3.2) — the stored version, to read and retry on.
fieldsobjectnoThe refused fields by path (400 person_invalid, profile_invalid).
missingarray of stringnoThe field paths a payment still needs (409 profile_incomplete).

Example

curl -sS "<base-url>/v1/kyc/sessions/<kycSessionId>" \
  --cookie "__Host-passkey_session=<api-key>"

POST /v1/kyc/sessions/{kycSessionId}/withdraw

Withdraw the responsible person's consent on the session

The withdrawal is recorded at the boundary on the session (terminal there; everything it backs is revoked upstream with reason consent_withdrawn), the record reads withdrawn, an offered or held principal credential reads revoked, and the agents minted on it are brought along. Terminal: the next verification is a new session on a new record. 409 invalid_state once rejected or withdrawn; 501 not_available when the substrate records no withdrawal.

Authentication: passkeySession.

Parameters

NameInRequiredTypeDescription
kycSessionIdpathyesstringThe issuer's KYC session handle (opaque), as session_id names it.

Responses

200 — The session, withdrawn.

Content type application/json.

Schema: KycSession

PropertyTypeRequiredDescriptionValues
session_idstringyesThe issuer's KYC session handle (opaque).
statestringyes"pending", "approved", "rejected", "expired", "withdrawn"
handoff_urlstring, nullablenoWhere the person completes the verification at the issuer's provider; while pending, and only once a consent to the face comparison is recorded for this session (ZADQ-331) — absent (null) otherwise, with biometric_consent_required: true.
biometric_consent_requiredbooleannoWhile pending (ZADQ-331): true when no consent to the face comparison is recorded for this session (one opened before the rule) — the link is withheld until POST /v1/kyc/sessions/{id}/biometric-consent records one.
expires_atstring (date-time)noThe proofing deadline of a pending session.
gradeinteger, nullableyesThe issuer's assurance grade the approval was recorded at (ZADQ-321); null while not approved or where the boundary named none.
reusable_untilstring (date-time), nullableyesThe end of an approved session's reuse window; the principal credential expires exactly with it.
credentialKycCredentialyes

default — A /v1 refusal — {"error", "detail"} (platform API v1 §5).

Content type application/json.

Schema: V1Error

PropertyTypeRequiredDescriptionValues
errorstringyessession_required · passkey_required · last_passkey · ceremony_invalid · attestation_invalid · assertion_invalid · email_operational_invalid · body_invalid · origin_refused · not_found · not_available · internal · runtime_token_invalid · approval_not_pending · result_already_taken · declaration_invalid · request_invalid · cursor_invalid · rate_limited · offer_refused:<issuer code> (ZADQ-289) · kyc_current · kyc_required · entry_fee_due · reverification_required · invalid_state · sandbox_hint_not_available · invalid_sandbox_hint · issuer_unavailable (ZADQ-316) · kyc_grade_below_bundle (ZADQ-321) · person_invalid · profile_invalid · profile_incomplete · kind_locked · terms_changed · business_use_required · reauth_required (ZADQ-307) · account_blocked (ZADQ-311) · custody_version_conflict · last_wrap · passkey_not_on_account (ZADQ-293) · wraps_required (ZADQ-293, v1.3.2) · origin_invalid · key_invalid · private_key_refused · origin_in_use · key_reused · evidence_required · obligations_not_published · obligations_changed (ZADQ-362, v1.3.13) · mintid_unavailable (503, ZADQ-407: MintID unreachable since the start-up and the ids not discovered yet; nothing recorded, retry later)
detailstringyes
custody_versioninteger (int64)no409 custody_version_conflict (§5.8, v1.3.2) — the stored version, to read and retry on.
fieldsobjectnoThe refused fields by path (400 person_invalid, profile_invalid).
missingarray of stringnoThe field paths a payment still needs (409 profile_incomplete).

Example

curl -sS -X POST "<base-url>/v1/kyc/sessions/<kycSessionId>/withdraw" \
  --cookie "__Host-passkey_session=<api-key>"

POST /v1/kyc/sessions/{kycSessionId}/biometric-consent

Record the consent to the face comparison on a pending session (ZADQ-331)

For a pending session that has no consent recorded (opened before the rule, or its consent not written): the person's consent to the face comparison, given on ZadQ's page, {version} the label of the text shown. 409 biometric_consent_required without a version, 409 biometric_consent_version_stale (the current label in the detail) with another label — checked before the session is read at the boundary: nothing reaches the issuer when refused. Then 409 invalid_state unless the session is pending. Accepted, the consent is recorded (version, time, this session; activity biometric_consent_given) and the session is returned with its handoff_url. A repeat records the consent again (each press of the button is a consent given).

Authentication: passkeySession.

Parameters

NameInRequiredTypeDescription
kycSessionIdpathyesstringThe issuer's KYC session handle (opaque), as session_id names it.

Request body

application/json — required

Schema: BiometricConsentGiven

PropertyTypeRequiredDescriptionValues
versionstringyesThe consent text's version label (e.g. 2026-10.2).

Responses

200 — The session, with its link.

Content type application/json.

Schema: KycSession

PropertyTypeRequiredDescriptionValues
session_idstringyesThe issuer's KYC session handle (opaque).
statestringyes"pending", "approved", "rejected", "expired", "withdrawn"
handoff_urlstring, nullablenoWhere the person completes the verification at the issuer's provider; while pending, and only once a consent to the face comparison is recorded for this session (ZADQ-331) — absent (null) otherwise, with biometric_consent_required: true.
biometric_consent_requiredbooleannoWhile pending (ZADQ-331): true when no consent to the face comparison is recorded for this session (one opened before the rule) — the link is withheld until POST /v1/kyc/sessions/{id}/biometric-consent records one.
expires_atstring (date-time)noThe proofing deadline of a pending session.
gradeinteger, nullableyesThe issuer's assurance grade the approval was recorded at (ZADQ-321); null while not approved or where the boundary named none.
reusable_untilstring (date-time), nullableyesThe end of an approved session's reuse window; the principal credential expires exactly with it.
credentialKycCredentialyes

default — A /v1 refusal — {"error", "detail"} (platform API v1 §5).

Content type application/json.

Schema: V1Error

PropertyTypeRequiredDescriptionValues
errorstringyessession_required · passkey_required · last_passkey · ceremony_invalid · attestation_invalid · assertion_invalid · email_operational_invalid · body_invalid · origin_refused · not_found · not_available · internal · runtime_token_invalid · approval_not_pending · result_already_taken · declaration_invalid · request_invalid · cursor_invalid · rate_limited · offer_refused:<issuer code> (ZADQ-289) · kyc_current · kyc_required · entry_fee_due · reverification_required · invalid_state · sandbox_hint_not_available · invalid_sandbox_hint · issuer_unavailable (ZADQ-316) · kyc_grade_below_bundle (ZADQ-321) · person_invalid · profile_invalid · profile_incomplete · kind_locked · terms_changed · business_use_required · reauth_required (ZADQ-307) · account_blocked (ZADQ-311) · custody_version_conflict · last_wrap · passkey_not_on_account (ZADQ-293) · wraps_required (ZADQ-293, v1.3.2) · origin_invalid · key_invalid · private_key_refused · origin_in_use · key_reused · evidence_required · obligations_not_published · obligations_changed (ZADQ-362, v1.3.13) · mintid_unavailable (503, ZADQ-407: MintID unreachable since the start-up and the ids not discovered yet; nothing recorded, retry later)
detailstringyes
custody_versioninteger (int64)no409 custody_version_conflict (§5.8, v1.3.2) — the stored version, to read and retry on.
fieldsobjectnoThe refused fields by path (400 person_invalid, profile_invalid).
missingarray of stringnoThe field paths a payment still needs (409 profile_incomplete).

Example

curl -sS -X POST "<base-url>/v1/kyc/sessions/<kycSessionId>/biometric-consent" \
  --cookie "__Host-passkey_session=<api-key>" \
  -H "Content-Type: application/json" \
  -d @request-body.json

POST /v1/kyc/sessions/{kycSessionId}/credential/offer

Hand out the offer of the person's identity credential to the runtime, once (erratum E3)

Platform API v1.2.1, erratum E3: the hand-off of the responsible person's identity credential — the principal the account's agents are minted from — to the holder in the operator's runtime (stage 1, principal_mode: runtime), under the passkey session (the v0 wallet path's offer is retired since v1.3.33): the offer is created from the approved session on the issuer's route and returned exactly once (Cache-Control: no-store); the operator's runtime redeems it at once with the holder library, and the credential and its keys stay there. This service never stores or logs the offer and never sees the credential, a key or a proof. The code and the credential expire exactly with the verification. 409 entry_fee_due until the entry fee is recorded, kyc_required unless approved with the window open, reverification_required after the holder revoked the credential on this verification, invalid_state while one is held; 501 not_available when the substrate offers no credential rail.

location (ZADQ-293, §5.8; MintID ADR-0027: one identity credential per custody location, all from the same KYC session) picks the place the credential is offered for: server (the default, the behaviour above) or browser — a second identity credential offer from the same approved session for the person's browser holder, judged on the browser location's own state: 409 invalid_state while a browser credential is held (revoke it first; custody bytes never move between places), reverification_required after the holder revoked the browser credential on this verification. The answer's credential block is the state of the location offered for.

Authentication: passkeySession.

Parameters

NameInRequiredTypeDescription
kycSessionIdpathyesstringThe issuer's KYC session handle (opaque), as session_id names it.

Request body

application/json

Schema: KycCredentialOfferRequest

PropertyTypeRequiredDescriptionValues
locationCustodyLocationno

Responses

201 — The offer, handed out once, and when it expires.

Content type application/json.

Schema: KycCredentialOffer

PropertyTypeRequiredDescriptionValues
locationCustodyLocationno
offerobjectyesThe credential offer object, as the issuer returned it — opaque, one-shot; redeem it at once.
expires_atstring (date-time)yesWhen the code and the credential it yields expire — the verification's own window end at the latest. No grace.
credentialKycCredentialyes

default — A /v1 refusal — {"error", "detail"} (platform API v1 §5).

Content type application/json.

Schema: V1Error

PropertyTypeRequiredDescriptionValues
errorstringyessession_required · passkey_required · last_passkey · ceremony_invalid · attestation_invalid · assertion_invalid · email_operational_invalid · body_invalid · origin_refused · not_found · not_available · internal · runtime_token_invalid · approval_not_pending · result_already_taken · declaration_invalid · request_invalid · cursor_invalid · rate_limited · offer_refused:<issuer code> (ZADQ-289) · kyc_current · kyc_required · entry_fee_due · reverification_required · invalid_state · sandbox_hint_not_available · invalid_sandbox_hint · issuer_unavailable (ZADQ-316) · kyc_grade_below_bundle (ZADQ-321) · person_invalid · profile_invalid · profile_incomplete · kind_locked · terms_changed · business_use_required · reauth_required (ZADQ-307) · account_blocked (ZADQ-311) · custody_version_conflict · last_wrap · passkey_not_on_account (ZADQ-293) · wraps_required (ZADQ-293, v1.3.2) · origin_invalid · key_invalid · private_key_refused · origin_in_use · key_reused · evidence_required · obligations_not_published · obligations_changed (ZADQ-362, v1.3.13) · mintid_unavailable (503, ZADQ-407: MintID unreachable since the start-up and the ids not discovered yet; nothing recorded, retry later)
detailstringyes
custody_versioninteger (int64)no409 custody_version_conflict (§5.8, v1.3.2) — the stored version, to read and retry on.
fieldsobjectnoThe refused fields by path (400 person_invalid, profile_invalid).
missingarray of stringnoThe field paths a payment still needs (409 profile_incomplete).

Example

curl -sS -X POST "<base-url>/v1/kyc/sessions/<kycSessionId>/credential/offer" \
  --cookie "__Host-passkey_session=<api-key>" \
  -H "Content-Type: application/json" \
  -d @request-body.json

POST /v1/kyc/sessions/{kycSessionId}/credential

Report the person's credential state from the operator's runtime (erratum E3)

Platform API v1.2.1, erratum E3: what the operator's runtime did with the offer — held (optionally with an opaque reference of its choosing; the record reads credential held and the account's enrolments can be backed by it) or self_revoked (the holder revoked the credential through the network's privacy relay; revoked is the older spelling of the same report). A self_revoked report is recorded as the state change and nothing else — no event, no time, no log line; the way back is a new verification (POST /v1/kyc/sessions). 409 invalid_state when no offer was handed out on this verification.

Authentication: passkeySession.

Parameters

NameInRequiredTypeDescription
kycSessionIdpathyesstringThe issuer's KYC session handle (opaque), as session_id names it.

Request body

application/json — required

Schema: KycCredentialReport

PropertyTypeRequiredDescriptionValues
statestringyesheld, or self_revoked (revoked is the older spelling of the same report)."held", "self_revoked", "revoked"
credential_refstringnoAn opaque reference of the runtime's choosing for the credential it holds. Never a key.

Responses

200 — The session with the reported credential state.

Content type application/json.

Schema: KycSession

PropertyTypeRequiredDescriptionValues
session_idstringyesThe issuer's KYC session handle (opaque).
statestringyes"pending", "approved", "rejected", "expired", "withdrawn"
handoff_urlstring, nullablenoWhere the person completes the verification at the issuer's provider; while pending, and only once a consent to the face comparison is recorded for this session (ZADQ-331) — absent (null) otherwise, with biometric_consent_required: true.
biometric_consent_requiredbooleannoWhile pending (ZADQ-331): true when no consent to the face comparison is recorded for this session (one opened before the rule) — the link is withheld until POST /v1/kyc/sessions/{id}/biometric-consent records one.
expires_atstring (date-time)noThe proofing deadline of a pending session.
gradeinteger, nullableyesThe issuer's assurance grade the approval was recorded at (ZADQ-321); null while not approved or where the boundary named none.
reusable_untilstring (date-time), nullableyesThe end of an approved session's reuse window; the principal credential expires exactly with it.
credentialKycCredentialyes

default — A /v1 refusal — {"error", "detail"} (platform API v1 §5).

Content type application/json.

Schema: V1Error

PropertyTypeRequiredDescriptionValues
errorstringyessession_required · passkey_required · last_passkey · ceremony_invalid · attestation_invalid · assertion_invalid · email_operational_invalid · body_invalid · origin_refused · not_found · not_available · internal · runtime_token_invalid · approval_not_pending · result_already_taken · declaration_invalid · request_invalid · cursor_invalid · rate_limited · offer_refused:<issuer code> (ZADQ-289) · kyc_current · kyc_required · entry_fee_due · reverification_required · invalid_state · sandbox_hint_not_available · invalid_sandbox_hint · issuer_unavailable (ZADQ-316) · kyc_grade_below_bundle (ZADQ-321) · person_invalid · profile_invalid · profile_incomplete · kind_locked · terms_changed · business_use_required · reauth_required (ZADQ-307) · account_blocked (ZADQ-311) · custody_version_conflict · last_wrap · passkey_not_on_account (ZADQ-293) · wraps_required (ZADQ-293, v1.3.2) · origin_invalid · key_invalid · private_key_refused · origin_in_use · key_reused · evidence_required · obligations_not_published · obligations_changed (ZADQ-362, v1.3.13) · mintid_unavailable (503, ZADQ-407: MintID unreachable since the start-up and the ids not discovered yet; nothing recorded, retry later)
detailstringyes
custody_versioninteger (int64)no409 custody_version_conflict (§5.8, v1.3.2) — the stored version, to read and retry on.
fieldsobjectnoThe refused fields by path (400 person_invalid, profile_invalid).
missingarray of stringnoThe field paths a payment still needs (409 profile_incomplete).

Example

curl -sS -X POST "<base-url>/v1/kyc/sessions/<kycSessionId>/credential" \
  --cookie "__Host-passkey_session=<api-key>" \
  -H "Content-Type: application/json" \
  -d @request-body.json

GET /v1/custody

The person's identity credential at each custody location

Platform API v1.2.1 §5.8 (MintID ADR-0027, accepted 2026-10-18): one identity credential per custody location, server (the holder in the operator's runtime, stage 1 — the agent-operator record's credential block, read here, never duplicated) and browser (the person's browser holder, stage 2 — the ciphertext store of /v1/custody/browser), all backed by the account's one KYC session: both expire with it, the session's withdrawal revokes both. State only; never a byte of custody.

Authentication: passkeySession.

Responses

200 — The two locations.

Content type application/json.

Schema: CustodyLocations

PropertyTypeRequiredDescriptionValues
credentialsarray of CustodyLocationStateyes

default — A /v1 refusal — {"error", "detail"} (platform API v1 §5).

Content type application/json.

Schema: V1Error

PropertyTypeRequiredDescriptionValues
errorstringyessession_required · passkey_required · last_passkey · ceremony_invalid · attestation_invalid · assertion_invalid · email_operational_invalid · body_invalid · origin_refused · not_found · not_available · internal · runtime_token_invalid · approval_not_pending · result_already_taken · declaration_invalid · request_invalid · cursor_invalid · rate_limited · offer_refused:<issuer code> (ZADQ-289) · kyc_current · kyc_required · entry_fee_due · reverification_required · invalid_state · sandbox_hint_not_available · invalid_sandbox_hint · issuer_unavailable (ZADQ-316) · kyc_grade_below_bundle (ZADQ-321) · person_invalid · profile_invalid · profile_incomplete · kind_locked · terms_changed · business_use_required · reauth_required (ZADQ-307) · account_blocked (ZADQ-311) · custody_version_conflict · last_wrap · passkey_not_on_account (ZADQ-293) · wraps_required (ZADQ-293, v1.3.2) · origin_invalid · key_invalid · private_key_refused · origin_in_use · key_reused · evidence_required · obligations_not_published · obligations_changed (ZADQ-362, v1.3.13) · mintid_unavailable (503, ZADQ-407: MintID unreachable since the start-up and the ids not discovered yet; nothing recorded, retry later)
detailstringyes
custody_versioninteger (int64)no409 custody_version_conflict (§5.8, v1.3.2) — the stored version, to read and retry on.
fieldsobjectnoThe refused fields by path (400 person_invalid, profile_invalid).
missingarray of stringnoThe field paths a payment still needs (409 profile_incomplete).

Example

curl -sS "<base-url>/v1/custody" \
  --cookie "__Host-passkey_session=<api-key>"

GET /v1/custody/browser

Read the browser credential's ciphertext and wraps

The account's browser-location credential as last written: the state, the version, the ciphertext (base64; absent once revoked or before the first upload) and the wraps — per passkey, the PRF input and HKDF salt the browser drew and the wrapped data key. The browser evaluates the PRF on its passkey, derives the key-encryption key, unwraps the data key and decrypts in page memory; this service holds no key and performs no step of it: a ciphertext the service cannot open is not custody. rotation_due (v1.3.2): a wrap went without a rotation of the data key — the browser rotates on its next opening of the credential (PUT with rotation: true). Cache-Control: no-store. 404 not_found before any browser offer was handed out.

Authentication: passkeySession.

Responses

200 — The credential with its ciphertext and wraps.

Content type application/json.

Schema: BrowserCustody

PropertyTypeRequiredDescriptionValues
idstringyes
locationCustodyLocationyes
statestringyes"offered", "held", "expired", "revoked", "self_revoked"
kyc_session_idstringnoThe session handle the credential was offered on.
schemestringyesThe browser's name for the wrap and AEAD construction (default prf-hkdf-aead-v1). Never interpreted here.
custody_versioninteger (int64)yes
rotation_duebooleanyesv1.3.2: true once a wrap went without a rotation of the data key (a wrap removed, or a passkey removed with its wrap); cleared by the next rotation (PUT with rotation: true).
ciphertextstring (byte)noBase64 of the ciphertext, as uploaded.
issuer_credential_handlestringnoThe issuer's opaque credential handle, when the browser reported it.
offered_atstring (date-time)no
issued_atstring (date-time)no
expires_atstring (date-time)no
wrapsarray of CustodyWrapyes

default — A /v1 refusal — {"error", "detail"} (platform API v1 §5).

Content type application/json.

Schema: V1Error

PropertyTypeRequiredDescriptionValues
errorstringyessession_required · passkey_required · last_passkey · ceremony_invalid · attestation_invalid · assertion_invalid · email_operational_invalid · body_invalid · origin_refused · not_found · not_available · internal · runtime_token_invalid · approval_not_pending · result_already_taken · declaration_invalid · request_invalid · cursor_invalid · rate_limited · offer_refused:<issuer code> (ZADQ-289) · kyc_current · kyc_required · entry_fee_due · reverification_required · invalid_state · sandbox_hint_not_available · invalid_sandbox_hint · issuer_unavailable (ZADQ-316) · kyc_grade_below_bundle (ZADQ-321) · person_invalid · profile_invalid · profile_incomplete · kind_locked · terms_changed · business_use_required · reauth_required (ZADQ-307) · account_blocked (ZADQ-311) · custody_version_conflict · last_wrap · passkey_not_on_account (ZADQ-293) · wraps_required (ZADQ-293, v1.3.2) · origin_invalid · key_invalid · private_key_refused · origin_in_use · key_reused · evidence_required · obligations_not_published · obligations_changed (ZADQ-362, v1.3.13) · mintid_unavailable (503, ZADQ-407: MintID unreachable since the start-up and the ids not discovered yet; nothing recorded, retry later)
detailstringyes
custody_versioninteger (int64)no409 custody_version_conflict (§5.8, v1.3.2) — the stored version, to read and retry on.
fieldsobjectnoThe refused fields by path (400 person_invalid, profile_invalid).
missingarray of stringnoThe field paths a payment still needs (409 profile_incomplete).

Example

curl -sS "<base-url>/v1/custody/browser" \
  --cookie "__Host-passkey_session=<api-key>"

PUT /v1/custody/browser

Upload the browser credential's ciphertext with its version

The browser's upload after issuance, and after every witness refresh: the holder's storage bytes encrypted under the data key, the version it read (custody_version: 0 on the first upload), optionally the scheme name, the issuer's opaque credential handle, the issuance time and the wraps. The first upload (201) turns the offered credential into held and must carry at least one wrap; later uploads (200) must carry the stored version and advance it by one — 409 custody_version_conflict otherwise, with the stored version in custody_version (another browser of the person uploaded meanwhile: read and retry on its bytes). After the first upload a plain upload keeps the stored wraps and carries none (400 body_invalid with wraps and without rotation).

The rotation (v1.3.2, ZADQ-293; MintID's binding scheme): with rotation: true the browser drew a new data key, sealed the storage bytes under it and lists the wrap of every passkey that stays. In one write: the ciphertext replaced, one version step, each listed wrap replaced (created_at now), every wrap not listed removed (one custody_wrap_removed each; several may go, never all), rotation_due cleared; 200. Refusals change nothing: 409 custody_version_conflict; 400 wraps_required (no list, a wrap missing a field, a passkey twice, or a passkey that holds no wrap now — a rotation never adds one); 409 last_wrap (an empty list); 409 invalid_state before the first upload.

409 passkey_not_on_account for a passkey that is not one of the account's, invalid_state without a live browser offer, 400 body_invalid. Activity (§5.7): custody_uploaded on the first upload only.

Authentication: passkeySession.

Request body

application/json — required

Schema: BrowserCustodyUpload

PropertyTypeRequiredDescriptionValues
ciphertextstring (byte)yesBase64 of the encrypted holder record (1 to 262144 bytes decoded).
custody_versioninteger (int64)yesThe version the browser read; 0 on the first upload. The stored version advances by one.
schemestringno
issuer_credential_handlestringnoThe issuer's opaque credential handle. Never a key, a code or a proof.
issued_atstring (date-time)no
wrapsarray of CustodyWrapInputnoRequired on the first upload (at least one); on a rotation the wrap of every passkey that stays, under the new data key (empty: 409 last_wrap); refused on a later plain upload.
rotationbooleannov1.3.2: this upload rotates the data key — the ciphertext and every wrap replaced in one write, wraps not listed removed, rotation_due cleared.

Responses

200 — Re-uploaded; the version advanced.

Content type application/json.

Schema: BrowserCustody

PropertyTypeRequiredDescriptionValues
idstringyes
locationCustodyLocationyes
statestringyes"offered", "held", "expired", "revoked", "self_revoked"
kyc_session_idstringnoThe session handle the credential was offered on.
schemestringyesThe browser's name for the wrap and AEAD construction (default prf-hkdf-aead-v1). Never interpreted here.
custody_versioninteger (int64)yes
rotation_duebooleanyesv1.3.2: true once a wrap went without a rotation of the data key (a wrap removed, or a passkey removed with its wrap); cleared by the next rotation (PUT with rotation: true).
ciphertextstring (byte)noBase64 of the ciphertext, as uploaded.
issuer_credential_handlestringnoThe issuer's opaque credential handle, when the browser reported it.
offered_atstring (date-time)no
issued_atstring (date-time)no
expires_atstring (date-time)no
wrapsarray of CustodyWrapyes

201 — The first upload; the credential reads held.

Content type application/json.

Schema: BrowserCustody

PropertyTypeRequiredDescriptionValues
idstringyes
locationCustodyLocationyes
statestringyes"offered", "held", "expired", "revoked", "self_revoked"
kyc_session_idstringnoThe session handle the credential was offered on.
schemestringyesThe browser's name for the wrap and AEAD construction (default prf-hkdf-aead-v1). Never interpreted here.
custody_versioninteger (int64)yes
rotation_duebooleanyesv1.3.2: true once a wrap went without a rotation of the data key (a wrap removed, or a passkey removed with its wrap); cleared by the next rotation (PUT with rotation: true).
ciphertextstring (byte)noBase64 of the ciphertext, as uploaded.
issuer_credential_handlestringnoThe issuer's opaque credential handle, when the browser reported it.
offered_atstring (date-time)no
issued_atstring (date-time)no
expires_atstring (date-time)no
wrapsarray of CustodyWrapyes

default — A /v1 refusal — {"error", "detail"} (platform API v1 §5).

Content type application/json.

Schema: V1Error

PropertyTypeRequiredDescriptionValues
errorstringyessession_required · passkey_required · last_passkey · ceremony_invalid · attestation_invalid · assertion_invalid · email_operational_invalid · body_invalid · origin_refused · not_found · not_available · internal · runtime_token_invalid · approval_not_pending · result_already_taken · declaration_invalid · request_invalid · cursor_invalid · rate_limited · offer_refused:<issuer code> (ZADQ-289) · kyc_current · kyc_required · entry_fee_due · reverification_required · invalid_state · sandbox_hint_not_available · invalid_sandbox_hint · issuer_unavailable (ZADQ-316) · kyc_grade_below_bundle (ZADQ-321) · person_invalid · profile_invalid · profile_incomplete · kind_locked · terms_changed · business_use_required · reauth_required (ZADQ-307) · account_blocked (ZADQ-311) · custody_version_conflict · last_wrap · passkey_not_on_account (ZADQ-293) · wraps_required (ZADQ-293, v1.3.2) · origin_invalid · key_invalid · private_key_refused · origin_in_use · key_reused · evidence_required · obligations_not_published · obligations_changed (ZADQ-362, v1.3.13) · mintid_unavailable (503, ZADQ-407: MintID unreachable since the start-up and the ids not discovered yet; nothing recorded, retry later)
detailstringyes
custody_versioninteger (int64)no409 custody_version_conflict (§5.8, v1.3.2) — the stored version, to read and retry on.
fieldsobjectnoThe refused fields by path (400 person_invalid, profile_invalid).
missingarray of stringnoThe field paths a payment still needs (409 profile_incomplete).

Example

curl -sS -X PUT "<base-url>/v1/custody/browser" \
  --cookie "__Host-passkey_session=<api-key>" \
  -H "Content-Type: application/json" \
  -d @request-body.json

POST /v1/custody/browser/wraps

Add the data key wrapped under one more of the account's passkeys

Multi-wrap: the data key wrapped under another passkey of the account, so losing one passkey is not losing the credential. A wrap for a passkey that already has one is replaced. The body carries the custody_version the browser read (v1.3.2): a wrap of a data key another page rotated away would open nothing, so another version is 409 custody_version_conflict (the stored version in custody_version) and nothing changes; the addition is one version step and the answer carries the new one. 409 passkey_not_on_account for a passkey of another account or none; invalid_state before the first upload. The answer carries the wraps and no ciphertext. Activity: custody_wrap_added.

Authentication: passkeySession.

Request body

application/json — required

Schema: CustodyWrapAdd

PropertyTypeRequiredDescriptionValues
passkey_idstringyesOne of the account's passkeys.
prf_saltstring (byte)yes
wrapped_dekstring (byte)yes
custody_versioninteger (int64)yesThe version the browser read; the addition advances it by one.

Responses

201 — The credential's wraps after the addition.

Content type application/json.

Schema: BrowserCustody

PropertyTypeRequiredDescriptionValues
idstringyes
locationCustodyLocationyes
statestringyes"offered", "held", "expired", "revoked", "self_revoked"
kyc_session_idstringnoThe session handle the credential was offered on.
schemestringyesThe browser's name for the wrap and AEAD construction (default prf-hkdf-aead-v1). Never interpreted here.
custody_versioninteger (int64)yes
rotation_duebooleanyesv1.3.2: true once a wrap went without a rotation of the data key (a wrap removed, or a passkey removed with its wrap); cleared by the next rotation (PUT with rotation: true).
ciphertextstring (byte)noBase64 of the ciphertext, as uploaded.
issuer_credential_handlestringnoThe issuer's opaque credential handle, when the browser reported it.
offered_atstring (date-time)no
issued_atstring (date-time)no
expires_atstring (date-time)no
wrapsarray of CustodyWrapyes

default — A /v1 refusal — {"error", "detail"} (platform API v1 §5).

Content type application/json.

Schema: V1Error

PropertyTypeRequiredDescriptionValues
errorstringyessession_required · passkey_required · last_passkey · ceremony_invalid · attestation_invalid · assertion_invalid · email_operational_invalid · body_invalid · origin_refused · not_found · not_available · internal · runtime_token_invalid · approval_not_pending · result_already_taken · declaration_invalid · request_invalid · cursor_invalid · rate_limited · offer_refused:<issuer code> (ZADQ-289) · kyc_current · kyc_required · entry_fee_due · reverification_required · invalid_state · sandbox_hint_not_available · invalid_sandbox_hint · issuer_unavailable (ZADQ-316) · kyc_grade_below_bundle (ZADQ-321) · person_invalid · profile_invalid · profile_incomplete · kind_locked · terms_changed · business_use_required · reauth_required (ZADQ-307) · account_blocked (ZADQ-311) · custody_version_conflict · last_wrap · passkey_not_on_account (ZADQ-293) · wraps_required (ZADQ-293, v1.3.2) · origin_invalid · key_invalid · private_key_refused · origin_in_use · key_reused · evidence_required · obligations_not_published · obligations_changed (ZADQ-362, v1.3.13) · mintid_unavailable (503, ZADQ-407: MintID unreachable since the start-up and the ids not discovered yet; nothing recorded, retry later)
detailstringyes
custody_versioninteger (int64)no409 custody_version_conflict (§5.8, v1.3.2) — the stored version, to read and retry on.
fieldsobjectnoThe refused fields by path (400 person_invalid, profile_invalid).
missingarray of stringnoThe field paths a payment still needs (409 profile_incomplete).

Example

curl -sS -X POST "<base-url>/v1/custody/browser/wraps" \
  --cookie "__Host-passkey_session=<api-key>" \
  -H "Content-Type: application/json" \
  -d @request-body.json

DELETE /v1/custody/browser/wraps/{passkeyId}

Remove one passkey's wrap (never the last one)

Removes the wrap without a rotation (v1.3.2): one version step and rotation_due set — the stored ciphertext stays under the data key that passkey once read until the browser rotates it (PUT with rotation: true); the dashboard calls this route only when a passkey that stays cannot answer. 200 the credential without ciphertext (204 before v1.3.2). 409 last_wrap for the last one: a held credential nobody could open is not a state — revoke the credential instead (POST /v1/custody/browser/report). 404 not_found when the passkey carries no wrap. The same rule guards DELETE /v1/me/passkeys/{id}: the passkey that carries the last wrap of a live browser credential is not removed (409 last_wrap); another passkey's wrap goes with it the same way. Activity: custody_wrap_removed, written with the removal.

Authentication: passkeySession.

Parameters

NameInRequiredTypeDescription
passkeyIdpathyesstring

Responses

200 — The credential's wraps after the removal, its new version, rotation_due set.

Content type application/json.

Schema: BrowserCustody

PropertyTypeRequiredDescriptionValues
idstringyes
locationCustodyLocationyes
statestringyes"offered", "held", "expired", "revoked", "self_revoked"
kyc_session_idstringnoThe session handle the credential was offered on.
schemestringyesThe browser's name for the wrap and AEAD construction (default prf-hkdf-aead-v1). Never interpreted here.
custody_versioninteger (int64)yes
rotation_duebooleanyesv1.3.2: true once a wrap went without a rotation of the data key (a wrap removed, or a passkey removed with its wrap); cleared by the next rotation (PUT with rotation: true).
ciphertextstring (byte)noBase64 of the ciphertext, as uploaded.
issuer_credential_handlestringnoThe issuer's opaque credential handle, when the browser reported it.
offered_atstring (date-time)no
issued_atstring (date-time)no
expires_atstring (date-time)no
wrapsarray of CustodyWrapyes

default — A /v1 refusal — {"error", "detail"} (platform API v1 §5).

Content type application/json.

Schema: V1Error

PropertyTypeRequiredDescriptionValues
errorstringyessession_required · passkey_required · last_passkey · ceremony_invalid · attestation_invalid · assertion_invalid · email_operational_invalid · body_invalid · origin_refused · not_found · not_available · internal · runtime_token_invalid · approval_not_pending · result_already_taken · declaration_invalid · request_invalid · cursor_invalid · rate_limited · offer_refused:<issuer code> (ZADQ-289) · kyc_current · kyc_required · entry_fee_due · reverification_required · invalid_state · sandbox_hint_not_available · invalid_sandbox_hint · issuer_unavailable (ZADQ-316) · kyc_grade_below_bundle (ZADQ-321) · person_invalid · profile_invalid · profile_incomplete · kind_locked · terms_changed · business_use_required · reauth_required (ZADQ-307) · account_blocked (ZADQ-311) · custody_version_conflict · last_wrap · passkey_not_on_account (ZADQ-293) · wraps_required (ZADQ-293, v1.3.2) · origin_invalid · key_invalid · private_key_refused · origin_in_use · key_reused · evidence_required · obligations_not_published · obligations_changed (ZADQ-362, v1.3.13) · mintid_unavailable (503, ZADQ-407: MintID unreachable since the start-up and the ids not discovered yet; nothing recorded, retry later)
detailstringyes
custody_versioninteger (int64)no409 custody_version_conflict (§5.8, v1.3.2) — the stored version, to read and retry on.
fieldsobjectnoThe refused fields by path (400 person_invalid, profile_invalid).
missingarray of stringnoThe field paths a payment still needs (409 profile_incomplete).

Example

curl -sS -X DELETE "<base-url>/v1/custody/browser/wraps/<passkeyId>" \
  --cookie "__Host-passkey_session=<api-key>"

POST /v1/custody/browser/report

Report that the browser credential ended

What the browser learnt about its credential: revoked (the issuer's policy, as the holder's witness refresh reported it) or self_revoked (the holder revoked it through the network's privacy relay). Per-place revocation (ADR-0027): the server location is untouched. The ciphertext is cleared and the wraps deleted: nothing of a credential that is gone stays here. A self_revoked report is recorded as the state change and nothing else — no event, no log line (MintID R11); revoked writes custody_revoked to the activity. The way back after a self-revocation is a new verification (POST /v1/kyc/sessions). 409 invalid_state without a live browser credential.

Authentication: passkeySession.

Request body

application/json — required

Schema: BrowserCustodyReport

PropertyTypeRequiredDescriptionValues
statestringyes"revoked", "self_revoked"

Responses

200 — The credential, ended.

Content type application/json.

Schema: BrowserCustody

PropertyTypeRequiredDescriptionValues
idstringyes
locationCustodyLocationyes
statestringyes"offered", "held", "expired", "revoked", "self_revoked"
kyc_session_idstringnoThe session handle the credential was offered on.
schemestringyesThe browser's name for the wrap and AEAD construction (default prf-hkdf-aead-v1). Never interpreted here.
custody_versioninteger (int64)yes
rotation_duebooleanyesv1.3.2: true once a wrap went without a rotation of the data key (a wrap removed, or a passkey removed with its wrap); cleared by the next rotation (PUT with rotation: true).
ciphertextstring (byte)noBase64 of the ciphertext, as uploaded.
issuer_credential_handlestringnoThe issuer's opaque credential handle, when the browser reported it.
offered_atstring (date-time)no
issued_atstring (date-time)no
expires_atstring (date-time)no
wrapsarray of CustodyWrapyes

default — A /v1 refusal — {"error", "detail"} (platform API v1 §5).

Content type application/json.

Schema: V1Error

PropertyTypeRequiredDescriptionValues
errorstringyessession_required · passkey_required · last_passkey · ceremony_invalid · attestation_invalid · assertion_invalid · email_operational_invalid · body_invalid · origin_refused · not_found · not_available · internal · runtime_token_invalid · approval_not_pending · result_already_taken · declaration_invalid · request_invalid · cursor_invalid · rate_limited · offer_refused:<issuer code> (ZADQ-289) · kyc_current · kyc_required · entry_fee_due · reverification_required · invalid_state · sandbox_hint_not_available · invalid_sandbox_hint · issuer_unavailable (ZADQ-316) · kyc_grade_below_bundle (ZADQ-321) · person_invalid · profile_invalid · profile_incomplete · kind_locked · terms_changed · business_use_required · reauth_required (ZADQ-307) · account_blocked (ZADQ-311) · custody_version_conflict · last_wrap · passkey_not_on_account (ZADQ-293) · wraps_required (ZADQ-293, v1.3.2) · origin_invalid · key_invalid · private_key_refused · origin_in_use · key_reused · evidence_required · obligations_not_published · obligations_changed (ZADQ-362, v1.3.13) · mintid_unavailable (503, ZADQ-407: MintID unreachable since the start-up and the ids not discovered yet; nothing recorded, retry later)
detailstringyes
custody_versioninteger (int64)no409 custody_version_conflict (§5.8, v1.3.2) — the stored version, to read and retry on.
fieldsobjectnoThe refused fields by path (400 person_invalid, profile_invalid).
missingarray of stringnoThe field paths a payment still needs (409 profile_incomplete).

Example

curl -sS -X POST "<base-url>/v1/custody/browser/report" \
  --cookie "__Host-passkey_session=<api-key>" \
  -H "Content-Type: application/json" \
  -d @request-body.json

GET /v1/verifier-keys

The verifier records ZadQ pins for the browser holder (staticVerifierKeys)

The records the browser holder passes to staticVerifierKeys (MintID's @mintid-net/holder 0.1.0, whose VerifierKeys shape each record is: verifier_id, the record's state and its request_signing_keys, hex bytes and proto enum numbers). A browser has no light client, so the verifier keys it accepts challenges from are pinned server-side: this deployment serves the set its configuration pins (VERIFIER_KEY_RECORDS), recorded by the operator from a proven read of the chain — every value ics23-proven against the anchor's app hash with the published verifier SDK's chain client; this service runs no MintID chain reader of its own. A key rotation reaches the holder only when the set is recorded again. 501 not_available when the deployment pins none: the holder then refuses every challenge (challenge_key_unknown), the fail-closed answer. Cache-Control: private, max-age=300.

Authentication: passkeySession.

Responses

200 — The pinned records.

Content type application/json.

Schema: PinnedVerifierKeys

PropertyTypeRequiredDescriptionValues
recordsarray of PinnedVerifierKeyRecordyes
pinned_atstring (date-time)noWhen the operator recorded the set from its proven read, when the configuration says.

default — A /v1 refusal — {"error", "detail"} (platform API v1 §5).

Content type application/json.

Schema: V1Error

PropertyTypeRequiredDescriptionValues
errorstringyessession_required · passkey_required · last_passkey · ceremony_invalid · attestation_invalid · assertion_invalid · email_operational_invalid · body_invalid · origin_refused · not_found · not_available · internal · runtime_token_invalid · approval_not_pending · result_already_taken · declaration_invalid · request_invalid · cursor_invalid · rate_limited · offer_refused:<issuer code> (ZADQ-289) · kyc_current · kyc_required · entry_fee_due · reverification_required · invalid_state · sandbox_hint_not_available · invalid_sandbox_hint · issuer_unavailable (ZADQ-316) · kyc_grade_below_bundle (ZADQ-321) · person_invalid · profile_invalid · profile_incomplete · kind_locked · terms_changed · business_use_required · reauth_required (ZADQ-307) · account_blocked (ZADQ-311) · custody_version_conflict · last_wrap · passkey_not_on_account (ZADQ-293) · wraps_required (ZADQ-293, v1.3.2) · origin_invalid · key_invalid · private_key_refused · origin_in_use · key_reused · evidence_required · obligations_not_published · obligations_changed (ZADQ-362, v1.3.13) · mintid_unavailable (503, ZADQ-407: MintID unreachable since the start-up and the ids not discovered yet; nothing recorded, retry later)
detailstringyes
custody_versioninteger (int64)no409 custody_version_conflict (§5.8, v1.3.2) — the stored version, to read and retry on.
fieldsobjectnoThe refused fields by path (400 person_invalid, profile_invalid).
missingarray of stringnoThe field paths a payment still needs (409 profile_incomplete).

Example

curl -sS "<base-url>/v1/verifier-keys" \
  --cookie "__Host-passkey_session=<api-key>"

GET /v1/holder/network

The network the browser holder talks to (and the browser path's capability read)

What the browser holder needs to reach the network on its own: the issuer's base URL (the six holder routes, CORS-enabled for the app's origin by the issuer), the chain id, the self-revocation relay and, when configured, a chain RPC for the holder's own read of a self-revocation (submitSelfRevocation's chain). The dashboard offers the browser path only when this answers 200 (zadq-public ZADQ-295's proposal 8); 501 not_available on a deployment without the network configured (fake mode). Public facts of the network, no account data. Cache-Control: private, max-age=300.

Authentication: passkeySession.

Responses

200 — The network.

Content type application/json.

Schema: HolderNetwork

PropertyTypeRequiredDescriptionValues
issuer_urlstringyes
chain_idstringyes
relay_urlstringyes
chain_rpc_urlstring, nullableno

default — A /v1 refusal — {"error", "detail"} (platform API v1 §5).

Content type application/json.

Schema: V1Error

PropertyTypeRequiredDescriptionValues
errorstringyessession_required · passkey_required · last_passkey · ceremony_invalid · attestation_invalid · assertion_invalid · email_operational_invalid · body_invalid · origin_refused · not_found · not_available · internal · runtime_token_invalid · approval_not_pending · result_already_taken · declaration_invalid · request_invalid · cursor_invalid · rate_limited · offer_refused:<issuer code> (ZADQ-289) · kyc_current · kyc_required · entry_fee_due · reverification_required · invalid_state · sandbox_hint_not_available · invalid_sandbox_hint · issuer_unavailable (ZADQ-316) · kyc_grade_below_bundle (ZADQ-321) · person_invalid · profile_invalid · profile_incomplete · kind_locked · terms_changed · business_use_required · reauth_required (ZADQ-307) · account_blocked (ZADQ-311) · custody_version_conflict · last_wrap · passkey_not_on_account (ZADQ-293) · wraps_required (ZADQ-293, v1.3.2) · origin_invalid · key_invalid · private_key_refused · origin_in_use · key_reused · evidence_required · obligations_not_published · obligations_changed (ZADQ-362, v1.3.13) · mintid_unavailable (503, ZADQ-407: MintID unreachable since the start-up and the ids not discovered yet; nothing recorded, retry later)
detailstringyes
custody_versioninteger (int64)no409 custody_version_conflict (§5.8, v1.3.2) — the stored version, to read and retry on.
fieldsobjectnoThe refused fields by path (400 person_invalid, profile_invalid).
missingarray of stringnoThe field paths a payment still needs (409 profile_incomplete).

Example

curl -sS "<base-url>/v1/holder/network" \
  --cookie "__Host-passkey_session=<api-key>"

GET /v1/verifiers

The account's verifier records, oldest first (platform API v1 §5.15)

The business as verifier of record under its own exact origin and request-signing key: each record with its current key, the keys it replaced, the evidence summary, the issuer's commitment handle and the admission request. ZadQ's own record — no proof, pseudonym, envelope or decision of the issuer, no private key.

Authentication: passkeySession.

Responses

200 — The records.

Content type application/json.

Schema: VerifierList

PropertyTypeRequiredDescriptionValues
verifiersarray of VerifierRecordyes

default — A /v1 refusal — {"error", "detail"} (platform API v1 §5).

Content type application/json.

Schema: V1Error

PropertyTypeRequiredDescriptionValues
errorstringyessession_required · passkey_required · last_passkey · ceremony_invalid · attestation_invalid · assertion_invalid · email_operational_invalid · body_invalid · origin_refused · not_found · not_available · internal · runtime_token_invalid · approval_not_pending · result_already_taken · declaration_invalid · request_invalid · cursor_invalid · rate_limited · offer_refused:<issuer code> (ZADQ-289) · kyc_current · kyc_required · entry_fee_due · reverification_required · invalid_state · sandbox_hint_not_available · invalid_sandbox_hint · issuer_unavailable (ZADQ-316) · kyc_grade_below_bundle (ZADQ-321) · person_invalid · profile_invalid · profile_incomplete · kind_locked · terms_changed · business_use_required · reauth_required (ZADQ-307) · account_blocked (ZADQ-311) · custody_version_conflict · last_wrap · passkey_not_on_account (ZADQ-293) · wraps_required (ZADQ-293, v1.3.2) · origin_invalid · key_invalid · private_key_refused · origin_in_use · key_reused · evidence_required · obligations_not_published · obligations_changed (ZADQ-362, v1.3.13) · mintid_unavailable (503, ZADQ-407: MintID unreachable since the start-up and the ids not discovered yet; nothing recorded, retry later)
detailstringyes
custody_versioninteger (int64)no409 custody_version_conflict (§5.8, v1.3.2) — the stored version, to read and retry on.
fieldsobjectnoThe refused fields by path (400 person_invalid, profile_invalid).
missingarray of stringnoThe field paths a payment still needs (409 profile_incomplete).

Example

curl -sS "<base-url>/v1/verifiers" \
  --cookie "__Host-passkey_session=<api-key>"

POST /v1/verifiers

Open a verifier record — the exact origin and the request-signing key as the kit generated them (§5.15)

201 the record, requested. origin is exactly https://<host>[:<port>]: a lowercase DNS host of at least two labels, no IP literal, an optional port other than 443, no path (not even /), query, fragment or user-info — not normalised (400 origin_invalid, the detail names the rule). request_signing_key is the public half: key_id 64 lowercase hex, algorithm ed25519 (32-byte public key) or ecdsa_p256 (the SEC1 point, 33 or 65 bytes), hex (400 key_invalid). ZadQ never receives the private key: a member named like one (private_key, secret, seed, d, …) or a key of the private form's length answers 400 private_key_refused before anything else is read, and nothing of the body is kept or logged. 409 origin_in_use when another live record holds the origin (its holder is never named); 409 account_blocked.

Authentication: passkeySession.

Request body

application/json — required

Schema: VerifierCreate

PropertyTypeRequiredDescriptionValues
originstringyesThe exact origin, https://<host>[:<port>], not normalised.
request_signing_keyVerifierKeyInputyes

Responses

201 — Created.

Content type application/json.

Schema: VerifierRecord

PropertyTypeRequiredDescriptionValues
idstringyes
originstringyes
stateVerifierStateyes
activebooleanyes
managedbooleanyes
evidence_formatstringyesThe evidence's format: bip-0005/1 (v1.3.22, ZADQ-431), the format a record without an upload expects too. A record that holds an upload made before v1.3.22 reads pending-MINT-599 until the business uploads the v1 document.
operator_accountstring, nullableyesThe bech32 account the bIP-0005 v1 evidence names — the account that signs the registration on the chain (v1.3.22, ZADQ-431); public. Null without a v1 upload.
request_signing_keyVerifierKeyyes
previous_keysarray of VerifierPreviousKeyyes
evidenceall of VerifierEvidenceSummaryyes
commitment_handlestring, nullableyesThe recorded commitment's commitment_hex (MINT-600; v1.3.24), null before one; kept after its reuse window ends.
commitmentVerifierRecordCommitmentyes
admissionall of VerifierAdmissionyes
created_atstring (date-time)yes
updated_atstring (date-time)yes
withdrawn_atstring (date-time), nullableyes
evidence_renewed_atstring (date-time), nullableyesv1.3.23 (ZADQ-436): when the current evidence document was uploaded as a renewal on the admitted record; null while it is the one the record was admitted with.
renewal_reminder_atstring (date-time), nullableyesv1.3.23: the revalidation's reminder date — the last renewal, or the admission's decision before one, plus the reminder (150 days by default; configuration). Null unless admitted.
renewal_due_atstring (date-time), nullableyesv1.3.23: the revalidation's due date — the same start plus the chain's revalidation window (180 days by default; configuration, never read from the chain). Null unless admitted.
renewal_duebooleanyesv1.3.23 — the due date is past and no renewal was uploaded since; false unless admitted.

default — A /v1 refusal — {"error", "detail"} (platform API v1 §5).

Content type application/json.

Schema: V1Error

PropertyTypeRequiredDescriptionValues
errorstringyessession_required · passkey_required · last_passkey · ceremony_invalid · attestation_invalid · assertion_invalid · email_operational_invalid · body_invalid · origin_refused · not_found · not_available · internal · runtime_token_invalid · approval_not_pending · result_already_taken · declaration_invalid · request_invalid · cursor_invalid · rate_limited · offer_refused:<issuer code> (ZADQ-289) · kyc_current · kyc_required · entry_fee_due · reverification_required · invalid_state · sandbox_hint_not_available · invalid_sandbox_hint · issuer_unavailable (ZADQ-316) · kyc_grade_below_bundle (ZADQ-321) · person_invalid · profile_invalid · profile_incomplete · kind_locked · terms_changed · business_use_required · reauth_required (ZADQ-307) · account_blocked (ZADQ-311) · custody_version_conflict · last_wrap · passkey_not_on_account (ZADQ-293) · wraps_required (ZADQ-293, v1.3.2) · origin_invalid · key_invalid · private_key_refused · origin_in_use · key_reused · evidence_required · obligations_not_published · obligations_changed (ZADQ-362, v1.3.13) · mintid_unavailable (503, ZADQ-407: MintID unreachable since the start-up and the ids not discovered yet; nothing recorded, retry later)
detailstringyes
custody_versioninteger (int64)no409 custody_version_conflict (§5.8, v1.3.2) — the stored version, to read and retry on.
fieldsobjectnoThe refused fields by path (400 person_invalid, profile_invalid).
missingarray of stringnoThe field paths a payment still needs (409 profile_incomplete).

Example

curl -sS -X POST "<base-url>/v1/verifiers" \
  --cookie "__Host-passkey_session=<api-key>" \
  -H "Content-Type: application/json" \
  -d @request-body.json

GET /v1/verifiers/{verifierId}

One verifier record (§5.15)

404 not_found for another account's record.

Authentication: passkeySession.

Parameters

NameInRequiredTypeDescription
verifierIdpathyesstringThe verifier record's id (vrf_…).

Responses

200 — The record.

Content type application/json.

Schema: VerifierRecord

PropertyTypeRequiredDescriptionValues
idstringyes
originstringyes
stateVerifierStateyes
activebooleanyes
managedbooleanyes
evidence_formatstringyesThe evidence's format: bip-0005/1 (v1.3.22, ZADQ-431), the format a record without an upload expects too. A record that holds an upload made before v1.3.22 reads pending-MINT-599 until the business uploads the v1 document.
operator_accountstring, nullableyesThe bech32 account the bIP-0005 v1 evidence names — the account that signs the registration on the chain (v1.3.22, ZADQ-431); public. Null without a v1 upload.
request_signing_keyVerifierKeyyes
previous_keysarray of VerifierPreviousKeyyes
evidenceall of VerifierEvidenceSummaryyes
commitment_handlestring, nullableyesThe recorded commitment's commitment_hex (MINT-600; v1.3.24), null before one; kept after its reuse window ends.
commitmentVerifierRecordCommitmentyes
admissionall of VerifierAdmissionyes
created_atstring (date-time)yes
updated_atstring (date-time)yes
withdrawn_atstring (date-time), nullableyes
evidence_renewed_atstring (date-time), nullableyesv1.3.23 (ZADQ-436): when the current evidence document was uploaded as a renewal on the admitted record; null while it is the one the record was admitted with.
renewal_reminder_atstring (date-time), nullableyesv1.3.23: the revalidation's reminder date — the last renewal, or the admission's decision before one, plus the reminder (150 days by default; configuration). Null unless admitted.
renewal_due_atstring (date-time), nullableyesv1.3.23: the revalidation's due date — the same start plus the chain's revalidation window (180 days by default; configuration, never read from the chain). Null unless admitted.
renewal_duebooleanyesv1.3.23 — the due date is past and no renewal was uploaded since; false unless admitted.

default — A /v1 refusal — {"error", "detail"} (platform API v1 §5).

Content type application/json.

Schema: V1Error

PropertyTypeRequiredDescriptionValues
errorstringyessession_required · passkey_required · last_passkey · ceremony_invalid · attestation_invalid · assertion_invalid · email_operational_invalid · body_invalid · origin_refused · not_found · not_available · internal · runtime_token_invalid · approval_not_pending · result_already_taken · declaration_invalid · request_invalid · cursor_invalid · rate_limited · offer_refused:<issuer code> (ZADQ-289) · kyc_current · kyc_required · entry_fee_due · reverification_required · invalid_state · sandbox_hint_not_available · invalid_sandbox_hint · issuer_unavailable (ZADQ-316) · kyc_grade_below_bundle (ZADQ-321) · person_invalid · profile_invalid · profile_incomplete · kind_locked · terms_changed · business_use_required · reauth_required (ZADQ-307) · account_blocked (ZADQ-311) · custody_version_conflict · last_wrap · passkey_not_on_account (ZADQ-293) · wraps_required (ZADQ-293, v1.3.2) · origin_invalid · key_invalid · private_key_refused · origin_in_use · key_reused · evidence_required · obligations_not_published · obligations_changed (ZADQ-362, v1.3.13) · mintid_unavailable (503, ZADQ-407: MintID unreachable since the start-up and the ids not discovered yet; nothing recorded, retry later)
detailstringyes
custody_versioninteger (int64)no409 custody_version_conflict (§5.8, v1.3.2) — the stored version, to read and retry on.
fieldsobjectnoThe refused fields by path (400 person_invalid, profile_invalid).
missingarray of stringnoThe field paths a payment still needs (409 profile_incomplete).

Example

curl -sS "<base-url>/v1/verifiers/<verifierId>" \
  --cookie "__Host-passkey_session=<api-key>"

GET /v1/verifiers/{verifierId}/evidence

The domain-control evidence file to publish at the origin, and its digest (§5.15; bIP-0005 v1)

The file as uploaded (content_base64), its digest (lowercase hex), the format and its digest rule, the operator account the document names, and where to publish it (publish_path, publish_url). format: bip-0005/1 (v1.3.22, ZADQ-431): the digest is SHA-256 over the RFC 8785 canonical form (digest_rule: sha256-rfc8785). A record that holds an upload made before v1.3.22 keeps it and reads format: pending-MINT-599 with digest_rule: sha256 (over the exact bytes) until the business uploads the v1 document. v1.3.23 (ZADQ-436): renewed_at and renewal_check when the file is a renewal on the admitted record (the console's served-file check of it), and history, the documents it replaced, the newest first. 404 not_found before the upload.

Authentication: passkeySession.

Parameters

NameInRequiredTypeDescription
verifierIdpathyesstringThe verifier record's id (vrf_…).

Responses

200 — The evidence.

Content type application/json.

Schema: VerifierEvidence

PropertyTypeRequiredDescriptionValues
formatstringyesbip-0005/1 (v1.3.22, ZADQ-431); pending-MINT-599 on a record that holds an upload made before v1.3.22.
digeststringyes
digest_rulestringyessha256-rfc8785 for bip-0005/1: SHA-256 over the RFC 8785 canonical form (equal to the SHA-256 of the served bytes when the served file is canonical). sha256 for pending-MINT-599: over the exact bytes."sha256", "sha256-rfc8785"
operator_accountstring, nullableyesThe bech32 account the v1 document names; null for pending-MINT-599.
size_bytesintegeryes
content_base64stringyes
publish_pathstringyes
publish_urlstringyes
uploaded_atstring (date-time)yes
renewed_atstring (date-time), nullableyesv1.3.23 (ZADQ-436) — set when this document came as a renewal on the admitted record.
renewal_checkall of VerifierRenewalCheckyesv1.3.23 — the console's served-file check of this renewed document; null before it, or without a renewal.
historyarray of VerifierEvidencePreviousyesv1.3.23 — the documents renewals replaced, the newest first; empty before a renewal.

default — A /v1 refusal — {"error", "detail"} (platform API v1 §5).

Content type application/json.

Schema: V1Error

PropertyTypeRequiredDescriptionValues
errorstringyessession_required · passkey_required · last_passkey · ceremony_invalid · attestation_invalid · assertion_invalid · email_operational_invalid · body_invalid · origin_refused · not_found · not_available · internal · runtime_token_invalid · approval_not_pending · result_already_taken · declaration_invalid · request_invalid · cursor_invalid · rate_limited · offer_refused:<issuer code> (ZADQ-289) · kyc_current · kyc_required · entry_fee_due · reverification_required · invalid_state · sandbox_hint_not_available · invalid_sandbox_hint · issuer_unavailable (ZADQ-316) · kyc_grade_below_bundle (ZADQ-321) · person_invalid · profile_invalid · profile_incomplete · kind_locked · terms_changed · business_use_required · reauth_required (ZADQ-307) · account_blocked (ZADQ-311) · custody_version_conflict · last_wrap · passkey_not_on_account (ZADQ-293) · wraps_required (ZADQ-293, v1.3.2) · origin_invalid · key_invalid · private_key_refused · origin_in_use · key_reused · evidence_required · obligations_not_published · obligations_changed (ZADQ-362, v1.3.13) · mintid_unavailable (503, ZADQ-407: MintID unreachable since the start-up and the ids not discovered yet; nothing recorded, retry later)
detailstringyes
custody_versioninteger (int64)no409 custody_version_conflict (§5.8, v1.3.2) — the stored version, to read and retry on.
fieldsobjectnoThe refused fields by path (400 person_invalid, profile_invalid).
missingarray of stringnoThe field paths a payment still needs (409 profile_incomplete).

Example

curl -sS "<base-url>/v1/verifiers/<verifierId>/evidence" \
  --cookie "__Host-passkey_session=<api-key>"

PUT /v1/verifiers/{verifierId}/evidence

Upload the bIP-0005 v1 evidence document the kit produced (§5.15)

Exactly the bytes the kit produced, standard base64, 1 byte to 16 KiB (400 body_invalid otherwise). The file is a bIP-0005 v1 document (v1.3.22, ZADQ-431): one JSON object with exactly the six members v (the integer 1), origin, verifier_id_hex ("derived" or 64 lowercase hex), request_key_pub_hex (64 lowercase hex), operator_account (bech32, prefix mintid, valid checksum) and issued_at_unix (a non-negative integer); a member missing, unknown, repeated or of the wrong type or shape answers 400 evidence_invalid, the detail naming the member (the pending-MINT-599 format is refused so). origin other than the record's origin, or request_key_pub_hex other than the public key of the record's active request-signing key, answers 409 evidence_mismatch, the detail naming the member. The digest is SHA-256 over the RFC 8785 canonical form; the bytes are kept as uploaded. The record moves to evidence_pending and keeps operator_account. Uploading again replaces the file and its digest (the same canonical document: 200, nothing changes) while no admission request is made.

Renewal (v1.3.23, ZADQ-436). On an admitted record the upload is a renewal: the chain revalidates the origin every 180 days with a fresh document, and a wrong digest is corrected the same way. The same checks apply (bIP-0005 v1 only; origin and active key). The record stays admitted, the admission request is untouched, the document it replaces goes to history, evidence_renewed_at is set and the revalidation clock restarts from it. A record that holds a pending-MINT-599 upload moves to bip-0005/1 (digest_rule: sha256-rfc8785) the same way. The same canonical document again: 200, nothing changes. While the request is submitted or filed (the console is deciding on that file), and on a refused or withdrawn record: 409 invalid_state.

Authentication: passkeySession.

Parameters

NameInRequiredTypeDescription
verifierIdpathyesstringThe verifier record's id (vrf_…).

Request body

application/json — required

Schema: VerifierEvidenceUpload

PropertyTypeRequiredDescriptionValues
content_base64stringyesThe exact bytes of the file the kit produced, standard base64; 1 byte to 16 KiB decoded.

Responses

200 — The evidence as recorded.

Content type application/json.

Schema: VerifierEvidence

PropertyTypeRequiredDescriptionValues
formatstringyesbip-0005/1 (v1.3.22, ZADQ-431); pending-MINT-599 on a record that holds an upload made before v1.3.22.
digeststringyes
digest_rulestringyessha256-rfc8785 for bip-0005/1: SHA-256 over the RFC 8785 canonical form (equal to the SHA-256 of the served bytes when the served file is canonical). sha256 for pending-MINT-599: over the exact bytes."sha256", "sha256-rfc8785"
operator_accountstring, nullableyesThe bech32 account the v1 document names; null for pending-MINT-599.
size_bytesintegeryes
content_base64stringyes
publish_pathstringyes
publish_urlstringyes
uploaded_atstring (date-time)yes
renewed_atstring (date-time), nullableyesv1.3.23 (ZADQ-436) — set when this document came as a renewal on the admitted record.
renewal_checkall of VerifierRenewalCheckyesv1.3.23 — the console's served-file check of this renewed document; null before it, or without a renewal.
historyarray of VerifierEvidencePreviousyesv1.3.23 — the documents renewals replaced, the newest first; empty before a renewal.

default — A /v1 refusal — {"error", "detail"} (platform API v1 §5).

Content type application/json.

Schema: V1Error

PropertyTypeRequiredDescriptionValues
errorstringyessession_required · passkey_required · last_passkey · ceremony_invalid · attestation_invalid · assertion_invalid · email_operational_invalid · body_invalid · origin_refused · not_found · not_available · internal · runtime_token_invalid · approval_not_pending · result_already_taken · declaration_invalid · request_invalid · cursor_invalid · rate_limited · offer_refused:<issuer code> (ZADQ-289) · kyc_current · kyc_required · entry_fee_due · reverification_required · invalid_state · sandbox_hint_not_available · invalid_sandbox_hint · issuer_unavailable (ZADQ-316) · kyc_grade_below_bundle (ZADQ-321) · person_invalid · profile_invalid · profile_incomplete · kind_locked · terms_changed · business_use_required · reauth_required (ZADQ-307) · account_blocked (ZADQ-311) · custody_version_conflict · last_wrap · passkey_not_on_account (ZADQ-293) · wraps_required (ZADQ-293, v1.3.2) · origin_invalid · key_invalid · private_key_refused · origin_in_use · key_reused · evidence_required · obligations_not_published · obligations_changed (ZADQ-362, v1.3.13) · mintid_unavailable (503, ZADQ-407: MintID unreachable since the start-up and the ids not discovered yet; nothing recorded, retry later)
detailstringyes
custody_versioninteger (int64)no409 custody_version_conflict (§5.8, v1.3.2) — the stored version, to read and retry on.
fieldsobjectnoThe refused fields by path (400 person_invalid, profile_invalid).
missingarray of stringnoThe field paths a payment still needs (409 profile_incomplete).

Example

curl -sS -X PUT "<base-url>/v1/verifiers/<verifierId>/evidence" \
  --cookie "__Host-passkey_session=<api-key>" \
  -H "Content-Type: application/json" \
  -d @request-body.json

GET /v1/verifiers/{verifierId}/commitment

The issuer's verifier identity commitment for the record's origin (§5.15; MINT-600, v1.3.24)

The issuer's verifier identity commitment (MINT-600) for the record's exact origin, from the responsible person's approved KYC session — one check serves the seller, agent-operator and verifier roles of the same business. available while the record holds a commitment whose reuse window is open, with its members and status_key_check; not_available on a deployment that does not ask an issuer; kyc_required while the person is not verified with the reuse window open; pending_issuer when the issuer did not answer the last request (nothing failed; ask again); refused with refusal_reason when the issuer refused the request or its answer failed ZadQ's check. When no commitment serves and no request for the person's current session was refused, the read asks the issuer first (as POST does); a refusal for that session is answered as recorded.

Authentication: passkeySession.

Parameters

NameInRequiredTypeDescription
verifierIdpathyesstringThe verifier record's id (vrf_…).

Responses

200 — The commitment's state.

Content type application/json.

Schema: VerifierCommitment

PropertyTypeRequiredDescriptionValues
statestringyes"not_available", "kyc_required", "pending_issuer", "refused", "available"
handlestring, nullableyesThe commitment's commitment_hex, 64 lowercase hex.
kyc_session_idstring, nullableyes
obtained_atstring (date-time), nullableyes
issuer_idstring, nullableyes
assurance_gradeinteger, nullableyes
approved_atstring (date-time), nullableyes
reusable_untilstring (date-time), nullableyes
signaturestring, nullableyes
status_key_checkall of VerifierStatusKeyCheckyes
refusal_reasonall of VerifierCommitmentRefusalReasonyes
checked_atstring (date-time), nullableyesWhen the last request was made.

default — A /v1 refusal — {"error", "detail"} (platform API v1 §5).

Content type application/json.

Schema: V1Error

PropertyTypeRequiredDescriptionValues
errorstringyessession_required · passkey_required · last_passkey · ceremony_invalid · attestation_invalid · assertion_invalid · email_operational_invalid · body_invalid · origin_refused · not_found · not_available · internal · runtime_token_invalid · approval_not_pending · result_already_taken · declaration_invalid · request_invalid · cursor_invalid · rate_limited · offer_refused:<issuer code> (ZADQ-289) · kyc_current · kyc_required · entry_fee_due · reverification_required · invalid_state · sandbox_hint_not_available · invalid_sandbox_hint · issuer_unavailable (ZADQ-316) · kyc_grade_below_bundle (ZADQ-321) · person_invalid · profile_invalid · profile_incomplete · kind_locked · terms_changed · business_use_required · reauth_required (ZADQ-307) · account_blocked (ZADQ-311) · custody_version_conflict · last_wrap · passkey_not_on_account (ZADQ-293) · wraps_required (ZADQ-293, v1.3.2) · origin_invalid · key_invalid · private_key_refused · origin_in_use · key_reused · evidence_required · obligations_not_published · obligations_changed (ZADQ-362, v1.3.13) · mintid_unavailable (503, ZADQ-407: MintID unreachable since the start-up and the ids not discovered yet; nothing recorded, retry later)
detailstringyes
custody_versioninteger (int64)no409 custody_version_conflict (§5.8, v1.3.2) — the stored version, to read and retry on.
fieldsobjectnoThe refused fields by path (400 person_invalid, profile_invalid).
missingarray of stringnoThe field paths a payment still needs (409 profile_incomplete).

Example

curl -sS "<base-url>/v1/verifiers/<verifierId>/commitment" \
  --cookie "__Host-passkey_session=<api-key>"

POST /v1/verifiers/{verifierId}/commitment

Ask the issuer for the record's commitment now (§5.15; v1.3.24, ZADQ-433)

Asks the issuer (POST <issuer>/v0/verifier-identity-commitments with the account's approved session and the record's exact origin) unless a commitment whose reuse window is open is recorded, checks the answer — the issuer is the deployment's, the signature verifies under the issuer's status key when the deployment holds it (else status_key_check: unverified), the origin is the record's, the grade is A2 or above, the reuse window is open — and records it. 200 with the state after the request, the same shape as GET: an issuer that does not answer reads pending_issuer and nothing fails. 409 invalid_state on a refused or withdrawn record.

Authentication: passkeySession.

Parameters

NameInRequiredTypeDescription
verifierIdpathyesstringThe verifier record's id (vrf_…).

Responses

200 — The commitment's state after the request.

Content type application/json.

Schema: VerifierCommitment

PropertyTypeRequiredDescriptionValues
statestringyes"not_available", "kyc_required", "pending_issuer", "refused", "available"
handlestring, nullableyesThe commitment's commitment_hex, 64 lowercase hex.
kyc_session_idstring, nullableyes
obtained_atstring (date-time), nullableyes
issuer_idstring, nullableyes
assurance_gradeinteger, nullableyes
approved_atstring (date-time), nullableyes
reusable_untilstring (date-time), nullableyes
signaturestring, nullableyes
status_key_checkall of VerifierStatusKeyCheckyes
refusal_reasonall of VerifierCommitmentRefusalReasonyes
checked_atstring (date-time), nullableyesWhen the last request was made.

default — A /v1 refusal — {"error", "detail"} (platform API v1 §5).

Content type application/json.

Schema: V1Error

PropertyTypeRequiredDescriptionValues
errorstringyessession_required · passkey_required · last_passkey · ceremony_invalid · attestation_invalid · assertion_invalid · email_operational_invalid · body_invalid · origin_refused · not_found · not_available · internal · runtime_token_invalid · approval_not_pending · result_already_taken · declaration_invalid · request_invalid · cursor_invalid · rate_limited · offer_refused:<issuer code> (ZADQ-289) · kyc_current · kyc_required · entry_fee_due · reverification_required · invalid_state · sandbox_hint_not_available · invalid_sandbox_hint · issuer_unavailable (ZADQ-316) · kyc_grade_below_bundle (ZADQ-321) · person_invalid · profile_invalid · profile_incomplete · kind_locked · terms_changed · business_use_required · reauth_required (ZADQ-307) · account_blocked (ZADQ-311) · custody_version_conflict · last_wrap · passkey_not_on_account (ZADQ-293) · wraps_required (ZADQ-293, v1.3.2) · origin_invalid · key_invalid · private_key_refused · origin_in_use · key_reused · evidence_required · obligations_not_published · obligations_changed (ZADQ-362, v1.3.13) · mintid_unavailable (503, ZADQ-407: MintID unreachable since the start-up and the ids not discovered yet; nothing recorded, retry later)
detailstringyes
custody_versioninteger (int64)no409 custody_version_conflict (§5.8, v1.3.2) — the stored version, to read and retry on.
fieldsobjectnoThe refused fields by path (400 person_invalid, profile_invalid).
missingarray of stringnoThe field paths a payment still needs (409 profile_incomplete).

Example

curl -sS -X POST "<base-url>/v1/verifiers/<verifierId>/commitment" \
  --cookie "__Host-passkey_session=<api-key>"

GET /v1/verifiers/{verifierId}/admission

The admission request and what became of it (§5.15; MINT-601)

404 not_found before the request.

Authentication: passkeySession.

Parameters

NameInRequiredTypeDescription
verifierIdpathyesstringThe verifier record's id (vrf_…).

Responses

200 — The request.

Content type application/json.

Schema: VerifierAdmission

PropertyTypeRequiredDescriptionValues
statestringyes"submitted", "filed", "admitted", "refused", "withdrawn"
originstringyes
evidence_digeststringyes
commitmentVerifierAdmissionCommitmentyes
obligationsVerifierObligationsAcceptedyes
submitted_atstring (date-time)yes
evidence_checked_atstring (date-time), nullableyes
filed_atstring (date-time), nullableyes
decided_atstring (date-time), nullableyes
refused_reasonall of VerifierRefusedReasonyes
turnaroundVerifierTurnaroundyes
admissions_log_refstring, nullableyesThe public admissions log entry's reference, once recorded.

default — A /v1 refusal — {"error", "detail"} (platform API v1 §5).

Content type application/json.

Schema: V1Error

PropertyTypeRequiredDescriptionValues
errorstringyessession_required · passkey_required · last_passkey · ceremony_invalid · attestation_invalid · assertion_invalid · email_operational_invalid · body_invalid · origin_refused · not_found · not_available · internal · runtime_token_invalid · approval_not_pending · result_already_taken · declaration_invalid · request_invalid · cursor_invalid · rate_limited · offer_refused:<issuer code> (ZADQ-289) · kyc_current · kyc_required · entry_fee_due · reverification_required · invalid_state · sandbox_hint_not_available · invalid_sandbox_hint · issuer_unavailable (ZADQ-316) · kyc_grade_below_bundle (ZADQ-321) · person_invalid · profile_invalid · profile_incomplete · kind_locked · terms_changed · business_use_required · reauth_required (ZADQ-307) · account_blocked (ZADQ-311) · custody_version_conflict · last_wrap · passkey_not_on_account (ZADQ-293) · wraps_required (ZADQ-293, v1.3.2) · origin_invalid · key_invalid · private_key_refused · origin_in_use · key_reused · evidence_required · obligations_not_published · obligations_changed (ZADQ-362, v1.3.13) · mintid_unavailable (503, ZADQ-407: MintID unreachable since the start-up and the ids not discovered yet; nothing recorded, retry later)
detailstringyes
custody_versioninteger (int64)no409 custody_version_conflict (§5.8, v1.3.2) — the stored version, to read and retry on.
fieldsobjectnoThe refused fields by path (400 person_invalid, profile_invalid).
missingarray of stringnoThe field paths a payment still needs (409 profile_incomplete).

Example

curl -sS "<base-url>/v1/verifiers/<verifierId>/admission" \
  --cookie "__Host-passkey_session=<api-key>"

POST /v1/verifiers/{verifierId}/admission

Ask ZadQ to file the admission request with the chain's operator, accepting the verifier obligations (§5.15)

Checked in this order: the record is live (409 invalid_state after a refusal or a withdrawal); a request already made answers 200 as it is; the evidence is uploaded (409 evidence_required); the body (400 body_invalid); the account is not blocked (409 account_blocked); the responsible person is verified with the window open (409 kyc_required); verifier obligations are published (409 obligations_not_published) and the {version, sha256} sent are the ones in force (409 obligations_changed). 201 the request, submitted: the record stays evidence_pending while ZadQ checks the file at the origin, then the console files it. The request asks the issuer for the commitment first (v1.3.24, as POST …/commitment) and carries it when one serves; an issuer that does not answer or refuses never fails the request (commitment.state pending_issuer or refused), and a commitment recorded before the filing joins the request. The acceptance is appended to the consents log. No price line: verification is free, and the chain's fee is the chain's.

Authentication: passkeySession.

Parameters

NameInRequiredTypeDescription
verifierIdpathyesstringThe verifier record's id (vrf_…).

Request body

application/json — required

Schema: VerifierAdmissionRequest

PropertyTypeRequiredDescriptionValues
obligationsVerifierObligationsAcceptanceyes

Responses

200 — The request already made, as it is.

Content type application/json.

Schema: VerifierAdmission

PropertyTypeRequiredDescriptionValues
statestringyes"submitted", "filed", "admitted", "refused", "withdrawn"
originstringyes
evidence_digeststringyes
commitmentVerifierAdmissionCommitmentyes
obligationsVerifierObligationsAcceptedyes
submitted_atstring (date-time)yes
evidence_checked_atstring (date-time), nullableyes
filed_atstring (date-time), nullableyes
decided_atstring (date-time), nullableyes
refused_reasonall of VerifierRefusedReasonyes
turnaroundVerifierTurnaroundyes
admissions_log_refstring, nullableyesThe public admissions log entry's reference, once recorded.

201 — Requested.

Content type application/json.

Schema: VerifierAdmission

PropertyTypeRequiredDescriptionValues
statestringyes"submitted", "filed", "admitted", "refused", "withdrawn"
originstringyes
evidence_digeststringyes
commitmentVerifierAdmissionCommitmentyes
obligationsVerifierObligationsAcceptedyes
submitted_atstring (date-time)yes
evidence_checked_atstring (date-time), nullableyes
filed_atstring (date-time), nullableyes
decided_atstring (date-time), nullableyes
refused_reasonall of VerifierRefusedReasonyes
turnaroundVerifierTurnaroundyes
admissions_log_refstring, nullableyesThe public admissions log entry's reference, once recorded.

default — A /v1 refusal — {"error", "detail"} (platform API v1 §5).

Content type application/json.

Schema: V1Error

PropertyTypeRequiredDescriptionValues
errorstringyessession_required · passkey_required · last_passkey · ceremony_invalid · attestation_invalid · assertion_invalid · email_operational_invalid · body_invalid · origin_refused · not_found · not_available · internal · runtime_token_invalid · approval_not_pending · result_already_taken · declaration_invalid · request_invalid · cursor_invalid · rate_limited · offer_refused:<issuer code> (ZADQ-289) · kyc_current · kyc_required · entry_fee_due · reverification_required · invalid_state · sandbox_hint_not_available · invalid_sandbox_hint · issuer_unavailable (ZADQ-316) · kyc_grade_below_bundle (ZADQ-321) · person_invalid · profile_invalid · profile_incomplete · kind_locked · terms_changed · business_use_required · reauth_required (ZADQ-307) · account_blocked (ZADQ-311) · custody_version_conflict · last_wrap · passkey_not_on_account (ZADQ-293) · wraps_required (ZADQ-293, v1.3.2) · origin_invalid · key_invalid · private_key_refused · origin_in_use · key_reused · evidence_required · obligations_not_published · obligations_changed (ZADQ-362, v1.3.13) · mintid_unavailable (503, ZADQ-407: MintID unreachable since the start-up and the ids not discovered yet; nothing recorded, retry later)
detailstringyes
custody_versioninteger (int64)no409 custody_version_conflict (§5.8, v1.3.2) — the stored version, to read and retry on.
fieldsobjectnoThe refused fields by path (400 person_invalid, profile_invalid).
missingarray of stringnoThe field paths a payment still needs (409 profile_incomplete).

Example

curl -sS -X POST "<base-url>/v1/verifiers/<verifierId>/admission" \
  --cookie "__Host-passkey_session=<api-key>" \
  -H "Content-Type: application/json" \
  -d @request-body.json

POST /v1/verifiers/{verifierId}/key-rotation

Declare a new request-signing key (§5.15; MINT-604's managed line needs it)

The body is the key's own shape, checked as on create (400 key_invalid, private_key_refused). The current key is replaced and listed in previous_keys; the same key id again: 200 unchanged; a key id the record held before: 409 key_reused; while the admission request is filed, or on a refused or withdrawn record: 409 invalid_state. The rotation on the chain is the business's own transaction; ZadQ records the declaration.

Authentication: passkeySession.

Parameters

NameInRequiredTypeDescription
verifierIdpathyesstringThe verifier record's id (vrf_…).

Request body

application/json — required

Schema: VerifierKeyInput

PropertyTypeRequiredDescriptionValues
key_idstringyes64 lowercase hex, as the kit wrote it.
algorithmVerifierAlgorithmyes
public_keystringyesLowercase hex — 32 bytes (ed25519) or the SEC1 point, 33 or 65 bytes (ecdsa_p256).

Responses

200 — The record with its new key.

Content type application/json.

Schema: VerifierRecord

PropertyTypeRequiredDescriptionValues
idstringyes
originstringyes
stateVerifierStateyes
activebooleanyes
managedbooleanyes
evidence_formatstringyesThe evidence's format: bip-0005/1 (v1.3.22, ZADQ-431), the format a record without an upload expects too. A record that holds an upload made before v1.3.22 reads pending-MINT-599 until the business uploads the v1 document.
operator_accountstring, nullableyesThe bech32 account the bIP-0005 v1 evidence names — the account that signs the registration on the chain (v1.3.22, ZADQ-431); public. Null without a v1 upload.
request_signing_keyVerifierKeyyes
previous_keysarray of VerifierPreviousKeyyes
evidenceall of VerifierEvidenceSummaryyes
commitment_handlestring, nullableyesThe recorded commitment's commitment_hex (MINT-600; v1.3.24), null before one; kept after its reuse window ends.
commitmentVerifierRecordCommitmentyes
admissionall of VerifierAdmissionyes
created_atstring (date-time)yes
updated_atstring (date-time)yes
withdrawn_atstring (date-time), nullableyes
evidence_renewed_atstring (date-time), nullableyesv1.3.23 (ZADQ-436): when the current evidence document was uploaded as a renewal on the admitted record; null while it is the one the record was admitted with.
renewal_reminder_atstring (date-time), nullableyesv1.3.23: the revalidation's reminder date — the last renewal, or the admission's decision before one, plus the reminder (150 days by default; configuration). Null unless admitted.
renewal_due_atstring (date-time), nullableyesv1.3.23: the revalidation's due date — the same start plus the chain's revalidation window (180 days by default; configuration, never read from the chain). Null unless admitted.
renewal_duebooleanyesv1.3.23 — the due date is past and no renewal was uploaded since; false unless admitted.

default — A /v1 refusal — {"error", "detail"} (platform API v1 §5).

Content type application/json.

Schema: V1Error

PropertyTypeRequiredDescriptionValues
errorstringyessession_required · passkey_required · last_passkey · ceremony_invalid · attestation_invalid · assertion_invalid · email_operational_invalid · body_invalid · origin_refused · not_found · not_available · internal · runtime_token_invalid · approval_not_pending · result_already_taken · declaration_invalid · request_invalid · cursor_invalid · rate_limited · offer_refused:<issuer code> (ZADQ-289) · kyc_current · kyc_required · entry_fee_due · reverification_required · invalid_state · sandbox_hint_not_available · invalid_sandbox_hint · issuer_unavailable (ZADQ-316) · kyc_grade_below_bundle (ZADQ-321) · person_invalid · profile_invalid · profile_incomplete · kind_locked · terms_changed · business_use_required · reauth_required (ZADQ-307) · account_blocked (ZADQ-311) · custody_version_conflict · last_wrap · passkey_not_on_account (ZADQ-293) · wraps_required (ZADQ-293, v1.3.2) · origin_invalid · key_invalid · private_key_refused · origin_in_use · key_reused · evidence_required · obligations_not_published · obligations_changed (ZADQ-362, v1.3.13) · mintid_unavailable (503, ZADQ-407: MintID unreachable since the start-up and the ids not discovered yet; nothing recorded, retry later)
detailstringyes
custody_versioninteger (int64)no409 custody_version_conflict (§5.8, v1.3.2) — the stored version, to read and retry on.
fieldsobjectnoThe refused fields by path (400 person_invalid, profile_invalid).
missingarray of stringnoThe field paths a payment still needs (409 profile_incomplete).

Example

curl -sS -X POST "<base-url>/v1/verifiers/<verifierId>/key-rotation" \
  --cookie "__Host-passkey_session=<api-key>" \
  -H "Content-Type: application/json" \
  -d @request-body.json

POST /v1/verifiers/{verifierId}/withdraw

Withdraw the verifier record and its open admission request (§5.15)

Terminal; frees the origin. Again: 200 as it is. 409 invalid_state after a refusal.

Authentication: passkeySession.

Parameters

NameInRequiredTypeDescription
verifierIdpathyesstringThe verifier record's id (vrf_…).

Responses

200 — Withdrawn.

Content type application/json.

Schema: VerifierRecord

PropertyTypeRequiredDescriptionValues
idstringyes
originstringyes
stateVerifierStateyes
activebooleanyes
managedbooleanyes
evidence_formatstringyesThe evidence's format: bip-0005/1 (v1.3.22, ZADQ-431), the format a record without an upload expects too. A record that holds an upload made before v1.3.22 reads pending-MINT-599 until the business uploads the v1 document.
operator_accountstring, nullableyesThe bech32 account the bIP-0005 v1 evidence names — the account that signs the registration on the chain (v1.3.22, ZADQ-431); public. Null without a v1 upload.
request_signing_keyVerifierKeyyes
previous_keysarray of VerifierPreviousKeyyes
evidenceall of VerifierEvidenceSummaryyes
commitment_handlestring, nullableyesThe recorded commitment's commitment_hex (MINT-600; v1.3.24), null before one; kept after its reuse window ends.
commitmentVerifierRecordCommitmentyes
admissionall of VerifierAdmissionyes
created_atstring (date-time)yes
updated_atstring (date-time)yes
withdrawn_atstring (date-time), nullableyes
evidence_renewed_atstring (date-time), nullableyesv1.3.23 (ZADQ-436): when the current evidence document was uploaded as a renewal on the admitted record; null while it is the one the record was admitted with.
renewal_reminder_atstring (date-time), nullableyesv1.3.23: the revalidation's reminder date — the last renewal, or the admission's decision before one, plus the reminder (150 days by default; configuration). Null unless admitted.
renewal_due_atstring (date-time), nullableyesv1.3.23: the revalidation's due date — the same start plus the chain's revalidation window (180 days by default; configuration, never read from the chain). Null unless admitted.
renewal_duebooleanyesv1.3.23 — the due date is past and no renewal was uploaded since; false unless admitted.

default — A /v1 refusal — {"error", "detail"} (platform API v1 §5).

Content type application/json.

Schema: V1Error

PropertyTypeRequiredDescriptionValues
errorstringyessession_required · passkey_required · last_passkey · ceremony_invalid · attestation_invalid · assertion_invalid · email_operational_invalid · body_invalid · origin_refused · not_found · not_available · internal · runtime_token_invalid · approval_not_pending · result_already_taken · declaration_invalid · request_invalid · cursor_invalid · rate_limited · offer_refused:<issuer code> (ZADQ-289) · kyc_current · kyc_required · entry_fee_due · reverification_required · invalid_state · sandbox_hint_not_available · invalid_sandbox_hint · issuer_unavailable (ZADQ-316) · kyc_grade_below_bundle (ZADQ-321) · person_invalid · profile_invalid · profile_incomplete · kind_locked · terms_changed · business_use_required · reauth_required (ZADQ-307) · account_blocked (ZADQ-311) · custody_version_conflict · last_wrap · passkey_not_on_account (ZADQ-293) · wraps_required (ZADQ-293, v1.3.2) · origin_invalid · key_invalid · private_key_refused · origin_in_use · key_reused · evidence_required · obligations_not_published · obligations_changed (ZADQ-362, v1.3.13) · mintid_unavailable (503, ZADQ-407: MintID unreachable since the start-up and the ids not discovered yet; nothing recorded, retry later)
detailstringyes
custody_versioninteger (int64)no409 custody_version_conflict (§5.8, v1.3.2) — the stored version, to read and retry on.
fieldsobjectnoThe refused fields by path (400 person_invalid, profile_invalid).
missingarray of stringnoThe field paths a payment still needs (409 profile_incomplete).

Example

curl -sS -X POST "<base-url>/v1/verifiers/<verifierId>/withdraw" \
  --cookie "__Host-passkey_session=<api-key>"

GET /v1/verifiers/{verifierId}/door

The record's door — the market and the bundles its refusal sends principals to ZadQ for (§5.16)

The business's declaration on its verifier record (ZADQ-365): the market its refusal sentence is chosen by (1, 2, 3 or null) and the bundles of the served catalogue it accepts, with the landing URL to configure in the refusal for each bundle. 404 not_found before a declaration and for another account's record. The business never reads who arrived through its door.

Authentication: passkeySession.

Parameters

NameInRequiredTypeDescription
verifierIdpathyesstringThe verifier record's id (vrf_…).

Responses

200 — The door.

Content type application/json.

Schema: VerifierDoor

PropertyTypeRequiredDescriptionValues
verifier_idstringyes
marketinteger, nullableyes
bundlesarray of stringyes
declared_atstring (date-time)yes
urlsarray of VerifierDoorUrlyesThe landing URL to configure in the refusal, one per bundle.

default — A /v1 refusal — {"error", "detail"} (platform API v1 §5).

Content type application/json.

Schema: V1Error

PropertyTypeRequiredDescriptionValues
errorstringyessession_required · passkey_required · last_passkey · ceremony_invalid · attestation_invalid · assertion_invalid · email_operational_invalid · body_invalid · origin_refused · not_found · not_available · internal · runtime_token_invalid · approval_not_pending · result_already_taken · declaration_invalid · request_invalid · cursor_invalid · rate_limited · offer_refused:<issuer code> (ZADQ-289) · kyc_current · kyc_required · entry_fee_due · reverification_required · invalid_state · sandbox_hint_not_available · invalid_sandbox_hint · issuer_unavailable (ZADQ-316) · kyc_grade_below_bundle (ZADQ-321) · person_invalid · profile_invalid · profile_incomplete · kind_locked · terms_changed · business_use_required · reauth_required (ZADQ-307) · account_blocked (ZADQ-311) · custody_version_conflict · last_wrap · passkey_not_on_account (ZADQ-293) · wraps_required (ZADQ-293, v1.3.2) · origin_invalid · key_invalid · private_key_refused · origin_in_use · key_reused · evidence_required · obligations_not_published · obligations_changed (ZADQ-362, v1.3.13) · mintid_unavailable (503, ZADQ-407: MintID unreachable since the start-up and the ids not discovered yet; nothing recorded, retry later)
detailstringyes
custody_versioninteger (int64)no409 custody_version_conflict (§5.8, v1.3.2) — the stored version, to read and retry on.
fieldsobjectnoThe refused fields by path (400 person_invalid, profile_invalid).
missingarray of stringnoThe field paths a payment still needs (409 profile_incomplete).

Example

curl -sS "<base-url>/v1/verifiers/<verifierId>/door" \
  --cookie "__Host-passkey_session=<api-key>"

PUT /v1/verifiers/{verifierId}/door

Declare (or replace) the record's door (§5.16)

market 1, 2, 3 or null; bundles 1 to 8 distinct bundle ids of the issuer's served catalogue (400 bundle_unknown; 400 body_invalid otherwise). 409 invalid_state once the record is refused or withdrawn; 503 catalogue_unavailable. A referral reads valid only while the record is admitted and its door names the bundle.

Authentication: passkeySession.

Parameters

NameInRequiredTypeDescription
verifierIdpathyesstringThe verifier record's id (vrf_…).

Request body

application/json — required

Schema: VerifierDoorDeclare

PropertyTypeRequiredDescriptionValues
marketinteger, nullableyesThe market the refusal sentence is chosen by (1 paid APIs and metered data, 2 reference and community content, 3 developer and orchestration platforms); null for the generic sentence.
bundlesarray of stringyes

Responses

200 — The door as recorded.

Content type application/json.

Schema: VerifierDoor

PropertyTypeRequiredDescriptionValues
verifier_idstringyes
marketinteger, nullableyes
bundlesarray of stringyes
declared_atstring (date-time)yes
urlsarray of VerifierDoorUrlyesThe landing URL to configure in the refusal, one per bundle.

default — A /v1 refusal — {"error", "detail"} (platform API v1 §5).

Content type application/json.

Schema: V1Error

PropertyTypeRequiredDescriptionValues
errorstringyessession_required · passkey_required · last_passkey · ceremony_invalid · attestation_invalid · assertion_invalid · email_operational_invalid · body_invalid · origin_refused · not_found · not_available · internal · runtime_token_invalid · approval_not_pending · result_already_taken · declaration_invalid · request_invalid · cursor_invalid · rate_limited · offer_refused:<issuer code> (ZADQ-289) · kyc_current · kyc_required · entry_fee_due · reverification_required · invalid_state · sandbox_hint_not_available · invalid_sandbox_hint · issuer_unavailable (ZADQ-316) · kyc_grade_below_bundle (ZADQ-321) · person_invalid · profile_invalid · profile_incomplete · kind_locked · terms_changed · business_use_required · reauth_required (ZADQ-307) · account_blocked (ZADQ-311) · custody_version_conflict · last_wrap · passkey_not_on_account (ZADQ-293) · wraps_required (ZADQ-293, v1.3.2) · origin_invalid · key_invalid · private_key_refused · origin_in_use · key_reused · evidence_required · obligations_not_published · obligations_changed (ZADQ-362, v1.3.13) · mintid_unavailable (503, ZADQ-407: MintID unreachable since the start-up and the ids not discovered yet; nothing recorded, retry later)
detailstringyes
custody_versioninteger (int64)no409 custody_version_conflict (§5.8, v1.3.2) — the stored version, to read and retry on.
fieldsobjectnoThe refused fields by path (400 person_invalid, profile_invalid).
missingarray of stringnoThe field paths a payment still needs (409 profile_incomplete).

Example

curl -sS -X PUT "<base-url>/v1/verifiers/<verifierId>/door" \
  --cookie "__Host-passkey_session=<api-key>" \
  -H "Content-Type: application/json" \
  -d @request-body.json

GET /v1/products/verifier/prices

The verifier product's business lines and their prices on this deployment (§5.17)

ZadQ's own price table of the business-side lines of the verifier product (ZADQ-373; VERIFIER_PRODUCT_PRICES): the verifier kit set-up (once per business, opened with the first verifier record), the onboarding of the responsible person at cost (opened with it only when the account has paid no entry of any product), the managed deployment's set-up and each managed environment and period (billed in advance; opened only for a managed record). A line the table does not price reads on_sale: false with the amount null. managed_kit_setup: withdrawn since v1.3.16 (ZADQ-382, P-13: the kit set-up line is no longer opened, for a managed business or any other). Never a verification line: the protocol charges nothing to verify; operators price their own services. Under the passkey session: the figures stay in the operator agreement, not on a public page.

Authentication: passkeySession.

Responses

200 — The business lines and their prices.

Content type application/json.

Schema: BusinessLinePriceTable

PropertyTypeRequiredDescriptionValues
linesarray of BusinessLinePriceyes
managed_kit_setupstringyesv1.3.15 — whether a managed business pays the kit set-up too; v1.3.16 (ZADQ-382, P-13) — always withdrawn, the kit set-up line is no longer opened."charged", "waived", "withdrawn"
relying_partyRelyingPartyPricesno
onboarding_rulestringyesThe onboarding at cost opens only where no entry of a product is paid; the re-check at the grade's renewal opens no line."at_cost_unless_entry_paid"

default — A /v1 refusal — {"error", "detail"} (platform API v1 §5).

Content type application/json.

Schema: V1Error

PropertyTypeRequiredDescriptionValues
errorstringyessession_required · passkey_required · last_passkey · ceremony_invalid · attestation_invalid · assertion_invalid · email_operational_invalid · body_invalid · origin_refused · not_found · not_available · internal · runtime_token_invalid · approval_not_pending · result_already_taken · declaration_invalid · request_invalid · cursor_invalid · rate_limited · offer_refused:<issuer code> (ZADQ-289) · kyc_current · kyc_required · entry_fee_due · reverification_required · invalid_state · sandbox_hint_not_available · invalid_sandbox_hint · issuer_unavailable (ZADQ-316) · kyc_grade_below_bundle (ZADQ-321) · person_invalid · profile_invalid · profile_incomplete · kind_locked · terms_changed · business_use_required · reauth_required (ZADQ-307) · account_blocked (ZADQ-311) · custody_version_conflict · last_wrap · passkey_not_on_account (ZADQ-293) · wraps_required (ZADQ-293, v1.3.2) · origin_invalid · key_invalid · private_key_refused · origin_in_use · key_reused · evidence_required · obligations_not_published · obligations_changed (ZADQ-362, v1.3.13) · mintid_unavailable (503, ZADQ-407: MintID unreachable since the start-up and the ids not discovered yet; nothing recorded, retry later)
detailstringyes
custody_versioninteger (int64)no409 custody_version_conflict (§5.8, v1.3.2) — the stored version, to read and retry on.
fieldsobjectnoThe refused fields by path (400 person_invalid, profile_invalid).
missingarray of stringnoThe field paths a payment still needs (409 profile_incomplete).

Example

curl -sS "<base-url>/v1/products/verifier/prices" \
  --cookie "__Host-passkey_session=<api-key>"

GET /v1/products/verifier/relying-party

The relying-party rebate on the business's account — the discovery fee ZadQ pays per principal its door sends (§5.18, v1.3.18)

ZADQ-389 (Platform Decision 24). R1 changed sign: ZadQ pays the business a one-off rebate per principal who arrives through its door (the principal's first referral from one of its verifier records) and keeps a paid plan — once per person, the amount of the plan held when it is earned (GET /v1/products/verifier/prices). A rebate is pending from the plan's payment and earned once the holding days are past, the identity check approved and nothing refunded; each month is closed after it ends: up to the cap (the rest held for review), set off against the business's invoice of the month (a principal_enrolled line with a negative amount) or paid out once the balance reaches the threshold; a refund or a chargeback reverses it, deducted from the next statement once settled. Counts and amounts only, never who; never keyed to a presentation or a verification decision. Reading this route moves the business's rebates and closes the months due. v1.3.16's R1 charge and R2 are withdrawn (the meter route is removed).

Authentication: passkeySession.

Responses

200 — The business's rebates.

Content type application/json.

Schema: RelyingPartyStatus

PropertyTypeRequiredDescriptionValues
monthstring (date)yesThe current month (its first day, UTC).
offeredbooleanyesWhether the deployment offers the rebate.
unitstring, nullableyes
pendingintegeryesRebates whose guards are not all met yet (the holding days, the identity check).
earnedintegeryesRebates earned and not settled yet (settled at their month's close).
earned_minorinteger (int64)yes
heldintegeryesRebates held beyond the cap of their month, for the operator's review.
held_minorinteger (int64)yes
balance_minorinteger (int64)yesThe balance carried out of the last statement (below the payout threshold, or negative after reversals).
statementsarray of RebateStatementyesThe closed months, newest first.

default — A /v1 refusal — {"error", "detail"} (platform API v1 §5).

Content type application/json.

Schema: V1Error

PropertyTypeRequiredDescriptionValues
errorstringyessession_required · passkey_required · last_passkey · ceremony_invalid · attestation_invalid · assertion_invalid · email_operational_invalid · body_invalid · origin_refused · not_found · not_available · internal · runtime_token_invalid · approval_not_pending · result_already_taken · declaration_invalid · request_invalid · cursor_invalid · rate_limited · offer_refused:<issuer code> (ZADQ-289) · kyc_current · kyc_required · entry_fee_due · reverification_required · invalid_state · sandbox_hint_not_available · invalid_sandbox_hint · issuer_unavailable (ZADQ-316) · kyc_grade_below_bundle (ZADQ-321) · person_invalid · profile_invalid · profile_incomplete · kind_locked · terms_changed · business_use_required · reauth_required (ZADQ-307) · account_blocked (ZADQ-311) · custody_version_conflict · last_wrap · passkey_not_on_account (ZADQ-293) · wraps_required (ZADQ-293, v1.3.2) · origin_invalid · key_invalid · private_key_refused · origin_in_use · key_reused · evidence_required · obligations_not_published · obligations_changed (ZADQ-362, v1.3.13) · mintid_unavailable (503, ZADQ-407: MintID unreachable since the start-up and the ids not discovered yet; nothing recorded, retry later)
detailstringyes
custody_versioninteger (int64)no409 custody_version_conflict (§5.8, v1.3.2) — the stored version, to read and retry on.
fieldsobjectnoThe refused fields by path (400 person_invalid, profile_invalid).
missingarray of stringnoThe field paths a payment still needs (409 profile_incomplete).

Example

curl -sS "<base-url>/v1/products/verifier/relying-party" \
  --cookie "__Host-passkey_session=<api-key>"

POST /v1/verifiers/{verifierId}/managed/setup

Open the managed deployment's set-up line for a managed record (§5.17)

Once per business: 201 with the line opened, 200 with the line already due or settled. 409 managed_not_offered unless the record is a managed one (no record is managed in this version: the managed deployment, ZADQ-364, is not built); 409 invalid_state for a refused or withdrawn record; 409 account_blocked; 503 billing_unavailable when ZadQ's price table does not price it (nothing opened). Where the deployment waives a managed business's kit set-up, its unpaid kit set-up is voided.

Authentication: passkeySession.

Parameters

NameInRequiredTypeDescription
verifierIdpathyesstringThe verifier record's id (vrf_…).

Responses

200 — The line already due or settled, as it is.

Content type application/json.

Schema: PriceLine

PropertyTypeRequiredDescriptionValues
idstringyes
periodstring, nullablenov1.3.14 (§5.16) — the period a principal plan's seat line pays; its amount is the plan's whole price for it. v1.3.15 (§5.17) — the period a managed environment's line pays, in advance."month", "year"
environmentstring, nullablenov1.3.15 (§5.17) — a managed environment's environment; null on every other line."production", "test"
kindPriceLineKindyes
amount_minorinteger (int64), nullableyesv1.3.18 (ZADQ-389) — negative on a principal_enrolled line opened since (the month's rebate set off on the invoice; not payable).
unitstring, nullableyes
statePriceLineStateyes
refPriceLineRefyes
settlementstringyes"console", "stripe"
channelstringyesHow the line is collected (ZADQ-324, derived at read time, never stored): invoice on the console settlement (a manual invoice) and for a provider customer whose subscription collects by invoice; card otherwise (the hosted checkout). The dashboard shows "Pay" for card, "on your invoice" for invoice."card", "invoice"
quantityinteger, nullablenoSeats (seat), lease days (lease_year); v1.3.16 — the month's count of principals enrolled (principal_enrolled); v1.3.18 — on a rebate credit, the rebates settled in the month.
bundlestring, nullableno
vat_treatmentstring, nullablenov1.3.16 (ZADQ-382) — how the amount stands to VAT, on the lines opened since (null on the lines before). v1.3.29 (ZADQ-469) — every amount is net, ex-VAT: a line opens exclusive (the billing provider adds the VAT at checkout and on the invoice) or reverse_charge (the same net, no VAT, for a business whose customer record holds a valid VAT number of another member state). included is a legacy value: it is never opened now and stays only on lines opened before v1.3.29."included", "reverse_charge", "exclusive"
covers_untilstring (date-time), nullablenov1.3.16 — the end of the period a step's line (agent_extra, grade_a3_option) pays, from its settlement; null until settled and on every other line. No step is offered since v1.3.25.
credit_minorinteger (int64), nullablenov1.3.16 — on a switch's seat line (Personal → Premium), the credit of the unused period; amount_minor is the new period's price less it.
free_quantityinteger, nullablenov1.3.16 — on a principal_enrolled line, the free volume applied to the month's count; null on a rebate credit (v1.3.18).
billing_monthstring (date), nullablenov1.3.16 — on a principal_enrolled line, the month counted (its first day); v1.3.18 — the rebate statement's month.
retained_minorinteger (int64), nullablenov1.3.17 (ZADQ-387) — on a plan_refund line, the cost of the identity check performed at the person's request, retained; amount_minor is what is paid back. v1.3.29 (ZADQ-469) — net, ex-VAT, on a line exclusive or reverse_charge: the provider's refund pays back amount_minor plus its share of the VAT the payment collected (a legacy included line keeps the amounts it was opened with).
refund_reasonstring, nullablenov1.3.17 — on a plan_refund line, why the plan closed (ZadQ's own code; nothing of the issuer's reason); v1.3.34 (ZADQ-472) — enterprise_replaces_paid_plan, the paid plan replaced by an Enterprise contract (its unused period paid back by hand)."identity_check_refused", "identity_check_withdrawn", "enterprise_replaces_paid_plan"
created_atstring (date-time)yes

201 — The line opened.

Content type application/json.

Schema: PriceLine

PropertyTypeRequiredDescriptionValues
idstringyes
periodstring, nullablenov1.3.14 (§5.16) — the period a principal plan's seat line pays; its amount is the plan's whole price for it. v1.3.15 (§5.17) — the period a managed environment's line pays, in advance."month", "year"
environmentstring, nullablenov1.3.15 (§5.17) — a managed environment's environment; null on every other line."production", "test"
kindPriceLineKindyes
amount_minorinteger (int64), nullableyesv1.3.18 (ZADQ-389) — negative on a principal_enrolled line opened since (the month's rebate set off on the invoice; not payable).
unitstring, nullableyes
statePriceLineStateyes
refPriceLineRefyes
settlementstringyes"console", "stripe"
channelstringyesHow the line is collected (ZADQ-324, derived at read time, never stored): invoice on the console settlement (a manual invoice) and for a provider customer whose subscription collects by invoice; card otherwise (the hosted checkout). The dashboard shows "Pay" for card, "on your invoice" for invoice."card", "invoice"
quantityinteger, nullablenoSeats (seat), lease days (lease_year); v1.3.16 — the month's count of principals enrolled (principal_enrolled); v1.3.18 — on a rebate credit, the rebates settled in the month.
bundlestring, nullableno
vat_treatmentstring, nullablenov1.3.16 (ZADQ-382) — how the amount stands to VAT, on the lines opened since (null on the lines before). v1.3.29 (ZADQ-469) — every amount is net, ex-VAT: a line opens exclusive (the billing provider adds the VAT at checkout and on the invoice) or reverse_charge (the same net, no VAT, for a business whose customer record holds a valid VAT number of another member state). included is a legacy value: it is never opened now and stays only on lines opened before v1.3.29."included", "reverse_charge", "exclusive"
covers_untilstring (date-time), nullablenov1.3.16 — the end of the period a step's line (agent_extra, grade_a3_option) pays, from its settlement; null until settled and on every other line. No step is offered since v1.3.25.
credit_minorinteger (int64), nullablenov1.3.16 — on a switch's seat line (Personal → Premium), the credit of the unused period; amount_minor is the new period's price less it.
free_quantityinteger, nullablenov1.3.16 — on a principal_enrolled line, the free volume applied to the month's count; null on a rebate credit (v1.3.18).
billing_monthstring (date), nullablenov1.3.16 — on a principal_enrolled line, the month counted (its first day); v1.3.18 — the rebate statement's month.
retained_minorinteger (int64), nullablenov1.3.17 (ZADQ-387) — on a plan_refund line, the cost of the identity check performed at the person's request, retained; amount_minor is what is paid back. v1.3.29 (ZADQ-469) — net, ex-VAT, on a line exclusive or reverse_charge: the provider's refund pays back amount_minor plus its share of the VAT the payment collected (a legacy included line keeps the amounts it was opened with).
refund_reasonstring, nullablenov1.3.17 — on a plan_refund line, why the plan closed (ZadQ's own code; nothing of the issuer's reason); v1.3.34 (ZADQ-472) — enterprise_replaces_paid_plan, the paid plan replaced by an Enterprise contract (its unused period paid back by hand)."identity_check_refused", "identity_check_withdrawn", "enterprise_replaces_paid_plan"
created_atstring (date-time)yes

default — A /v1 refusal — {"error", "detail"} (platform API v1 §5).

Content type application/json.

Schema: V1Error

PropertyTypeRequiredDescriptionValues
errorstringyessession_required · passkey_required · last_passkey · ceremony_invalid · attestation_invalid · assertion_invalid · email_operational_invalid · body_invalid · origin_refused · not_found · not_available · internal · runtime_token_invalid · approval_not_pending · result_already_taken · declaration_invalid · request_invalid · cursor_invalid · rate_limited · offer_refused:<issuer code> (ZADQ-289) · kyc_current · kyc_required · entry_fee_due · reverification_required · invalid_state · sandbox_hint_not_available · invalid_sandbox_hint · issuer_unavailable (ZADQ-316) · kyc_grade_below_bundle (ZADQ-321) · person_invalid · profile_invalid · profile_incomplete · kind_locked · terms_changed · business_use_required · reauth_required (ZADQ-307) · account_blocked (ZADQ-311) · custody_version_conflict · last_wrap · passkey_not_on_account (ZADQ-293) · wraps_required (ZADQ-293, v1.3.2) · origin_invalid · key_invalid · private_key_refused · origin_in_use · key_reused · evidence_required · obligations_not_published · obligations_changed (ZADQ-362, v1.3.13) · mintid_unavailable (503, ZADQ-407: MintID unreachable since the start-up and the ids not discovered yet; nothing recorded, retry later)
detailstringyes
custody_versioninteger (int64)no409 custody_version_conflict (§5.8, v1.3.2) — the stored version, to read and retry on.
fieldsobjectnoThe refused fields by path (400 person_invalid, profile_invalid).
missingarray of stringnoThe field paths a payment still needs (409 profile_incomplete).

Example

curl -sS -X POST "<base-url>/v1/verifiers/<verifierId>/managed/setup" \
  --cookie "__Host-passkey_session=<api-key>"

POST /v1/verifiers/{verifierId}/managed/environments

Open a managed environment's line for one period, in advance (§5.17)

environment production or test, period month (default) or year; billed in advance, one line per period. One unpaid line per environment of the record: the same period again answers it (200), another period replaces it (the old one void). 400 body_invalid; 409 managed_not_offered unless the record is a managed one; 409 invalid_state for a refused or withdrawn record; 409 account_blocked; 503 billing_unavailable when ZadQ's price table does not price the environment and period (nothing opened).

Authentication: passkeySession.

Parameters

NameInRequiredTypeDescription
verifierIdpathyesstringThe verifier record's id (vrf_…).

Request body

application/json — required

Schema: ManagedEnvironmentOpen

PropertyTypeRequiredDescriptionValues
environmentstringyes"production", "test"
periodstringnoBilled in advance; month when left out."month", "year"

Responses

200 — The unpaid line of the same period, as it is.

Content type application/json.

Schema: PriceLine

PropertyTypeRequiredDescriptionValues
idstringyes
periodstring, nullablenov1.3.14 (§5.16) — the period a principal plan's seat line pays; its amount is the plan's whole price for it. v1.3.15 (§5.17) — the period a managed environment's line pays, in advance."month", "year"
environmentstring, nullablenov1.3.15 (§5.17) — a managed environment's environment; null on every other line."production", "test"
kindPriceLineKindyes
amount_minorinteger (int64), nullableyesv1.3.18 (ZADQ-389) — negative on a principal_enrolled line opened since (the month's rebate set off on the invoice; not payable).
unitstring, nullableyes
statePriceLineStateyes
refPriceLineRefyes
settlementstringyes"console", "stripe"
channelstringyesHow the line is collected (ZADQ-324, derived at read time, never stored): invoice on the console settlement (a manual invoice) and for a provider customer whose subscription collects by invoice; card otherwise (the hosted checkout). The dashboard shows "Pay" for card, "on your invoice" for invoice."card", "invoice"
quantityinteger, nullablenoSeats (seat), lease days (lease_year); v1.3.16 — the month's count of principals enrolled (principal_enrolled); v1.3.18 — on a rebate credit, the rebates settled in the month.
bundlestring, nullableno
vat_treatmentstring, nullablenov1.3.16 (ZADQ-382) — how the amount stands to VAT, on the lines opened since (null on the lines before). v1.3.29 (ZADQ-469) — every amount is net, ex-VAT: a line opens exclusive (the billing provider adds the VAT at checkout and on the invoice) or reverse_charge (the same net, no VAT, for a business whose customer record holds a valid VAT number of another member state). included is a legacy value: it is never opened now and stays only on lines opened before v1.3.29."included", "reverse_charge", "exclusive"
covers_untilstring (date-time), nullablenov1.3.16 — the end of the period a step's line (agent_extra, grade_a3_option) pays, from its settlement; null until settled and on every other line. No step is offered since v1.3.25.
credit_minorinteger (int64), nullablenov1.3.16 — on a switch's seat line (Personal → Premium), the credit of the unused period; amount_minor is the new period's price less it.
free_quantityinteger, nullablenov1.3.16 — on a principal_enrolled line, the free volume applied to the month's count; null on a rebate credit (v1.3.18).
billing_monthstring (date), nullablenov1.3.16 — on a principal_enrolled line, the month counted (its first day); v1.3.18 — the rebate statement's month.
retained_minorinteger (int64), nullablenov1.3.17 (ZADQ-387) — on a plan_refund line, the cost of the identity check performed at the person's request, retained; amount_minor is what is paid back. v1.3.29 (ZADQ-469) — net, ex-VAT, on a line exclusive or reverse_charge: the provider's refund pays back amount_minor plus its share of the VAT the payment collected (a legacy included line keeps the amounts it was opened with).
refund_reasonstring, nullablenov1.3.17 — on a plan_refund line, why the plan closed (ZadQ's own code; nothing of the issuer's reason); v1.3.34 (ZADQ-472) — enterprise_replaces_paid_plan, the paid plan replaced by an Enterprise contract (its unused period paid back by hand)."identity_check_refused", "identity_check_withdrawn", "enterprise_replaces_paid_plan"
created_atstring (date-time)yes

201 — The line opened.

Content type application/json.

Schema: PriceLine

PropertyTypeRequiredDescriptionValues
idstringyes
periodstring, nullablenov1.3.14 (§5.16) — the period a principal plan's seat line pays; its amount is the plan's whole price for it. v1.3.15 (§5.17) — the period a managed environment's line pays, in advance."month", "year"
environmentstring, nullablenov1.3.15 (§5.17) — a managed environment's environment; null on every other line."production", "test"
kindPriceLineKindyes
amount_minorinteger (int64), nullableyesv1.3.18 (ZADQ-389) — negative on a principal_enrolled line opened since (the month's rebate set off on the invoice; not payable).
unitstring, nullableyes
statePriceLineStateyes
refPriceLineRefyes
settlementstringyes"console", "stripe"
channelstringyesHow the line is collected (ZADQ-324, derived at read time, never stored): invoice on the console settlement (a manual invoice) and for a provider customer whose subscription collects by invoice; card otherwise (the hosted checkout). The dashboard shows "Pay" for card, "on your invoice" for invoice."card", "invoice"
quantityinteger, nullablenoSeats (seat), lease days (lease_year); v1.3.16 — the month's count of principals enrolled (principal_enrolled); v1.3.18 — on a rebate credit, the rebates settled in the month.
bundlestring, nullableno
vat_treatmentstring, nullablenov1.3.16 (ZADQ-382) — how the amount stands to VAT, on the lines opened since (null on the lines before). v1.3.29 (ZADQ-469) — every amount is net, ex-VAT: a line opens exclusive (the billing provider adds the VAT at checkout and on the invoice) or reverse_charge (the same net, no VAT, for a business whose customer record holds a valid VAT number of another member state). included is a legacy value: it is never opened now and stays only on lines opened before v1.3.29."included", "reverse_charge", "exclusive"
covers_untilstring (date-time), nullablenov1.3.16 — the end of the period a step's line (agent_extra, grade_a3_option) pays, from its settlement; null until settled and on every other line. No step is offered since v1.3.25.
credit_minorinteger (int64), nullablenov1.3.16 — on a switch's seat line (Personal → Premium), the credit of the unused period; amount_minor is the new period's price less it.
free_quantityinteger, nullablenov1.3.16 — on a principal_enrolled line, the free volume applied to the month's count; null on a rebate credit (v1.3.18).
billing_monthstring (date), nullablenov1.3.16 — on a principal_enrolled line, the month counted (its first day); v1.3.18 — the rebate statement's month.
retained_minorinteger (int64), nullablenov1.3.17 (ZADQ-387) — on a plan_refund line, the cost of the identity check performed at the person's request, retained; amount_minor is what is paid back. v1.3.29 (ZADQ-469) — net, ex-VAT, on a line exclusive or reverse_charge: the provider's refund pays back amount_minor plus its share of the VAT the payment collected (a legacy included line keeps the amounts it was opened with).
refund_reasonstring, nullablenov1.3.17 — on a plan_refund line, why the plan closed (ZadQ's own code; nothing of the issuer's reason); v1.3.34 (ZADQ-472) — enterprise_replaces_paid_plan, the paid plan replaced by an Enterprise contract (its unused period paid back by hand)."identity_check_refused", "identity_check_withdrawn", "enterprise_replaces_paid_plan"
created_atstring (date-time)yes

default — A /v1 refusal — {"error", "detail"} (platform API v1 §5).

Content type application/json.

Schema: V1Error

PropertyTypeRequiredDescriptionValues
errorstringyessession_required · passkey_required · last_passkey · ceremony_invalid · attestation_invalid · assertion_invalid · email_operational_invalid · body_invalid · origin_refused · not_found · not_available · internal · runtime_token_invalid · approval_not_pending · result_already_taken · declaration_invalid · request_invalid · cursor_invalid · rate_limited · offer_refused:<issuer code> (ZADQ-289) · kyc_current · kyc_required · entry_fee_due · reverification_required · invalid_state · sandbox_hint_not_available · invalid_sandbox_hint · issuer_unavailable (ZADQ-316) · kyc_grade_below_bundle (ZADQ-321) · person_invalid · profile_invalid · profile_incomplete · kind_locked · terms_changed · business_use_required · reauth_required (ZADQ-307) · account_blocked (ZADQ-311) · custody_version_conflict · last_wrap · passkey_not_on_account (ZADQ-293) · wraps_required (ZADQ-293, v1.3.2) · origin_invalid · key_invalid · private_key_refused · origin_in_use · key_reused · evidence_required · obligations_not_published · obligations_changed (ZADQ-362, v1.3.13) · mintid_unavailable (503, ZADQ-407: MintID unreachable since the start-up and the ids not discovered yet; nothing recorded, retry later)
detailstringyes
custody_versioninteger (int64)no409 custody_version_conflict (§5.8, v1.3.2) — the stored version, to read and retry on.
fieldsobjectnoThe refused fields by path (400 person_invalid, profile_invalid).
missingarray of stringnoThe field paths a payment still needs (409 profile_incomplete).

Example

curl -sS -X POST "<base-url>/v1/verifiers/<verifierId>/managed/environments" \
  --cookie "__Host-passkey_session=<api-key>" \
  -H "Content-Type: application/json" \
  -d @request-body.json

GET /v1/referrals

The referral read — what the refusing service accepts and why (no session; §5.16)

The landing's read (ZADQ-365), with the parameters of the URL the business configures in its refusal: verifier (the verifier record's id) and bundle (a bundle of the served catalogue). valid while the record is admitted, its door names the bundle and a plan of this wave reaches the bundle's grade — then the service's host, the bundle's description and grade floor, the market for the sentence, the plans' fit and the first bounded agent's preset; closed otherwise, with a closed reason and nothing of the service. 404 referral_unknown for a malformed parameter, no such record, or a bundle the catalogue does not carry (the landing's generic form); 503 catalogue_unavailable. Never the business's customer data.

Authentication: none — this operation is public.

Parameters

NameInRequiredTypeDescription
verifierquerynostringThe refusing service's verifier record id; absent or malformed answers 404 referral_unknown.
bundlequerynostringA bundle id of the served catalogue; absent answers 404 referral_unknown.

Responses

200 — The referral.

Content type application/json.

Schema: Referral

PropertyTypeRequiredDescriptionValues
statestringyes"valid", "closed"
closed_reasonstring, nullableyes"verifier_not_admitted", "door_not_declared", "bundle_not_accepted", "grade_not_offered"
verifierstringyes
bundleReferralBundleyes
serviceall of ReferralServiceyes
marketinteger, nullableyes1, 2 or 3 — the refusal sentence's market as the business declared it; null for the generic sentence.
plansarray of ReferralPlanFityes
presetall of ReferralPresetyes
urlstringnoThe landing URL of this referral (valid only).

default — A /v1 refusal — {"error", "detail"} (platform API v1 §5).

Content type application/json.

Schema: V1Error

PropertyTypeRequiredDescriptionValues
errorstringyessession_required · passkey_required · last_passkey · ceremony_invalid · attestation_invalid · assertion_invalid · email_operational_invalid · body_invalid · origin_refused · not_found · not_available · internal · runtime_token_invalid · approval_not_pending · result_already_taken · declaration_invalid · request_invalid · cursor_invalid · rate_limited · offer_refused:<issuer code> (ZADQ-289) · kyc_current · kyc_required · entry_fee_due · reverification_required · invalid_state · sandbox_hint_not_available · invalid_sandbox_hint · issuer_unavailable (ZADQ-316) · kyc_grade_below_bundle (ZADQ-321) · person_invalid · profile_invalid · profile_incomplete · kind_locked · terms_changed · business_use_required · reauth_required (ZADQ-307) · account_blocked (ZADQ-311) · custody_version_conflict · last_wrap · passkey_not_on_account (ZADQ-293) · wraps_required (ZADQ-293, v1.3.2) · origin_invalid · key_invalid · private_key_refused · origin_in_use · key_reused · evidence_required · obligations_not_published · obligations_changed (ZADQ-362, v1.3.13) · mintid_unavailable (503, ZADQ-407: MintID unreachable since the start-up and the ids not discovered yet; nothing recorded, retry later)
detailstringyes
custody_versioninteger (int64)no409 custody_version_conflict (§5.8, v1.3.2) — the stored version, to read and retry on.
fieldsobjectnoThe refused fields by path (400 person_invalid, profile_invalid).
missingarray of stringnoThe field paths a payment still needs (409 profile_incomplete).

Example

curl -sS "<base-url>/v1/referrals"

GET /v1/me/referrals

The account's referrals, the arrival first (§5.16)

Authentication: passkeySession.

Responses

200 — The referrals.

Content type application/json.

Schema: AccountReferralList

PropertyTypeRequiredDescriptionValues
referralsarray of AccountReferralyes

default — A /v1 refusal — {"error", "detail"} (platform API v1 §5).

Content type application/json.

Schema: V1Error

PropertyTypeRequiredDescriptionValues
errorstringyessession_required · passkey_required · last_passkey · ceremony_invalid · attestation_invalid · assertion_invalid · email_operational_invalid · body_invalid · origin_refused · not_found · not_available · internal · runtime_token_invalid · approval_not_pending · result_already_taken · declaration_invalid · request_invalid · cursor_invalid · rate_limited · offer_refused:<issuer code> (ZADQ-289) · kyc_current · kyc_required · entry_fee_due · reverification_required · invalid_state · sandbox_hint_not_available · invalid_sandbox_hint · issuer_unavailable (ZADQ-316) · kyc_grade_below_bundle (ZADQ-321) · person_invalid · profile_invalid · profile_incomplete · kind_locked · terms_changed · business_use_required · reauth_required (ZADQ-307) · account_blocked (ZADQ-311) · custody_version_conflict · last_wrap · passkey_not_on_account (ZADQ-293) · wraps_required (ZADQ-293, v1.3.2) · origin_invalid · key_invalid · private_key_refused · origin_in_use · key_reused · evidence_required · obligations_not_published · obligations_changed (ZADQ-362, v1.3.13) · mintid_unavailable (503, ZADQ-407: MintID unreachable since the start-up and the ids not discovered yet; nothing recorded, retry later)
detailstringyes
custody_versioninteger (int64)no409 custody_version_conflict (§5.8, v1.3.2) — the stored version, to read and retry on.
fieldsobjectnoThe refused fields by path (400 person_invalid, profile_invalid).
missingarray of stringnoThe field paths a payment still needs (409 profile_incomplete).

Example

curl -sS "<base-url>/v1/me/referrals" \
  --cookie "__Host-passkey_session=<api-key>"

POST /v1/me/referrals

Record a referral on a signed-in account (a person who already has one, §5.16)

201 the referral (200: the same referral, as recorded). 404 referral_unknown; 409 referral_closed (the reason in the detail).

Authentication: passkeySession.

Request body

application/json — required

Schema: ReferralParams

PropertyTypeRequiredDescriptionValues
verifierstringyesThe refusing service's verifier record id.
bundlestringyesThe bundle id of the served catalogue the refusal names.

Responses

200 — Already recorded.

Content type application/json.

Schema: AccountReferral

PropertyTypeRequiredDescriptionValues
idstringyesThe referral's reference (rfl_…).
verifierstringyes
bundlestringyes
marketinteger, nullableyes
at_signupbooleanyes
recorded_atstring (date-time)yes

201 — Recorded.

Content type application/json.

Schema: AccountReferral

PropertyTypeRequiredDescriptionValues
idstringyesThe referral's reference (rfl_…).
verifierstringyes
bundlestringyes
marketinteger, nullableyes
at_signupbooleanyes
recorded_atstring (date-time)yes

default — A /v1 refusal — {"error", "detail"} (platform API v1 §5).

Content type application/json.

Schema: V1Error

PropertyTypeRequiredDescriptionValues
errorstringyessession_required · passkey_required · last_passkey · ceremony_invalid · attestation_invalid · assertion_invalid · email_operational_invalid · body_invalid · origin_refused · not_found · not_available · internal · runtime_token_invalid · approval_not_pending · result_already_taken · declaration_invalid · request_invalid · cursor_invalid · rate_limited · offer_refused:<issuer code> (ZADQ-289) · kyc_current · kyc_required · entry_fee_due · reverification_required · invalid_state · sandbox_hint_not_available · invalid_sandbox_hint · issuer_unavailable (ZADQ-316) · kyc_grade_below_bundle (ZADQ-321) · person_invalid · profile_invalid · profile_incomplete · kind_locked · terms_changed · business_use_required · reauth_required (ZADQ-307) · account_blocked (ZADQ-311) · custody_version_conflict · last_wrap · passkey_not_on_account (ZADQ-293) · wraps_required (ZADQ-293, v1.3.2) · origin_invalid · key_invalid · private_key_refused · origin_in_use · key_reused · evidence_required · obligations_not_published · obligations_changed (ZADQ-362, v1.3.13) · mintid_unavailable (503, ZADQ-407: MintID unreachable since the start-up and the ids not discovered yet; nothing recorded, retry later)
detailstringyes
custody_versioninteger (int64)no409 custody_version_conflict (§5.8, v1.3.2) — the stored version, to read and retry on.
fieldsobjectnoThe refused fields by path (400 person_invalid, profile_invalid).
missingarray of stringnoThe field paths a payment still needs (409 profile_incomplete).

Example

curl -sS -X POST "<base-url>/v1/me/referrals" \
  --cookie "__Host-passkey_session=<api-key>" \
  -H "Content-Type: application/json" \
  -d @request-body.json

GET /v1/plans

The principal plans — Personal and Plus — with their prices on this deployment (no session; §5.16)

Each plan's seats (minimum = cap), the grade its verification is at, the renewal by grade (no grace) and, per period (month, year; year by default), the plan's whole price as one amount from ZadQ's own price table — on_sale: false and the amount null when the table does not price it (choosing it answers 503 billing_unavailable). Billed in advance, before the identity check. Who may subscribe: organisations and sole traders; the consumer path is refused until counsel answers. Whether a public page shows these figures is a publication act (Marc's).

Authentication: none — this operation is public.

Responses

200 — The plans.

Content type application/json.

Schema: PrincipalPlanList

PropertyTypeRequiredDescriptionValues
plansarray of PrincipalPlanyes
contactobjectyesv1.3.30 (ZADQ-472, §5.20) — beyond Premium, Enterprise — the agent-operator product by contract, agreed by contact and activated by ZadQ; never an amount.
contact.idstringyes"enterprise"
contact.labelstringyes
contact.seats_fromintegeryesThe fewest bounded agents an Enterprise contract carries (6, beyond Premium's 5).
contact.by_contactbooleanyestrue
default_periodstringyes"month", "year"
eligibilityobjectyes
eligibility.account_kindsarray of AccountKindyes
eligibility.consumerstringyes"not_offered"

default — A /v1 refusal — {"error", "detail"} (platform API v1 §5).

Content type application/json.

Schema: V1Error

PropertyTypeRequiredDescriptionValues
errorstringyessession_required · passkey_required · last_passkey · ceremony_invalid · attestation_invalid · assertion_invalid · email_operational_invalid · body_invalid · origin_refused · not_found · not_available · internal · runtime_token_invalid · approval_not_pending · result_already_taken · declaration_invalid · request_invalid · cursor_invalid · rate_limited · offer_refused:<issuer code> (ZADQ-289) · kyc_current · kyc_required · entry_fee_due · reverification_required · invalid_state · sandbox_hint_not_available · invalid_sandbox_hint · issuer_unavailable (ZADQ-316) · kyc_grade_below_bundle (ZADQ-321) · person_invalid · profile_invalid · profile_incomplete · kind_locked · terms_changed · business_use_required · reauth_required (ZADQ-307) · account_blocked (ZADQ-311) · custody_version_conflict · last_wrap · passkey_not_on_account (ZADQ-293) · wraps_required (ZADQ-293, v1.3.2) · origin_invalid · key_invalid · private_key_refused · origin_in_use · key_reused · evidence_required · obligations_not_published · obligations_changed (ZADQ-362, v1.3.13) · mintid_unavailable (503, ZADQ-407: MintID unreachable since the start-up and the ids not discovered yet; nothing recorded, retry later)
detailstringyes
custody_versioninteger (int64)no409 custody_version_conflict (§5.8, v1.3.2) — the stored version, to read and retry on.
fieldsobjectnoThe refused fields by path (400 person_invalid, profile_invalid).
missingarray of stringnoThe field paths a payment still needs (409 profile_incomplete).

Example

curl -sS "<base-url>/v1/plans"

GET /v1/legal/verifier-obligations

The verifier obligations in force — the exact text and its SHA-256 (§5.15, as §5.11's legal versions)

The latest published version (no session). 404 not_found until the operator console publishes one (the text is the legal layer's, ZADQ-361). url is where the public web shows it, null when it is served here only.

Authentication: none — this operation is public.

Responses

200 — The version in force.

Content type application/json.

Schema: VerifierObligations

PropertyTypeRequiredDescriptionValues
versionstringyes
sha256stringyes
urlstring, nullableyes
textstringyes
published_atstring (date-time)yes

default — A /v1 refusal — {"error", "detail"} (platform API v1 §5).

Content type application/json.

Schema: V1Error

PropertyTypeRequiredDescriptionValues
errorstringyessession_required · passkey_required · last_passkey · ceremony_invalid · attestation_invalid · assertion_invalid · email_operational_invalid · body_invalid · origin_refused · not_found · not_available · internal · runtime_token_invalid · approval_not_pending · result_already_taken · declaration_invalid · request_invalid · cursor_invalid · rate_limited · offer_refused:<issuer code> (ZADQ-289) · kyc_current · kyc_required · entry_fee_due · reverification_required · invalid_state · sandbox_hint_not_available · invalid_sandbox_hint · issuer_unavailable (ZADQ-316) · kyc_grade_below_bundle (ZADQ-321) · person_invalid · profile_invalid · profile_incomplete · kind_locked · terms_changed · business_use_required · reauth_required (ZADQ-307) · account_blocked (ZADQ-311) · custody_version_conflict · last_wrap · passkey_not_on_account (ZADQ-293) · wraps_required (ZADQ-293, v1.3.2) · origin_invalid · key_invalid · private_key_refused · origin_in_use · key_reused · evidence_required · obligations_not_published · obligations_changed (ZADQ-362, v1.3.13) · mintid_unavailable (503, ZADQ-407: MintID unreachable since the start-up and the ids not discovered yet; nothing recorded, retry later)
detailstringyes
custody_versioninteger (int64)no409 custody_version_conflict (§5.8, v1.3.2) — the stored version, to read and retry on.
fieldsobjectnoThe refused fields by path (400 person_invalid, profile_invalid).
missingarray of stringnoThe field paths a payment still needs (409 profile_incomplete).

Example

curl -sS "<base-url>/v1/legal/verifier-obligations"

Schemas

TermsDocument

PropertyTypeRequiredDescriptionValues
versionstringyesVersion name of the acknowledgement document.
sha256stringyesHex SHA-256 of text.
urlstring (uri)yesWhere the full Terms of Service are published.
textstringyesThe acknowledgement text the wallet signs for.

SellerTerms

PropertyTypeRequiredDescriptionValues
currentTermsDocumentyes
acknowledgedbooleanyesWhether the current version is acknowledged by this seller.
acknowledgedVersionstringno
signedAtstring (date-time)noWhen the current version was signed, if it was.
messagestringyesThe exact text to sign for the current version.
messageSignedAtstring (date-time)yesThe signing time embedded in message; submit it back as signedAt.

TermsAcknowledgement

PropertyTypeRequiredDescriptionValues
versionstringyes
sha256stringyes
signedAtstring (date-time)yes
signaturestringyesWallet signature over the message (hex for EVM, base58 or hex for Solana).

SellerWebhooks

PropertyTypeRequiredDescriptionValues
webhooksarray of Webhookyes

SellerEvent

PropertyTypeRequiredDescriptionValues
typestringyesEvent name of the seller stream (e.g. intake, kyc_approved, attested, status_suspended, consent_withdrawn).
occurredAtstring (date-time)yes

SellerEvents

PropertyTypeRequiredDescriptionValues
eventsarray of SellerEventyes

Chain

The chain a payTo address is paid on (Platform Decision 14, ZADQ-66): USDC on Base (base, an EVM address, stored and compared lowercase) or on Solana (solana, case-sensitive). Any other value is refused with a 400 problem; other EVM chains are not declared until a seller needs one.

Type: string, one of "base", "solana".

AuthChallengeRequest

PropertyTypeRequiredDescriptionValues
chainChainyes
addressstringyes

AuthChallenge

PropertyTypeRequiredDescriptionValues
noncestringyes
messagestringyesExact text to sign, byte for byte.
expiresAtstring (date-time)yes

AuthSessionRequest

PropertyTypeRequiredDescriptionValues
chainChainyes
addressstringyes
noncestringyes
signaturestringyesEVM — 0x-hex r||s||v from personal_sign; Solana — base58 (or hex) 64-byte signature.

AuthSession

PropertyTypeRequiredDescriptionValues
bearerstringyesOpaque session credential for the Authorization header.
expiresAtstring (date-time)yes
chainChainyes
addressstringyes

Health

PropertyTypeRequiredDescriptionValues
statusstringyes"ok"
versionstringno
mintidstringnoThe readiness of this deployment's MintID ids (ZADQ-407): discovering while MintID was unreachable at start-up and the ids are retried in the background (the MintID-dependent routes answer 503 mintid_unavailable), ready otherwise. The probe answers 200 either way."discovering", "ready"

CredentialOfferHandoff

PropertyTypeRequiredDescriptionValues
offerobjectyesThe credential offer object, as the issuer returned it — opaque, one-shot; redeem it at once.
expiresAtstring (date-time)yesWhen the code and the credential it yields expire — the verification's own expiry at the latest. No grace.
credentialCredentialStateyes

CredentialReport

PropertyTypeRequiredDescriptionValues
statestringyesheld, or self_revoked (revoked is the older spelling of the same report)."held", "self_revoked", "revoked"
credentialRefstringnoAn opaque reference of the seller's choosing for the credential it holds. Never a key.
presentationUrlstring (uri)noWhere the seller's holder answers this service's challenges (ZADQ-84): POST of the issued challenge as the verifier returned it ({request, signature_hex}), 200 with the envelope ({proof_hex, issuer_id, status_root, claimed_predicates}); any other status means the holder cannot present this time. Only with held; kept when omitted on a later report.

CredentialState

The v1 credential the seller holds in its own infrastructure, as this service knows it (ZADQ-83): state only. expired is derived — an offered or held credential past the verification's expiry — since a credential lasts exactly what the verification lasts. revoked: revoked by the issuer's policy (consent withdrawn). self_revoked (ZADQ-89): revoked by its holder through the network's privacy relay; terminal on this verification, with nothing recorded next to it — the way back is a new verification.

PropertyTypeRequiredDescriptionValues
statestringyes"none", "offered", "held", "expired", "revoked", "self_revoked"
offeredAtstring (date-time)no
expiresAtstring (date-time)noThe verification's expiry, which is the credential's.
credentialRefstringno
presentationUrlstring (uri)noThe holder's presentation endpoint registered with held (ZADQ-84); absent on the v0 path.
lastPresentationPresentationOutcomeno

PresentationOutcome

The outcome of the last cadence presentation of the held credential (ZADQ-84), as the verifier's own decision record keeps it: never the challenge, the envelope or a proof. stage says where it ended — challenge (no challenge issued: the verifier's proven state was unavailable), transport (the holder did not present: holder_unreachable, holder_refused, envelope_malformed) or decision (the verifier decided; reason is its code — accepted, or one of its closed vocabulary such as proof_invalid, predicate_missing, deadline_exceeded, status_root_stale, request_not_ours). A refused decision withholds the positive claim on the public verdict; the public reason stays in the standing vocabulary, so the exact code lives here and on the seller's channel. Since the verifier contract 1.8.0 the vocabulary also holds dispute_retention_unavailable, produced for agent requests only (an identity presentation, which this outcome records, never meets it): it names the verifier's own fault, never the holder's, and would read state_unavailable on the public verdict.

PropertyTypeRequiredDescriptionValues
stagestringyes"challenge", "transport", "decision"
acceptedbooleanyes
reasonstringyes
sessionIdstringnoThe verifier's session id of the decision record.
decidedAtstring (date-time)yes

SubstrateStatus

PropertyTypeRequiredDescriptionValues
substratestringyes"ok", "degraded", "unknown"
sourcestringyesWhere the state comes from — the verifier's status read, or this service's cadence accounting."verifier", "cadence"
reasonstringnoWhy the substrate is not ok, in the verifier's standing vocabulary (for example height_stale, root_expired, state_unavailable). Absent when ok.
checkedAtstring (date-time)yes
lastSuccessfulStandingReadstring (date-time)noThe last time a standing read answered with a known status. Absent before the first.
cadenceobjectyes
cadence.recheckEveryHoursintegeryesThe published cadence promise.
cadence.lastCycleAtstring (date-time)no
cadence.checkedintegernoAttestations the last cycle asked the verifier about.
cadence.withheldintegernoOf those, how many came back with an unknown standing.

BillingCheckout

PropertyTypeRequiredDescriptionValues
tierstringyesThe schedule tier, by name. Amounts are on the checkout page and in the operator agreement."attested_vendor", "regulated_compliance"
cadencestringnoHow the tier's minimum is billed: monthly or annually (ZADQ-230). The cadence rides on the session's metadata like the tier and lands on the record with the provider's completed event. 400 when this deployment has no price for the cadence requested."monthly", "annual"

BillingHandoff

PropertyTypeRequiredDescriptionValues
urlstring (uri)yesThe hosted checkout page — open it as-is.
billingstringyesThe record's billing state as the session opens — none, since opening a session records nothing (ZADQ-221). It moves to active with the provider's signed completed event, never here."none", "active"

BillingEventReceipt

PropertyTypeRequiredDescriptionValues
appliedbooleanyes

AddressProof

Proof of control of a payment address: the nonce of an auth challenge issued for it and the wallet's signature over the challenge message. Consumed on use, valid or not, like a login.

PropertyTypeRequiredDescriptionValues
noncestringyes
signaturestringyes

EndpointAddition

PropertyTypeRequiredDescriptionValues
resourceUrlstring (uri)yes
payToPayTono
proofAddressProofno

WalletRotation

PropertyTypeRequiredDescriptionValues
payToPayToyes
proofAddressProofyes

VendorBilling

v1.3.31 (ZADQ-470) — the vendor lines of an operator group, amounts net in minor units.

PropertyTypeRequiredDescriptionValues
seller_idstringyesThe seller record asked about.
billing_seller_idstring, nullablenoThe operator group's seller record whose billing is active (the oldest); null when none.
billingstringyesThe group's billing state."none", "active"
tierstring, nullableno"attested_vendor", "regulated_compliance"
cadencestring, nullableno"monthly", "annual"
entry_feeVendorEntryFeeyes
endpointsVendorEndpointsyes
usage_feeVendorUsageFeeyes

VendorEntryFee

The entry fee — one-off, not credited (it pays the onboarding's support and integration; the tier pays the infrastructure).

PropertyTypeRequiredDescriptionValues
paid_tierstring, nullablenoThe highest tier whose entry fee the group paid; null when none."attested_vendor", "regulated_compliance"
paid_minorinteger (int64)yesThe net paid in total by the group.
unitstring, nullableno
duearray of VendorEntryDueyesWhat a checkout of each tier would charge now (0 once paid; a higher tier the difference). Empty where the deployment prices no entry fee.

VendorEntryDue

PropertyTypeRequiredDescriptionValues
tierstringyes"attested_vendor", "regulated_compliance"
amount_minorinteger (int64)yes
unitstringyes

VendorEndpoints

The group's admitted endpoint records against the tier's included ones, and the additional-endpoint item.

PropertyTypeRequiredDescriptionValues
liveintegeryesAdmitted endpoint records of the operator group.
includedintegeryesIncluded by the tier (3 Attested Vendor, 10 Regulated / Compliance; Attested's without a tier).
additionalintegeryesEndpoints above the quota (what the item should carry).
billedintegeryesThe quantity last set on the provider's additional-endpoint item (0 without one). An increase is charged at once, prorated; a decrease credits nothing and counts from the next period.
priceobject, nullablenoOne additional endpoint for one period of the group's cadence; null when not priced.
price.amount_minorinteger (int64)yes
price.unitstringyes
price.periodstringyes"month", "year"

VendorUsageFee

The usage fee — 0.75 % of each covered settlement received, capped at USD 0.40 a settlement, converted at the ECB rule, credited against the minimum (the tier and the additional endpoints paid; never the entry fee). Billed only above it.

PropertyTypeRequiredDescriptionValues
invoicingstringyeson: a billable month is invoiced at the meter's close on a monthly invoice of its own, whatever the cadence (v1.3.32) — the collection method of the vendor's subscription, automatic tax; its id is the statement's invoice_ref. off (the default until the counsel items of Platform Decision 15): the statement is recorded and shown, never invoiced."off", "on"
rate_basis_pointsintegeryes75 (0.75 %).
cap_micro_usdcinteger (int64)yes400000 (USD 0.40) per settlement.
statementsarray of VendorUsageStatementyesThe monthly closes of the last 24 months, oldest first.

VendorUsageStatement

PropertyTypeRequiredDescriptionValues
periodstringyesYYYY-MM (UTC).
settlementsinteger (int64)yesCovered settlements received in the month.
fee_micro_usdcinteger (int64)yesThe month's fee, each settlement's fee rounded down and capped before the sum.
fee_eur_centsinteger (int64)yes
fx_rulestringyes
fx_ratestringyesEUR per USD applied (eight decimals).
fx_rate_datestring (date)yes
fx_quotestring, nullablenoThe ECB quotation (1 EUR = q USD) the rate came from; null on the configured rate.
minimum_eur_centsinteger (int64)yesThe annual minimum credited against (the tier and the additional endpoints).
cadencestringno"monthly", "annual"
minimum_credited_eur_centsinteger (int64)yesThe minimum credited to date in the contract year (all of it billed annually; the twelfths invoiced billed monthly).
ytd_fee_eur_centsinteger (int64)yes
billable_eur_centsinteger (int64)yesWhat stands above the minimum credited, less what was billed earlier in the contract year.
statestringyeswithheld_counsel: closed with the usage fee's invoicing off — shown, never invoiced. invoiced: on the provider — since v1.3.32 on the month's own invoice (invoice_ref). recorded: closed and not invoiced (nothing above the minimum, or the invoice not posted yet)."recorded", "invoiced", "withheld_counsel"
invoice_refstring, nullablenov1.3.32 (ZADQ-470; Marc, 2026-11-08) — the provider's invoice the month's usage fee is billed on, a monthly invoice of its own (every cadence, yearly included; the collection method of the vendor's subscription — by invoice due in 30 days, or charged to its default payment method; automatic tax). Null while the month is not invoiced.

OperatorEndpoints

PropertyTypeRequiredDescriptionValues
endpointsarray of EndpointSummaryyes

EndpointSummary

PropertyTypeRequiredDescriptionValues
sellerIdstringyes
payToPayToyes
resourceUrlstringyes
statestringyes"pending_kyc", "kyc_expired", "admitted", "rejected", "withdrawn"
attestationStatusstringno"active", "suspended", "revoked"

InterestForm

The register-interest form's fields; contact data is not among them.

PropertyTypeRequiredDescriptionValues
sidestringyesWhich side of the trust perimeter the person stands on."vendor", "agent_operator"
resource_urlstring (uri)noThe x402 resource URL a vendor sells at (optional, vendors).
agent_count_bandstringnoThe size band of an operator's fleet (optional, agent operators)."up_to_10", "up_to_100", "more_than_100"
sourcestringnoThe page family the form was reached from (optional; a hidden field rendered at build time, ZADQ-160). An unknown value is dropped, not refused."home", "seller", "agent", "plans", "industries", "trust_about", "docs", "blog", "legal", "metrics"
websitestringnoTrap field for automated submitters; a person leaves it empty.

SellerIntake

PropertyTypeRequiredDescriptionValues
payToPayToyes
resourceUrlstring (uri)yes
operatorTypestringyes"person", "organisation"
segmentSegmentDeclarationyes
kycSandboxHintKycSandboxHintno
biometric_consentBiometricConsentGivenno

BiometricConsentGiven

The person's explicit consent to the face comparison (ZADQ-331; GDPR Art. 9(2)(a)), given on ZadQ's own page by the button whose label is the consent, before the verification link is opened: version is the label of the consent text the page showed. Every route that opens a verification session requires it — absent: 409 biometric_consent_required; a label other than the deployment's current one (GET /v1/me → biometric_consent.version_required): 409 biometric_consent_version_stale, the current label in the detail. Refused, nothing reaches the issuer and nothing is recorded. Accepted, ZadQ records the label, the time and the session it opened — no identity data. The field is spelled biometric_consent on the v0 bodies too (the one snake-case field there). A session opened without a consent record (before this rule, ZADQ-331) is served without its link until one is recorded on it: POST /v1/kyc/sessions/{id}/biometric-consent, POST /v0/sellers/{id}/biometric-consent (the v0 agent-operator route is retired since v1.3.33).

PropertyTypeRequiredDescriptionValues
versionstringyesThe consent text's version label (e.g. 2026-10.2).

KycSessionRestart

The body of the v0 routes that open a new verification session on an existing record (ZADQ-331): the consent to the face comparison.

PropertyTypeRequiredDescriptionValues
biometric_consentBiometricConsentGivenno

KycSandboxHint

Staging only (ZADQ-196). The outcome a tester picks for the KYC session on an issuer whose KYC provider is MintID's sandbox driver (MintID's public testnet), in the sandbox grammar sandbox:<outcome>[:g1..g4][:F1..F4][:window=<s>][:review=<s>][:ttl=<s>] (ops/runbook-staging.md; the grammar's identity-data option is refused here: this service carries no identity data, not even synthetic). Accepted only when the issuer's build-info reported kyc_provider sandbox at start-up and this instance is not the production service; otherwise 400 sandbox_hint_not_available (a malformed value is 400 invalid_sandbox_hint). When accepted it replaces this service's opaque handle as the session's seller_ref at the issuer — on sandbox issuers only — and is kept nowhere else and never logged. Without it the sandbox approves at grade 2.

Type: string.

PayTo

Chain-qualified x402 payment address.

PropertyTypeRequiredDescriptionValues
chainChainyes
addressstringyesThe address that receives the payment; on base stored and compared lowercase.

SegmentDeclaration

PARAM-29 declaration. Recorded, not enforced in v0.

PropertyTypeRequiredDescriptionValues
annualVolumeUsdAtLeast300booleanyes
regulatedB2bCounterpartiesbooleanyes

Seller

PropertyTypeRequiredDescriptionValues
idstringyes
payToPayToyes
resourceUrlstring (uri)yes
operatorTypestringyes"person", "organisation"
statestringyeskyc_expired: the proofing session ran past its deadline without an outcome; a new session can be opened (POST …/kyc/sessions). withdrawn: consent to the service withdrawn — terminal."pending_kyc", "kyc_expired", "admitted", "rejected", "withdrawn"
billingstringyesBilling state at the operator's billing provider (ZADQ-54): none until the provider's signed checkout.session.completed lands, active afterwards; back to none on customer.subscription.deleted. Opening a checkout session records nothing (ZADQ-221). The service holds no legal or payment data."none", "active"
billingTierstringnoThe schedule tier, by name, as the provider's completed event carried it from the session's metadata. Absent until billing is active (ZADQ-221)."attested_vendor", "regulated_compliance"
billingCadencestringnoHow the minimum is billed, as the provider's completed event carried it from the session's metadata (ZADQ-230). Absent until billing is active; a record active before cadences existed reads annual."monthly", "annual"
kycSessionIdstringnoOpaque session handle at the KYC boundary. Not identity data.
kycKycHandoffno
credentialCredentialStateno
depositDepositno
renewalall of KycHandoffnoThe pending re-verification session, while one is open (ZADQ-91): the person completes it on handoffUrl; the approved session in kyc keeps backing the attestation meanwhile.
attestationAttestationno
createdAtstring (date-time)yes

Deposit

The seller's guarantee deposit state as mirrored by this service (ZADQ-151): the state, its dashboard label, the holder's verification state, the level owed, the balance as last read from the holder and when, and the claims pending. Never a bank or card detail: this service mirrors states and amounts and holds nothing.

PropertyTypeRequiredDescriptionValues
statestringyes"required", "awaiting_funds", "held", "below_level", "returning", "returned"
dashboardStatestringyesOne of the eight labels shown as state only."Deposit required", "Awaiting funds", "Held (≥ level)", "Below level (top-up)", "Claim pending", "Released (partial)", "Returning", "Returned"
kybstringyesThe holder's verification of the vendor, as reported."none", "pending", "review", "validated", "refused", "expired", "out_of_date"
requiredMinorinteger (int64)yesThe level owed, in minor units of currency.
currencystringyes
balanceMinorinteger (int64)yesThe wallet balance as last read from the holder.
syncedAtstring (date-time)no
openClaimsintegeryes
returnDueAtstring (date-time)noWhen the return falls due after termination.

DepositKybHandoff

PropertyTypeRequiredDescriptionValues
urlstring (uri)yesThe holder's hosted verification page.

DepositPayInInstructions

The holder's collection details for one bank wire, relayed once and never stored by this service.

PropertyTypeRequiredDescriptionValues
collectionAccountstringyesThe holder's collection account to wire to.
bankNamestringyes
bankCodestringyes
wireReferencestringyesMust travel with the wire so the holder credits the right wallet.
amountMinorinteger (int64)yes
currencystringyes

KycHandoff

The person's side of the KYC session (ZADQ-52). handoffUrl is the identity provider's hosted page where the proofing is completed — open it as-is; it is present only while the session is pending and a consent to the face comparison is recorded for this session (ZADQ-331): without one it is absent (null) and biometric_consent_required reads true — record the consent with POST …/biometric-consent and the link comes back. Nothing here is identity data.

PropertyTypeRequiredDescriptionValues
statestringyes"pending", "approved", "rejected", "expired", "withdrawn"
handoffUrlstring (uri), nullableno
biometric_consent_requiredbooleannoWhile pending (ZADQ-331): true when no consent to the face comparison is recorded for this session — the link is withheld until POST …/biometric-consent records one; false once it is.
expiresAtstring (date-time)noProofing deadline of the current session.
reusableUntilstring (date-time)noEnd of the approved session's reuse window (approval + the grade's validity — 12 months at grades 1–2, 6 at grade 3, 3 at grade 4). No grace and no extension: the attestation is suspended rekyc_overdue at the first root after it unless a re-verification was bound before. Re-verify ahead of it (POST …/kyc/sessions).
freshnessBandstringnoAge of the last successful proofing as a band (F4 < 30 days, F3 < 90, F2 < 180, F1 < 365) — never a date. "Human-backed at G" means grade ≥ 2 and freshness ≥ F1; the issuer enforces it."F4", "F3", "F2", "F1"
reverificationDueAtstring (date-time)noWhen "re-verification due" starts: reusableUntil minus the service's lead (ZADQ-79). Present while approved and no re-verification is pending. The issuer extends nothing; this is the whole of the notice.
reverificationDuebooleannoTrue from reverificationDueAt until the window ends: re-verify now (POST …/kyc/sessions) so the attestation keeps its standing and its reference. Past the window the issuer refuses every step with 409 session_reuse_expired — terminal: the seller reads kyc_expired and starts a new verification.

KycResult

Outcome metadata only — the contract carries no identity data.

PropertyTypeRequiredDescriptionValues
sessionIdstringyes
outcomestringyes"approved", "rejected"
assuranceLevelstringnoAssurance grade met by the proofing process (e.g. "G").

Attestation

PropertyTypeRequiredDescriptionValues
idstringyes
sellerIdstringyes
assuranceLevelstringyes
statusstringyes"active", "suspended", "revoked"
statusReasonstringnoWhy a non-active status was set — never silent. rekyc_overdue: the reuse window ended; restored under the same reference by a bound re-verification. consent_withdrawn: terminal. self_revoked: the holder revoked its own credential and the attestation was retired at the next verdict cadence — terminal for this attestation; a new verification yields a new one. Absent for operator changes and while active."rekyc_overdue", "consent_withdrawn", "self_revoked"
freshnessBandstringnoFreshness band of the backing session, as the issuer reports it."F4", "F3", "F2", "F1"
issuedAtstring (date-time)yes
updatedAtstring (date-time)yes

AttestationReceipt

The attestation-ref/v0 payload, field for field (snake_case as the issuer signs it): Ed25519 over `"mintid/seller-attestation/v0" || 0x00

|| SHA-256(canonical JSON of the seven fields but signature)`. Only opaque handles and public endpoint identifiers.

PropertyTypeRequiredDescriptionValues
attestation_refstringyes32-byte opaque reference, hex.
issuer_idstringyes
chainstringyes
pay_tostringyes
resource_urlstringyes
assurance_gradeintegeryes
issued_at_unixintegeryes
signaturestringyesEd25519 by the issuer's registered status signing key, hex (64 bytes).

AttestationStatusUpdate

PropertyTypeRequiredDescriptionValues
statusstringyes"active", "suspended", "revoked"

Verdict

The explorer-consumable signed verdict: "human-backed at assurance ≥ G, verified at T, re-checked every N hours." Staleness is policy-driven. Issuer-standing policy: the positive claim is published only while the issuer's bond on the network meets the published minimum; otherwise the outcome is no_signal with reason: bond_insufficient. Every non-positive outcome carries reason from the closed vocabulary (ZADQ-78); human_backed never does.

PropertyTypeRequiredDescriptionValues
outcomestringyes"human_backed", "revoked", "stale", "no_signal"
subjectobjectyes
subject.chainChainyes
subject.payTostringyes
subject.resourceUrlstringyes
assuranceLevelstringno
verifiedAtstring (date-time)no
recheckEveryHoursintegeryes
signaturestringnoEd25519 over the canonical verdict payload, base64.
keyIdstringno
reasonstringnoWhy the outcome is not human_backed: the standing read's reason code (closed vocabulary), or suspended when the witnessed status is suspended. Absent on human_backed; absent on revoked too. The policy reason of a suspension (rekyc_overdue) is the seller's own record, never part of the public verdict. On the v1 path (ZADQ-84) a verifier-side condition of the presentation decision is carried with the same code (issuer_not_active, status_root_stale, height_stale) or as state_unavailable; a presentation the verifier refused on the holder's side withholds the positive claim with no reason — the decision's exact code is the seller's own record (credential.lastPresentation). The freshness half of "human-backed" (grade ≥ 2 and freshness ≥ F1) is the issuer's state on both rails (ZADQ-182): the issuer computes the band and suspends rekyc_overdue when the reuse window ends; ZadQ mirrors that state and never asks a presentation about recency (a presentation proves the grade threshold, expiry and non-revocation only). The verdict carries neither the band nor a date; the band is the seller's own record (freshnessBand)."state_unavailable", "issuer_unknown", "issuer_not_active", "status_root_stale", "height_stale", "witness_unavailable", "witness_malformed", "witness_invalid", "witness_root_mismatch", "bond_insufficient", "suspended"
extensionsVerdictExtensionsno

VerdictExtensions

Declarations of the verifying party, beside the verdict and outside it (ZADQ-240). The verdict's own fields above are the identity network's vocabulary and are closed; what ZadQ states on its own account travels under its own key, zadq, labelled as ZadQ's claim and not as a statement of the identity network. A reader that does not know the key ignores it and loses nothing. The signature covers the verdict's canonical payload only, not this object. Absent when ZadQ has nothing of its own to declare.

PropertyTypeRequiredDescriptionValues
zadqZadqVerdictExtensionno

ZadqVerdictExtension

ZadQ's own declarations about the seller, under ZadQ's Terms.

PropertyTypeRequiredDescriptionValues
depositDepositDeclarationno

DepositDeclaration

ZadQ's statement about the seller's guarantee deposit under ZadQ's Terms (Platform Decision 18); not a statement of the identity network, which carries no fact about this deposit. A state and a level band, read from ZadQ's mirrored record at verifiedAt — the record moves on every event of the deposit holder, so the read is the re-check. Never a balance, never an amount, never a holder reference. Present only while the deposit rail is on and the seller owes a deposit on the record. The gate on the positive claim (a positive standing whose deposit is not held reads no_signal) is ZadQ's verdict policy and is stated as such; this field is the reading behind it.

PropertyTypeRequiredDescriptionValues
statestringyesThe deposit's public state, one code per label of the seller's deposit.dashboardState."required", "awaiting_funds", "held", "below_level", "claim_pending", "released_partial", "returning", "returned"
levelstringyesThe band of the deposit, named by the tier of the schedule it belongs to; the level's amount is published on the plans page, never here."attested_vendor", "regulated_compliance"
verifiedAtstring (date-time)yesWhen ZadQ read its mirrored record for this answer.

WebhookRegistration

PropertyTypeRequiredDescriptionValues
urlstring (uri)yes

Webhook

PropertyTypeRequiredDescriptionValues
idstringyes
urlstring (uri)yes
secretstringnoHex signing secret for X-Signature. Returned once at registration.
createdAtstring (date-time)yes

VerificationKeys

PropertyTypeRequiredDescriptionValues
keysarray of VerificationKeyyes

VerificationKey

PropertyTypeRequiredDescriptionValues
keyIdstringyesFirst 8 bytes of the public key's SHA-256, hex.
algorithmstringyes"Ed25519"
publicKeystringyesRaw 32-byte Ed25519 public key, base64.
statusstringnocurrent signs new verdicts; previous is a key a rotation retired, kept published for at least the re-check window so verdicts signed before the rotation keep verifying (select the key by keyId, never by position)."current", "previous"

ScopeVocabulary

The delegation vocabulary carried on chain (mintid.scope-vocabulary.v2), as read under its pinned content hash: the active scope values, the forms and canonical patterns per axis, the value units and the key-custody classes an agent offer may name. Gated values are not served.

PropertyTypeRequiredDescriptionValues
contentSha256stringyesSHA-256 (hex) of the RFC 8785 canonical JSON of the vocabulary content it was read under.
versionstringno
scopesarray of stringyesThe enumerated active values as an offer writes them (actions, mintid: categories).
axesarray of ScopeAxisno
unitsarray of ScopeValueUnitno
custodyClassesarray of stringyesKey-custody class codes, lowest rank first.

ScopeAxis

One axis of the vocabulary as an offer may write it.

PropertyTypeRequiredDescriptionValues
axisstringyes"action", "counterparty", "category", "geo"
valuesarray of stringyesThe enumerated active values of the axis (canonical form).
formsarray of ScopeFormyesThe forms (counterparty) or namespaces (category, geo) and their canonical patterns.

ScopeForm

PropertyTypeRequiredDescriptionValues
formstringyes
patternstringyesThe canonical pattern a value of this form matches.

ScopeValueUnit

PropertyTypeRequiredDescriptionValues
codestringyes
minorExponentintegeryes

AgentBundleCatalogue

ZadQ's bundle catalogue as served to the dashboard: identifier and version, the vocabulary it is written against, the content digest (SHA-256 of the RFC 8785 canonical form, hex) and the bundles with ZadQ's price line.

PropertyTypeRequiredDescriptionValues
versionstringyes<namespace>.agent-bundles[.<name>].v<N>; ZadQ's namespace is zadq.
vocabularystringyes
digeststringyesLowercase hex SHA-256 of the catalogue's canonical form.
bundlesarray of AgentBundleyes
servedByIssuerbooleanyesWhether the network's issuer serves this catalogue (same id and digest). False also when its catalogue could not be read.
servedCataloguestringnoThe id of the catalogue the issuer serves, when read.

AgentBundle

One named, bounded scope an agent credential is minted from.

PropertyTypeRequiredDescriptionValues
bundleIdstringyes
descriptionstringyes
assuranceGradeMinintegeryesThe lowest backing grade (the principal's KYC grade) an agent of this bundle may be minted at.
keyCustodyMinstringyes
leaseSecondsAgentBundleRangeyes
actionsarray of stringyesThe actions every agent of the bundle is granted (never agent.delegate).
categoriesAgentBundleCategoriesyes
regionsAgentBundleRegionsyes
counterpartyAgentBundleCounterpartyyes
limitsobjectyesPer value unit (EUR, USD, USDC, EURC), the per-transaction limit in minor units — the default when the offer names none and the highest it may ask for.
defaultUnitstringyes
priceAgentBundlePriceno

AgentBundleRange

PropertyTypeRequiredDescriptionValues
defaultinteger (int64)yes
maxinteger (int64)yes

AgentBundleCategories

Categories the operator may choose from at mint (mcc:NNNN or mintid:<code>), the ones used when it chooses none, and how many one agent may carry.

PropertyTypeRequiredDescriptionValues
allowedarray of stringyes
defaultarray of stringyes
maxintegeryes

AgentBundleRegions

Regions the operator may choose from at mint (iso3166-1:XX or iso3166-2:XX-YYY; at least one is required) and how many one agent may carry.

PropertyTypeRequiredDescriptionValues
allowedarray of stringyes
maxintegeryes

AgentBundleCounterparty

The named counterparty forms the operator may list at mint and how many one agent may carry; the counterparties themselves are chosen per mint.

PropertyTypeRequiredDescriptionValues
formsarray of stringyesbIP-0004 named counterparty forms: merchant, url, caip10, verifier.
maxintegeryes

AgentBundlePrice

ZadQ's price line for the bundle, in minor units of its unit; absent when the bundle is unpriced.

PropertyTypeRequiredDescriptionValues
amountMinorinteger (int64)yes
unitstringyes

MetricsReport

PropertyTypeRequiredDescriptionValues
schemastringyesThe wire shape's name (published-metrics/v1).
computedAtstring (date-time)yes
asOfstring (date)yesThe cut-off — the last day of the last complete month (UTC). Partial months are never published.
periodMetricsPeriodno
cadenceobjectyes
cadence.publicationstringyesmonthly.
cadence.snapshotstringyesquarterly, aligned to the two-consecutive-quarters clock.
relatedPartybooleanyesAlways true — the operator's position is a property of the dataset.
operatorMetricsOperatoryes
seriesarray of MetricsSeriesyes
contextNotestringyes

MetricsPeriod

Inclusive month range, YYYY-MM at both ends. Absent while no complete month holds a record.

PropertyTypeRequiredDescriptionValues
fromstringyes
tostringyes

MetricsOperator

PropertyTypeRequiredDescriptionValues
servicestringyes
operatorstringyes
relatedPartybooleanyes
positionstringyes
disclosurestringyesThe canonical metrics disclosure, embedded in every report.
managedLinestringyesThe managed-line related-party sentence the corpus adds for every published dataset (seed section 6 v1.34; ZADQ-392), embedded in every report.

MetricsSeries

PropertyTypeRequiredDescriptionValues
idstringyes"sellers_attested", "retention_r90", "verifications_free_path", "independent_verifiers", "anchor_service_revenue"
titlestringyes
disciplinestringyes"registry-based", "aggregate", "context"
definitionstringyes
relatedPartybooleanyesAlways true, on every series.
periodMetricsPeriodno
availablebooleanyesFalse when the records hold no source for the series; unavailableReason says why and points is empty.
unavailableReasonstringno
pointsarray of MetricsPointyes

MetricsPoint

One month-end observation. Which fields carry a value depends on the series: cumulative, active, independent (sellers_attested); cohort, retained, r (retention_r90; r absent while the cohort is empty); count, registrations (independent_verifiers); count (verifications_free_path: reads served on the free path in the month, summed from the per-minute counters — never one read at a time).

PropertyTypeRequiredDescriptionValues
periodstringyesYYYY-MM.
cumulativeintegerno
activeintegerno
independentintegerno
cohortintegerno
retainedintegerno
rnumbernoRatio, two decimals.
countintegerno
registrationsintegerno

Problem

RFC 9457 problem details.

PropertyTypeRequiredDescriptionValues
typestringno
titlestringno
statusintegerno
detailstringno
instancestringno

V1Error

The /v1 error envelope (platform API v1 §5). Value-free: fields (400 person_invalid, profile_invalid) maps a field path to a code and missing (409 profile_incomplete) lists field paths — never a value.

PropertyTypeRequiredDescriptionValues
errorstringyessession_required · passkey_required · last_passkey · ceremony_invalid · attestation_invalid · assertion_invalid · email_operational_invalid · body_invalid · origin_refused · not_found · not_available · internal · runtime_token_invalid · approval_not_pending · result_already_taken · declaration_invalid · request_invalid · cursor_invalid · rate_limited · offer_refused:<issuer code> (ZADQ-289) · kyc_current · kyc_required · entry_fee_due · reverification_required · invalid_state · sandbox_hint_not_available · invalid_sandbox_hint · issuer_unavailable (ZADQ-316) · kyc_grade_below_bundle (ZADQ-321) · person_invalid · profile_invalid · profile_incomplete · kind_locked · terms_changed · business_use_required · reauth_required (ZADQ-307) · account_blocked (ZADQ-311) · custody_version_conflict · last_wrap · passkey_not_on_account (ZADQ-293) · wraps_required (ZADQ-293, v1.3.2) · origin_invalid · key_invalid · private_key_refused · origin_in_use · key_reused · evidence_required · obligations_not_published · obligations_changed (ZADQ-362, v1.3.13) · mintid_unavailable (503, ZADQ-407: MintID unreachable since the start-up and the ids not discovered yet; nothing recorded, retry later)
detailstringyes
custody_versioninteger (int64)no409 custody_version_conflict (§5.8, v1.3.2) — the stored version, to read and retry on.
fieldsobjectnoThe refused fields by path (400 person_invalid, profile_invalid).
missingarray of stringnoThe field paths a payment still needs (409 profile_incomplete).

PasskeyRegisterOptionsRequest

PropertyTypeRequiredDescriptionValues
new_accountobjectnoWith no session, the account the registration creates. kind (default organisation, so a v1.2 front still works) and country seed the customer record (ZADQ-307 §2.2); the kind may change until the first payment.
new_account.namestringyesThe organisation's label in the dashboard.
new_account.kindNewAccountKindno
new_account.countrystringnoISO 3166-1 alpha-2, the country of registration.
new_account.referralall of ReferralParamsnov1.3.14 (§5.16): the door the sign-up came through — the landing URL's parameters. Checked here (404 referral_unknown, 409 referral_closed; 501 not_available while the door is off) and recorded in the account's transaction at the finish (account_referred).
consentsall of ConsentsUpdatenoThe consents given at Create your account (ZADQ-307 §2.3), recorded in the account's own transaction when the registration finishes. Checked here: 409 terms_changed for a stale Terms version or hash, 400 business_use_required for business_use: false. Only with new_account.
labelstringnoThe passkey's label (e.g. the device).

AccountKind

A legal entity, or a natural person acting for their trade, business or profession. Consumers are not customers.

Type: string, one of "organisation", "sole_trader".

PasskeyCeremonyOptions

PropertyTypeRequiredDescriptionValues
publicKeyobjectyesWebAuthn PublicKeyCredentialCreationOptions or RequestOptions (JSON, base64url binaries).

PasskeyRegisterRequest

PropertyTypeRequiredDescriptionValues
attestationobjectyesThe PublicKeyCredential the browser answered (toJSON form).

PasskeyLoginRequest

PropertyTypeRequiredDescriptionValues
assertionobjectyesThe PublicKeyCredential the browser answered (toJSON form).

PasskeyRegistered

PropertyTypeRequiredDescriptionValues
passkey_idstringyes
prf_supportedbooleanyes
session_expires_atstring (date-time)yes

PasskeySessionOpened

PropertyTypeRequiredDescriptionValues
session_expires_atstring (date-time)yes

Me

PropertyTypeRequiredDescriptionValues
accountMeAccountyes
personMePersonyes
passkeysarray of MePasskeyyes
payto_bindingsarray of MePaytoBindingyes
productsMeProductsyes
biometric_consentMeBiometricConsentyes

MeBiometricConsent

The consent to the face comparison (ZADQ-331): the label of the consent text the deployment requires now (BIOMETRIC_CONSENT_VERSION) — the page shows that text and no other — and the last consent the account's person gave (on the account or on one of its records), null before any. A last_given.version other than version_required means the text changed since: the next verification asks again.

PropertyTypeRequiredDescriptionValues
version_requiredstringyes
last_givenall of BiometricConsentLastyes

BiometricConsentLast

PropertyTypeRequiredDescriptionValues
versionstringyes
atstring (date-time)yes

MeAccount

PropertyTypeRequiredDescriptionValues
idstringyes
namestring, nullableyesThe account's label; null for a migrated account until the person names it.
kindAccountKindyes
erasure_requested_atstring (date-time), nullableyesWhen the person requested the erasure of the account's data (ZADQ-307 §2.4); null otherwise.
blocked_atstring (date-time), nullablenoSince when the account is blocked (ZADQ-311): an erasure request or the contract's end. While set, the customer record is not served (409 account_blocked on the record routes) and the person's names and e-mail read null here.
closes_atstring (date-time), nullablenoWhen the account closes after an erasure request (ZADQ-311): the end of the current billing period at the provider, or the moment the close was scheduled when nothing is billed periodically. Null until the retention job schedules it.
referralall of AccountReferralnov1.3.14 (§5.16) — the referral the account arrived through (the first recorded); null otherwise.
created_atstring (date-time)yes

MePerson

The responsible person (ZADQ-307 §2.1): names, operational e-mail and preferred language — the customer record's, never KYC data. No phone, no identity-verification data and no job title (data minimisation).

PropertyTypeRequiredDescriptionValues
idstringyes
given_namestring, nullableyes
family_namestring, nullableyes
email_operationalstring, nullableyesThe operational contact address; never KYC data.
preferred_languagestringyesISO 639-1, from the service's supported set (en, es, ca, et, de, fr, it, pt, nl); en by default.
kycMeKycyes

MeKyc

PropertyTypeRequiredDescriptionValues
statestringyesnone before any session."none", "pending", "approved", "rejected", "expired", "withdrawn"
session_idstringnoThe issuer's KYC session handle (opaque).
gradeinteger, nullableyesThe assurance grade of the approved session (ZADQ-321); null while unknown.
reusable_untilstring (date-time), nullableyes
reverification_offerMeKycReverificationOfferno

MeKycReverificationOffer

v1.3.10 (ZADQ-336): present while the Issuer operator's answer to a review or a rectification offered a re-verification and the person has not opened it yet. Show it as for a due re-verification: the person's next POST /v1/kyc/sessions opens it (after its own steps, the consent step included), at no cost — charge reads none.

PropertyTypeRequiredDescriptionValues
session_idstringyesThe session handle the re-verification renews.
offered_atstring (date-time)yes
chargestringyes"none"

MePasskey

PropertyTypeRequiredDescriptionValues
idstringyes
credential_idstringyesThe passkey's WebAuthn credential id, base64url without padding (the browser's prf.evalByCredential key; ZADQ-293).
labelstring, nullableyes
prf_supportedbooleanyes
created_atstring (date-time)yes

MePaytoBinding

PropertyTypeRequiredDescriptionValues
paytostringyesThe wallet address.
chainstringyes
bound_atstring (date-time)yes

MeProducts

PropertyTypeRequiredDescriptionValues
vendorMeVendorProductyes
agent_operatorMeAgentOperatorProductyes
verifierMeVerifierProductyes

MeProductState

pending_payment (v1.3.14, §5.16): a principal plan chosen and not paid yet.

Type: string, one of "inactive", "pending_payment", "pending_kyc", "pending_entry_fee", "active", "suspended", "closed".

MeVendorProduct

The vendor product as derived from the account's seller records (platform API v1.3 §5.9, ZADQ-324): inactive without a record; pending_kyc while an endpoint is verifying or its session expired; pending_entry_fee with an admitted endpoint whose schedule is not paid yet (the tier's hosted checkout is the vendor's entry fee); active once the provider's completed event recorded the billing, plan then the endpoint's billing tier; closed when only rejected or withdrawn records remain. The best state across the account's endpoints wins; suspended is not derived for the vendor in this version.

PropertyTypeRequiredDescriptionValues
stateMeProductStateyes
planstring, nullableyes

PlatformSellerList

PropertyTypeRequiredDescriptionValues
sellersarray of PlatformSelleryes

PlatformSeller

One seller record of the account as the dashboard lists it (platform API v1.3 §5.9): the v0 record's public facts in the v1 spelling. Endpoint identifiers and states only — never identity data.

PropertyTypeRequiredDescriptionValues
idstringyes
chainChainyes
paytostringyesThe payTo address.
resource_urlstring (uri)yes
operator_typestringyes"person", "organisation"
statestringyes"pending_kyc", "kyc_expired", "admitted", "rejected", "withdrawn"
terms_acknowledgedbooleanyesWhether the current terms version is acknowledged by the payTo's wallet (GET /v0/sellers/{id}/terms carries the message to sign when not).
billingstringyesBilling state at the operator's billing provider, as GET /v0/sellers/{id} serves it."none", "active"
billing_tierstringno"attested_vendor", "regulated_compliance"
billing_cadencestringno"monthly", "annual"
kycKycHandoffno
attestationAttestationno
credentialCredentialStateno
verdictVerdictno
created_atstring (date-time)yes

MeAgentOperatorProduct

PropertyTypeRequiredDescriptionValues
stateMeProductStateyes
planstring, nullableyes
seatsobjectyes
seats.usedintegeryes
seats.planinteger, nullableyes
seats.cap_per_personintegeryes
mints_this_hourobjectyes
mints_this_hour.usedintegeryes
mints_this_hour.allowedintegeryes
principal_planMePrincipalPlanno
enterpriseMeEnterpriseno

MeEnterprise

v1.3.30 (ZADQ-472, §5.20) — the account's Enterprise contract, as ZadQ activated it from the operator console once agreed: the seats agreed (products.agent_operator.seats.plan is the same number bounded by the issuer's cap per person), the period billed in advance, how its lines are collected (invoice: on the provider's invoice or ZadQ's manual invoice — never paid from the app), the end of the period paid where the record knows it, and its end once stopped. Absent on any other plan. Never an amount: the contract's amount is on its invoice.

PropertyTypeRequiredDescriptionValues
seatsintegeryes
periodstringyes"month", "year"
channelstringyes"invoice"
paid_untilstring (date-time), nullableno
ends_atstring (date-time), nullableno

MePersonUpdate

PATCH /v1/me/person (ZADQ-307 §2.1): any of the fields; null clears a name or the e-mail. Unknown fields answer 400 body_invalid; 400 person_invalid with fields: {<field>: required | too_long | invalid} otherwise.

PropertyTypeRequiredDescriptionValues
given_namestring, nullableno
family_namestring, nullableno
email_operationalstring, nullableno
preferred_languagestringno

Organisation

The organisation (or the sole trader's trade) as the responsible person declared it. Nothing here was verified by a register check; vat_id.status is VIES's answer.

PropertyTypeRequiredDescriptionValues
kindAccountKindyes
legal_namestring, nullableyesRequired to save; for a sole trader the trading name or the person's own name, as on their tax registration.
trade_namestring, nullableyes
legal_formstring, nullableyes
registration_numberstring, nullableyesThe national business-register number as declared (EE registry code, ES Registro Mercantil entry, DE HRB, FR SIREN…).
countrystring, nullableyesISO 3166-1 alpha-2, the country of registration.
vat_idall of OrganisationVatIdyes
tax_idall of OrganisationTaxIdyes
registered_addressall of OrganisationAddressyes
invoice_emailstring, nullableyesThe invoicing address; the operational e-mail is used when absent.
completebooleanyes
missingarray of stringyesThe field paths a payment still needs, e.g. registered_address.line1, tax_id.

OrganisationVatId

PropertyTypeRequiredDescriptionValues
valuestringyesThe EU VAT number with its ISO prefix (Greece EL), normalised.
statusstringyes"valid", "invalid", "unchecked", "unavailable"
checked_atstring (date-time), nullableyes

OrganisationTaxId

PropertyTypeRequiredDescriptionValues
schemestringyeses_nif covers the Spanish NIF, NIE and the entity NIF formerly called CIF (format and control character checked); other is free text."es_nif", "other"
valuestringyes

OrganisationAddress

PropertyTypeRequiredDescriptionValues
line1string, nullableyes
line2string, nullableyes
postal_codestring, nullableyes
citystring, nullableyes
regionstring, nullableyes
countrystring, nullableyesISO 3166-1 alpha-2.

OrganisationUpdate

PUT /v1/organisation — the full object minus the computed fields.

PropertyTypeRequiredDescriptionValues
kindAccountKindno
legal_namestringyes
trade_namestring, nullableno
legal_formstring, nullableno
registration_numberstring, nullableno
countrystringyes
vat_idstring, nullablenoThe EU VAT number with its ISO prefix; checked against VIES on write. On PUT the record's own shape {value, status?, checked_at?} is accepted too — the contract's "object minus the computed fields" (zadq.app sends it); the computed fields are ignored.
tax_idall of OrganisationTaxIdno
registered_addressall of OrganisationAddressno
invoice_emailstring, nullableno

Consents

The current view of the account's append-only consents log (addendum §1).

PropertyTypeRequiredDescriptionValues
termsobject, nullableyes
terms.versionstringyes
terms.sha256stringyes
terms.accepted_atstring (date-time)yes
privacy_noticeobject, nullableyesThe Privacy Policy version shown — information, never a consent.
privacy_notice.versionstringyes
privacy_notice.shown_atstring (date-time)yes
business_useobject, nullableyes
business_use.atstring (date-time)yes
marketingobjectyes
marketing.opt_inbooleanyes
marketing.atstring (date-time), nullableyes

ConsentsUpdate

Any of the four; each appends to the log.

PropertyTypeRequiredDescriptionValues
termsobjectno
terms.versionstringyes
terms.sha256stringyes
privacy_noticeobjectno
privacy_notice.versionstringyes
business_usebooleannoThe declaration "I act for my business or profession"; false is refused (400 business_use_required).
marketingbooleanno

LegalCurrent

PropertyTypeRequiredDescriptionValues
termsobjectyes
terms.versionstringyes
terms.sha256stringyes
terms.urlstringyes
terms.effective_atstring (date-time)yes
privacyobjectyes
privacy.versionstringyes
privacy.urlstringyes
privacy.effective_atstring (date-time)yes

LegalUpcoming

PropertyTypeRequiredDescriptionValues
termsarray of LegalUpcomingTermsyes
privacyarray of LegalUpcomingPrivacyyes

LegalUpcomingTerms

PropertyTypeRequiredDescriptionValues
versionstringyes
sha256stringyes
urlstringyes
published_atstring (date-time)yes
effective_atstring (date-time)yes
required_by_lawbooleanyesThe change is required by law and applies from its entry into force (Terms clause 20).

LegalUpcomingPrivacy

PropertyTypeRequiredDescriptionValues
versionstringyes
urlstringyes
published_atstring (date-time)yes
effective_atstring (date-time)yes

ChangeNotices

PropertyTypeRequiredDescriptionValues
noticesarray of ChangeNoticeyes

ChangeNotice

One account's notice of a legal version (ZADQ-313). accepted (Terms only) is true when the account accepted this version or a later one; seen_at (Privacy Policy only) is the dismissal; mailed_at is when the e-mail to the Responsible Person went out (null until then, or without an operational e-mail).

PropertyTypeRequiredDescriptionValues
idstringyes
kindstringyes"terms", "privacy"
versionstringyes
urlstringyes
effective_atstring (date-time)yes
in_forcebooleanyesThe version applies already.
openbooleanyesThe notice still asks for something — the acceptance, or reading it.
sha256string, nullableyesThe Terms version's SHA-256, to accept it with (null for the Privacy Policy).
required_by_lawbooleanyes
acceptedboolean, nullableyes
seen_atstring (date-time), nullableyes
mailed_atstring (date-time), nullableyes

LegalTermsText

PropertyTypeRequiredDescriptionValues
versionstringyes
sha256stringyes
textstringyes

ErasureState

PropertyTypeRequiredDescriptionValues
statestringyes"requested"
atstring (date-time)yes

ApprovalKind

Type: string, one of "delegate", "present", "renew".

ApprovalState

Type: string, one of "pending", "approved", "declined", "expired", "failed".

ApprovalSummary

PropertyTypeRequiredDescriptionValues
idstringyes
kindApprovalKindyes
stateApprovalStateyes
created_atstring (date-time)yes
expires_atstring (date-time)yes
summarystringyesOne line for the inbox (the agent's name and bundle, or the purpose).

ApprovalList

PropertyTypeRequiredDescriptionValues
approvalsarray of ApprovalSummaryyes

Approval

PropertyTypeRequiredDescriptionValues
idstringyes
kindApprovalKindyes
stateApprovalStateyes
created_atstring (date-time)yes
expires_atstring (date-time)yes
decided_atstring (date-time)no
failurestringnoThe reason code of a failed approval (e.g. offer_refused:session_reuse_expired, result_not_taken).
result_takenbooleannoPresent approvals only — the holder's result was delivered to the operator's poll (and deleted).
delegateApprovalDelegateno
presentApprovalPresentno
renewApprovalRenewno

ApprovalDelegate

PropertyTypeRequiredDescriptionValues
enrolment_idstringyes
namestringyesThe agent's name in the operator's runtime.
bundlestringyes
bundle_paramsobjectyes
lease_secondsintegeryes
price_linestring, nullableyesThe agent's recorded price line id (/v1/price-lines) where a deployment recorded one, null otherwise — and null on a principal plan (personal, premium; §5.16), which includes its bounded agents (ZADQ-423) — no line, no price clause, nothing authorised on a card.
principal_modePrincipalModeno

PrincipalMode

Where the person's holder answers (ZADQ-294); absent reads as runtime.

Type: string, one of "runtime", "browser".

ApprovalRenew

PropertyTypeRequiredDescriptionValues
agent_idstringyes
enrolment_idstring, nullablenoThe renewal's own enrolment (ZADQ-294) — where a browser-mode renewal's material is posted (POST /v1/enrolments/{id}/mint) and a late offer collected (POST /v1/enrolments/{id}/offer). Null on renewals opened before 2026-10-18.
namestringyes
bundlestringyes
lease_secondsintegeryes
price_linestring, nullableyesThe lease price line's id (/v1/price-lines), null until billing records one — and null on a principal plan (personal, premium; §5.16), which includes its bounded agents' leases (ZADQ-423).
principal_modePrincipalModeno

ApprovalPresent

PropertyTypeRequiredDescriptionValues
purposestringyes
fromApprovalFromyes
declarationPresentDeclarationyes
principal_modePrincipalModeno

ApprovalFrom

PropertyTypeRequiredDescriptionValues
agent_idstringno
enrolment_idstringno
runtimeobjectyes
runtime.kindstringyes
runtime.instance_refstringyes

PresentDeclaration

The verifier's declaration — never a challenge.

PropertyTypeRequiredDescriptionValues
profilestringyes
verifier_originstringyesThe verifier's origin (https; http on loopback only).
challenge_endpointstringyesWhere the holder fetches the challenge after approval; on the origin's host or a subdomain.
claim_policyarray of ClaimRuleyes
issuer_policyanyyesThe verifier's accepted issuers, as the verifier states them.

ClaimRule

PropertyTypeRequiredDescriptionValues
claimstringyes
operatorstringno
valueanyyesThe policy's threshold or value set, as the verifier states it.

PresentApprovalRequest

PropertyTypeRequiredDescriptionValues
kindstringyes"present"
purposestringyes
declarationPresentDeclarationyes
expires_in_sintegerno
principal_modePrincipalModeno

PresentApprovalCreated

PropertyTypeRequiredDescriptionValues
idstringyes
stateApprovalStateyes
expires_atstring (date-time)yes

ApproveRequest

PropertyTypeRequiredDescriptionValues
assertionobjectyesThe PublicKeyCredential the browser answered to the login options (toJSON form).

ApprovalDecided

PropertyTypeRequiredDescriptionValues
stateApprovalStateyes
offerobjectnoBrowser-mode delegate or renew only (ZADQ-294), once: the issuer's agent offer for the browser's credential step — {credential_offer, mint_challenge, expires_at, scope, bundle}, the operator's price line stripped. Never stored or logged.
offer_expires_atstring (date-time)no

HolderFailure

PropertyTypeRequiredDescriptionValues
failurestringyesA code of the closed vocabulary (ZADQ-294), never a value.

BrowserOffer

PropertyTypeRequiredDescriptionValues
offerobjectyesThe issuer's agent offer, the operator's price line stripped (the runtime-mode material shape).
expires_atstring (date-time)yes

EnrolmentMintRequest

Exactly one of mint and failure.

PropertyTypeRequiredDescriptionValues
mintMintMaterialno
failurestringnoA code of the closed vocabulary instead of a material.

MintMaterial

The split mint's material, MintID's stage-2 interface v1.1 §1 (MintMaterial.to_json()): one use at the issuer, nothing of the principal. A bearer: held sealed only until the runtime's poll takes it, never logged.

PropertyTypeRequiredDescriptionValues
vintegeryes1
issuer_urlstringyes
credential_configuration_idstringyes"mintid_agent_v1", "mintid_agent_v2"
access_tokenstringyes
c_noncestringyes
expires_atinteger (int64)yesUnix seconds; the issuer's offer lifetime (token_ttl_seconds, 300).
scopearray of objectyes
scope[].axisstringyes
scope[].valueanyyes
scope[].value_idstringyes
scope_endpointstringyes
bundle_idstring, nullableno
renews_credential_idstring, nullableno

ApprovalPoll

PropertyTypeRequiredDescriptionValues
stateApprovalStateyes
failurestringno
resultPresentResultno

PresentResult

The holder's result, passed through once: the verifier's session id, the verifier's own signed request (it keeps none by session id) and the presentation envelope. ZadQ never reads inside it.

PropertyTypeRequiredDescriptionValues
session_idstringyes
requestobjectyes
envelopeanyyesThe presentation envelope, opaque to ZadQ.

ActivityPage

PropertyTypeRequiredDescriptionValues
eventsarray of ActivityEventyes
next_cursorstringno

ActivityEvent

PropertyTypeRequiredDescriptionValues
atstring (date-time)yes
kindstringyes"passkey_added", "passkey_removed", "kyc_opened", "kyc_approved", "kyc_withdrawn", "product_activated", "enrolment_created", "enrolment_claimed", "approval_decided", "agent_registered", "agent_usable", "agent_stopped", "agent_renewed", "price_line_captured", "price_line_credited", "agent_reconciled", "agent_drift", "data_exported", "erasure_requested", "custody_uploaded", "custody_wrap_added", "custody_wrap_removed", "custody_revoked", "biometric_consent_given", "kyc_reverification_offered", "verifier_requested", "verifier_evidence_uploaded", "verifier_admission_requested", "verifier_key_rotated", "verifier_withdrawn", "verifier_admission_filed", "verifier_admission_decided", "verifier_commitment_recorded", "verifier_door_declared", "account_referred", "plan_chosen", "plan_period_opened", "verifier_line_opened", "verifier_line_voided", "plan_step_opened", "plan_switched", "relying_party_line_opened", "plan_refund_opened", "plan_refunded", "verifier_evidence_renewed", "verifier_evidence_renewal_checked", "enterprise_activated", "enterprise_stopped"
statestringno
reason_codestringno
refobjectyesAt most one reference.
ref.enrolment_idstringno
ref.agent_idstringno
ref.approval_idstringno
ref.verifier_idstringnoThe verifier record (ZADQ-362, §5.15); on account_referred (ZADQ-365, §5.16) the refusing service's record.
actorstringyes"person", "runtime", "zadq", "issuer"

EnrolmentState

Type: string, one of "created", "claimed", "approved", "minting", "registered", "expired", "cancelled", "declined", "failed".

EnrolmentKind

Type: string, one of "enrol", "renewal".

EnrolmentRuntime

PropertyTypeRequiredDescriptionValues
kindstringyesThe runtime's software, e.g. mas-library-mintid (lowercase, digits, ., _, -).
versionstringno
instance_refstringyesThe operator's own reference of the runtime instance; never a person's.

EnrolmentRequest

PropertyTypeRequiredDescriptionValues
namestringyesThe agent's name in the runtime, e.g. trip-planner/concierge_agent.
bundlestringnoA bundle of the issuer's served catalogue (GET /v1/catalogue); required unless referral_id presets it.
referral_idstringnov1.3.14 (§5.16) — the first bounded agent preset from one of the account's referrals: the bundle (when left out; else it must be the referral's) and the refusing service's origin as a counterparty (added when left out). 404 referral_unknown; 409 referral_closed; 400 bundle_params_invalid for another bundle.
bundle_paramsEnrolmentBundleParamsyes
lease_secondsintegerno
principal_modestringyes"runtime", "browser"

EnrolmentBundleParams

PropertyTypeRequiredDescriptionValues
counterpartiesarray of stringyes
geoarray of stringyes
categoriesarray of stringno
limit_unitstringno
transaction_limit_minorinteger (int64)no

EnrolmentCreated

PropertyTypeRequiredDescriptionValues
idstringyes
codestringyesThe one-time code (8 characters), shown once.
claim_urlstringyesThe app's origin with the code in the fragment (<origin>/claim#<code>), for the QR code.
expires_atstring (date-time)yes

EnrolmentSummary

PropertyTypeRequiredDescriptionValues
idstringyes
kindEnrolmentKindyes
namestringyes
stateEnrolmentStateyes
bundlestringyes
created_atstring (date-time)yes
expires_atstring (date-time)yesThe code's expiry (enrol), or the material's / the approval's (renewal).
agent_idstringno
failurestringno

EnrolmentList

PropertyTypeRequiredDescriptionValues
enrolmentsarray of EnrolmentSummaryyes

Enrolment

PropertyTypeRequiredDescriptionValues
idstringyes
kindEnrolmentKindyes
namestringyes
stateEnrolmentStateyes
bundlestringyes
bundle_paramsEnrolmentBundleParamsyes
lease_secondsintegeryes
principal_modestringyes"runtime", "browser"
runtimeEnrolmentRuntimeno
approval_idstringno
agent_idstringno
price_linestringnoThe price line's id (§5.3); absent on a principal plan (§5.16), which includes its bounded agents (ZADQ-423).
failurestringnoThe reason code of a failed enrolment (e.g. token_expired, offer_refused:session_reuse_expired).
offer_readybooleannoBrowser mode (ZADQ-294) — an offer waits for the person's browser to collect it (POST …/offer).
referral_idstringnov1.3.14 (§5.16) — the referral the enrolment was preset from.
created_atstring (date-time)yes
expires_atstring (date-time)yes

EnrolmentClaimRequest

PropertyTypeRequiredDescriptionValues
codestringyes
runtimeEnrolmentRuntimeyes
key_attestationobjectnoAccepted, not used, not kept (ZadQ sends the issuer no attestation evidence).

EnrolmentClaimed

PropertyTypeRequiredDescriptionValues
enrolment_idstringyes
runtime_tokenstringyesThe runtime credential (rt1_…), shown once; sent as Authorization: Bearer on the runtime routes.
expires_atstring (date-time)yesWhen the delegate approval expires (keep polling until then).

EnrolmentPoll

PropertyTypeRequiredDescriptionValues
stateEnrolmentStateyes
failurestringno
agent_idstringno
mintobjectnoThe mint material, once (runtime mode: the issuer's agent offer, the price line stripped; browser mode: the browser's MintMaterial, ZADQ-294).

EnrolmentControlHook

PropertyTypeRequiredDescriptionValues
urlstringyeshttps on a public address; ZadQ posts a signed kill here.
secret_refstringyesThe shared secret ZadQ signs with (HMAC-SHA256); the runtime keeps its copy, ZadQ keeps it sealed.

EnrolmentRegisteredRequest

PropertyTypeRequiredDescriptionValues
credential_idstringyesThe issuer's handle of the credential (64 hex), as the holder received it.
expires_atstring (date-time)yes
scope_endpointstringno
control_hookEnrolmentControlHookno
usablebooleannoThe agent's scope is anchored (it can present its delegation); also on a later call.

EnrolmentRegistered

PropertyTypeRequiredDescriptionValues
agent_idstringyes

EnrolmentFailedRequest

PropertyTypeRequiredDescriptionValues
reason_codestringyes

EnrolmentStateAnswer

PropertyTypeRequiredDescriptionValues
statestringyes

PlatformAgentState

Type: string, one of "registered", "usable", "expiring", "revoked", "expired".

PlatformAgent

PropertyTypeRequiredDescriptionValues
idstringyes
namestringyes
bundlestringyes
bundle_paramsEnrolmentBundleParamsyes
lease_ends_atstring (date-time)yes
statePlatformAgentStateyes
enrolment_idstringyes
runtimeEnrolmentRuntimeyes
control_hookbooleanyes
issuer_statestringnoThe issuer's own state of the agent as the reconciliation last read it (ZADQ-296): active, revoked or expired. Absent until a pass matched the agent. When it disagrees with state, the issuer's is the truth the dashboard shows."active", "revoked", "expired"
issuer_reasonstringnoThe issuer's reason beside issuer_state when it is not active (a closed code, e.g. lease_expired, principal_revoked).
reconciled_atstring (date-time)noWhen the reconciliation last read the agent at the issuer.

PlatformAgentList

PropertyTypeRequiredDescriptionValues
agentsarray of PlatformAgentyes

AgentRenewalRequested

PropertyTypeRequiredDescriptionValues
approval_idstringyes

PriceLineKind

v1.3.15 (§5.17, ZADQ-373) adds the verifier product's business lines: kit_setup (the verifier kit set-up — withdrawn in v1.3.16: no longer opened, an unpaid one voided), onboarding_at_cost (the responsible person's onboarding at cost), managed_environment and managed_setup (the managed deployment). v1.3.16 (ZADQ-382) adds the relying party's principal_enrolled (one month of principals enrolled through the business's door) — since v1.3.18 (ZADQ-389) the month's rebate credit on the business's invoice, a negative amount — and the plan step kinds agent_extra and grade_a3_option, no longer opened since v1.3.25 (no deployment offers a step). None is a verification line. v1.3.17 (ZADQ-387) adds plan_refund: a principal plan's refund after its identity check ended refused or withdrawn — the amount paid back, the verification cost retained (retained_minor). v1.3.31 (ZADQ-470) adds the vendor product's lines on an account whose seller records are bound to it: vendor_entry (the entry fee paid at the tier's checkout, once per operator) and vendor_endpoint (the additional endpoints on the subscription, quantity the endpoints above the tier's quota, period month or year); ref.seller_id names the seller record. Neither is payable on /v1/price-lines/{id}/pay.

Type: string, one of "entry", "seat", "bundle_mint", "lease_year", "usage", "kit_setup", "onboarding_at_cost", "managed_environment", "managed_setup", "agent_extra", "grade_a3_option", "principal_enrolled", "plan_refund", "vendor_entry", "vendor_endpoint".

PriceLineState

v1.3.17 (ZADQ-387) adds refunded — a plan_refund line paid back (the console's mark, or the provider's refund).

Type: string, one of "open", "authorised", "captured", "invoiced", "failed", "credited", "void", "refunded".

PriceLineRef

What the line belongs to (an enrolment, an agent, a verifier record); empty for the activation's own lines.

PropertyTypeRequiredDescriptionValues
enrolment_idstringno
agent_idstringno
verifier_idstringnov1.3.15 (§5.17) — the verifier record a business line was opened for.
seller_idstringnov1.3.31 (ZADQ-470) — the seller record a vendor line belongs to.

PriceLine

PropertyTypeRequiredDescriptionValues
idstringyes
periodstring, nullablenov1.3.14 (§5.16) — the period a principal plan's seat line pays; its amount is the plan's whole price for it. v1.3.15 (§5.17) — the period a managed environment's line pays, in advance."month", "year"
environmentstring, nullablenov1.3.15 (§5.17) — a managed environment's environment; null on every other line."production", "test"
kindPriceLineKindyes
amount_minorinteger (int64), nullableyesv1.3.18 (ZADQ-389) — negative on a principal_enrolled line opened since (the month's rebate set off on the invoice; not payable).
unitstring, nullableyes
statePriceLineStateyes
refPriceLineRefyes
settlementstringyes"console", "stripe"
channelstringyesHow the line is collected (ZADQ-324, derived at read time, never stored): invoice on the console settlement (a manual invoice) and for a provider customer whose subscription collects by invoice; card otherwise (the hosted checkout). The dashboard shows "Pay" for card, "on your invoice" for invoice."card", "invoice"
quantityinteger, nullablenoSeats (seat), lease days (lease_year); v1.3.16 — the month's count of principals enrolled (principal_enrolled); v1.3.18 — on a rebate credit, the rebates settled in the month.
bundlestring, nullableno
vat_treatmentstring, nullablenov1.3.16 (ZADQ-382) — how the amount stands to VAT, on the lines opened since (null on the lines before). v1.3.29 (ZADQ-469) — every amount is net, ex-VAT: a line opens exclusive (the billing provider adds the VAT at checkout and on the invoice) or reverse_charge (the same net, no VAT, for a business whose customer record holds a valid VAT number of another member state). included is a legacy value: it is never opened now and stays only on lines opened before v1.3.29."included", "reverse_charge", "exclusive"
covers_untilstring (date-time), nullablenov1.3.16 — the end of the period a step's line (agent_extra, grade_a3_option) pays, from its settlement; null until settled and on every other line. No step is offered since v1.3.25.
credit_minorinteger (int64), nullablenov1.3.16 — on a switch's seat line (Personal → Premium), the credit of the unused period; amount_minor is the new period's price less it.
free_quantityinteger, nullablenov1.3.16 — on a principal_enrolled line, the free volume applied to the month's count; null on a rebate credit (v1.3.18).
billing_monthstring (date), nullablenov1.3.16 — on a principal_enrolled line, the month counted (its first day); v1.3.18 — the rebate statement's month.
retained_minorinteger (int64), nullablenov1.3.17 (ZADQ-387) — on a plan_refund line, the cost of the identity check performed at the person's request, retained; amount_minor is what is paid back. v1.3.29 (ZADQ-469) — net, ex-VAT, on a line exclusive or reverse_charge: the provider's refund pays back amount_minor plus its share of the VAT the payment collected (a legacy included line keeps the amounts it was opened with).
refund_reasonstring, nullablenov1.3.17 — on a plan_refund line, why the plan closed (ZadQ's own code; nothing of the issuer's reason); v1.3.34 (ZADQ-472) — enterprise_replaces_paid_plan, the paid plan replaced by an Enterprise contract (its unused period paid back by hand)."identity_check_refused", "identity_check_withdrawn", "enterprise_replaces_paid_plan"
created_atstring (date-time)yes

PriceLineList

PropertyTypeRequiredDescriptionValues
linesarray of PriceLineyes

PriceLinePay

PropertyTypeRequiredDescriptionValues
return_tostringnoThe dashboard's account page the hosted checkout returns to (account, verification, agent-operator (default), enrolments, approvals, agents, billing, activity)."account", "verification", "agent-operator", "enrolments", "approvals", "agents", "billing", "activity"

PriceLinePayment

PropertyTypeRequiredDescriptionValues
checkout_urlstringnoThe billing provider's hosted checkout page.
statePriceLineStateno

ActivateAgentOperator

PropertyTypeRequiredDescriptionValues
planstringyesA principal plan's id (personal, premium — v1.3.16; plus is retired). v1.3.30 — enterprise answers 409 plan_by_contact (the console activates it, §5.20).
periodstringnov1.3.14 (§5.16) — the principal plan's billing period, in advance (default year; on a switch, the current one)."month", "year"

PlanStepOpen

PropertyTypeRequiredDescriptionValues
kindstringyes"agent_extra", "grade_a3_option"
periodstringnoBilled in advance; the plan's period when left out."month", "year"

PlanRefund

v1.3.17 (ZADQ-387; Marc's answer of 2026-10-29: "retain the verification cost, refund the rest") — the plan closed because its identity check ended refused (identity_check_refused) or was withdrawn after it started (identity_check_withdrawn). line is the plan_refund line (its amount_minor paid back, its state open until paid back, then refunded); paid_minor what the refund is computed from — the amount paid on the plan for the first check, the unused period for a re-check; retained_minor the cost of the identity check performed at the person's request (retained_for: identity_check_performed).

PropertyTypeRequiredDescriptionValues
linePriceLineyes
reasonstringyes"identity_check_refused", "identity_check_withdrawn"
paid_minorinteger (int64)yes
retained_minorinteger (int64)yes
retained_forstringyes"identity_check_performed"

PlanSwitch

v1.3.16 (ZADQ-382) — a switch Personal → Premium asked; the plan stays Personal until line is paid.

PropertyTypeRequiredDescriptionValues
tostringyes"premium"
linePriceLineyes

AgentOperatorActivation

PropertyTypeRequiredDescriptionValues
statestringyes"pending_payment", "pending_kyc", "pending_entry_fee", "active", "suspended", "closed"
periodstring, nullablenov1.3.14 — the principal plan's period."month", "year"
plan_lineall of PriceLinenov1.3.14 — the principal plan's seat line for the period (pay it with POST /v1/price-lines/{id}/pay).
planstringyes
settlementstringno"console", "stripe"
entry_feeall of PriceLineyesv1.3.30 (ZADQ-472) — always null; no entry fee is sold (kept in the shape for the client app).
plan_switchall of PlanSwitchnov1.3.16 — the switch Personal → Premium waiting on its line; null otherwise.

CataloguePlan

PropertyTypeRequiredDescriptionValues
idstringyes
seatsintegeryes
labelstringyes
kindstringnov1.3.14 — principal for the principal plans (v1.3.16 Personal and Premium; §5.16; amounts on GET /v1/plans). v1.3.30 (ZADQ-472) — contact for enterprise, sold by contact and activated by ZadQ (§5.20); operator is gone with the earlier plans."principal", "contact"

CatalogueBundle

A bundle as the issuer serves it, on the keys the enrolment form reads (bundle_id, description, action, category, geo, counterparty, limits, lease_seconds, assurance_grade_min); never its price.

PropertyTypeRequiredDescriptionValues
bundle_idstringyes

PlatformCatalogue

PropertyTypeRequiredDescriptionValues
bundlesarray of CatalogueBundleyes
plansarray of CataloguePlanyes

KycSessionCreate

PropertyTypeRequiredDescriptionValues
sandboxstringnoStaging only: the sandbox KYC driver's outcome grammar without its sandbox: prefix (<outcome>[:<option>…], e.g. approved:g2, rejected, expired). Identity options are refused.
biometric_consentBiometricConsentGivenno

KycSession

PropertyTypeRequiredDescriptionValues
session_idstringyesThe issuer's KYC session handle (opaque).
statestringyes"pending", "approved", "rejected", "expired", "withdrawn"
handoff_urlstring, nullablenoWhere the person completes the verification at the issuer's provider; while pending, and only once a consent to the face comparison is recorded for this session (ZADQ-331) — absent (null) otherwise, with biometric_consent_required: true.
biometric_consent_requiredbooleannoWhile pending (ZADQ-331): true when no consent to the face comparison is recorded for this session (one opened before the rule) — the link is withheld until POST /v1/kyc/sessions/{id}/biometric-consent records one.
expires_atstring (date-time)noThe proofing deadline of a pending session.
gradeinteger, nullableyesThe issuer's assurance grade the approval was recorded at (ZADQ-321); null while not approved or where the boundary named none.
reusable_untilstring (date-time), nullableyesThe end of an approved session's reuse window; the principal credential expires exactly with it.
credentialKycCredentialyes

KycCredential

The responsible person's identity credential in the operator's runtime, as this service knows it: state only. expired is derived (offered or held past the verification's window); revoked: by the issuer's policy (consent withdrawn); self_revoked: by its holder, terminal on this verification.

PropertyTypeRequiredDescriptionValues
statestringyes"none", "offered", "held", "expired", "revoked", "self_revoked"
offered_atstring (date-time)no
expires_atstring (date-time)noThe verification's window end, which is the credential's.
credential_refstringnoThe runtime's own opaque reference. Never a key, a code or a proof.

KycCredentialOffer

PropertyTypeRequiredDescriptionValues
locationCustodyLocationno
offerobjectyesThe credential offer object, as the issuer returned it — opaque, one-shot; redeem it at once.
expires_atstring (date-time)yesWhen the code and the credential it yields expire — the verification's own window end at the latest. No grace.
credentialKycCredentialyes

KycCredentialReport

PropertyTypeRequiredDescriptionValues
statestringyesheld, or self_revoked (revoked is the older spelling of the same report)."held", "self_revoked", "revoked"
credential_refstringnoAn opaque reference of the runtime's choosing for the credential it holds. Never a key.

KycCredentialOfferRequest

PropertyTypeRequiredDescriptionValues
locationCustodyLocationno

CustodyLocation

Where the person's identity credential lives (MintID ADR-0027): server — the holder in the operator's runtime (stage 1); browser — the person's browser holder (stage 2). Default server.

Type: string, one of "server", "browser".

CustodyLocations

PropertyTypeRequiredDescriptionValues
credentialsarray of CustodyLocationStateyes

CustodyLocationState

One custody location's credential, state only.

PropertyTypeRequiredDescriptionValues
locationCustodyLocationyes
statestringyes"none", "offered", "held", "expired", "revoked", "self_revoked"
offered_atstring (date-time)no
issued_atstring (date-time)no
expires_atstring (date-time)noThe verification's window end, which is the credential's.
credential_refstringnoThe server location's opaque reference (the runtime's own). Never a key.
custody_versioninteger (int64)noThe browser location's stored version.
wrapsintegernoThe browser location's number of wraps (passkeys that can open it).
rotation_duebooleannoThe browser location's rotation_due (v1.3.2); absent for the server location.

BrowserCustody

The browser-location credential. ciphertext is the holder's storage bytes encrypted in the browser (base64; present on the read route only, and there absent before the first upload and after a revocation); wraps are the data key wrapped under each passkey. Opaque to this service: no key, no plaintext, no PRF output ever reaches it.

PropertyTypeRequiredDescriptionValues
idstringyes
locationCustodyLocationyes
statestringyes"offered", "held", "expired", "revoked", "self_revoked"
kyc_session_idstringnoThe session handle the credential was offered on.
schemestringyesThe browser's name for the wrap and AEAD construction (default prf-hkdf-aead-v1). Never interpreted here.
custody_versioninteger (int64)yes
rotation_duebooleanyesv1.3.2: true once a wrap went without a rotation of the data key (a wrap removed, or a passkey removed with its wrap); cleared by the next rotation (PUT with rotation: true).
ciphertextstring (byte)noBase64 of the ciphertext, as uploaded.
issuer_credential_handlestringnoThe issuer's opaque credential handle, when the browser reported it.
offered_atstring (date-time)no
issued_atstring (date-time)no
expires_atstring (date-time)no
wrapsarray of CustodyWrapyes

CustodyWrap

PropertyTypeRequiredDescriptionValues
passkey_idstringyes
prf_saltstring (byte)yesBase64 of the PRF input and HKDF salt the browser drew for this passkey (16 to 64 bytes). Not a secret; opaque here.
wrapped_dekstring (byte)yesBase64 of the data key wrapped under this passkey's PRF-derived key-encryption key (32 to 512 bytes). Opaque here.
created_atstring (date-time)yes

CustodyWrapAdd

A wrap for one more passkey, with the custody version the browser read (v1.3.2).

PropertyTypeRequiredDescriptionValues
passkey_idstringyesOne of the account's passkeys.
prf_saltstring (byte)yes
wrapped_dekstring (byte)yes
custody_versioninteger (int64)yesThe version the browser read; the addition advances it by one.

CustodyWrapInput

PropertyTypeRequiredDescriptionValues
passkey_idstringyesOne of the account's passkeys.
prf_saltstring (byte)yes
wrapped_dekstring (byte)yes

BrowserCustodyUpload

PropertyTypeRequiredDescriptionValues
ciphertextstring (byte)yesBase64 of the encrypted holder record (1 to 262144 bytes decoded).
custody_versioninteger (int64)yesThe version the browser read; 0 on the first upload. The stored version advances by one.
schemestringno
issuer_credential_handlestringnoThe issuer's opaque credential handle. Never a key, a code or a proof.
issued_atstring (date-time)no
wrapsarray of CustodyWrapInputnoRequired on the first upload (at least one); on a rotation the wrap of every passkey that stays, under the new data key (empty: 409 last_wrap); refused on a later plain upload.
rotationbooleannov1.3.2: this upload rotates the data key — the ciphertext and every wrap replaced in one write, wraps not listed removed, rotation_due cleared.

BrowserCustodyReport

PropertyTypeRequiredDescriptionValues
statestringyes"revoked", "self_revoked"

PinnedVerifierKeys

PropertyTypeRequiredDescriptionValues
recordsarray of PinnedVerifierKeyRecordyes
pinned_atstring (date-time)noWhen the operator recorded the set from its proven read, when the configuration says.

PinnedVerifierKeyRecord

One verifier's registry record as @mintid-net/holder 0.1.0's VerifierKeys reads it (identity.v1.verifier.Verifier: hex bytes, proto enum numbers).

PropertyTypeRequiredDescriptionValues
verifier_idstringyes64 lowercase hex.
stateintegeryesThe record's authority state (proto enum number).
request_signing_keysarray of PinnedRequestKeyyes

PinnedRequestKey

One identity.v1.core.KeyRecord of the verifier's request_signing_keys.

PropertyTypeRequiredDescriptionValues
key_idstringyes64 lowercase hex.
algorithmintegeryesProto enum number.
public_keystringyesHex.
stateintegeryesThe key's state (proto enum number); the holder verifies only under an active key.

HolderNetwork

PropertyTypeRequiredDescriptionValues
issuer_urlstringyes
chain_idstringyes
relay_urlstringyes
chain_rpc_urlstring, nullableno

VerifierState

Type: string, one of "requested", "evidence_pending", "filed", "admitted", "refused", "withdrawn".

VerifierAlgorithm

ed25519 or ecdsa_p256 (the request-signing key's algorithm, as the kit generated it).

Type: string.

VerifierRefusedReason

The closed list a refusal carries: the admission policy's refusal reason codes (ADR-0030, Accepted 2026-10-28; v1.3.24, ZADQ-433). A refusal recorded before v1.3.24 with ZadQ's provisional code reads the code it maps to.

Type: string, one of "not_registered_business", "identity_check_missing", "evidence_not_ok", "obligations_not_accepted", "request_invalid".

VerifierCommitmentRefusalReason

Why a request for the commitment did not bring one (v1.3.24): the answer is not the issuer's seven members (commitment_malformed), names another issuer (commitment_issuer_mismatch), its signature does not verify under the issuer's status key (commitment_signature_invalid), is for another origin (commitment_origin_mismatch), its grade is below A2 (commitment_grade_below_floor), its reuse window has ended (commitment_expired); or the issuer refused the request (issuer_refused).

Type: string, one of "commitment_malformed", "commitment_issuer_mismatch", "commitment_signature_invalid", "commitment_origin_mismatch", "commitment_grade_below_floor", "commitment_expired", "issuer_refused".

VerifierStatusKeyCheck

ZadQ's check of the commitment's signature under the issuer's status key: verified, the signature verifies under a status key the deployment holds; unverified, the deployment holds none — the signature is kept, and the admission tool and the chain's operator check it.

Type: string, one of "verified", "unverified".

VerifierRecordCommitment

The commitment as the record holds it, without asking anyone (v1.3.24): available (a commitment whose reuse window is open), expired (its window ended and no request since brought another), pending_issuer or refused (the last request's result when no commitment serves), not_requested (no request yet).

PropertyTypeRequiredDescriptionValues
statestringyes"not_requested", "pending_issuer", "refused", "expired", "available"
handlestring, nullableyesThe commitment's commitment_hex (64 lowercase hex), also the record's commitment_handle.
issuer_idstring, nullableyes
assurance_gradeinteger, nullableyes
reusable_untilstring (date-time), nullableyes
status_key_checkall of VerifierStatusKeyCheckyes
refusal_reasonall of VerifierCommitmentRefusalReasonyes
checked_atstring (date-time), nullableyesWhen the last request was made.

VerifierKeyInput

A request-signing key as the kit generated it — the public half only; ZadQ never receives the private key.

PropertyTypeRequiredDescriptionValues
key_idstringyes64 lowercase hex, as the kit wrote it.
algorithmVerifierAlgorithmyes
public_keystringyesLowercase hex — 32 bytes (ed25519) or the SEC1 point, 33 or 65 bytes (ecdsa_p256).

VerifierCreate

PropertyTypeRequiredDescriptionValues
originstringyesThe exact origin, https://<host>[:<port>], not normalised.
request_signing_keyVerifierKeyInputyes

VerifierKey

PropertyTypeRequiredDescriptionValues
key_idstringyes
algorithmVerifierAlgorithmyes
public_keystringyes
declared_atstring (date-time)yes

VerifierPreviousKey

PropertyTypeRequiredDescriptionValues
key_idstringyes
algorithmVerifierAlgorithmyes
declared_atstring (date-time)yes
replaced_atstring (date-time)yes

VerifierEvidenceSummary

PropertyTypeRequiredDescriptionValues
digeststringyesSHA-256 over the exact bytes, 64 lowercase hex.
size_bytesintegeryes
uploaded_atstring (date-time)yes

VerifierRecord

A verifier record (§5.15): the exact origin, the current request-signing key and the ones it replaced, the evidence summary, the issuer's commitment handle and the admission request. active is true exactly when admitted; managed is false in this version (MINT-604's managed line is not built).

PropertyTypeRequiredDescriptionValues
idstringyes
originstringyes
stateVerifierStateyes
activebooleanyes
managedbooleanyes
evidence_formatstringyesThe evidence's format: bip-0005/1 (v1.3.22, ZADQ-431), the format a record without an upload expects too. A record that holds an upload made before v1.3.22 reads pending-MINT-599 until the business uploads the v1 document.
operator_accountstring, nullableyesThe bech32 account the bIP-0005 v1 evidence names — the account that signs the registration on the chain (v1.3.22, ZADQ-431); public. Null without a v1 upload.
request_signing_keyVerifierKeyyes
previous_keysarray of VerifierPreviousKeyyes
evidenceall of VerifierEvidenceSummaryyes
commitment_handlestring, nullableyesThe recorded commitment's commitment_hex (MINT-600; v1.3.24), null before one; kept after its reuse window ends.
commitmentVerifierRecordCommitmentyes
admissionall of VerifierAdmissionyes
created_atstring (date-time)yes
updated_atstring (date-time)yes
withdrawn_atstring (date-time), nullableyes
evidence_renewed_atstring (date-time), nullableyesv1.3.23 (ZADQ-436): when the current evidence document was uploaded as a renewal on the admitted record; null while it is the one the record was admitted with.
renewal_reminder_atstring (date-time), nullableyesv1.3.23: the revalidation's reminder date — the last renewal, or the admission's decision before one, plus the reminder (150 days by default; configuration). Null unless admitted.
renewal_due_atstring (date-time), nullableyesv1.3.23: the revalidation's due date — the same start plus the chain's revalidation window (180 days by default; configuration, never read from the chain). Null unless admitted.
renewal_duebooleanyesv1.3.23 — the due date is past and no renewal was uploaded since; false unless admitted.

VerifierRenewalCheckResult

The console's served-file check of a renewed document (v1.3.23, ZADQ-436): the served bytes' SHA-256 is the renewed digest, the file is not served at publish_url, or it is served with another digest.

Type: string, one of "matched", "not_served", "digest_mismatch".

VerifierRenewalCheck

PropertyTypeRequiredDescriptionValues
resultVerifierRenewalCheckResultyes
checked_atstring (date-time)yes

VerifierEvidencePrevious

A document a renewal replaced (v1.3.23, ZADQ-436).

PropertyTypeRequiredDescriptionValues
digeststringyes
formatstringyes
digest_rulestringyes"sha256", "sha256-rfc8785"
operator_accountstring, nullableyes
uploaded_atstring (date-time)yes
replaced_atstring (date-time)yes

VerifierList

PropertyTypeRequiredDescriptionValues
verifiersarray of VerifierRecordyes

VerifierEvidenceUpload

PropertyTypeRequiredDescriptionValues
content_base64stringyesThe exact bytes of the file the kit produced, standard base64; 1 byte to 16 KiB decoded.

VerifierEvidence

PropertyTypeRequiredDescriptionValues
formatstringyesbip-0005/1 (v1.3.22, ZADQ-431); pending-MINT-599 on a record that holds an upload made before v1.3.22.
digeststringyes
digest_rulestringyessha256-rfc8785 for bip-0005/1: SHA-256 over the RFC 8785 canonical form (equal to the SHA-256 of the served bytes when the served file is canonical). sha256 for pending-MINT-599: over the exact bytes."sha256", "sha256-rfc8785"
operator_accountstring, nullableyesThe bech32 account the v1 document names; null for pending-MINT-599.
size_bytesintegeryes
content_base64stringyes
publish_pathstringyes
publish_urlstringyes
uploaded_atstring (date-time)yes
renewed_atstring (date-time), nullableyesv1.3.23 (ZADQ-436) — set when this document came as a renewal on the admitted record.
renewal_checkall of VerifierRenewalCheckyesv1.3.23 — the console's served-file check of this renewed document; null before it, or without a renewal.
historyarray of VerifierEvidencePreviousyesv1.3.23 — the documents renewals replaced, the newest first; empty before a renewal.

VerifierCommitment

The commitment's state (§5.15; v1.3.24, ZADQ-433). With available: the issuer's commitment for the record's origin — handle (its commitment_hex), issuer_id, assurance_grade, approved_at, reusable_until, signature and ZadQ's status_key_check — the session it came from and when it was recorded. With refused: refusal_reason. The other members are null otherwise.

PropertyTypeRequiredDescriptionValues
statestringyes"not_available", "kyc_required", "pending_issuer", "refused", "available"
handlestring, nullableyesThe commitment's commitment_hex, 64 lowercase hex.
kyc_session_idstring, nullableyes
obtained_atstring (date-time), nullableyes
issuer_idstring, nullableyes
assurance_gradeinteger, nullableyes
approved_atstring (date-time), nullableyes
reusable_untilstring (date-time), nullableyes
signaturestring, nullableyes
status_key_checkall of VerifierStatusKeyCheckyes
refusal_reasonall of VerifierCommitmentRefusalReasonyes
checked_atstring (date-time), nullableyesWhen the last request was made.

VerifierObligationsAcceptance

PropertyTypeRequiredDescriptionValues
versionstringyes
sha256stringyes

VerifierAdmissionRequest

PropertyTypeRequiredDescriptionValues
obligationsVerifierObligationsAcceptanceyes

VerifierAdmissionCommitment

What the request carries of the commitment (v1.3.24): available with the handle (commitment_hex), the issuer, the grade, the reuse window and ZadQ's status-key check; pending_issuer (the issuer did not answer) or refused — the request went ahead, and a commitment recorded before the filing joins it; not_available on a deployment that does not ask an issuer, or a request made before v1.3.24 without one.

PropertyTypeRequiredDescriptionValues
statestringyes"not_available", "pending_issuer", "refused", "available"
handlestring, nullableyes
issuer_idstring, nullableyes
assurance_gradeinteger, nullableyes
reusable_untilstring (date-time), nullableyes
status_key_checkall of VerifierStatusKeyCheckyes

VerifierObligationsAccepted

PropertyTypeRequiredDescriptionValues
versionstringyes
sha256stringyes
accepted_atstring (date-time)yes

VerifierTurnaround

PropertyTypeRequiredDescriptionValues
working_daysintegeryesWorking days (Monday to Friday, UTC) from the filing to the decision, or to today while open.
target_working_daysintegeryesThe admission policy's target (five working days; ADR-0030).
openbooleanyesFiled and not decided.

VerifierAdmission

The admission request ZadQ files with the operator of the single-node production chain under MINT-601's policy, and what became of it. The decision is the chain operator's; ZadQ records it.

PropertyTypeRequiredDescriptionValues
statestringyes"submitted", "filed", "admitted", "refused", "withdrawn"
originstringyes
evidence_digeststringyes
commitmentVerifierAdmissionCommitmentyes
obligationsVerifierObligationsAcceptedyes
submitted_atstring (date-time)yes
evidence_checked_atstring (date-time), nullableyes
filed_atstring (date-time), nullableyes
decided_atstring (date-time), nullableyes
refused_reasonall of VerifierRefusedReasonyes
turnaroundVerifierTurnaroundyes
admissions_log_refstring, nullableyesThe public admissions log entry's reference, once recorded.

VerifierObligations

PropertyTypeRequiredDescriptionValues
versionstringyes
sha256stringyes
urlstring, nullableyes
textstringyes
published_atstring (date-time)yes

MeVerifierProduct

The verifier product (§5.15, ZADQ-362), derived from the account's verifier records: none without a record, else the best state — admitted over filed over evidence_pending over requested over refused over withdrawn. plan is null in this version (no price line exists for this product until Marc decides; verification is never a line).

PropertyTypeRequiredDescriptionValues
statestringyes"none", "requested", "evidence_pending", "filed", "admitted", "refused", "withdrawn"
planstring, nullableyes
verifiersobjectyes
verifiers.liveintegeryes
verifiers.admittedintegeryes
linesMeVerifierLinesno
relying_partyMeRelyingPartyno

MeRelyingParty

v1.3.18 (§5.18, ZADQ-389) — the relying-party rebate on the business's account: the rebates pending, earned and not settled yet, held by the cap, the balance carried, the last statement's credit line and the payouts due. Counts and amounts, never who. Null where the deployment wires no billing. (v1.3.16's R1 members are withdrawn with the charge.)

PropertyTypeRequiredDescriptionValues
monthstring (date)yes
offeredbooleanyesWhether the deployment offers the rebate.
pendingintegeryes
earnedintegeryes
heldintegeryes
unitstring, nullableyes
balance_minorinteger (int64)yes
last_lineMeVerifierLineyes
payouts_dueintegeryes

RelyingPartyStatus

v1.3.18 (§5.18, ZADQ-389) — the business's rebates: counts and amounts, never who.

PropertyTypeRequiredDescriptionValues
monthstring (date)yesThe current month (its first day, UTC).
offeredbooleanyesWhether the deployment offers the rebate.
unitstring, nullableyes
pendingintegeryesRebates whose guards are not all met yet (the holding days, the identity check).
earnedintegeryesRebates earned and not settled yet (settled at their month's close).
earned_minorinteger (int64)yes
heldintegeryesRebates held beyond the cap of their month, for the operator's review.
held_minorinteger (int64)yes
balance_minorinteger (int64)yesThe balance carried out of the last statement (below the payout threshold, or negative after reversals).
statementsarray of RebateStatementyesThe closed months, newest first.

RebateStatement

v1.3.18 (§5.18) — a business's month closed: the rebates settled per plan and their amount, those held by the cap, the reversals deducted, the balance carried in, the set-off on the month's invoice (its credit line), the payout and the balance carried out.

PropertyTypeRequiredDescriptionValues
monthstring (date)yes
unitstringyes
settledintegeryesRebates settled in the month (earned, within the cap or released).
by_planarray of objectyesThe rebates settled per plan the principal held when each was earned.
by_plan[].planstringyes"personal", "premium"
by_plan[].countintegeryes
earned_minorinteger (int64)yes
heldintegeryes
held_minorinteger (int64)yes
reversedintegeryes
reversed_minorinteger (int64)yes
carried_in_minorinteger (int64)yes
set_off_minorinteger (int64)yes
payout_minorinteger (int64)yes
carried_out_minorinteger (int64)yes
line_idstring, nullableyesThe month's credit line (principal_enrolled, negative amount); null when nothing was set off.
payoutRebatePayoutyes

RebatePayout

PropertyTypeRequiredDescriptionValues
idstringyes
amount_minorinteger (int64)yes
unitstringyes
statestringyes"due", "paid"
paid_atstring (date-time), nullableyes

MeVerifierLines

v1.3.15 (§5.17, ZADQ-373) — the verifier product's business lines on the account; null where the deployment wires none. kit_setup and onboarding_at_cost are null until opened (and the onboarding stays null where an entry of a product is paid: onboarding: in_entry); onboarding is null before the first record; due counts the business lines open or failed (the managed ones included).

PropertyTypeRequiredDescriptionValues
kit_setupMeVerifierLineyes
onboarding_at_costMeVerifierLineyes
onboardingstring, nullableyes"at_cost", "in_entry"
dueintegeryes

MeVerifierLine

PropertyTypeRequiredDescriptionValues
idstringyes
statePriceLineStateyes
settledbooleanyesCaptured or invoiced (on the provider, after the capture; on the console, once marked).

BusinessLinePriceTable

PropertyTypeRequiredDescriptionValues
linesarray of BusinessLinePriceyes
managed_kit_setupstringyesv1.3.15 — whether a managed business pays the kit set-up too; v1.3.16 (ZADQ-382, P-13) — always withdrawn, the kit set-up line is no longer opened."charged", "waived", "withdrawn"
relying_partyRelyingPartyPricesno
onboarding_rulestringyesThe onboarding at cost opens only where no entry of a product is paid; the re-check at the grade's renewal opens no line."at_cost_unless_entry_paid"

RelyingPartyPrices

v1.3.18 (§5.18, ZADQ-389) — the relying-party rebate on this deployment (v1.3.16's R1 tiers and R2 are withdrawn).

PropertyTypeRequiredDescriptionValues
rebateRebateTermsyes

RebateTerms

The discovery fee ZadQ pays a business per principal its door sends who keeps a paid plan: once per person, the plan's amount when earned, every figure from configuration (RELYING_PARTY_REBATE).

PropertyTypeRequiredDescriptionValues
offeredbooleanyes
unitstring, nullableyes
amountsarray of objectyes
amounts[].planstringyes"personal", "premium"
amounts[].amount_minorinteger (int64)yes
hold_daysinteger, nullableyesThe days a rebate waits from the plan's payment (the withdrawal period).
cap_per_month_minorinteger (int64), nullableyesThe rebates settled per business and month at most; the excess is held for review. Null — no cap.
payout_min_minorinteger (int64), nullableyesThe balance a payout needs; below it the balance carries forward. Null — no threshold.
onboarding_nettingbooleanyesWhether the onboarding at cost is set off against the rebates too (the managed lines always are).
first_agentbooleanyesWhether a rebate is earned only once a bounded agent preset from the referral is registered.

BusinessLinePrice

PropertyTypeRequiredDescriptionValues
kindPriceLineKindyes
environmentstring, nullableyes"production", "test"
periodstring, nullableyes"month", "year"
on_salebooleanyes
amount_minorinteger (int64), nullableyes
unitstring, nullableyes

ManagedEnvironmentOpen

PropertyTypeRequiredDescriptionValues
environmentstringyes"production", "test"
periodstringnoBilled in advance; month when left out."month", "year"

VerifierDoorDeclare

PropertyTypeRequiredDescriptionValues
marketinteger, nullableyesThe market the refusal sentence is chosen by (1 paid APIs and metered data, 2 reference and community content, 3 developer and orchestration platforms); null for the generic sentence.
bundlesarray of stringyes

VerifierDoor

PropertyTypeRequiredDescriptionValues
verifier_idstringyes
marketinteger, nullableyes
bundlesarray of stringyes
declared_atstring (date-time)yes
urlsarray of VerifierDoorUrlyesThe landing URL to configure in the refusal, one per bundle.

VerifierDoorUrl

PropertyTypeRequiredDescriptionValues
bundlestringyes
urlstringyes

ReferralParams

The landing URL's parameters, passed through as the URL carries them.

PropertyTypeRequiredDescriptionValues
verifierstringyesThe refusing service's verifier record id.
bundlestringyesThe bundle id of the served catalogue the refusal names.

Referral

What the refusing service accepts and why (§5.16). service, preset and the plans' fit only when valid. Never the business's customer data, never a proof, a pseudonym or an envelope.

PropertyTypeRequiredDescriptionValues
statestringyes"valid", "closed"
closed_reasonstring, nullableyes"verifier_not_admitted", "door_not_declared", "bundle_not_accepted", "grade_not_offered"
verifierstringyes
bundleReferralBundleyes
serviceall of ReferralServiceyes
marketinteger, nullableyes1, 2 or 3 — the refusal sentence's market as the business declared it; null for the generic sentence.
plansarray of ReferralPlanFityes
presetall of ReferralPresetyes
urlstringnoThe landing URL of this referral (valid only).

ReferralBundle

PropertyTypeRequiredDescriptionValues
idstringyes
descriptionstring, nullableyes
grade_mininteger, nullableyesThe served assurance_grade_min; null when the catalogue does not say.

ReferralService

PropertyTypeRequiredDescriptionValues
hoststringyesThe refusing service's origin host (and port), from its verifier record.

ReferralPlanFit

PropertyTypeRequiredDescriptionValues
idstringyes"personal", "premium"
fitsbooleanyesThe grade the plan includes reaches the bundle's grade floor (since v1.3.25 both plans include A3 when a relying party requires it).
optionstring, nullablenov1.3.16 — the step the plan needs for this bundle. Since v1.3.25 no deployment offers a step, so it reads null."grade_a3_option"

ReferralPreset

The first bounded agent's preset — the enrolment's bundle and the refusing service's origin as its counterparty.

PropertyTypeRequiredDescriptionValues
bundlestringyes
counterpartiesarray of stringyes

AccountReferral

A referral recorded on the account — an opaque reference of ZadQ's own.

PropertyTypeRequiredDescriptionValues
idstringyesThe referral's reference (rfl_…).
verifierstringyes
bundlestringyes
marketinteger, nullableyes
at_signupbooleanyes
recorded_atstring (date-time)yes

AccountReferralList

PropertyTypeRequiredDescriptionValues
referralsarray of AccountReferralyes

PrincipalPlanList

PropertyTypeRequiredDescriptionValues
plansarray of PrincipalPlanyes
contactobjectyesv1.3.30 (ZADQ-472, §5.20) — beyond Premium, Enterprise — the agent-operator product by contract, agreed by contact and activated by ZadQ; never an amount.
contact.idstringyes"enterprise"
contact.labelstringyes
contact.seats_fromintegeryesThe fewest bounded agents an Enterprise contract carries (6, beyond Premium's 5).
contact.by_contactbooleanyestrue
default_periodstringyes"month", "year"
eligibilityobjectyes
eligibility.account_kindsarray of AccountKindyes
eligibility.consumerstringyes"not_offered"

PrincipalPlan

PropertyTypeRequiredDescriptionValues
idstringyes"personal", "premium"
labelstringyes
seatsintegeryesThe bounded agents the plan includes.
seats_minintegeryesThe seats billed on the plan's line — the included agents (minimum = included).
seats_maxintegeryesv1.3.16 — the most bounded agents alive at a time on the plan. v1.3.27 (the caps as decided 2026-11-07; supersedes the caps of v1.3.16 and v1.3.25) — Personal 1, Premium 5; beyond Premium, Enterprise by contact (v1.3.30).
gradeintegeryesThe assurance grade the plan's verification is at (2 = A2).
grade_includedintegeryesv1.3.16 — the highest grade the plan includes when a relying party requires it; a verification at A3 renews by A3's own period. v1.3.25 (supersedes v1.3.16's per-plan grades) — 3 on both plans, A3 being included in every plan when a relying party requires it.
renewal_monthsintegeryesThe verification's renewal at the plan's grade, no grace (12 at A2).
periodsarray of PrincipalPlanPriceyes
usage_feebooleanyesAlways false — the principal plans carry no settlement-based fee of any kind; that fee belongs to the vendor tiers alone.
fair_use_presentationsinteger, nullableyesv1.3.16 (P-8) — the fair-use allowance of presentations a month by the plan's bounded agents; a number, never billed, never metered. Null where the deployment states none.
vatstringyesv1.3.29 (ZADQ-469; Marc, 2026-11-07) — exclusive on every deployment — the amounts are net and VAT is added on top, computed by the billing provider at checkout per customer (location; reverse charge for a business with a valid VAT number of another member state). included is a legacy value, no longer answered."exclusive", "included"
stepsarray of PrincipalPlanStepyesv1.3.16 — the plan's steps with their prices. v1.3.25 — only the steps the deployment's price table prices; no deployment prices one, so the list is empty on both plans.

PrincipalPlanStep

PropertyTypeRequiredDescriptionValues
kindstringyes"agent_extra", "grade_a3_option"
periodsarray of PrincipalPlanPriceyes

PrincipalPlanPrice

PropertyTypeRequiredDescriptionValues
net_amount_minorinteger (int64), nullablenov1.3.16 — the net a business under reverse charge is invoiced. v1.3.29 (ZADQ-469) — every amount is net, so it equals amount_minor (kept for clients of v1.3.16); null when amount_minor is.
periodstringyes"month", "year"
on_salebooleanyes
amount_minorinteger (int64), nullableyesThe plan's whole price for one period, in minor units, net — VAT is added on top at checkout (v1.3.29) — null when not on sale, or when it lives on the provider's price.
unitstring, nullableyes
first_period_amount_minorinteger (int64), nullablenoMonthly only — the first month's amount when ZadQ's table sets one (the floor that covers the check).

MePrincipalPlan

The account's principal plan (§5.16); null on an earlier plan or without one.

PropertyTypeRequiredDescriptionValues
seatsintegernov1.3.16 — the plan's seats now — the included agents (no step adds any since v1.3.25).
seats_maxintegernov1.3.16 — the most bounded agents alive at a time (v1.3.27 — Personal 1, Premium 5).
grade_includedintegernov1.3.16 — the highest grade the plan includes now (3 on both plans since v1.3.25 — A3 when a relying party requires it).
agent_stepsobjectnov1.3.16 — the step lines covering now and unpaid (ids). Since v1.3.25 no deployment offers a step; both lists read empty.
agent_steps.coveringarray of stringyes
agent_steps.duearray of stringyes
grade_optionobjectnov1.3.16 — a grade step's covering period and unpaid line. Superseded by v1.3.25 — no deployment offers the step, and the object is absent.
grade_option.covered_untilstring (date-time), nullableyes
grade_option.duestring, nullableyes
plan_switchall of PlanSwitchnov1.3.16 — the switch Personal → Premium waiting on its line.
fair_use_presentationsinteger, nullablenov1.3.16 — the plan's fair-use allowance (a number; never metered).
refundall of PlanRefundnov1.3.17 (ZADQ-387) — the plan closed after its identity check ended refused or withdrawn, and its refund; null otherwise.
planstringyes"personal", "premium"
periodstringyes"month", "year"
grade_requiredintegeryes
renewal_monthsintegeryes
paid_untilstring (date-time), nullableyesThe end of the period paid; null before the first payment.
grade_metboolean, nullableyesThe person's verification reaches the plan's grade; null while unknown.
verified_untilstring (date-time), nullableyesWhen the person's verification ends (renewal by grade, no grace).
plan_linestring, nullableyesThe plan's current seat line (§5.3).

NewAccountKind

The account kind a sign-up declares. consumer is refused with 409 consumer_not_offered until counsel answers the consumer-terms question (§5.16): plans are for organisations and for people acting for their business or profession.

Type: string, one of "organisation", "sole_trader", "consumer".