paybondpaybond
Sign in

Paybond API documentation

Authentication, versioning, and idempotency rules shared by Harbor, Gateway, and Signal HTTP APIs.

Service references

Three tenant-scoped HTTP surfaces. Each reference is backed by the canonical OpenAPI document plus SDK usage snippets.

Paybond API documentation

Paybond exposes three HTTP surfaces — Harbor, Gateway, and Signal — each linked as a service card above. All three are tenant-scoped: every authenticated call is bound to exactly one tenant realm, and cross-tenant reads or writes are a severity-zero defect.

Error contracts and status-code conventions are shared across all three services: see Errors.

Authentication

Every request to Harbor or Gateway must carry one of the following:

  1. A session Bearer JWT minted by the Gateway login endpoints (POST /v1/auth/login, POST /v1/auth/sso/*). Used by the admin console and by browser-originated workflows.
  2. A short-lived Harbor access JWT minted from a service-account API key at POST /v1/auth/harbor-access. Used by the Paybond Kit (ServiceAccountHarborSession.open) and by non-browser integrations.
  3. A dedicated download JWT (aud = paybond-audit-export-download) for signed bundle downloads. Issued alongside the create/get responses for audit exports and must not be mixed with session tokens.

In every case the token carries a tid claim (tenant realm) that is the authorization identity. Unauthenticated identifiers in the request body (tenant_id, org_id) are treated only as hints and must match the token. Kit SDKs do this automatically through ServiceAccountHarborSession; when calling the HTTP surfaces directly from another language, you are responsible for attaching Authorization: Bearer … and — where required — the x-tenant-id header that must match tid.

Implementations: paybond-identity, go/gateway/internal/auth.

Versioning

  • HTTP paths carry their version in the path (/v1/…, /policy/v1/…, /signal/v1/…). Breaking changes bump that segment and ship alongside the previous version until the deprecation window closes.
  • Signed artifacts (Signal receipts, portfolio snapshots, audit export manifests) carry an independent schema_version integer plus an artifact_version or receipt_version string. Parsers must reject unknown schema_version values before attempting signature verification.
  • Harbor intent signing is versioned inside the payload itself (IntentCreationSignV2, policy-bound v3). Offline signers should pin to a specific bincode payload version.

The OpenAPI documents served under /docs/api/{harbor,gateway,signal} pin the current major; the per-service fragments in this folder (harbor-idempotency-openapi.yaml, harbor-policy-openapi.yaml, gateway-audit-export-openapi.yaml) carry their own info.version.

Idempotency

Mutating Harbor POST routes honor an optional idempotency-key header (1–256 chars). The key is scoped per authenticated tenant and HTTP operation. Reusing a key with a different request body returns 409 Conflict. Reusing it with the same body replays the original response.

Currently honored by:

  • POST /intents
  • POST /intents/{intent_id}/evidence
  • POST /intents/{intent_id}/settlement/confirm

See harbor-idempotency-openapi.yaml for the wire shape. Policy-registry POSTs do not honor idempotency keys today — use natural-key reads (GET …/versions) to detect existing drafts before retrying.

Gateway and Signal endpoints are read-only or state-reconciling (Stripe webhook replays, audit export builds) and do not require client-supplied idempotency keys today.