SDK docs · sdk/03

Service mode & the OpenAPI contract

The same SDK wrapped in a thin first-party HTTP service you deploy yourself, behind a frozen, versioned OpenAPI contract.

The contract

Service mode is embedded mode plus transport: the same SDK wrapped in a thin first-party HTTP service that you deploy next to your backend. It adds no authority, exposes no extra options, and runs the identical nine-condition pipeline — there is no "lite" verification path. It exists so that non-Python backends (TypeScript today, PHP next) can integrate through transport-only clients.

verifier-service.v1 — a versioned OpenAPI 3.1 document, frozen under the project's standards process. Three operations:

OperationMethod & pathPurpose
createChallengePOST /v1/challengesIssue one signed §10.5 challenge bound to the deployment's registered identity
validatePresentationPOST /v1/presentationsRun the nine conditions; returns the decision
getBuildInfoGET /v1/build-infoThe artifact's release pins (versions — never secrets)

Semver at the contract level: decision semantics or reason-vocabulary changes are major; additive surface is minor (current: 1.1.0, which added the conformance-suite pin to build-info).

Deliberately absent from the wire — these are invariants, not parameters: any lifetime setting (10 s is a constant), any skip flag for the conditions, and max_height_lag (local deployment policy, configured at service start — a compromised web tier must not be able to widen staleness acceptance).

Decision vs transport error

  • Anything parseable into the §10.5 schema flows through the pipeline and returns HTTP 200 with a decision — accept or reject — plus exactly one decision record server-side.
  • HTTP 400 exists only for bodies that cannot be parsed into the schema at all (no session identity exists, so no decision record is possible).
  • HTTP 503 means the service refused to issue a challenge because proven chain state was unavailable — fail closed; retry, never work around.

Deploying

Notes that matter:

  • Identity is deployment configuration (origin, verifier id, request key) — bound to your on-chain registrations, never accepted from HTTP callers.
  • Challenge signing is your key custody. The service takes a RequestSigner you provide (--signer module:attribute, e.g. an HSM wrapper). For devnet integration only, --insecure-unsigned-challenges exists and warns loudly.
  • The built-in runner is a single-threaded reference server for devnet and integration; front it with your own web tier for anything more.
  • The service holds no state: durability lives in the nonce store and the decision log you configured.

Trust boundaries, restated

Your service instance is part of your verifier. Deploy it inside your perimeter, point your transport clients at it, and never at anyone else's — outsourcing the service outsources the decision, which the protocol's paid-verification permission (R26) explicitly does not cover.