Credits & payments
What each verb costs, and every option a 402 can offer you.
Quote, then spend
Every spending call takes an expected_credits integer. Get it from a quote, send it with the request, and the server refuses rather than charging you a different number.
Create with a price you have agreed to
curl -s -X POST https://api.askdeck.ai/v1/decks \
-H "Authorization: Bearer $ASKDECK_API_KEY" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{
"core_message": "Q3 revenue grew 22% on enterprise renewals",
"slide_count": 10,
"expected_credits": 300
}'A 409 price_drift means the live price is not the number you sent. It is a refusal, not a charge — nothing is written. The body carries both numbers: credits is what the server would charge now, expectedCreditsis what you sent. Re-send with the server's number if that price is acceptable to whoever is paying. Do not strip the field to make it pass.
When you run out: the 402
A 402 is not an error to log and move on from — it carries an ordered options array describing exactly what a human could do next. Render them; do not invent a price.
| cta | What to offer | Kind |
|---|---|---|
| unlock_or_subscribe | Unlock this one deck as a one-off purchase, or start a subscription. | checkout |
| top_up | Buy credits. The amounts on offer arrive in the options array. | checkout |
| manage_decks | Nothing to buy — retry later, or free something up first. | client action |
| upgrade_for_slides | The deck is over the free slide cap: upgrade, or send fewer slides. | checkout / client action |
| confirm_slide_surcharge | Show the higher price, then re-send with confirm_slide_surcharge: true. Never set it without asking. | client action |
| subscribe_for_translation | Translation is subscriber-only at launch. Offer a subscription, not a top-up. | checkout |
| translation_top_up | A subscriber whose balance cannot cover the copies. Offer credits, or removing languages. | checkout |
| buy_revision | Pay for a revision beyond the included round. | checkout |
| insufficient_credits | The video paywall discriminates on code rather than cta. Treat it as top_up. | checkout |
That is the whole set — it is mirrored from the server's own table and a contract test fails the build if the two diverge in either direction. Switch on ctaexhaustively and give the unknown branch a generic “open your account” link rather than silence.
What a key can spend
A key you mint from your own settings spends your personal wallet. An organisation-owned key spends the organisation's pooled wallet, and an org admin can switch that off. If a call fails with forbidden rather than insufficient_credits, that switch is the first thing to check — see forbidden.