Award endpoint
POST /v1/ep/webhook
| Field | Type | Required | Rules |
|---|---|---|---|
tenantId | string | yes | Must be one of your allowedTenants. |
orderId | string | yes | 1–200 chars. Unique per award on your side. Drives idempotency. |
userEmail | string | yes | Valid email. Normalized to lowercase on our side. |
amount | integer | yes | Positive raw amount (e.g. order value). Converted to EP — see below. |
note | string | no | ≤ 500 chars. Shown in the user’s EP history. |
meta | object | no | Free-form key/values stored on the ledger entry for your auditing. |
{ "tenantId": "7g1RP3", "orderId": "order-2026-0001", "userEmail": "user@example.com", "amount": 50000, "note": "Order #2026-0001 cashback", "meta": { "campaign": "summer-sale", "channel": "pos" }}Conversion: raw amount → EP
Section titled “Conversion: raw amount → EP”EP credited is floored at a fixed rate of 1000 raw units = 1 EP:
points = floor(amount / 1000)amount | EP credited | Result |
|---|---|---|
50000 | 50 | OK |
1500 | 1 | OK |
999 | 0 | Rejected — 422 AMOUNT_BELOW_MIN |
Send amount ≥ 1000. A sub-rate amount credits 0 EP and is rejected rather than
recorded as a no-op. The raw amount and the rate are stored on the ledger entry
(rawAmount, amountPerEp) so the conversion is auditable.
All caps are checked against the credited EP (points), not the raw amount:
| Cap | Meaning | On exceed |
|---|---|---|
perTx | Max EP in a single award. | 422 PER_TX_CAP_EXCEEDED |
perPartnerDay | Max EP you may award (per tenant) in one day. | 429 DAILY_CAP_EXCEEDED |
perUserDay | Max EP one user may receive (per tenant, across all partners) per day. | 429 DAILY_CAP_EXCEEDED |
The “day” window is the Vietnam day (UTC+7) — daily counters reset at midnight Vietnam time.
Responses
Section titled “Responses”A fresh award returns 202 Accepted:
{ "epTransactionId": "ep_tx_01HX...", "status": "COMPLETED", "orderId": "order-2026-0001", "points": 50}A replay of the same orderId with the same payload returns
200 OK with code: "DUPLICATE" (no double
credit):
{ "epTransactionId": "ep_tx_01HX...", "status": "COMPLETED", "points": 50, "code": "DUPLICATE"}See Idempotency & retries for the full contract, and
the error contract for every failure code.