Skip to content

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.

ctaWhat to offerKind
unlock_or_subscribeUnlock this one deck as a one-off purchase, or start a subscription.checkout
top_upBuy credits. The amounts on offer arrive in the options array.checkout
manage_decksNothing to buy — retry later, or free something up first.client action
upgrade_for_slidesThe deck is over the free slide cap: upgrade, or send fewer slides.checkout / client action
confirm_slide_surchargeShow the higher price, then re-send with confirm_slide_surcharge: true. Never set it without asking.client action
subscribe_for_translationTranslation is subscriber-only at launch. Offer a subscription, not a top-up.checkout
translation_top_upA subscriber whose balance cannot cover the copies. Offer credits, or removing languages.checkout
buy_revisionPay for a revision beyond the included round.checkout
insufficient_creditsThe 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.