{"components":{"headers":{"RetryAfter":{"description":"Suggested number of seconds to wait before retrying.","schema":{"type":"integer"}},"XRateLimitLimit":{"description":"The maximum number of requests allowed within the rate-limit window.","schema":{"type":"integer"}},"XRateLimitRemaining":{"description":"The number of requests remaining in the current rate-limit window.","schema":{"type":"integer"}},"XRateLimitReset":{"description":"Unix timestamp (seconds) at which the rate-limit window resets.","schema":{"type":"integer"}},"XRequestId":{"description":"Unique identifier for this request. Echo in support tickets.","schema":{"example":"req_01HXQZW7V4K2F7E1N7P0C3S2AE","type":"string"}}},"parameters":{"Cursor":{"description":"Opaque cursor returned by the previous page. Omit for the first page.","in":"query","name":"cursor","schema":{"type":"string"}},"IdempotencyKey":{"description":"Required on every `POST /orders` call — **including the first attempt** (Stripe-style).\n\n- **New order:** generate a new unique key (UUID recommended).\n- **Retry same order** (e.g. after `504` or network timeout): send the **same** key and **same** body.\n- **New attempt after an error or body change:** generate a **new** key; reusing a key replays the stored response (even `400`s).\n\nSame key + different body returns `idempotency_key_body_mismatch`. Keys expire after 24 hours.\n\nIn Scalar Try-it, set the header to `{{idempotencyKey}}` or edit `idempotencyKey` in the\n**Environment** panel (globe icon). Set it to `NEW` before each new attempt.\n","in":"header","name":"Idempotency-Key","required":true,"schema":{"example":"{{idempotencyKey}}","maxLength":255,"minLength":1,"type":"string"}},"Limit":{"description":"Items per page. Default 50, max 200.","in":"query","name":"limit","schema":{"default":50,"maximum":200,"minimum":1,"type":"integer"}}},"responses":{"ActivationFailed":{"content":{"application/json":{"examples":{"activationFailed":{"summary":"Brand rejected the activation request","value":{"error":{"code":"activation_failed","message":"Brand activation step failed. No code was issued; no funds were debited.","request_id":"req_01HXQZW7V4K2F7E1N7P0C3S2AE"}}},"activationTimeout":{"summary":"Brand activation exceeded the synchronous budget","value":{"error":{"code":"activation_timeout","message":"Brand activation step did not complete within the synchronous budget.","request_id":"req_01HXQZW7V4K2F7E1N7P0C3S2AE"}}},"outOfStock":{"summary":"No inventory available for this brand + denomination","value":{"error":{"code":"out_of_stock","message":"The requested denomination is currently out of stock.","request_id":"req_01HXQZW7V4K2F7E1N7P0C3S2AE"}}}},"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}},"description":"Order could not be fulfilled after validation — no code was issued and no\nfunds were debited. Covers inventory shortfalls, brand activation failures,\nand activation timeouts.\n","headers":{"X-Request-Id":{"$ref":"#/components/headers/XRequestId"}}},"BadRequest":{"content":{"application/json":{"examples":{"idempotencyKeyBodyMismatch":{"summary":"Same key reused with a different body","value":{"error":{"code":"idempotency_key_body_mismatch","message":"An existing Idempotency-Key was sent with a different request body.","request_id":"req_01HXQZW7V4K2F7E1N7P0C3S2AE"}}},"invalidDenomination":{"summary":"Requested denomination is not offered for this brand","value":{"error":{"code":"invalid_denomination","message":"Denomination 250 EGP is not available for brand br_metro.","request_id":"req_01HXQZW7V4K2F7E1N7P0C3S2AE"}}},"missingIdempotencyKey":{"summary":"Mutating call without Idempotency-Key header","value":{"error":{"code":"missing_idempotency_key","message":"The Idempotency-Key header is required for this endpoint.","request_id":"req_01HXQZW7V4K2F7E1N7P0C3S2AE"}}}},"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}},"description":"The request could not be processed as submitted.","headers":{"X-Request-Id":{"$ref":"#/components/headers/XRequestId"}}},"BrandNotAvailable":{"content":{"application/json":{"examples":{"brand_not_available":{"value":{"error":{"code":"brand_not_available","message":"Brand br_xyz is not available to this reseller.","request_id":"req_01HXQZW7V4K2F7E1N7P0C3S2AE"}}}},"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}},"description":"Brand does not exist or is not assigned to this reseller.","headers":{"X-Request-Id":{"$ref":"#/components/headers/XRequestId"}}},"Conflict":{"content":{"application/json":{"examples":{"idempotencyKeyInProgress":{"summary":"Same key currently being processed by another request","value":{"error":{"code":"idempotency_key_in_progress","message":"A request with this Idempotency-Key is currently in progress.","request_id":"req_01HXQZW7V4K2F7E1N7P0C3S2AE"}}},"rateCardMissing":{"summary":"No applicable rate at the time of the request","value":{"error":{"code":"rate_card_missing","message":"No applicable outbound rate is configured for this brand at this time.","request_id":"req_01HXQZW7V4K2F7E1N7P0C3S2AE"}}}},"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}},"description":"Request conflicts with existing state.","headers":{"X-Request-Id":{"$ref":"#/components/headers/XRequestId"}}},"Forbidden":{"content":{"application/json":{"examples":{"forbidden":{"value":{"error":{"code":"forbidden","message":"This API key is not authorized to access this endpoint from this source IP.","request_id":"req_01HXQZW7V4K2F7E1N7P0C3S2AE"}}}},"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}},"description":"Client IP not allowlisted for this key, or key lacks required scope.","headers":{"X-Request-Id":{"$ref":"#/components/headers/XRequestId"}}},"GatewayTimeout":{"content":{"application/json":{"examples":{"gateway_timeout":{"value":{"error":{"code":"gateway_timeout","message":"Request exceeded the synchronous budget. Retry with the same Idempotency-Key.","request_id":"req_01HXQZW7V4K2F7E1N7P0C3S2AE"}}}},"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}},"description":"Server could not complete the request within the synchronous budget.\nRetry with the **same** `Idempotency-Key` to either pick up the completed response\nor continue waiting.\n","headers":{"X-Request-Id":{"$ref":"#/components/headers/XRequestId"}}},"IdempotencyKeyExpired":{"content":{"application/json":{"examples":{"idempotency_key_expired":{"value":{"error":{"code":"idempotency_key_expired","message":"The provided Idempotency-Key has expired. Generate a new key and retry.","request_id":"req_01HXQZW7V4K2F7E1N7P0C3S2AE"}}}},"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}},"description":"The provided Idempotency-Key has passed its 24h TTL.","headers":{"X-Request-Id":{"$ref":"#/components/headers/XRequestId"}}},"InsufficientFunds":{"content":{"application/json":{"examples":{"insufficient_funds":{"value":{"error":{"code":"insufficient_funds","message":"Wallet balance is below the required amount for this order.","request_id":"req_01HXQZW7V4K2F7E1N7P0C3S2AE"}}}},"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}},"description":"Wallet balance minus reservations is below the required amount.","headers":{"X-Request-Id":{"$ref":"#/components/headers/XRequestId"}}},"InternalError":{"content":{"application/json":{"examples":{"internal_error":{"value":{"error":{"code":"internal_error","message":"An unexpected error occurred. Quote request_id when contacting support.","request_id":"req_01HXQZW7V4K2F7E1N7P0C3S2AE"}}}},"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}},"description":"Unexpected server-side error. Safe to retry idempotent operations.","headers":{"X-Request-Id":{"$ref":"#/components/headers/XRequestId"}}},"NotFound":{"content":{"application/json":{"examples":{"brand_not_available":{"value":{"error":{"code":"brand_not_available","message":"The requested resource does not exist or is not available to you.","request_id":"req_01HXQZW7V4K2F7E1N7P0C3S2AE"}}}},"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}},"description":"The requested resource does not exist or does not belong to this reseller.","headers":{"X-Request-Id":{"$ref":"#/components/headers/XRequestId"}}},"RateLimited":{"content":{"application/json":{"examples":{"rate_limited":{"value":{"error":{"code":"rate_limited","message":"Rate limit exceeded. Retry after the window resets.","request_id":"req_01HXQZW7V4K2F7E1N7P0C3S2AE"}}}},"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}},"description":"Too many requests. Back off and retry after the window resets.","headers":{"Retry-After":{"$ref":"#/components/headers/RetryAfter"},"X-RateLimit-Limit":{"$ref":"#/components/headers/XRateLimitLimit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/XRateLimitRemaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/XRateLimitReset"},"X-Request-Id":{"$ref":"#/components/headers/XRequestId"}}},"Unauthorized":{"content":{"application/json":{"examples":{"unauthorized":{"value":{"error":{"code":"unauthorized","message":"The provided API key is missing, revoked, or expired.","request_id":"req_01HXQZW7V4K2F7E1N7P0C3S2AE"}}}},"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}},"description":"Missing, unknown, revoked, or expired API key.","headers":{"X-Request-Id":{"$ref":"#/components/headers/XRequestId"}}},"UpstreamError":{"content":{"application/json":{"examples":{"upstream_error":{"value":{"error":{"code":"upstream_error","message":"A downstream dependency returned an error. No funds were debited.","request_id":"req_01HXQZW7V4K2F7E1N7P0C3S2AE"}}}},"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}},"description":"A downstream system returned an error.","headers":{"X-Request-Id":{"$ref":"#/components/headers/XRequestId"}}}},"schemas":{"CatalogEntry":{"description":"A brand the authenticated reseller is allowed to order against. Use `brandId`\nwhen placing an order. Channel is hidden — Qboon picks fulfillment internally\nbased on the assignment row.\n","properties":{"brandId":{"description":"Brand identifier (opaque, `br_*` format). Use in `POST /orders`.","type":"string"},"denominations":{"description":"All denominations currently stockable + priced for this reseller.","items":{"$ref":"#/components/schemas/Denomination"},"type":"array"},"description":{"description":"Per-reseller description override applied if set; otherwise the brand's description.","type":"string"},"displayName":{"description":"Brand name shown to the reseller (per-reseller override when set; otherwise the canonical brand name).","type":"string"}},"required":["brandId","displayName","denominations"],"type":"object"},"CatalogListResponse":{"allOf":[{"$ref":"#/components/schemas/CursorPage"},{"properties":{"data":{"items":{"$ref":"#/components/schemas/CatalogEntry"},"type":"array"}},"required":["data"],"type":"object"}]},"CodeVerifyRequest":{"properties":{"brandId":{"description":"Brand identifier from `GET /catalog` (`br_*` format).","minLength":1,"type":"string"},"code":{"description":"Plaintext voucher code to verify.","minLength":1,"type":"string"}},"required":["brandId","code"],"type":"object"},"CodeVerifyResponse":{"properties":{"brandId":{"type":"string"},"codeLast5":{"description":"Last five characters of the verified code.","type":"string"},"currency":{"$ref":"#/components/schemas/Currency"},"expiresAt":{"description":"Code expiry timestamp when known.","format":"date-time","nullable":true,"type":"string"},"faceValueInCents":{"description":"Face value from the owning order.","format":"int64","type":"integer"},"netCostInCents":{"description":"Net cost the reseller paid on the owning order.","format":"int64","type":"integer"},"orderId":{"description":"Owning reseller order identifier.","type":"string"},"status":{"$ref":"#/components/schemas/CodeVerifyStatus"}},"required":["brandId","faceValueInCents","netCostInCents","currency","status","orderId","codeLast5"],"type":"object"},"CodeVerifyStatus":{"description":"Derived verification verdict for the submitted code.","enum":["VALID","EXPIRED","VOIDED"],"type":"string"},"Currency":{"description":"ISO 4217 currency code.","example":"EGP","maxLength":3,"minLength":3,"type":"string"},"CursorPage":{"properties":{"hasMore":{"type":"boolean"},"nextCursor":{"description":"Pass as `cursor` on the next request. Null when there are no more pages.","nullable":true,"type":"string"}},"required":["nextCursor","hasMore"],"type":"object"},"Denomination":{"properties":{"currency":{"$ref":"#/components/schemas/Currency"},"discountBps":{"description":"Reseller discount off face value, in basis points (e.g., 500 = 5.00%).","maximum":10000,"minimum":0,"type":"integer"},"faceValueInCents":{"description":"Face value in the smallest unit of `currency`.","format":"int64","minimum":1,"type":"integer"},"netCostInCents":{"description":"Amount debited from the reseller wallet when ordering this denomination.\n`netCostInCents = faceValueInCents - (faceValueInCents * discountBps / 10000)`.\n","format":"int64","minimum":1,"type":"integer"},"rateEffectiveFrom":{"description":"Timestamp from which the currently-returned rate is effective.","format":"date-time","type":"string"}},"required":["faceValueInCents","currency","netCostInCents","discountBps","rateEffectiveFrom"],"type":"object"},"ErrorBody":{"properties":{"code":{"$ref":"#/components/schemas/ErrorCode"},"message":{"description":"Human-readable description. Not for programmatic use.","type":"string"},"request_id":{"description":"Echoes the `X-Request-Id` response header for traceability.","type":"string"}},"required":["code","message","request_id"],"type":"object"},"ErrorCode":{"enum":["missing_idempotency_key","idempotency_key_body_mismatch","idempotency_key_in_progress","idempotency_key_expired","brand_not_available","invalid_request","not_found","method_not_allowed","order_not_found","invalid_denomination","rate_card_missing","insufficient_funds","out_of_stock","upstream_error","activation_failed","activation_timeout","order_timeout","gateway_timeout","rate_limited","unauthorized","forbidden","internal_error"],"type":"string"},"ErrorEnvelope":{"properties":{"error":{"$ref":"#/components/schemas/ErrorBody"}},"required":["error"],"type":"object"},"HealthResponse":{"properties":{"status":{"enum":["ok"],"type":"string"},"time":{"format":"date-time","type":"string"}},"required":["status","time"],"type":"object"},"IssuedCode":{"description":"The issued voucher code details. Present only when the order is `ISSUED`.","properties":{"expiryDate":{"description":"Absolute expiry date of the voucher. Null if not applicable.","format":"date","nullable":true,"type":"string"},"extra":{"additionalProperties":{"type":"string"},"description":"Optional brand-specific fields (e.g., barcode format).","type":"object"},"multicode":{"description":"Primary code string to display to the end-user.","type":"string"},"pin":{"description":"Secondary PIN or security code, if issued by the brand.","type":"string"}},"required":["multicode","pin"],"type":"object"},"Order":{"properties":{"brandId":{"type":"string"},"createdAt":{"format":"date-time","type":"string"},"currency":{"$ref":"#/components/schemas/Currency"},"denominationInCents":{"format":"int64","type":"integer"},"discountBps":{"description":"Applied reseller discount in basis points.","type":"integer"},"errorCode":{"$ref":"#/components/schemas/ErrorCode"},"faceValueInCents":{"description":"Face value delivered to the end-user.","format":"int64","type":"integer"},"id":{"description":"Order identifier (opaque).","type":"string"},"issuedCode":{"$ref":"#/components/schemas/IssuedCode"},"metadata":{"additionalProperties":{"type":"string"},"type":"object"},"netCostInCents":{"description":"Amount actually debited from the wallet for this order.","format":"int64","type":"integer"},"status":{"$ref":"#/components/schemas/OrderStatus"},"updatedAt":{"format":"date-time","type":"string"},"usableFrom":{"description":"Timestamp at which the issued code becomes live at the merchant. Null for\nimmediately-usable codes. For `ACTIVATION_DEFERRED` products, typically\n`now()` + up to 48 hours.\n","format":"date-time","nullable":true,"type":"string"}},"required":["id","status","brandId","denominationInCents","currency","faceValueInCents","netCostInCents","createdAt"],"type":"object"},"OrderCreateRequest":{"properties":{"brandId":{"description":"Brand identifier from `GET /catalog` (`br_*` format).","minLength":1,"type":"string"},"currency":{"$ref":"#/components/schemas/Currency"},"denominationInCents":{"description":"Must exactly match one of the `faceValueInCents` values returned for the brand.\nArbitrary amounts are not supported.\n","format":"int64","minimum":1,"type":"integer"},"metadata":{"additionalProperties":{"type":"string"},"description":"Optional client-side key-value tags stored with the order for caller-side\nreconciliation. Returned verbatim. Max 10 keys, max 256 chars each.\n","type":"object"}},"required":["brandId","denominationInCents","currency"],"type":"object"},"OrderListResponse":{"allOf":[{"$ref":"#/components/schemas/CursorPage"},{"properties":{"data":{"items":{"$ref":"#/components/schemas/Order"},"type":"array"}},"required":["data"],"type":"object"}]},"OrderStatus":{"description":"Lifecycle of an order. Successful orders end at `ISSUED`. Failed orders end at `FAILED`\nwith no wallet debit. `MANUAL_REVIEW` indicates a catastrophic compensation failure\n— ops will reach out proactively.\n","enum":["PENDING","RESERVED","ISSUED","FAILED","MANUAL_REVIEW"],"type":"string"},"Wallet":{"properties":{"availableInCents":{"description":"`balanceInCents - reservedInCents`. Maximum net-cost of a single new order.","format":"int64","type":"integer"},"balanceInCents":{"description":"Total credited balance.","format":"int64","type":"integer"},"currency":{"$ref":"#/components/schemas/Currency"},"reservedInCents":{"description":"Currently reserved against in-flight orders. Not yet debited.","format":"int64","type":"integer"},"updatedAt":{"format":"date-time","type":"string"}},"required":["currency","balanceInCents","reservedInCents","availableInCents","updatedAt"],"type":"object"},"WalletTransaction":{"properties":{"amountInCents":{"description":"Signed — credits positive, debits negative.","format":"int64","type":"integer"},"balanceAfterInCents":{"description":"Wallet balance snapshot after this entry was applied.","format":"int64","type":"integer"},"createdAt":{"format":"date-time","type":"string"},"currency":{"$ref":"#/components/schemas/Currency"},"id":{"description":"Ledger entry identifier (opaque).","type":"string"},"note":{"nullable":true,"type":"string"},"referenceType":{"$ref":"#/components/schemas/WalletTransactionReferenceType"},"type":{"$ref":"#/components/schemas/WalletTransactionType"}},"required":["id","type","amountInCents","currency","balanceAfterInCents","createdAt"],"type":"object"},"WalletTransactionListResponse":{"allOf":[{"$ref":"#/components/schemas/CursorPage"},{"properties":{"data":{"items":{"$ref":"#/components/schemas/WalletTransaction"},"type":"array"}},"required":["data"],"type":"object"}]},"WalletTransactionReferenceType":{"enum":["order","top_up","manual_adjustment","fee"],"type":"string"},"WalletTransactionType":{"enum":["TOP_UP","ORDER_DEBIT","ORDER_REVERSAL","FEE","ADJUSTMENT"],"type":"string"}},"securitySchemes":{"apiKey":{"description":"Static API key issued to the reseller. Format: `qrk_{live|test}_{opaque}`.\nPer-key IP allowlist is enforced server-side. Missing or invalid key returns 401.\nWrong source IP or missing scope returns 403.\n","in":"header","name":"X-Api-Key","type":"apiKey"}}},"info":{"contact":{"email":"info@qboon.net","name":"Qboon","url":"https://qboon.net/"},"description":"API for reseller partners to order Qboon gift vouchers and deliver them to their end-users.","title":"Qboon Reseller API","version":"2.4"},"openapi":"3.0.2","paths":{"/catalog":{"get":{"description":"Returns only brands that have been explicitly assigned to the authenticated reseller.\nEach entry carries its denominations with inline rate information. Redemption channel\nis not exposed — Qboon picks the fulfillment channel internally based on the assignment.\n","operationId":"ListCatalog","parameters":[{"$ref":"#/components/parameters/Cursor"},{"$ref":"#/components/parameters/Limit"}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CatalogListResponse"}}},"description":"Paginated catalog","headers":{"X-RateLimit-Limit":{"$ref":"#/components/headers/XRateLimitLimit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/XRateLimitRemaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/XRateLimitReset"},"X-Request-Id":{"$ref":"#/components/headers/XRequestId"}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}},"security":[{"apiKey":["catalog.read"]}],"summary":"List brands available to the authenticated reseller","tags":["catalog"]}},"/codes/verify":{"post":{"description":"Re-check a code previously sold to the authenticated reseller. Confirms the code\nis genuine (decrypt-match), still valid, and returns face value and net cost from\nthe owning order. Codes not allocated to this reseller return `404`.\n","operationId":"VerifyCode","requestBody":{"content":{"application/json":{"examples":{"verifyCode":{"summary":"Verify a sold code","value":{"brandId":"brd_5NFDzoorNXaQ","code":"BTECH-100-00001"}}},"schema":{"$ref":"#/components/schemas/CodeVerifyRequest"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CodeVerifyResponse"}}},"description":"Verification result","headers":{"X-RateLimit-Limit":{"$ref":"#/components/headers/XRateLimitLimit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/XRateLimitRemaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/XRateLimitReset"},"X-Request-Id":{"$ref":"#/components/headers/XRequestId"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}},"security":[{"apiKey":["inventory.read"]}],"summary":"Verify an issued voucher code","tags":["codes"]}},"/health":{"get":{"description":"Public liveness endpoint. No authentication required.","operationId":"GetHealth","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HealthResponse"}}},"description":"Service is live","headers":{"X-Request-Id":{"$ref":"#/components/headers/XRequestId"}}}},"security":[],"summary":"Liveness probe","tags":["meta"]}},"/orders":{"get":{"operationId":"ListOrders","parameters":[{"$ref":"#/components/parameters/Cursor"},{"$ref":"#/components/parameters/Limit"},{"description":"Filter by order status.","in":"query","name":"status","schema":{"$ref":"#/components/schemas/OrderStatus"}},{"description":"Include orders created on or after this timestamp (inclusive). RFC3339 / ISO-8601 (UTC recommended).","in":"query","name":"startDatetime","schema":{"example":"2026-05-01T00:00:00Z","format":"date-time","type":"string"}},{"description":"Include orders created before this timestamp (exclusive). RFC3339 / ISO-8601 (UTC recommended).","in":"query","name":"endDatetime","schema":{"example":"2026-05-31T23:59:59Z","format":"date-time","type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrderListResponse"}}},"description":"Paginated order list","headers":{"X-RateLimit-Limit":{"$ref":"#/components/headers/XRateLimitLimit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/XRateLimitRemaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/XRateLimitReset"},"X-Request-Id":{"$ref":"#/components/headers/XRequestId"}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}},"security":[{"apiKey":["orders.read"]}],"summary":"List the authenticated reseller's orders","tags":["orders"]},"post":{"description":"Atomic, idempotent voucher issuance. One call produces exactly one issued code for\n`{brandId, denominationInCents, currency}`. Wallet is debited synchronously.\n\n**Idempotency:** send a **new** `Idempotency-Key` on every new order (first call included).\nOnly reuse a key when retrying the **same** request after `504` or transport failure.\nReusing a key after changing the body replays the old response (including prior errors).\n\n**Synchronous response:** if the server returns `504`, retry with the same idempotency key\n— this is the implicit polling mechanism.\n\n**Deferred-activation brands:** the response includes a `usableFrom` timestamp indicating\nwhen the code will become live at the merchant. Surface this in your end-user UI.\n\n**Scalar Try-it:** use the **globe (Environment)** picker → edit `idempotencyKey` (set to\n`NEW` to regenerate), or type `{{idempotencyKey}}` in the header field. A pre-request\nscript applies the value on Send.\n","operationId":"CreateOrder","parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"content":{"application/json":{"examples":{"placeOrder":{"summary":"Issue one voucher","value":{"brandId":"br_metro","currency":"EGP","denominationInCents":50000,"metadata":{"partnerRef":"INV-10042"}}}},"schema":{"$ref":"#/components/schemas/OrderCreateRequest"}}},"required":true},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Order"}}},"description":"Order issued","headers":{"X-RateLimit-Limit":{"$ref":"#/components/headers/XRateLimitLimit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/XRateLimitRemaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/XRateLimitReset"},"X-Request-Id":{"$ref":"#/components/headers/XRequestId"}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/InsufficientFunds"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/BrandNotAvailable"},"409":{"$ref":"#/components/responses/Conflict"},"410":{"$ref":"#/components/responses/IdempotencyKeyExpired"},"422":{"$ref":"#/components/responses/ActivationFailed"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"},"502":{"$ref":"#/components/responses/UpstreamError"},"504":{"$ref":"#/components/responses/GatewayTimeout"}},"security":[{"apiKey":["orders.write"]}],"summary":"Place a voucher order","tags":["orders"],"x-pre-request":"var STALE = '01HXQZW7V4K2F7E1N7P0C3S2AE';\nvar key = pm.environment.get('idempotencyKey');\nif (!key || key === 'NEW' || key === 'new' || key === STALE) {\n  key = pm.variables.replaceIn('{{$guid}}');\n}\npm.environment.set('idempotencyKey', key);\npm.request.headers.upsert({\n  key: 'Idempotency-Key',\n  value: key\n});"}},"/orders/{orderId}":{"get":{"operationId":"GetOrder","parameters":[{"description":"Order identifier.","in":"path","name":"orderId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Order"}}},"description":"Order found","headers":{"X-RateLimit-Limit":{"$ref":"#/components/headers/XRateLimitLimit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/XRateLimitRemaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/XRateLimitReset"},"X-Request-Id":{"$ref":"#/components/headers/XRequestId"}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}},"security":[{"apiKey":["orders.read"]}],"summary":"Fetch a single order by id","tags":["orders"]}},"/wallet":{"get":{"operationId":"GetWallet","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Wallet"}}},"description":"Wallet snapshot","headers":{"X-RateLimit-Limit":{"$ref":"#/components/headers/XRateLimitLimit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/XRateLimitRemaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/XRateLimitReset"},"X-Request-Id":{"$ref":"#/components/headers/XRequestId"}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}},"security":[{"apiKey":["wallet.read"]}],"summary":"Fetch the authenticated reseller's wallet balance","tags":["wallet"]}},"/wallet/transactions":{"get":{"description":"Append-only ledger. Newest first. Every balance-changing event is a row here — no entries\nare ever updated or deleted. Corrections appear as `ORDER_REVERSAL` or `ADJUSTMENT` entries.\n","operationId":"ListWalletTransactions","parameters":[{"$ref":"#/components/parameters/Cursor"},{"$ref":"#/components/parameters/Limit"},{"description":"Filter by ledger entry type.","in":"query","name":"type","schema":{"$ref":"#/components/schemas/WalletTransactionType"}},{"description":"Include entries on or after this timestamp (inclusive). RFC3339 / ISO-8601 (UTC recommended).","in":"query","name":"startDatetime","schema":{"example":"2026-05-01T00:00:00Z","format":"date-time","type":"string"}},{"description":"Include entries before this timestamp (exclusive). RFC3339 / ISO-8601 (UTC recommended).","in":"query","name":"endDatetime","schema":{"example":"2026-05-31T23:59:59Z","format":"date-time","type":"string"}},{"description":"Filter by the type of object referenced by the entry.","in":"query","name":"referenceType","schema":{"$ref":"#/components/schemas/WalletTransactionReferenceType"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WalletTransactionListResponse"}}},"description":"Paginated ledger","headers":{"X-RateLimit-Limit":{"$ref":"#/components/headers/XRateLimitLimit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/XRateLimitRemaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/XRateLimitReset"},"X-Request-Id":{"$ref":"#/components/headers/XRequestId"}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}},"security":[{"apiKey":["wallet.read"]}],"summary":"List wallet ledger entries","tags":["wallet"]}}},"security":[{"apiKey":[]}],"servers":[{"description":"Reseller partner API v1","url":"/api/reseller/v1"}],"tags":[{"description":"Liveness and metadata. `GET /health` is public — no API key required.\n","name":"meta"},{"description":"Brand catalog discovery. Returns only brands assigned to your reseller account.\nRequires scope `catalog.read`.\n","name":"catalog"},{"description":"Voucher order placement and lookup. `POST /orders` requires an `Idempotency-Key`\nheader and scope `orders.write`. On `504 Gateway Timeout`, retry with the same key.\n","name":"orders"},{"description":"Voucher code verification for codes previously sold to the authenticated reseller.\nRequires scope `inventory.read`.\n","name":"codes"},{"description":"Prefunded wallet balance and ledger. Requires scope `wallet.read`.\nTop-ups are handled by Qboon ops — contact your account manager to credit your wallet.\n","name":"wallet"}],"x-scalar-active-environment":"tryit","x-scalar-environments":{"tryit":{"color":"#784ef0","description":"Try-it defaults (Scalar docs)","variables":{"idempotencyKey":{"default":"NEW","description":"Idempotency-Key for POST /orders. Set to `NEW` (or clear) before each new order attempt\nto regenerate. Reusing a value replays cached responses (including errors).\n"}}}}}
