Preview — pending review
This reference is generated from the platform API contract and is still under review. Operations, fields, and descriptions can change before publication.
Redeem a coupon code into an active credit grant
Redeems a coupon code against the caller's tenant ("Redeem" in the Redeem-a-coupon panel of
the Credits page). The submitted code is normalized (trimmed, upper-cased) and validated against the
tenant's redeemable-code table; a valid code materializes a fresh active credit grant with
source: coupon, consumed: 0, remaining equal to the granted amount (in ten-thousandths of the currency unit), grantedAt set
to now and expiresAt derived from the code's validity window. Redeemed credits apply automatically
to the next invoice.
The grant is resolved by the body's code ALONE — there is no {creditId} path
parameter. A customer knows a coupon's code, never its internal credit id, so requiring the id would
demand information the customer cannot have; a coupon code is unique per tenant, so it is
sufficient on its own to address the grant.
Validation: the normalized code must exist in the tenant's redeemable-code table, not be
already consumed and not be expired. Every one of these failures (unknown, already
redeemed, expired) returns the SAME 422 VALIDATION_FAILED on field: code with the same body, so a
caller cannot tell which codes exist; caller must be authorized for billing commands (otherwise 403
FORBIDDEN). None of these is a 404.
Rate limit & audit: every attempt is recorded (outcome, caller, scope and a hash of
the code — never the code itself). After 5 failed attempts by the tenant within 15 minutes, redeem
answers 429 RATE_LIMITED with details.retryAfterSeconds until the oldest failure leaves the window.
Async & state: Synchronous; returns 200 with the resulting credit grant in active state. A
resource.updated SSE frame (kind: credit, patch: {status, remaining, grantedAt}) is emitted so open
credit lists refresh; the resulting state is immediately available to subsequent reads.
Errors: 401 unauthenticated; 403 caller lacks billing command permission; 404 unknown/unauthorized
scope; 422 unknown, already redeemed or expired coupon code, or missing code field; 429 too many
failed attempts; 500 on backend failure.
Idempotency/Concurrency: This operation does not use Idempotency-Key; it may be omitted
and a sent one is ignored. A retry is processed again rather than answered from a stored result.
A coupon is single-use: the first successful redeem stamps it redeemed under a FOR UPDATE row
lock, and any later redeem of the same code (including a retry of a request that already
succeeded) is refused with the same 422 VALIDATION_FAILED on field: code as an unknown code
and counts as a failed attempt toward the 429 limit. The credit is never granted twice.
bearerTokenAuthorizationBearer <token>An API token (pc_live_…) or a service-account key (sak_live_…), created in Identity & Access Management and sent as Authorization: Bearer <token>. Requests are rate limited per credential and per tenant: every response carries X-RateLimit-Limit, X-RateLimit-Remaining and X-RateLimit-Reset, and a refused request gets 429 RATE_LIMITED with Retry-After.
scopeId*stringOpaque ownership+authorization scope resolving to tenant + subscription + project.
application/json- body
Coupon redemption payload; the code is normalized (trimmed, upper-cased) before validation.
code*stringCoupon code to redeem against the tenant.
Coupon accepted; the resulting active credit grant.
application/json- response
A credit grant (coupon, promotion, support credit or prepaid top-up) with balances in ten-thousandths of the currency unit.
id*stringsource*CreditSourceOrigin of a credit grant.
"coupon""promo""support-credit""prepaid"label*stringcode*|Coupon code for coupon-sourced credits, otherwise null.
granted*integerGranted amount in ten-thousandths of the currency unit.
consumed*integerConsumed amount in ten-thousandths of the currency unit.
remaining*integerRemaining amount in ten-thousandths of the currency unit (0 for exhausted or expired grants).
grantedAt*stringdate-timeexpiresAt*stringdate-timestatus*CreditStatusCredit grant status.
"active""exhausted""expired"reference*stringARN-style billing reference for the credit grant.
curl -X POST "https://example.com/scopes/string/billing/credits/actions/redeem" \ -H "Content-Type: application/json" \ -d '{ "code": "PUBLICCLOUD-WELCOME-300" }'{ "id": "cr-prepaid-apr", "source": "coupon", "label": "Prepaid top-up — wire transfer", "code": "WELCOME2026", "granted": 0, "consumed": 0, "remaining": 0, "grantedAt": "2019-08-24T14:15:22Z", "expiresAt": "2019-08-24T14:15:22Z", "status": "active", "reference": "arn:publiccloud:billing:ist-1:acct-1:credit/cr-prepaid-apr"}