Credit

The client's promotional credit: the balance, the lifetime totals, and the movement history. The balance is split into three buckets by where it can be spent, so there is no single "available total" field. Paths are relative to the /api/v1 prefix; these routes require a client Authorization: Bearer {token}.

See Common errors.

Endpoints

Method URI Role Description
GET /credit/me Client Current promotional credit balance
GET /credit/me/transactions Client Paginated credit movement history

GET /credit/me

Returns the client's credit balance and lifetime totals. All seven fields are always present, 0 when there is no credit.

Response 200

{
  "credit": {
    "anyUSD": 10,
    "ordersUSD": 5,
    "surplusUSD": 0,
    "usableOnOrdersUSD": 15,
    "usableOnSurplusUSD": 10,
    "earnedUSD": 25,
    "redeemedUSD": 10
  }
}
Field Type Description
credit.anyUSD number Credit spendable on any order. May be negative after a manual admin debit
credit.ordersUSD number Credit spendable only on regular orders. May be negative
credit.surplusUSD number Credit spendable only on surplus reservations. May be negative
credit.usableOnOrdersUSD number anyUSD + ordersUSD β€” the maximum applicable to a regular order. Negative buckets count as 0
credit.usableOnSurplusUSD number anyUSD + surplusUSD β€” the maximum applicable to a surplus reservation. Negative buckets count as 0
credit.earnedUSD number Lifetime credit granted by promotion campaigns, across all buckets
credit.redeemedUSD number Lifetime credit consumed by orders and not returned β€” both the part that discounted them and the part burned past their total. Credit reserved on an in-flight order is included

earnedUSD and redeemedUSD cover campaign grants and order redemptions only; manual admin adjustments are in neither, so earnedUSD βˆ’ redeemedUSD need not equal the buckets.

Errors

Status When
401 Missing or invalid bearer token
403 The token is not a client token

GET /credit/me/transactions

Cursor-paginated movement history, newest first.

Query parameters

Field Type Required Rules
type string No One of PROMO_GRANT, ORDER_REDEMPTION, ORDER_FORFEIT, ORDER_REFUND, MANUAL_ADJUSTMENT
scope string No One of ANY, ORDERS, SURPLUS
date_from date No β€”
date_to date No after_or_equal:date_from
limit integer No min:1, max:100 (default 30)
cursor string No Cursor from a previous response

Response 200

{
  "items": [
    {
      "id": 12,
      "user_id": 3,
      "order_id": null,
      "promotion_id": 4,
      "type": "PROMO_GRANT",
      "scope": "SURPLUS",
      "direction": "CREDIT",
      "amount_cents": 1000,
      "amount_usd": 10,
      "balance_after_cents": 1000,
      "balance_after_usd": 10,
      "description": "CrΓ©dito Bienvenida",
      "created_at": "2026-08-27T12:00:00+00:00"
    }
  ],
  "next_cursor": null,
  "has_more": false
}
Field Type Description
items[].type string PROMO_GRANT, ORDER_REDEMPTION, ORDER_FORFEIT, ORDER_REFUND or MANUAL_ADJUSTMENT
items[].scope string The bucket that moved: ANY, ORDERS or SURPLUS
items[].direction string CREDIT or DEBIT
items[].amount_cents integer Always positive; the sign lives in direction
items[].amount_usd number Same amount in USD
items[].balance_after_cents integer Balance of that bucket after the movement; may be negative
items[].balance_after_usd number Same balance in USD
items[].order_id integer|null The order involved, for redemptions and refunds
items[].promotion_id integer|null The campaign that granted it
items[].description string|null Human-readable label
next_cursor string|null Cursor for the next page
has_more boolean Whether more pages exist

An order that draws from two buckets produces two ORDER_REDEMPTION rows for the same order_id. Placing an order spends every bucket spendable on it: the part up to the order total is ORDER_REDEMPTION, and any excess is ORDER_FORFEIT β€” consumed without discounting anything and not carried over. Cancelling or expiring the order reverses both with ORDER_REFUND rows.

Errors

Status When
401 Missing or invalid bearer token
403 The token is not a client token
422 type or scope is not one of the accepted values

Examples

curl /api/v1/credit/me -H "Authorization: Bearer {token}"

curl "/api/v1/credit/me/transactions?scope=SURPLUS&limit=10" \
  -H "Authorization: Bearer {token}"