Points Conversion API
Contract version 1.0.0 (accepted on 2026-09-04). Base URL: https://<host>/v1/conversions. JSON, UTF-8.
Machine-readable specification: points-conversion.v1.openapi.yaml.
What the API does
Section titled “What the API does”The API converts a balance of the partner’s points programme into WiBX credited to the authenticated user’s wallet, using the whitelabel’s contractual points/BRL rate and the market BRL/WiBX quotation.
Three operations form the contract: quote, credit and reversal (total or partial, at any time). Lookups by identifier complete the cycle.
The beneficiary is always the session user; no user identifier travels in the body. The partner is identified by the whitelabel.
Macro flow
Section titled “Macro flow”Every credit follows the same path — reserve, settlement queue, credit, reserve closure — with or without stock; the only difference is when the reserve can be taken: immediately, or after the liquidity desk replenishes the stock.
| Step | Who | What the partner sees |
|---|---|---|
| Credit request | Partner app | 201 CREDITED or 202 SCHEDULED immediately |
| Reserve → queue → credit → closure | Wibx (ledger) | settlement.state RESERVED → SETTLED |
| Manual approval and purchase request | Wibx operations | Nothing — internal; the credit stays SCHEDULED |
| Purchase and token delivery | Liquidity desk | Nothing — internal; within the 72 h SLA |
| Release of scheduled credits | Wibx | Lookup turns CREDITED, then SETTLED |
| Reversal | Partner backend or app | 201 REVERSED or 202 REVERSAL_PENDING_BALANCE |
How the Treasury is replenished
Section titled “How the Treasury is replenished”The liquidity desk is Wibx’s counterpart, not the partner’s. Internally: the platform states the need to buy (it does not execute the purchase); every purchase request leaves through a transactional queue (outbox) with retries and alerts; several scheduled credits may be batched into one request; the holding wallet is monitored and a preventive request is issued below a threshold; requests go through manual approval; delivery is recognised from the Treasury balance, after which scheduled credits are released.
Authentication and session
Section titled “Authentication and session”| Operation | Credential |
|---|---|
| Quote, credit, lookups | x-api-key + Wibx user session (cookie connect.sid) |
| Reversal | x-api-key + user session or partner machine-to-machine credential (static bearer with IP allowlist, HMAC signature, or OAuth2 client credentials — configured per whitelabel at onboarding) |
Without a session the response is 405. The session is server-side, expires after 7 days of inactivity and renews on every call.
The partner app obtains the session through the platform’s identity federation: POST /v4/accounts/authentication/inbound/jwt with x-api-key, x-whitelabel-id and the partner’s JWT; the response carries the user and the connect.sid cookie.
Headers
Section titled “Headers”| Header | Required | Description |
|---|---|---|
x-api-key | yes | Wibx infrastructure key routing the call to the environment; one per partner and environment |
x-whitelabel-id | yes | Whitelabel UUID; selects rate, decimals and M2M credential. Without it the platform assumes the legacy whitelabel and rejects with WLC_NOT_CONFIGURED |
cookie | yes* | Session connect.sid. *Not needed on M2M reversals |
authorization / x-hmac-code | M2M reversal | Bearer or HMAC signature, per whitelabel |
content-type | yes | application/json |
x-app-id | no | Partner apps omit it (resolved as 0); never send 1 |
traceparent | no | W3C Trace Context |
accept-language | no | pt-BR (default) or en |
Response: wiboo-trace-id (equals globalTraceId in the body — quote it to support), traceparent, set-cookie.
Conventions
Section titled “Conventions”- Amounts are decimal strings (
"1500","15.00");pointsfollows the whitelabel’s decimals. - Idempotency:
partnerReferenceIdis unique per whitelabel. Same id + same body →200with the original resource; same id + different body →409. On timeout, resend: there is never a duplicate credit. - The quote is informational: the credit is always re-quoted;
quoteIdis correlation only. - Success: the resource in the body plus
globalTraceId. Error:{ message, httpCode, status, globalTraceId, eventError: { errorCode, moduleName } }.
Status model
Section titled “Status model”| status | Meaning | Guarantee |
|---|---|---|
CREDITED | WiBX reserved; settlement in progress | Certain, amount fixed |
SCHEDULED | Stock insufficient; honoured by expectedBy (72 h); amount fixed | Certain, with deadline |
REJECTED | Business rule refused; nothing reserved | No effect |
REVERSED | Reversal executed | Certain |
REVERSAL_PENDING_BALANCE | User lacks WiBX; waits for balance and executes automatically | Certain, no deadline |
settlement.state: RESERVED (reserve taken), SETTLED (user balance updated), PENDING_STOCK (only for SCHEDULED), CANCELLED (pending part cancelled by a reversal).
Quote — POST /points/quotes
Section titled “Quote — POST /points/quotes”Request
Section titled “Request”{ "points": "1500" }Response 200
Section titled “Response 200”{ "quoteId": "0192c9f0-6b1e-7a5c-9d2f-3a4b5c6d7e8f", "wlc": "155f9cd6-2c5f-41a9-8d3c-ebf0ae433854", "points": "1500", "brlAmount": "15.00", "wibxAmount": "356.29453682", "rate": { "pointsPerBrl": "100", "brlPerWibx": "0.0421", "quotationAt": "2026-09-04T14:02:11Z" }, "expiresAt": "2026-09-04T14:04:11Z", "disclaimer": "Cotação de mercado sujeita a variação; o valor final é definido no momento do crédito.", "globalTraceId": "…"}brlAmount = points ÷ pointsPerBrl; wibxAmount = brlAmount ÷ brlPerWibx.
Credit — POST /points/credits
Section titled “Credit — POST /points/credits”Request
Section titled “Request”{ "partnerReferenceId": "GP-2026-000123", "points": "1500", "description": "Resgate campanha setembro", "quoteId": "0192c9f0-6b1e-7a5c-9d2f-3a4b5c6d7e8f", "metadata": { "storeId": "77" }}| HTTP | status | When |
|---|---|---|
| 201 | CREDITED | Stock available; WiBX reserved |
| 202 | SCHEDULED | Stock insufficient; expectedBy set; amount fixed |
| 200 | — | Idempotent replay |
| 409 | — | partnerReferenceId reused with a different body |
| 422 | REJECTED | Business rule; nothing reserved |
Response 201 (CREDITED)
Section titled “Response 201 (CREDITED)”{ "creditId": "0192c9f1-2c3d-7e4f-8a5b-6c7d8e9f0a1b", "partnerReferenceId": "GP-2026-000123", "wlc": "155f9cd6-2c5f-41a9-8d3c-ebf0ae433854", "status": "CREDITED", "points": "1500", "brlAmount": "15.00", "wibxAmount": "356.29453682", "rate": { "pointsPerBrl": "100", "brlPerWibx": "0.0421", "quotationAt": "2026-09-04T14:03:40Z" }, "createdAt": "2026-09-04T14:03:40Z", "expectedBy": null, "settlement": { "state": "RESERVED", "reserveId": "6f1c…", "settledAt": null }, "reversedPoints": "0", "globalTraceId": "…"}Lookup
Section titled “Lookup”GET /points/credits/{creditId}— credit status (404outside the whitelabel).GET /points/credits?partnerReferenceId=…— by the partner’s identifier; use after a timeout, before resending.GET /points/reversals/{reversalId}— reversal status.
No event push in this version; the partner polls the status.
Reversal — POST /points/reversals
Section titled “Reversal — POST /points/reversals”Reverses a credit in CREDITED or SCHEDULED, totally or partially, at any time. Debited WiBX is proportional to the credit’s original rate — never re-quoted.
Request
Section titled “Request”{ "partnerReferenceId": "GP-REV-000045", "creditId": "0192c9f1-2c3d-7e4f-8a5b-6c7d8e9f0a1b", "points": "500", "reason": "CANCELLED_PURCHASE", "description": "Cancelamento parcial do pedido 88213"}Response 201 (REVERSED)
Section titled “Response 201 (REVERSED)”{ "reversalId": "0192c9f4-8a1b-7c2d-9e3f-4a5b6c7d8e9f", "partnerReferenceId": "GP-REV-000045", "creditId": "0192c9f1-2c3d-7e4f-8a5b-6c7d8e9f0a1b", "wlc": "155f9cd6-2c5f-41a9-8d3c-ebf0ae433854", "status": "REVERSED", "points": "500", "wibxAmount": "118.76484561", "reason": "CANCELLED_PURCHASE", "createdAt": "2026-09-05T09:12:03Z", "settlement": { "state": "RESERVED" }, "globalTraceId": "…"}Rules: points ≤ credit points − reversedPoints (otherwise 422 REVERSAL_EXCEEDS_CREDIT); reason ∈ CANCELLED_PURCHASE | PARTNER_ERROR | FRAUD_SUSPECT | OTHER; a SCHEDULED credit → the pending part is cancelled without debit; insufficient user balance → 202 REVERSAL_PENDING_BALANCE, debited automatically once balance arrives.
Errors
Section titled “Errors”| HTTP | Code | Situation |
|---|---|---|
| 400 | — | Malformed body |
| 405 | — | No session |
| 404 | — | Resource not found for the whitelabel |
| 409 | IDEMPOTENCY_CONFLICT | partnerReferenceId reused with a different body |
| 422 | WLC_NOT_CONFIGURED / RATE_NOT_CONFIGURED | Whitelabel or rate not configured |
| 422 | POINTS_INVALID | Non-positive points or beyond the decimal scale |
| 422 | USER_WALLET_UNAVAILABLE | User has no wallet able to receive |
| 422 | CREDIT_NOT_REVERSIBLE / REVERSAL_EXCEEDS_CREDIT | Invalid reversal |
| 501 | APIS-C0001 | Transition: backend not deployed yet (see below) |
End-to-end flows
Section titled “End-to-end flows”Credit with stock
Section titled “Credit with stock”- The user picks the points; the app calls
POST /points/quotesand showswibxAmountwith the variation notice. - The user confirms; the app calls
POST /points/creditswith a newpartnerReferenceId. 201 CREDITED: the partner debits the points.settlement.stateturnsSETTLEDwithin seconds.
Credit without stock
Section titled “Credit without stock”POST /points/creditsanswers202 SCHEDULEDwithexpectedBy(72 h); the WiBX amount is already fixed.- The partner tells the user the credit is scheduled and debits the points.
- The platform replenishes the stock and releases; the lookup turns
CREDITED, thenSETTLED.
Release of a scheduled credit (Wibx side)
Section titled “Release of a scheduled credit (Wibx side)”Purchase request, approval, replenishment by the desk and release of scheduled credits in creation order at the fixed amount; if the stock covers only part, the rest stays scheduled and a new request is issued.
Timeout on creation
Section titled “Timeout on creation”- No response:
GET /points/credits?partnerReferenceId=…. - Found: use the resource.
404: resend the same body — idempotency guarantees a single credit.
Reversal
Section titled “Reversal”- Cancellation on the partner side;
POST /points/reversalswith thecreditIdand the points to return. 201 REVERSED: the partner re-credits the points.202 REVERSAL_PENDING_BALANCE: the debit happens once balance arrives; follow through the lookup.
Transition period
Section titled “Transition period”Until the conversion backend is deployed, every operation answers 501 with the standard error envelope and eventError.errorCode = "APIS-C0001". The contract does not change when the backend lands; only the 501 disappears. No body validation happens during the transition — validate against the OpenAPI specification (local mock).
Changelog
Section titled “Changelog”| Date | Version | Change |
|---|---|---|
| 2026-09-04 | 1.0.0 | Contract accepted; platform standard headers; session through JWT federation; transitional 501 |