Provision a scoped integration API key for a POS terminal
Provisions a new integration API key for a POS terminal or platform integration. The key’s authority scope is determined by which of enterprise_id, brand_id, or branch_id are supplied (most-specific wins): a branch-scoped key can only act on one branch, a brand-scoped key on any branch under that brand, and an enterprise-scoped key on any branch under the enterprise. The raw key is formatted as fddi_<segment>_<base64url(24 random bytes)> and stored only as a hash, alongside a key_prefix (prefix plus 4 chars, used for quick-reject during verification) and key_last_four (for list views). The <segment> is currently odo for ALL providers regardless of POS platform (a historical artifact, not provider-derived): treat key_prefix as an opaque value, never parse a provider out of it, and use the key_prefix field returned here for matching. The raw key is returned EXACTLY ONCE in this response and is never retrievable again: a lost key must be regenerated, not recovered. When a branch_id is supplied, it is validated against the caller’s own authority scope; a branch outside that scope returns FORBIDDEN (403). This is the platform-to-tenant minting handshake: a platform-scoped credential provisions per-merchant or per-branch keys, never a flat shared key. The tenant is the calling integration, and merchant_id is key-enforced, never free-text. Requires the integrations CREATE permission. Idempotent on the Idempotency-Key header: a retried create with the same key and same payload replays the original key record (including the same one-time raw key bytes) with meta.idempotency_replayed: true, while a same-key-different-payload request returns IDEMPOTENCY_KEY_REUSED (422).
Authorizations
Partner API key (platform- or merchant-scoped). Contract key-enforces context.merchant_id.
Headers
Partner-generated UUID; the ONE dedup key for all mutating endpoints. 24h TTL. Same key + same payload -> byte-identical replay; same key + different payload -> IDEMPOTENCY_KEY_REUSED (422).
Body
Provision a scoped integration API key. Scope is set by which of enterprise/brand/branch are supplied (most-specific wins). merchant_id in context is key-enforced.
Common request metadata shared across all Partner API domains. partner_request_id is a correlation identifier only: it appears in logs and responses for tracing but is never used as the deduplication key. Request deduplication is keyed exclusively on the Idempotency-Key header.
The canonical context block. merchant_id is key-enforced to a merchant the caller is authorized for, never a free-text trust field. cashier_id is server-trusted only when it is signed into the terminal JWT.
The enterprise this key belongs to. Must be a tenant the caller is authorized for.
Optional. Narrows the key to one brand under the enterprise.
Optional. Narrows the key to one branch. Validated against the caller's scope; out-of-scope → 403.
Human-friendly name for the ops/list UI, e.g. 'Al-Olaya Branch POS-360-0007'.
120Optional future expiry. Omit/null = non-expiring.
Response
Key provisioned. raw_key is present ONLY in this response (or an idempotent replay of it) and is never returned again.
The standard response envelope that every enveloped endpoint serializes through. ok is a boolean discriminator: when ok is true, the typed result is carried in data; when ok is false, a typed error object is returned instead. The meta object is uniform across the entire API surface.
The uniform response metadata block returned on every response. data_completeness_score is computed per call and reports the completeness of the returned data. decision_trace_id is present on responses that carry decision or insight output and can be used to correlate the response with its reasoning. capabilities is an additive, response-level array of hints advertising features the caller may use, and may be extended over time without notice.
The result of provisioning a key. raw_key appears ONLY here (or an idempotent replay of this exact create) and is never retrievable again.
The typed error object returned with every non-2xx response. code is a string enum (for example WALLET_PROGRAM_AMBIGUOUS, CREDENTIAL_TYPE_UNSUPPORTED, INSUFFICIENT_FUNDS, IDEMPOTENCY_KEY_REUSED, CURRENCY_NOT_SUPPORTED), never a bare HTTP status number. Inspect code for programmatic branching, not the HTTP status. Some codes echo the valid set in details so clients can present or reconcile the accepted values: for example CREDENTIAL_TYPE_UNSUPPORTED lists the supported credential types, CURRENCY_NOT_SUPPORTED lists the supported ISO-4217 currencies, and WALLET_PROGRAM_AMBIGUOUS lists the candidate wallet_program_id values that matched the request.