inmake DOCS
Docs / API / Promo

Promo

The credits ledger and coupons.

The credits ledger (credits/*) and coupons (coupons/*): push and read balances, page through records, mint, verify and claim coupons.

POST/api/promo/credits/pushwrites data

Push credits to customer account. value is an integer (negative = a charge). The central incore ledger (the platform AI wallet) moves for master only; identity tokens never push.

Parameters

NameTypeRequiredDescription
storestringrequiredStore ID.
idstringrequiredCustomer ID.
valuenumberrequiredAmount of credits to push.
recordstringoptionalOptional record ID to update.
notestringoptionalOptional label stored on the credits record (e.g. what the charge was for).

Response

object — Returns the new total value.

Sample request

{
  "id": "user_123",
  "value": 100,
  "note": "Welcome bonus"
}
POST/api/promo/credits/value

Get customer credits value.

Parameters

NameTypeRequiredDescription
storestringrequiredStore ID.
idstringrequiredCustomer ID.

Response

object — Returns the credits object with value. Incore-ledger wallets settle their weekly free bucket on read and additionally carry free, free_tier, spent and free_expires (ms timestamp the current period ends).

Sample request

{
  "id": "user_123"
}
POST/api/promo/credits/refreshwrites data

Master-only: force-settle a store's weekly free-credit bucket in the incore ledger and regrant it when the subscription plan changed (mid-week upgrade/downgrade/cancel effect). Idempotent per (period, plan) - redelivered tier events are no-ops. Called server-to-server by the tier order hook receiver.

Parameters

NameTypeRequiredDescription
storestringrequiredMust be the incore ledger (store: incore).
idstringrequiredThe store id whose wallet to refresh.

Response

object — Returns the settled wallet (value, free, free_tier, spent, free_period) plus free_expires.

Sample request

{
  "id": "{storeId}"
}

The store header must be incore (the ledger); id is the store whose wallet is refreshed.

POST/api/promo/credits/records

List a customer's credit records (the per-user ledger).

Parameters

NameTypeRequiredDescription
storestringrequiredStore ID.
idstringrequiredCustomer ID.
queryobjectoptionalFirestore query filter (field -> operator/value).
order_byobjectoptionalOrdering (field -> 'asc' | 'desc').
limitnumberoptionalMax number of records to return.
offsetnumberoptionalPagination offset (number or cursor).
maskarrayoptionalField names to project from each record.

Response

array — Returns the list of credit records.

Sample request

{
  "id": "user_123",
  "order_by": {
    "timestamp": "desc"
  },
  "limit": 20
}
POST/api/promo/coupons/mintwrites data

Mint exactly one new code for a dynamic or generated coupon batch. Rejects static batches. Authorized by a master/owner token, or by presenting the batch's secret (bearer credential for external campaign tools).

Parameters

NameTypeRequiredDescription
storestringrequiredStore ID.
idstringrequiredBatch ID to mint a code for.
customerstringoptionalBind the minted code to a single customer id.
limitnumberoptionalPer-code use limit (falls back to the batch default, then 1).
secretstringoptionalBatch bearer secret, when minting without a master/owner token.

Response

object — Returns the newly minted code.

Sample request

{
  "id": "spring-sale"
}
POST/api/promo/coupons/mint-batchwrites data

Bulk-mint many codes for a dynamic or generated batch in chunked Firestore batched writes. Hard-capped at 10000 per request. Same auth as mint (master/owner token or the batch secret). Returns a summary (count + timing), not the codes.

Parameters

NameTypeRequiredDescription
storestringrequiredStore ID.
idstringrequiredBatch ID to mint codes for.
countnumberrequiredHow many codes to mint (1..10000).
customerstringoptionalBind every minted code to a single customer id.
limitnumberoptionalPer-code use limit (falls back to the batch default, then 1).
secretstringoptionalBatch bearer secret, when minting without a master/owner token.

Response

object — Returns {minted, requested, chunks, ms}.

Sample request

{
  "id": "spring-sale",
  "count": 500
}
POST/api/promo/coupons/verify

Read-only validation of a coupon code against the batch rule chain. Returns the computed effect or a machine-readable rejection reason. Never mutates.

Parameters

NameTypeRequiredDescription
storestringrequiredStore ID.
codestringrequiredCoupon code to validate (or a static batch id).
customerstringoptionalCustomer id, for customer-bound coupons.
order_valuenumberoptionalCart value, to check the minimum-order condition.
productsarrayoptionalCart product/category ids, to check applicability/restriction.
secretstringoptionalBatch bearer secret, for token-less external callers.

Response

object — Returns {valid, batch, effect?, reason?, unverified?}. effect is {type, value?, max_discount?, product?} plus, for batches carrying a subscription duration, duration (repeating|forever; absent = once) and duration_months - enough to render "-25% for 3 months" before checkout.

Sample request

{
  "code": "SPRING25",
  "order_value": 120
}
POST/api/promo/coupons/claimwrites data

Redeem a coupon in a transaction — re-runs the rule chain, increments usage and flips the code to claimed when its limit is reached. This is the primitive the order flow calls at checkout.

Parameters

NameTypeRequiredDescription
storestringrequiredStore ID.
codestringrequiredCoupon code to redeem (or a static batch id).
customerstringoptionalRedeeming customer id (recorded as claimed_by).
orderstringoptionalOrder id (recorded as claimed_order).
order_valuenumberoptionalCart value, to check the minimum-order condition.
productsarrayoptionalCart product/category ids, to check applicability/restriction.
secretstringoptionalBatch bearer secret, for token-less external callers.

Response

object — Returns {valid, batch, effect} on success; a 400 with {valid:false, reason} otherwise.

Sample request

{
  "code": "SPRING25",
  "customer": "user_123",
  "order": "ord_123"
}