Skip to main content

Overview

The incentives surface exposes a customer’s promotional-grant ledger: the bonus credit they hold, the state of each grant, and the operator action to reverse a grant. Two operations are callable.
  • GET /customers/{customerId}/grants lists a customer’s promotional grants and the state of each.
  • POST /grants/{id}/clawback reverses a grant when the event that funded it is voided, refunded, or fraudulent.
Promotional money is a separate value class from a customer’s cash balance. It expires, it is never cashable out, and it is spent before cash under promo-first ordering. For the full money model and the grant state machine, see Money: actual vs promotional.
Call GET /capabilities and GET /openapi at runtime for the authoritative list of what is available. Where this page and the served spec disagree, the spec wins.

List a customer’s grants

GET /customers/{customerId}/grants returns the customer’s promotional grants, each with its source, its state-machine state, its original and remaining amounts, and its expiry. The feed is read-only, tenant-scoped (it returns only grants belonging to the authenticated tenant), and cursor-paginated. Authenticate with the PosTerminalJWT scheme. customerId is the customer’s wallet identity id, passed as a path parameter.

Query parameters

required
Filter by grant state. One of LOCKED, RELEASED, CLAWED_BACK, EXPIRED.
required
Opaque pagination cursor. Pass next_cursor from the previous page.
required
Max grants per page. Default 50, maximum 100.

Response fields

required
The wallet identity id the grants belong to.
required
The customer’s promotional grants. Each entry is a grant object (fields below).
required
The cursor for the next page, or null when there are no more pages.
required
true when more pages follow.
Each grant object carries:
required
The grant’s stable id. Pass this as the path id when clawing back.
required
What funded the grant. One of CASHBACK, RELOAD_BONUS, SKU_TOPUP_BONUS, GATEWAY_BONUS.
required
The state-machine state. One of LOCKED, RELEASED, CLAWED_BACK, EXPIRED. A LOCKED grant becomes RELEASED on claim; CLAWED_BACK and EXPIRED are terminal.
required
The grant’s original value, as amount_minor (integer, minor units) and currency (ISO-4217).
required
The unspent value, in the same amount_minor plus currency shape.
required
RFC3339 timestamp of when the grant accrued, or null.
required
RFC3339 timestamp of when the grant expires unclaimed or unspent, or null.
required
Server-derived reference to the finalized source event (for example pos:order:5512), or null.
An empty grants array is a success. It means the customer holds no grants matching the filter, not an error. A 404 (NOT_FOUND) means the customer was not found or belongs to another tenant.

Errors

The JWT is missing or invalid. Re-exchange your terminal credential for a fresh JWT and retry.
The customer was not found, or resolves to another tenant. Cross-tenant lookups collapse to NOT_FOUND so existence is not leaked.

Clawback a grant

POST /grants/{id}/clawback reverses a promotional grant when the source event that funded it is voided or refunded, or for fraud. Authenticate with the ApiKeyAuth scheme: this is an operator action gated to operator or admin keys, not a terminal JWT. id is the grant_id from the grants list, passed as a path parameter. A LOCKED grant claws back its full amount. A RELEASED grant claws back only the remaining unspent amount. Any already-spent portion is booked as a merchant loss and is never pulled back from the customer’s cash balance, because promotional money never converts to cash. The grant transitions to CLAWED_BACK, which is terminal, in a single atomic operation.
Clawback moves promotional money and lands the grant in a terminal state. It cannot be undone. Confirm the source event is genuinely voided, refunded, or fraudulent before calling.

Request fields

required
A unique key for this clawback. Replaying the same key is a no-op that returns the original result.
required
Request metadata. Requires partner_request_id (your correlation UUID) and api_version. occurred_at and sent_at are recommended RFC3339 timestamps. partner_request_id is a correlation id only, never the deduplication key; deduplication is keyed on the Idempotency-Key header.
required
Why the grant is being clawed back. One of SOURCE_ORDER_VOIDED, SOURCE_REFUNDED, FRAUD, DUPLICATE, OTHER.
required
Free-text note for the audit trail, or null.

Response fields

required
The grant that was clawed back.
required
Always CLAWED_BACK on success.
required
The amount reversed, as amount_minor and currency.
required
The already-spent promotional portion booked as a merchant loss, as amount_minor and currency. Not recovered from the customer.
required
RFC3339 timestamp of the clawback.

Idempotency

The clawback is mutating and idempotent on the Idempotency-Key header. Send a unique key per clawback. A same-key, same-payload retry replays the original result with meta.idempotency_replayed: true. Clawing back an already CLAWED_BACK grant is a no-op replay. A same-key, different-payload request returns IDEMPOTENCY_KEY_REUSED (422). See Idempotency and errors.

Errors

The grant is not in a clawback-able state (already EXPIRED or CLAWED_BACK), or the body failed validation. Re-read the grant with the list endpoint to confirm its current state.
The API key is missing or invalid.
The key lacks clawback permission. Clawback requires an operator or admin key.
The grant was not found, or belongs to another tenant.
The same Idempotency-Key was presented with a different payload. Use a new key.

Response metadata

Both operations return the standard meta envelope. Two fields are informational:
  • data_completeness_score: an opaque integer Feddi may use internally. No action required.
  • decision_trace_id: an opaque correlation id. Persist it and echo it where a call accepts one.

Where to go next

Money: actual vs promotional

The two-class balance model and the grant state machine: LOCKED, RELEASED, CLAWED_BACK, EXPIRED.

Transactions

Read the transaction record where redeemed promotional credit and clawbacks land.

Idempotency and errors

The idempotency contract and the typed error codes both operations return.

API conventions

The response envelope, money-as-minor-units, pagination, and versioning.