Runtime and admin API reference
Every operation, parameter, request model, response, and authentication boundary.
Download this chapterOn this page
This reference is generated from the reviewed OpenAPI contract. It covers all 37 runtime, store-ingress, webhook, health, and root-admin operations and their models. Download the OpenAPI YAML for the exact machine-readable contract, including nested/conditional schema constraints.
Choose the correct API boundary
The staging API origin is https://api-staging.cherrysub.com. Operator/local deployments use their own origin. Send JSON with the documented content type. The hosted dashboard's cookie-based /auth and /dashboard interface is a separate hosted API.
- Public client runtime:
iap_pk_plusX-IAP-Customer-Tokenfor the exact app/customer. - Trusted app server:
iap_sk_, including token minting and app-scoped catalog/webhook management. - Root administration: an operator bearer key from
ADMIN_API_KEYS; it is not a project-member credential. - Store ingress: verified Apple signed data or authenticated Google Pub/Sub push, not an app bearer key pasted into a notification URL.
Root app creation returns the core app and its first secret key. The hosted project/app creation flow has a different response and project association; use the dashboard/CLI when creating an app in a hosted project.
Runtime error responses use an error field. Keep client-facing event_id values as decimal strings. Subscriber 404 can mean no app-user alias exists yet; current product-set null is an explicit successful empty configuration.
Operation index
Public runtime and trusted catalog
POST /v1/receipts
Operation: submitReceipt. A secret server key may submit directly. A publishable client key must also present X-IAP-Customer-Token and app_user_id must match its authenticated subject. The service then verifies an Apple StoreKit transaction JWS or authoritatively fetches a Google purchase token and atomically reduces mapped access levels.
Authentication: bearerAPIKey
| Parameter | Location | Required | Type | Details |
|---|---|---|---|---|
X-IAP-Customer-Token | header | No | string | Required with an iap_pk_ publishable key; ignored for an iap_sk_ server key. pattern: "^iap_ct_". |
Request body: required.
Content type: application/json. ReceiptSubmission
| Response | Meaning |
|---|---|
| 200 | Receipt observation appended or deduplicated. |
| 400 | Payload is malformed or fails store validation. |
| 401 | The required bearer credential is missing, invalid, or revoked. |
| 403 | The authenticated key or customer token is not authorized for this resource. |
| 413 | Request exceeds 256 KiB. |
| 422 | Payload is malformed or fails store validation. |
| 429 | The authenticated API key exceeded its process-local receipt rate limit. |
| 503 | A verifier or durable dependency is temporarily unavailable. |
200 application/json body: IngestResult
GET /v1/subscribers/{app_user_id}
Operation: getSubscriber. Returns the current Apple and Google access level union for one app-scoped customer alias.
Authentication: bearerAPIKey
| Parameter | Location | Required | Type | Details |
|---|---|---|---|---|
app_user_id | path | Yes | string | minLength: 1. maxLength: 512. |
X-IAP-Customer-Token | header | No | string | Required with an iap_pk_ publishable key; ignored for an iap_sk_ server key. pattern: "^iap_ct_". |
| Response | Meaning |
|---|---|
| 200 | Current subscriber access level projection. |
| 400 | Payload is malformed or fails store validation. |
| 401 | The required bearer credential is missing, invalid, or revoked. |
| 403 | The authenticated key or customer token is not authorized for this resource. |
| 404 | No customer alias exists for this app-user id. |
| 503 | A verifier or durable dependency is temporarily unavailable. |
200 application/json body: Subscriber
GET /v1/product-sets/current
Operation: getCurrentProductSet. Returns the authenticated app's current cross-store product presentation. Publishable keys also require a customer token; secret keys do not.
Authentication: bearerAPIKey
| Parameter | Location | Required | Type | Details |
|---|---|---|---|---|
X-IAP-Customer-Token | header | No | string | Required with an iap_pk_ publishable key; ignored for an iap_sk_ server key. pattern: "^iap_ct_". |
| Response | Meaning |
|---|---|
| 200 | Current product set, or an explicit null when the app has not selected one. |
| 401 | The required bearer credential is missing, invalid, or revoked. |
| 403 | The authenticated key or customer token is not authorized for this resource. |
| 503 | A verifier or durable dependency is temporarily unavailable. |
200 application/json body: CurrentProductSet
Response headers: Cache-Control (const: "no-store".).
GET /v1/access-levels
Operation: listAccessLevels.
Authentication: bearerAPIKey
| Response | Meaning |
|---|---|
| 200 | Active app-scoped access level catalog. |
| 401 | The required bearer credential is missing, invalid, or revoked. |
| 503 | A verifier or durable dependency is temporarily unavailable. |
200 application/json body:
{
"type": "object",
"required": [
"access_levels"
],
"properties": {
"access_levels": {
"type": "array",
"items": {
"$ref": "#/components/schemas/CatalogAccessLevel"
}
}
},
"additionalProperties": false
}POST /v1/access-levels
Operation: createAccessLevel.
Authentication: bearerAPIKey
Request body: required.
Content type: application/json. CreateAccessLevel
| Response | Meaning |
|---|---|
| 201 | Access level created. |
| 400 | Payload is malformed or fails store validation. |
| 401 | The required bearer credential is missing, invalid, or revoked. |
| 409 | The requested identifier or lifecycle transition conflicts with existing state. |
| 503 | A verifier or durable dependency is temporarily unavailable. |
201 application/json body: CatalogAccessLevel
GET /v1/access-levels/{access_level_id}
Operation: getAccessLevel.
Authentication: bearerAPIKey
| Parameter | Location | Required | Type | Details |
|---|---|---|---|---|
access_level_id | path | Yes | string | format: "uuid". |
| Response | Meaning |
|---|---|
| 200 | Access level. |
| 401 | The required bearer credential is missing, invalid, or revoked. |
| 404 | The app-scoped resource does not exist. |
| 503 | A verifier or durable dependency is temporarily unavailable. |
200 application/json body: CatalogAccessLevel
PATCH /v1/access-levels/{access_level_id}
Operation: updateAccessLevel. Updates display_name; lookup_key is immutable.
Authentication: bearerAPIKey
| Parameter | Location | Required | Type | Details |
|---|---|---|---|---|
access_level_id | path | Yes | string | format: "uuid". |
Request body: required.
Content type: application/json.
{
"type": "object",
"required": [
"display_name"
],
"properties": {
"display_name": {
"type": "string",
"maxLength": 512
}
},
"additionalProperties": false
}| Response | Meaning |
|---|---|
| 200 | Access level updated. |
| 400 | Payload is malformed or fails store validation. |
| 401 | The required bearer credential is missing, invalid, or revoked. |
| 404 | The app-scoped resource does not exist. |
| 503 | A verifier or durable dependency is temporarily unavailable. |
200 application/json body: CatalogAccessLevel
DELETE /v1/access-levels/{access_level_id}
Operation: archiveAccessLevel. Archives the lookup key and ends active product access mappings without deleting replay history.
Authentication: bearerAPIKey
| Parameter | Location | Required | Type | Details |
|---|---|---|---|---|
access_level_id | path | Yes | string | format: "uuid". |
| Response | Meaning |
|---|---|
| 204 | Access level archived. |
| 401 | The required bearer credential is missing, invalid, or revoked. |
| 404 | The app-scoped resource does not exist. |
| 503 | A verifier or durable dependency is temporarily unavailable. |
GET /v1/product-access-mappings
Operation: listProductAccessMappings.
Authentication: bearerAPIKey
| Response | Meaning |
|---|---|
| 200 | Active Apple and Google product access mappings. |
| 401 | The required bearer credential is missing, invalid, or revoked. |
| 503 | A verifier or durable dependency is temporarily unavailable. |
200 application/json body:
{
"type": "object",
"required": [
"product_mappings"
],
"properties": {
"product_mappings": {
"type": "array",
"items": {
"$ref": "#/components/schemas/ProductAccessMapping"
}
}
},
"additionalProperties": false
}POST /v1/product-access-mappings
Operation: createProductAccessMapping. Starts a mapping after a short, safe ledger high-water boundary.
Authentication: bearerAPIKey
Request body: required.
Content type: application/json. CreateProductAccessMapping
| Response | Meaning |
|---|---|
| 201 | Active mapping version. |
| 400 | Payload is malformed or fails store validation. |
| 401 | The required bearer credential is missing, invalid, or revoked. |
| 404 | The app-scoped resource does not exist. |
| 409 | The requested identifier or lifecycle transition conflicts with existing state. |
| 503 | A verifier or durable dependency is temporarily unavailable. |
201 application/json body: ProductAccessMapping
PATCH /v1/product-access-mappings/{mapping_id}
Operation: updateProductAccessMapping. Ends the active version and starts a new grant-mode version at one ledger boundary.
Authentication: bearerAPIKey
| Parameter | Location | Required | Type | Details |
|---|---|---|---|---|
mapping_id | path | Yes | string | format: "uuid". |
Request body: required.
Content type: application/json.
{
"type": "object",
"required": [
"grant_mode"
],
"properties": {
"grant_mode": {
"$ref": "#/components/schemas/GrantMode"
}
},
"additionalProperties": false
}| Response | Meaning |
|---|---|
| 200 | New active mapping version. |
| 400 | Payload is malformed or fails store validation. |
| 401 | The required bearer credential is missing, invalid, or revoked. |
| 404 | The app-scoped resource does not exist. |
| 409 | The requested identifier or lifecycle transition conflicts with existing state. |
| 503 | A verifier or durable dependency is temporarily unavailable. |
200 application/json body: ProductAccessMapping
DELETE /v1/product-access-mappings/{mapping_id}
Operation: deleteProductAccessMapping. Ends the active version after the current safe ledger head.
Authentication: bearerAPIKey
| Parameter | Location | Required | Type | Details |
|---|---|---|---|---|
mapping_id | path | Yes | string | format: "uuid". |
| Response | Meaning |
|---|---|
| 204 | Mapping version ended. |
| 401 | The required bearer credential is missing, invalid, or revoked. |
| 404 | The app-scoped resource does not exist. |
| 503 | A verifier or durable dependency is temporarily unavailable. |
POST /v1/client-tokens
Operation: createClientToken. Requires a secret app key. Mints an opaque, short-lived token binding a publishable-key client to one app_user_id.
Authentication: bearerAPIKey
Request body: required.
Content type: application/json. CreateClientToken
| Response | Meaning |
|---|---|
| 201 | One-time opaque customer token. |
| 400 | Payload is malformed or fails store validation. |
| 401 | The required bearer credential is missing, invalid, or revoked. |
| 403 | The authenticated key or customer token is not authorized for this resource. |
| 503 | A verifier or durable dependency is temporarily unavailable. |
201 application/json body: CreatedClientToken
Response headers: Cache-Control (const: "no-store".).
DELETE /v1/client-tokens/{token_id}
Operation: revokeClientToken. Requires a secret app key and revokes one app-scoped customer token immediately.
Authentication: bearerAPIKey
| Parameter | Location | Required | Type | Details |
|---|---|---|---|---|
token_id | path | Yes | string | format: "uuid". |
| Response | Meaning |
|---|---|
| 204 | Client token revoked. |
| 401 | The required bearer credential is missing, invalid, or revoked. |
| 403 | The authenticated key or customer token is not authorized for this resource. |
| 404 | The app-scoped resource does not exist. |
| 503 | A verifier or durable dependency is temporarily unavailable. |
Webhook management and delivery
GET /v1/webhook-endpoints
Operation: listWebhookEndpoints.
Authentication: bearerAPIKey
| Response | Meaning |
|---|---|
| 200 | Non-deleted endpoints for the authenticated app. |
| 401 | The required bearer credential is missing, invalid, or revoked. |
| 503 | A verifier or durable dependency is temporarily unavailable. |
200 application/json body:
{
"type": "object",
"required": [
"endpoints"
],
"properties": {
"endpoints": {
"type": "array",
"items": {
"$ref": "#/components/schemas/WebhookEndpoint"
}
}
},
"additionalProperties": false
}POST /v1/webhook-endpoints
Operation: createWebhookEndpoint. Creates an HTTPS endpoint and returns its Standard Webhooks signing secret once. Destinations that are literal private or special-purpose addresses are rejected; resolved addresses are checked again on every dial.
Authentication: bearerAPIKey
Request body: required.
Content type: application/json. CreateWebhookEndpoint
| Response | Meaning |
|---|---|
| 201 | Endpoint and one-time signing secret. The response must not be cached. |
| 400 | Payload is malformed or fails store validation. |
| 401 | The required bearer credential is missing, invalid, or revoked. |
| 503 | A verifier or durable dependency is temporarily unavailable. |
201 application/json body: CreatedWebhookEndpoint
Response headers: Cache-Control (const: "no-store".).
GET /v1/webhook-endpoints/{endpoint_id}
Operation: getWebhookEndpoint.
Authentication: bearerAPIKey
| Parameter | Location | Required | Type | Details |
|---|---|---|---|---|
endpoint_id | path | Yes | string | format: "uuid". |
| Response | Meaning |
|---|---|
| 200 | Endpoint configuration without signing material. |
| 401 | The required bearer credential is missing, invalid, or revoked. |
| 404 | The app-scoped resource does not exist. |
| 503 | A verifier or durable dependency is temporarily unavailable. |
200 application/json body: WebhookEndpoint
PATCH /v1/webhook-endpoints/{endpoint_id}
Operation: updateWebhookEndpoint.
Authentication: bearerAPIKey
| Parameter | Location | Required | Type | Details |
|---|---|---|---|---|
endpoint_id | path | Yes | string | format: "uuid". |
Request body: required.
Content type: application/json. UpdateWebhookEndpoint
| Response | Meaning |
|---|---|
| 200 | Updated endpoint. |
| 400 | Payload is malformed or fails store validation. |
| 401 | The required bearer credential is missing, invalid, or revoked. |
| 404 | The app-scoped resource does not exist. |
| 503 | A verifier or durable dependency is temporarily unavailable. |
200 application/json body: WebhookEndpoint
DELETE /v1/webhook-endpoints/{endpoint_id}
Operation: deleteWebhookEndpoint. Soft-deletes the endpoint, cancels queued work, and retains delivery history.
Authentication: bearerAPIKey
| Parameter | Location | Required | Type | Details |
|---|---|---|---|---|
endpoint_id | path | Yes | string | format: "uuid". |
| Response | Meaning |
|---|---|
| 204 | Endpoint deleted. |
| 401 | The required bearer credential is missing, invalid, or revoked. |
| 404 | The app-scoped resource does not exist. |
| 503 | A verifier or durable dependency is temporarily unavailable. |
POST /v1/webhook-endpoints/{endpoint_id}/rotate-secret
Operation: rotateWebhookEndpointSecret. Returns a new signing secret once and dual-signs with the immediately previous secret for 24 hours.
Authentication: bearerAPIKey
| Parameter | Location | Required | Type | Details |
|---|---|---|---|---|
endpoint_id | path | Yes | string | format: "uuid". |
| Response | Meaning |
|---|---|
| 200 | One-time rotated secret and overlap boundary. |
| 401 | The required bearer credential is missing, invalid, or revoked. |
| 404 | The app-scoped resource does not exist. |
| 503 | A verifier or durable dependency is temporarily unavailable. |
200 application/json body: RotatedWebhookSecret
Response headers: Cache-Control (const: "no-store".).
GET /v1/webhook-deliveries
Operation: listWebhookDeliveries.
Authentication: bearerAPIKey
| Parameter | Location | Required | Type | Details |
|---|---|---|---|---|
endpoint_id | query | No | string | format: "uuid". |
status | query | No | WebhookDeliveryStatus | |
before_event_number | query | No | integer | Exclusive keyset cursor over the monotonic, non-gapless ledger event number. format: "int64". minimum: 1. |
limit | query | No | integer | minimum: 1. maximum: 200. default: 50. |
| Response | Meaning |
|---|---|
| 200 | Newest-first delivery history. |
| 400 | Payload is malformed or fails store validation. |
| 401 | The required bearer credential is missing, invalid, or revoked. |
| 503 | A verifier or durable dependency is temporarily unavailable. |
200 application/json body:
{
"type": "object",
"required": [
"deliveries"
],
"properties": {
"deliveries": {
"type": "array",
"items": {
"$ref": "#/components/schemas/WebhookDelivery"
}
}
},
"additionalProperties": false
}GET /v1/webhook-deliveries/{message_id}
Operation: getWebhookDelivery.
Authentication: bearerAPIKey
| Parameter | Location | Required | Type | Details |
|---|---|---|---|---|
message_id | path | Yes | string | pattern: "^msg_[A-Za-z0-9_-]{20,64}$". |
| Response | Meaning |
|---|---|
| 200 | Delivery and every recorded attempt, including expired worker leases. |
| 401 | The required bearer credential is missing, invalid, or revoked. |
| 404 | The app-scoped resource does not exist. |
| 503 | A verifier or durable dependency is temporarily unavailable. |
200 application/json body: WebhookDeliveryDetail
POST /v1/webhook-deliveries/{message_id}/retry
Operation: retryWebhookDelivery. Starts a fresh 72-hour retry cycle for a terminal delivery while retaining its message id and prior attempt history. The endpoint must first be enabled.
Authentication: bearerAPIKey
| Parameter | Location | Required | Type | Details |
|---|---|---|---|---|
message_id | path | Yes | string | pattern: "^msg_[A-Za-z0-9_-]{20,64}$". |
| Response | Meaning |
|---|---|
| 200 | Requeued delivery. |
| 400 | Payload is malformed or fails store validation. |
| 401 | The required bearer credential is missing, invalid, or revoked. |
| 404 | The app-scoped resource does not exist. |
| 409 | Endpoint is disabled or delivery is already queued/in flight. |
| 503 | A verifier or durable dependency is temporarily unavailable. |
200 application/json body: WebhookDelivery
Root operator administration
GET /admin/v1/apps
Operation: listApps.
Authentication: adminBearer
| Response | Meaning |
|---|---|
| 200 | All active and disabled apps in stable creation order. |
| 401 | The required bearer credential is missing, invalid, or revoked. |
| 503 | A verifier or durable dependency is temporarily unavailable. |
200 application/json body:
{
"type": "object",
"required": [
"apps"
],
"properties": {
"apps": {
"type": "array",
"items": {
"$ref": "#/components/schemas/App"
}
}
},
"additionalProperties": false
}POST /admin/v1/apps
Operation: createApp. Creates an Apple, Google, or cross-platform app and returns its first API key exactly once.
Authentication: adminBearer
Request body: required.
Content type: application/json. CreateApp
| Response | Meaning |
|---|---|
| 201 | App, safe key metadata, and one-time plaintext secret. |
| 400 | Payload is malformed or fails store validation. |
| 401 | The required bearer credential is missing, invalid, or revoked. |
| 409 | The requested identifier or lifecycle transition conflicts with existing state. |
| 503 | A verifier or durable dependency is temporarily unavailable. |
201 application/json body: CreatedApp
Response headers: Cache-Control (const: "no-store".).
GET /admin/v1/apps/{app_id}
Operation: getApp.
Authentication: adminBearer
| Parameter | Location | Required | Type | Details |
|---|---|---|---|---|
app_id | path | Yes | string | format: "uuid". |
| Response | Meaning |
|---|---|
| 200 | App configuration. |
| 401 | The required bearer credential is missing, invalid, or revoked. |
| 404 | The app-scoped resource does not exist. |
| 503 | A verifier or durable dependency is temporarily unavailable. |
200 application/json body: App
PATCH /admin/v1/apps/{app_id}
Operation: updateApp.
Authentication: adminBearer
| Parameter | Location | Required | Type | Details |
|---|---|---|---|---|
app_id | path | Yes | string | format: "uuid". |
Request body: required.
Content type: application/json. UpdateApp
| Response | Meaning |
|---|---|
| 200 | Updated app. Re-enabling does not un-revoke old keys. |
| 400 | Payload is malformed or fails store validation. |
| 401 | The required bearer credential is missing, invalid, or revoked. |
| 404 | The app-scoped resource does not exist. |
| 409 | The requested identifier or lifecycle transition conflicts with existing state. |
| 503 | A verifier or durable dependency is temporarily unavailable. |
200 application/json body: App
DELETE /admin/v1/apps/{app_id}
Operation: disableApp. Soft-disables ingestion, revokes all app API keys, disables webhooks, and retains audit history.
Authentication: adminBearer
| Parameter | Location | Required | Type | Details |
|---|---|---|---|---|
app_id | path | Yes | string | format: "uuid". |
| Response | Meaning |
|---|---|
| 204 | App disabled. |
| 401 | The required bearer credential is missing, invalid, or revoked. |
| 404 | The app-scoped resource does not exist. |
| 503 | A verifier or durable dependency is temporarily unavailable. |
GET /admin/v1/apps/{app_id}/api-keys
Operation: listAppAPIKeys.
Authentication: adminBearer
| Parameter | Location | Required | Type | Details |
|---|---|---|---|---|
app_id | path | Yes | string | format: "uuid". |
| Response | Meaning |
|---|---|
| 200 | Safe API-key metadata; plaintext keys are never returned. |
| 401 | The required bearer credential is missing, invalid, or revoked. |
| 404 | The app-scoped resource does not exist. |
| 503 | A verifier or durable dependency is temporarily unavailable. |
200 application/json body:
{
"type": "object",
"required": [
"api_keys"
],
"properties": {
"api_keys": {
"type": "array",
"items": {
"$ref": "#/components/schemas/APIKey"
}
}
},
"additionalProperties": false
}POST /admin/v1/apps/{app_id}/api-keys
Operation: createAppAPIKey.
Authentication: adminBearer
| Parameter | Location | Required | Type | Details |
|---|---|---|---|---|
app_id | path | Yes | string | format: "uuid". |
Request body: required.
Content type: application/json.
{
"type": "object",
"properties": {
"label": {
"type": "string",
"maxLength": 512
},
"kind": {
"type": "string",
"enum": [
"secret",
"publishable"
],
"default": "secret"
}
},
"additionalProperties": false
}| Response | Meaning |
|---|---|
| 201 | Safe metadata and one-time plaintext secret. |
| 400 | Payload is malformed or fails store validation. |
| 401 | The required bearer credential is missing, invalid, or revoked. |
| 404 | The app-scoped resource does not exist. |
| 409 | The requested identifier or lifecycle transition conflicts with existing state. |
| 503 | A verifier or durable dependency is temporarily unavailable. |
201 application/json body: CreatedAPIKey
Response headers: Cache-Control (const: "no-store".).
DELETE /admin/v1/apps/{app_id}/api-keys/{key_id}
Operation: revokeAppAPIKey.
Authentication: adminBearer
| Parameter | Location | Required | Type | Details |
|---|---|---|---|---|
app_id | path | Yes | string | format: "uuid". |
key_id | path | Yes | string | format: "uuid". |
| Response | Meaning |
|---|---|
| 204 | Key revoked. |
| 401 | The required bearer credential is missing, invalid, or revoked. |
| 404 | The app-scoped resource does not exist. |
| 503 | A verifier or durable dependency is temporarily unavailable. |
Incoming store notifications
POST /ingest/apple/assn
Operation: ingestAppleNotification. Verifies an App Store Server Notifications V2 outer and nested JWS values, attributes its app, and atomically appends and projects or rejects it.
Authentication: No app-key security scheme declared; store-ingress verification still applies where described.
Request body: required.
Content type: application/json.
{
"type": "object",
"required": [
"signedPayload"
],
"properties": {
"signedPayload": {
"type": "string"
}
},
"additionalProperties": false
}| Response | Meaning |
|---|---|
| 200 | Delivery appended, deduplicated, or durably rejected. |
| 503 | PostgreSQL or Apple's OCSP responder is temporarily unavailable. |
POST /ingest/google/rtdn
Operation: ingestGoogleNotification. Verifies Pub/Sub OIDC identity, appends the RTDN doorbell, fetches authoritative subscriptionsv2 or productsv2 state when required, and atomically projects all line items.
Authentication: googlePubSubOIDC
Request body: required.
Content type: application/json. PubSubPush
| Response | Meaning |
|---|---|
| 200 | Delivery appended, deduplicated, or durably rejected. |
| 401 | The required bearer credential is missing, invalid, or revoked. |
| 403 | The valid Google identity is not the configured Pub/Sub service account. |
| 503 | A verifier or durable dependency is temporarily unavailable. |
Health and observability
GET /livez
Operation: getLiveness.
Authentication: No app-key security scheme declared; store-ingress verification still applies where described.
| Response | Meaning |
|---|---|
| 200 | Process is alive. |
200 application/json body: Probe
GET /readyz
Operation: getReadiness.
Authentication: No app-key security scheme declared; store-ingress verification still applies where described.
| Response | Meaning |
|---|---|
| 200 | Process and PostgreSQL are ready. |
| 503 | PostgreSQL is unavailable. |
200 application/json body: Probe
GET /healthz
Operation: getHealth. Compatibility alias for readiness.
Authentication: No app-key security scheme declared; store-ingress verification still applies where described.
| Response | Meaning |
|---|---|
| 200 | Ready. |
| 503 | Not ready. |
200 application/json body: Probe
GET /metrics
Operation: getMetrics.
Authentication: No app-key security scheme declared; store-ingress verification still applies where described.
| Response | Meaning |
|---|---|
| 200 | Prometheus exposition. |
200 text/plain body:
{
"type": "string"
}Authentication schemes
googlePubSubOIDC
{
"type": "http",
"scheme": "bearer",
"bearerFormat": "Google OIDC ID token"
}bearerAPIKey
{
"type": "http",
"scheme": "bearer",
"bearerFormat": "iap_sk_ secret or iap_pk_ publishable app key"
}adminBearer
{
"type": "http",
"scheme": "bearer",
"bearerFormat": "root admin API key"
}Request and response models
Fields are listed below. Nested array/object definitions, alternatives, and conditional rules remain in the complete schema following each model when applicable. writeOnly denotes one-time/input secret material; do not assume it can be read back from management lists.
Probe
| Field | Required | Type | Details |
|---|---|---|---|
status | Yes | string | Values: ok, unavailable. |
{
"type": "object",
"required": [
"status"
],
"properties": {
"status": {
"type": "string",
"enum": [
"ok",
"unavailable"
]
}
},
"additionalProperties": false
}PubSubPush
| Field | Required | Type | Details |
|---|---|---|---|
message | Yes | object | |
subscription | No | string |
{
"type": "object",
"required": [
"message"
],
"properties": {
"message": {
"type": "object",
"required": [
"data",
"messageId"
],
"properties": {
"data": {
"type": "string",
"contentEncoding": "base64"
},
"messageId": {
"type": "string"
},
"publishTime": {
"type": "string",
"format": "date-time"
},
"attributes": {
"type": "object",
"additionalProperties": {
"type": "string"
}
}
},
"additionalProperties": true
},
"subscription": {
"type": "string"
}
},
"additionalProperties": true
}ReceiptSubmission
| Field | Required | Type | Details |
|---|---|---|---|
platform | Yes | string | Values: apple, google. |
app_user_id | Yes | string | minLength: 1. maxLength: 512. |
product_type | No | string | Required for Google; omitted for Apple. Values: subscription, one_time_product. |
store_payload | Yes | string | Apple StoreKit transaction jwsRepresentation or Google purchase token. |
{
"type": "object",
"required": [
"platform",
"app_user_id",
"store_payload"
],
"properties": {
"platform": {
"type": "string",
"enum": [
"apple",
"google"
]
},
"app_user_id": {
"type": "string",
"minLength": 1,
"maxLength": 512
},
"product_type": {
"type": "string",
"enum": [
"subscription",
"one_time_product"
],
"description": "Required for Google; omitted for Apple."
},
"store_payload": {
"type": "string",
"description": "Apple StoreKit transaction jwsRepresentation or Google purchase token."
}
},
"additionalProperties": false,
"allOf": [
{
"if": {
"properties": {
"platform": {
"const": "google"
}
}
},
"then": {
"required": [
"product_type"
]
}
}
]
}IngestResult
| Field | Required | Type | Details |
|---|---|---|---|
event_id | Yes | string | Positive decimal int64 ledger id (maximum 9223372036854775807) encoded as a string for lossless JavaScript and Dart interoperability. maxLength: 19. pattern: "^[1-9][0-9]*$". |
deduplicated | Yes | boolean |
{
"type": "object",
"required": [
"event_id",
"deduplicated"
],
"properties": {
"event_id": {
"type": "string",
"pattern": "^[1-9][0-9]*$",
"maxLength": 19,
"description": "Positive decimal int64 ledger id (maximum 9223372036854775807) encoded as a string for lossless JavaScript and Dart interoperability."
},
"deduplicated": {
"type": "boolean"
}
},
"additionalProperties": false
}Subscriber
| Field | Required | Type | Details |
|---|---|---|---|
app_user_id | Yes | string | |
customer_id | Yes | string | format: "uuid". |
access_levels | Yes | object |
{
"type": "object",
"required": [
"app_user_id",
"customer_id",
"access_levels"
],
"properties": {
"app_user_id": {
"type": "string"
},
"customer_id": {
"type": "string",
"format": "uuid"
},
"access_levels": {
"type": "object",
"additionalProperties": {
"$ref": "#/components/schemas/SubscriberAccessLevel"
}
}
},
"additionalProperties": false
}SubscriberAccessLevel
| Field | Required | Type | Details |
|---|---|---|---|
active | Yes | boolean | |
expires_at | No | string | format: "date-time". |
platform | Yes | string | Values: apple, google. |
product_id | Yes | string | |
last_verified_at | Yes | string | format: "date-time". |
event_id | Yes | string | Positive decimal int64 ledger id (maximum 9223372036854775807) encoded as a string for lossless JavaScript and Dart interoperability. maxLength: 19. pattern: "^[1-9][0-9]*$". |
{
"type": "object",
"required": [
"active",
"platform",
"product_id",
"last_verified_at",
"event_id"
],
"properties": {
"active": {
"type": "boolean"
},
"expires_at": {
"type": "string",
"format": "date-time"
},
"platform": {
"type": "string",
"enum": [
"apple",
"google"
]
},
"product_id": {
"type": "string"
},
"last_verified_at": {
"type": "string",
"format": "date-time"
},
"event_id": {
"type": "string",
"pattern": "^[1-9][0-9]*$",
"maxLength": 19,
"description": "Positive decimal int64 ledger id (maximum 9223372036854775807) encoded as a string for lossless JavaScript and Dart interoperability."
}
},
"additionalProperties": false
}CurrentProductSet
| Field | Required | Type | Details |
|---|---|---|---|
product_set | Yes | union |
{
"type": "object",
"required": [
"product_set"
],
"properties": {
"product_set": {
"anyOf": [
{
"$ref": "#/components/schemas/ProductSet"
},
{
"type": "null"
}
]
}
},
"additionalProperties": false
}ProductSet
| Field | Required | Type | Details |
|---|---|---|---|
id | Yes | string | format: "uuid". |
identifier | Yes | string | minLength: 1. maxLength: 128. pattern: "^[A-Za-z0-9._-]+$". |
display_name | Yes | string | minLength: 1. maxLength: 256. |
packages | Yes | array of ProductSetPackage | Ordered by ascending position; identifiers and positions are unique within the set. |
updated_at | Yes | string | format: "date-time". |
{
"type": "object",
"required": [
"id",
"identifier",
"display_name",
"packages",
"updated_at"
],
"properties": {
"id": {
"type": "string",
"format": "uuid"
},
"identifier": {
"type": "string",
"minLength": 1,
"maxLength": 128,
"pattern": "^[A-Za-z0-9._-]+$"
},
"display_name": {
"type": "string",
"minLength": 1,
"maxLength": 256
},
"packages": {
"type": "array",
"description": "Ordered by ascending position; identifiers and positions are unique within the set.",
"items": {
"$ref": "#/components/schemas/ProductSetPackage"
}
},
"updated_at": {
"type": "string",
"format": "date-time"
}
},
"additionalProperties": false
}ProductSetPackage
| Field | Required | Type | Details |
|---|---|---|---|
id | Yes | string | format: "uuid". |
identifier | Yes | string | minLength: 1. maxLength: 128. pattern: "^[A-Za-z0-9._-]+$". |
package_type | Yes | string | Values: custom, lifetime, annual, six_month, three_month, two_month, monthly, weekly. |
platform | Yes | string | Values: apple, google. |
product_id | Yes | string | minLength: 1. maxLength: 512. |
base_plan_id | No | string | Optional Google Play base-plan identifier. Present only for Google packages; preserve it when selecting a storefront offer. minLength: 1. maxLength: 128. pattern: "^[A-Za-z0-9._-]+$". |
position | Yes | integer | minimum: 0. maximum: 1000. |
{
"type": "object",
"required": [
"id",
"identifier",
"package_type",
"platform",
"product_id",
"position"
],
"properties": {
"id": {
"type": "string",
"format": "uuid"
},
"identifier": {
"type": "string",
"minLength": 1,
"maxLength": 128,
"pattern": "^[A-Za-z0-9._-]+$"
},
"package_type": {
"type": "string",
"enum": [
"custom",
"lifetime",
"annual",
"six_month",
"three_month",
"two_month",
"monthly",
"weekly"
]
},
"platform": {
"type": "string",
"enum": [
"apple",
"google"
]
},
"product_id": {
"type": "string",
"minLength": 1,
"maxLength": 512
},
"base_plan_id": {
"type": "string",
"minLength": 1,
"maxLength": 128,
"pattern": "^[A-Za-z0-9._-]+$",
"description": "Optional Google Play base-plan identifier. Present only for Google packages; preserve it when selecting a storefront offer."
},
"position": {
"type": "integer",
"minimum": 0,
"maximum": 1000
}
},
"additionalProperties": false
}WebhookEndpoint
| Field | Required | Type | Details |
|---|---|---|---|
id | Yes | string | format: "uuid". |
url | Yes | string | format: "uri". maxLength: 2048. |
description | Yes | string | maxLength: 512. |
event_types | Yes | array of string | |
enabled | Yes | boolean | |
disabled_reason | No | string | maxLength: 512. |
disabled_at | No | string | format: "date-time". |
created_at | Yes | string | format: "date-time". |
updated_at | Yes | string | format: "date-time". |
{
"type": "object",
"required": [
"id",
"url",
"description",
"event_types",
"enabled",
"created_at",
"updated_at"
],
"properties": {
"id": {
"type": "string",
"format": "uuid"
},
"url": {
"type": "string",
"format": "uri",
"maxLength": 2048
},
"description": {
"type": "string",
"maxLength": 512
},
"event_types": {
"type": "array",
"minItems": 1,
"maxItems": 100,
"uniqueItems": true,
"items": {
"type": "string"
}
},
"enabled": {
"type": "boolean"
},
"disabled_reason": {
"type": "string",
"maxLength": 512
},
"disabled_at": {
"type": "string",
"format": "date-time"
},
"created_at": {
"type": "string",
"format": "date-time"
},
"updated_at": {
"type": "string",
"format": "date-time"
}
},
"additionalProperties": false
}CreateWebhookEndpoint
| Field | Required | Type | Details |
|---|---|---|---|
url | Yes | string | format: "uri". maxLength: 2048. pattern: "^https://". |
description | No | string | maxLength: 512. |
event_types | No | array of string | default: ["access.changed"]. |
{
"type": "object",
"required": [
"url"
],
"properties": {
"url": {
"type": "string",
"format": "uri",
"pattern": "^https://",
"maxLength": 2048
},
"description": {
"type": "string",
"maxLength": 512
},
"event_types": {
"type": "array",
"minItems": 1,
"maxItems": 100,
"uniqueItems": true,
"default": [
"access.changed"
],
"items": {
"type": "string"
}
}
},
"additionalProperties": false
}UpdateWebhookEndpoint
| Field | Required | Type | Details |
|---|---|---|---|
url | No | string | format: "uri". maxLength: 2048. pattern: "^https://". |
description | No | string | maxLength: 512. |
event_types | No | array of string | |
enabled | No | boolean |
{
"type": "object",
"minProperties": 1,
"properties": {
"url": {
"type": "string",
"format": "uri",
"pattern": "^https://",
"maxLength": 2048
},
"description": {
"type": "string",
"maxLength": 512
},
"event_types": {
"type": "array",
"minItems": 1,
"maxItems": 100,
"uniqueItems": true,
"items": {
"type": "string"
}
},
"enabled": {
"type": "boolean"
}
},
"additionalProperties": false
}CreatedWebhookEndpoint
| Field | Required | Type | Details |
|---|---|---|---|
endpoint | Yes | WebhookEndpoint | |
secret | Yes | string | pattern: "^whsec_". writeOnly: true. |
{
"type": "object",
"required": [
"endpoint",
"secret"
],
"properties": {
"endpoint": {
"$ref": "#/components/schemas/WebhookEndpoint"
},
"secret": {
"type": "string",
"pattern": "^whsec_",
"writeOnly": true
}
},
"additionalProperties": false
}RotatedWebhookSecret
| Field | Required | Type | Details |
|---|---|---|---|
endpoint_id | Yes | string | format: "uuid". |
secret | Yes | string | pattern: "^whsec_". writeOnly: true. |
rotated_at | Yes | string | format: "date-time". |
overlap_ends_at | Yes | string | format: "date-time". |
{
"type": "object",
"required": [
"endpoint_id",
"secret",
"rotated_at",
"overlap_ends_at"
],
"properties": {
"endpoint_id": {
"type": "string",
"format": "uuid"
},
"secret": {
"type": "string",
"pattern": "^whsec_",
"writeOnly": true
},
"rotated_at": {
"type": "string",
"format": "date-time"
},
"overlap_ends_at": {
"type": "string",
"format": "date-time"
}
},
"additionalProperties": false
}WebhookDeliveryStatus
{
"type": "string",
"enum": [
"pending",
"in_flight",
"retry",
"succeeded",
"dead_letter",
"canceled"
]
}WebhookDelivery
| Field | Required | Type | Details |
|---|---|---|---|
message_id | Yes | string | pattern: "^msg_[A-Za-z0-9_-]{20,64}$". |
endpoint_id | Yes | string | format: "uuid". |
event_number | Yes | integer | format: "int64". |
event_type | Yes | string | |
status | Yes | WebhookDeliveryStatus | |
attempt_count | Yes | integer | minimum: 0. |
next_attempt_at | No | string | format: "date-time". |
first_attempt_at | No | string | format: "date-time". |
last_attempt_at | No | string | format: "date-time". |
succeeded_at | No | string | format: "date-time". |
last_http_status | No | integer | minimum: 100. maximum: 599. |
last_error | No | string | maxLength: 2048. |
last_response_body | No | string | UTF-8-safe preview capped at 64 KiB. |
cycle_started_at | Yes | string | format: "date-time". |
created_at | Yes | string | format: "date-time". |
updated_at | Yes | string | format: "date-time". |
{
"type": "object",
"required": [
"message_id",
"endpoint_id",
"event_number",
"event_type",
"status",
"attempt_count",
"cycle_started_at",
"created_at",
"updated_at"
],
"properties": {
"message_id": {
"type": "string",
"pattern": "^msg_[A-Za-z0-9_-]{20,64}$"
},
"endpoint_id": {
"type": "string",
"format": "uuid"
},
"event_number": {
"type": "integer",
"format": "int64"
},
"event_type": {
"type": "string"
},
"status": {
"$ref": "#/components/schemas/WebhookDeliveryStatus"
},
"attempt_count": {
"type": "integer",
"minimum": 0
},
"next_attempt_at": {
"type": "string",
"format": "date-time"
},
"first_attempt_at": {
"type": "string",
"format": "date-time"
},
"last_attempt_at": {
"type": "string",
"format": "date-time"
},
"succeeded_at": {
"type": "string",
"format": "date-time"
},
"last_http_status": {
"type": "integer",
"minimum": 100,
"maximum": 599
},
"last_error": {
"type": "string",
"maxLength": 2048
},
"last_response_body": {
"type": "string",
"description": "UTF-8-safe preview capped at 64 KiB."
},
"cycle_started_at": {
"type": "string",
"format": "date-time"
},
"created_at": {
"type": "string",
"format": "date-time"
},
"updated_at": {
"type": "string",
"format": "date-time"
}
},
"additionalProperties": false
}WebhookDeliveryAttempt
| Field | Required | Type | Details |
|---|---|---|---|
attempt_number | Yes | integer | minimum: 1. |
started_at | Yes | string | format: "date-time". |
finished_at | No | string | format: "date-time". |
http_status | No | integer | minimum: 100. maximum: 599. |
error | No | string | maxLength: 2048. |
response_body | No | string | |
duration_ms | No | integer | format: "int64". minimum: 0. |
succeeded | No | boolean |
{
"type": "object",
"required": [
"attempt_number",
"started_at"
],
"properties": {
"attempt_number": {
"type": "integer",
"minimum": 1
},
"started_at": {
"type": "string",
"format": "date-time"
},
"finished_at": {
"type": "string",
"format": "date-time"
},
"http_status": {
"type": "integer",
"minimum": 100,
"maximum": 599
},
"error": {
"type": "string",
"maxLength": 2048
},
"response_body": {
"type": "string"
},
"duration_ms": {
"type": "integer",
"format": "int64",
"minimum": 0
},
"succeeded": {
"type": "boolean"
}
},
"additionalProperties": false
}WebhookDeliveryDetail
| Field | Required | Type | Details |
|---|---|---|---|
delivery | Yes | WebhookDelivery | |
attempts | Yes | array of WebhookDeliveryAttempt |
{
"type": "object",
"required": [
"delivery",
"attempts"
],
"properties": {
"delivery": {
"$ref": "#/components/schemas/WebhookDelivery"
},
"attempts": {
"type": "array",
"items": {
"$ref": "#/components/schemas/WebhookDeliveryAttempt"
}
}
},
"additionalProperties": false
}OutboundWebhookEvent
Exact JSON body signed using Standard Webhooks headers.
| Field | Required | Type | Details |
|---|---|---|---|
id | Yes | string | pattern: "^evt_[0-9]+$". |
type | Yes | string | |
api_version | Yes | string | const: "2026-08-28". |
timestamp | Yes | string | format: "date-time". |
event_number | Yes | integer | Monotonic but not gapless ledger identifier. format: "int64". |
data | Yes | object |
{
"type": "object",
"description": "Exact JSON body signed using Standard Webhooks headers.",
"required": [
"id",
"type",
"api_version",
"timestamp",
"event_number",
"data"
],
"properties": {
"id": {
"type": "string",
"pattern": "^evt_[0-9]+$"
},
"type": {
"type": "string",
"example": "access.changed"
},
"api_version": {
"type": "string",
"const": "2026-08-28"
},
"timestamp": {
"type": "string",
"format": "date-time"
},
"event_number": {
"type": "integer",
"format": "int64",
"description": "Monotonic but not gapless ledger identifier."
},
"data": {
"type": "object",
"additionalProperties": true
}
},
"additionalProperties": false
}App
| Field | Required | Type | Details |
|---|---|---|---|
id | Yes | string | format: "uuid". |
name | Yes | string | minLength: 1. maxLength: 512. |
apple_bundle_id | No | string | minLength: 1. maxLength: 512. |
apple_app_apple_id | No | integer | format: "int64". minimum: 1. |
google_package_name | No | string | minLength: 1. maxLength: 512. |
enabled | Yes | boolean | |
disabled_at | No | string | format: "date-time". |
created_at | Yes | string | format: "date-time". |
updated_at | Yes | string | format: "date-time". |
{
"type": "object",
"required": [
"id",
"name",
"enabled",
"created_at",
"updated_at"
],
"properties": {
"id": {
"type": "string",
"format": "uuid"
},
"name": {
"type": "string",
"minLength": 1,
"maxLength": 512
},
"apple_bundle_id": {
"type": "string",
"minLength": 1,
"maxLength": 512
},
"apple_app_apple_id": {
"type": "integer",
"format": "int64",
"minimum": 1
},
"google_package_name": {
"type": "string",
"minLength": 1,
"maxLength": 512
},
"enabled": {
"type": "boolean"
},
"disabled_at": {
"type": "string",
"format": "date-time"
},
"created_at": {
"type": "string",
"format": "date-time"
},
"updated_at": {
"type": "string",
"format": "date-time"
}
},
"additionalProperties": false
}CreateApp
| Field | Required | Type | Details |
|---|---|---|---|
name | Yes | string | minLength: 1. maxLength: 512. |
apple_bundle_id | No | string | minLength: 1. maxLength: 512. |
apple_app_apple_id | No | integer | Required for production Apple notification attribution. format: "int64". minimum: 1. |
google_package_name | No | string | minLength: 1. maxLength: 512. |
initial_key_label | No | string | maxLength: 512. default: "default". |
{
"type": "object",
"required": [
"name"
],
"anyOf": [
{
"required": [
"apple_bundle_id"
]
},
{
"required": [
"google_package_name"
]
}
],
"properties": {
"name": {
"type": "string",
"minLength": 1,
"maxLength": 512
},
"apple_bundle_id": {
"type": "string",
"minLength": 1,
"maxLength": 512
},
"apple_app_apple_id": {
"type": "integer",
"format": "int64",
"minimum": 1,
"description": "Required for production Apple notification attribution."
},
"google_package_name": {
"type": "string",
"minLength": 1,
"maxLength": 512
},
"initial_key_label": {
"type": "string",
"maxLength": 512,
"default": "default"
}
},
"additionalProperties": false
}UpdateApp
| Field | Required | Type | Details |
|---|---|---|---|
name | No | string | minLength: 1. maxLength: 512. |
apple_bundle_id | No | string or null | minLength: 1. maxLength: 512. |
apple_app_apple_id | No | integer or null | format: "int64". minimum: 1. |
google_package_name | No | string or null | minLength: 1. maxLength: 512. |
enabled | No | boolean |
{
"type": "object",
"minProperties": 1,
"properties": {
"name": {
"type": "string",
"minLength": 1,
"maxLength": 512
},
"apple_bundle_id": {
"type": [
"string",
"null"
],
"minLength": 1,
"maxLength": 512
},
"apple_app_apple_id": {
"type": [
"integer",
"null"
],
"format": "int64",
"minimum": 1
},
"google_package_name": {
"type": [
"string",
"null"
],
"minLength": 1,
"maxLength": 512
},
"enabled": {
"type": "boolean"
}
},
"additionalProperties": false
}APIKey
| Field | Required | Type | Details |
|---|---|---|---|
id | Yes | string | format: "uuid". |
kind | Yes | string | Values: secret, publishable. |
label | Yes | string | maxLength: 512. |
hint | Yes | string | maxLength: 80. |
created_at | Yes | string | format: "date-time". |
revoked_at | No | string | format: "date-time". |
{
"type": "object",
"required": [
"id",
"kind",
"label",
"hint",
"created_at"
],
"properties": {
"id": {
"type": "string",
"format": "uuid"
},
"kind": {
"type": "string",
"enum": [
"secret",
"publishable"
]
},
"label": {
"type": "string",
"maxLength": 512
},
"hint": {
"type": "string",
"maxLength": 80
},
"created_at": {
"type": "string",
"format": "date-time"
},
"revoked_at": {
"type": "string",
"format": "date-time"
}
},
"additionalProperties": false
}CreatedAPIKey
| Field | Required | Type | Details |
|---|---|---|---|
api_key | Yes | APIKey | |
secret | Yes | string | pattern: "^iap_(sk|pk)_". writeOnly: true. |
{
"type": "object",
"required": [
"api_key",
"secret"
],
"properties": {
"api_key": {
"$ref": "#/components/schemas/APIKey"
},
"secret": {
"type": "string",
"pattern": "^iap_(sk|pk)_",
"writeOnly": true
}
},
"additionalProperties": false
}CreatedApp
| Field | Required | Type | Details |
|---|---|---|---|
app | Yes | App | |
api_key | Yes | APIKey | |
secret | Yes | string | pattern: "^iap_sk_". writeOnly: true. |
{
"type": "object",
"required": [
"app",
"api_key",
"secret"
],
"properties": {
"app": {
"$ref": "#/components/schemas/App"
},
"api_key": {
"$ref": "#/components/schemas/APIKey"
},
"secret": {
"type": "string",
"pattern": "^iap_sk_",
"writeOnly": true
}
},
"additionalProperties": false
}CatalogAccessLevel
| Field | Required | Type | Details |
|---|---|---|---|
id | Yes | string | format: "uuid". |
lookup_key | Yes | string | pattern: "^[A-Za-z0-9][A-Za-z0-9._-]{0,254}$". |
display_name | Yes | string | maxLength: 512. |
created_at | Yes | string | format: "date-time". |
updated_at | Yes | string | format: "date-time". |
{
"type": "object",
"required": [
"id",
"lookup_key",
"display_name",
"created_at",
"updated_at"
],
"properties": {
"id": {
"type": "string",
"format": "uuid"
},
"lookup_key": {
"type": "string",
"pattern": "^[A-Za-z0-9][A-Za-z0-9._-]{0,254}$"
},
"display_name": {
"type": "string",
"maxLength": 512
},
"created_at": {
"type": "string",
"format": "date-time"
},
"updated_at": {
"type": "string",
"format": "date-time"
}
},
"additionalProperties": false
}CreateAccessLevel
| Field | Required | Type | Details |
|---|---|---|---|
lookup_key | Yes | string | pattern: "^[A-Za-z0-9][A-Za-z0-9._-]{0,254}$". |
display_name | No | string | maxLength: 512. |
{
"type": "object",
"required": [
"lookup_key"
],
"properties": {
"lookup_key": {
"type": "string",
"pattern": "^[A-Za-z0-9][A-Za-z0-9._-]{0,254}$"
},
"display_name": {
"type": "string",
"maxLength": 512
}
},
"additionalProperties": false
}GrantMode
{
"type": "string",
"enum": [
"store_managed",
"lifetime"
]
}ProductAccessMapping
| Field | Required | Type | Details |
|---|---|---|---|
id | Yes | string | format: "uuid". |
platform | Yes | string | Values: apple, google. |
product_id | Yes | string | minLength: 1. maxLength: 512. |
access_level_id | Yes | string | format: "uuid". |
access_level_key | Yes | string | |
grant_mode | Yes | GrantMode | |
starts_after_event_id | Yes | integer | Mapping applies to source events with a greater ledger id. format: "int64". minimum: 0. |
created_at | Yes | string | format: "date-time". |
{
"type": "object",
"required": [
"id",
"platform",
"product_id",
"access_level_id",
"access_level_key",
"grant_mode",
"starts_after_event_id",
"created_at"
],
"properties": {
"id": {
"type": "string",
"format": "uuid"
},
"platform": {
"type": "string",
"enum": [
"apple",
"google"
]
},
"product_id": {
"type": "string",
"minLength": 1,
"maxLength": 512
},
"access_level_id": {
"type": "string",
"format": "uuid"
},
"access_level_key": {
"type": "string"
},
"grant_mode": {
"$ref": "#/components/schemas/GrantMode"
},
"starts_after_event_id": {
"type": "integer",
"format": "int64",
"minimum": 0,
"description": "Mapping applies to source events with a greater ledger id."
},
"created_at": {
"type": "string",
"format": "date-time"
}
},
"additionalProperties": false
}CreateProductAccessMapping
| Field | Required | Type | Details |
|---|---|---|---|
platform | Yes | string | Values: apple, google. |
product_id | Yes | string | minLength: 1. maxLength: 512. |
access_level_id | Yes | string | format: "uuid". |
grant_mode | No | GrantMode |
{
"type": "object",
"required": [
"platform",
"product_id",
"access_level_id"
],
"properties": {
"platform": {
"type": "string",
"enum": [
"apple",
"google"
]
},
"product_id": {
"type": "string",
"minLength": 1,
"maxLength": 512
},
"access_level_id": {
"type": "string",
"format": "uuid"
},
"grant_mode": {
"$ref": "#/components/schemas/GrantMode"
}
},
"additionalProperties": false
}CreateClientToken
| Field | Required | Type | Details |
|---|---|---|---|
app_user_id | Yes | string | minLength: 1. maxLength: 512. |
ttl_seconds | No | integer | format: "int64". minimum: 300. maximum: 86400. default: 3600. |
{
"type": "object",
"required": [
"app_user_id"
],
"properties": {
"app_user_id": {
"type": "string",
"minLength": 1,
"maxLength": 512
},
"ttl_seconds": {
"type": "integer",
"format": "int64",
"minimum": 300,
"maximum": 86400,
"default": 3600
}
},
"additionalProperties": false
}CreatedClientToken
| Field | Required | Type | Details |
|---|---|---|---|
id | Yes | string | format: "uuid". |
app_user_id | Yes | string | minLength: 1. maxLength: 512. |
hint | Yes | string | maxLength: 80. |
expires_at | Yes | string | format: "date-time". |
token | Yes | string | pattern: "^iap_ct_". writeOnly: true. |
{
"type": "object",
"required": [
"id",
"app_user_id",
"hint",
"expires_at",
"token"
],
"properties": {
"id": {
"type": "string",
"format": "uuid"
},
"app_user_id": {
"type": "string",
"minLength": 1,
"maxLength": 512
},
"hint": {
"type": "string",
"maxLength": 80
},
"expires_at": {
"type": "string",
"format": "date-time"
},
"token": {
"type": "string",
"pattern": "^iap_ct_",
"writeOnly": true
}
},
"additionalProperties": false
}Error
| Field | Required | Type | Details |
|---|---|---|---|
error | Yes | string |
{
"type": "object",
"required": [
"error"
],
"properties": {
"error": {
"type": "string"
}
},
"additionalProperties": false
}Shared error responses
InvalidRequest
Payload is malformed or fails store validation.
{
"description": "Payload is malformed or fails store validation.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}Unauthorized
The required bearer credential is missing, invalid, or revoked.
{
"description": "The required bearer credential is missing, invalid, or revoked.",
"headers": {
"WWW-Authenticate": {
"schema": {
"type": "string"
}
}
},
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}TooLarge
Request exceeds 256 KiB.
{
"description": "Request exceeds 256 KiB.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}RateLimited
The authenticated API key exceeded its process-local receipt rate limit.
{
"description": "The authenticated API key exceeded its process-local receipt rate limit.",
"headers": {
"Retry-After": {
"schema": {
"type": "string"
}
}
},
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}Unavailable
A verifier or durable dependency is temporarily unavailable.
{
"description": "A verifier or durable dependency is temporarily unavailable.",
"headers": {
"Retry-After": {
"schema": {
"type": "string"
}
}
},
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}NotFound
The app-scoped resource does not exist.
{
"description": "The app-scoped resource does not exist.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}Conflict
The requested identifier or lifecycle transition conflicts with existing state.
{
"description": "The requested identifier or lifecycle transition conflicts with existing state.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}Forbidden
The authenticated key or customer token is not authorized for this resource.
{
"description": "The authenticated key or customer token is not authorized for this resource.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}