{"openapi":"3.0.0","paths":{"/v1/partner/account":{"get":{"operationId":"PartnerAccountController_getAccount","parameters":[{"name":"X-Nexus-Timestamp","in":"header","required":true,"description":"Unix time in seconds","schema":{"type":"string","example":"1760054400"}},{"name":"X-Nexus-Nonce","in":"header","required":true,"description":"Unique per request, 16-64 of A-Z a-z 0-9 _ -","schema":{"type":"string"}},{"name":"X-Nexus-Signature","in":"header","required":true,"description":"Hex HMAC-SHA256 of the string to sign","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerAccountDto"}}}}},"security":[{"PartnerSignature":[]}],"summary":"Your API client: key ID, country, catalog scope and limits","tags":["Account"]}},"/v1/partner/webhooks/test":{"post":{"operationId":"PartnerAccountController_sendTestWebhook","parameters":[{"name":"X-Nexus-Timestamp","in":"header","required":true,"description":"Unix time in seconds","schema":{"type":"string","example":"1760054400"}},{"name":"X-Nexus-Nonce","in":"header","required":true,"description":"Unique per request, 16-64 of A-Z a-z 0-9 _ -","schema":{"type":"string"}},{"name":"X-Nexus-Signature","in":"header","required":true,"description":"Hex HMAC-SHA256 of the string to sign","schema":{"type":"string"}}],"responses":{"202":{"description":"Delivery queued; check the delivery log in your account"}},"security":[{"PartnerSignature":[]}],"summary":"Send a signed `test.ping` event to your webhook URL","tags":["Account"]}},"/v1/partner/catalog/products":{"get":{"description":"Active virtual products available in your catalog country, with your USD price per SKU. Paginate with `cursor`; use `updatedSince` for incremental syncs.","operationId":"PartnerCatalogController_listProducts","parameters":[{"name":"cursor","required":false,"in":"query","description":"Opaque cursor from the previous page (`nextCursor`)","schema":{"type":"string"}},{"name":"limit","required":false,"in":"query","schema":{"minimum":1,"maximum":100,"default":25,"type":"number"}},{"name":"category","required":false,"in":"query","description":"Only products in this category","schema":{"type":"string"}},{"name":"brand","required":false,"in":"query","description":"Only products of this brand","schema":{"type":"string"}},{"name":"type","required":false,"in":"query","schema":{"type":"string","enum":["voucher","range","topup"]}},{"name":"search","required":false,"in":"query","description":"Case-insensitive match on the product name","schema":{"type":"string"}},{"name":"updatedSince","required":false,"in":"query","description":"Only products changed at or after this time (ISO 8601), for incremental sync","schema":{"format":"date-time","example":"2026-10-01T00:00:00Z","type":"string"}},{"name":"X-Nexus-Timestamp","in":"header","required":true,"description":"Unix time in seconds","schema":{"type":"string","example":"1760054400"}},{"name":"X-Nexus-Nonce","in":"header","required":true,"description":"Unique per request, 16-64 of A-Z a-z 0-9 _ -","schema":{"type":"string"}},{"name":"X-Nexus-Signature","in":"header","required":true,"description":"Hex HMAC-SHA256 of the string to sign","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CatalogProductPageDto"}}}}},"security":[{"PartnerSignature":[]}],"summary":"List products","tags":["Catalog"]}},"/v1/partner/catalog/products/{productId}":{"get":{"operationId":"PartnerCatalogController_getProduct","parameters":[{"name":"productId","required":true,"in":"path","schema":{"type":"string"}},{"name":"X-Nexus-Timestamp","in":"header","required":true,"description":"Unix time in seconds","schema":{"type":"string","example":"1760054400"}},{"name":"X-Nexus-Nonce","in":"header","required":true,"description":"Unique per request, 16-64 of A-Z a-z 0-9 _ -","schema":{"type":"string"}},{"name":"X-Nexus-Signature","in":"header","required":true,"description":"Hex HMAC-SHA256 of the string to sign","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CatalogProductDetailDto"}}}}},"security":[{"PartnerSignature":[]}],"summary":"Get a product with descriptions and redemption instructions","tags":["Catalog"]}},"/v1/partner/catalog/categories":{"get":{"operationId":"PartnerCatalogController_listCategories","parameters":[{"name":"X-Nexus-Timestamp","in":"header","required":true,"description":"Unix time in seconds","schema":{"type":"string","example":"1760054400"}},{"name":"X-Nexus-Nonce","in":"header","required":true,"description":"Unique per request, 16-64 of A-Z a-z 0-9 _ -","schema":{"type":"string"}},{"name":"X-Nexus-Signature","in":"header","required":true,"description":"Hex HMAC-SHA256 of the string to sign","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/CatalogCategoryDto"}}}}}},"security":[{"PartnerSignature":[]}],"summary":"List categories, for filtering the product list","tags":["Catalog"]}},"/v1/partner/orders/quote":{"post":{"description":"Runs every check an order would (availability, inputs, limits per SKU) and returns the exact USD total. Nothing is charged.","operationId":"PartnerOrdersController_quote","parameters":[{"name":"X-Nexus-Timestamp","in":"header","required":true,"description":"Unix time in seconds","schema":{"type":"string","example":"1760054400"}},{"name":"X-Nexus-Nonce","in":"header","required":true,"description":"Unique per request, 16-64 of A-Z a-z 0-9 _ -","schema":{"type":"string"}},{"name":"X-Nexus-Signature","in":"header","required":true,"description":"Hex HMAC-SHA256 of the string to sign","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuotePartnerOrderDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerQuoteDto"}}}}},"security":[{"PartnerSignature":[]}],"summary":"Price an order without placing it","tags":["Orders"]}},"/v1/partner/orders":{"post":{"description":"Requires an `Idempotency-Key` header. Retrying with the same key and body returns the original result instead of placing a second order.","operationId":"PartnerOrdersController_create","parameters":[{"name":"Idempotency-Key","in":"header","description":"8-100 characters: letters, digits, `.`, `_`, `:` or `-`. Use a new key per order.","required":true,"schema":{"type":"string"}},{"name":"X-Nexus-Timestamp","in":"header","required":true,"description":"Unix time in seconds","schema":{"type":"string","example":"1760054400"}},{"name":"X-Nexus-Nonce","in":"header","required":true,"description":"Unique per request, 16-64 of A-Z a-z 0-9 _ -","schema":{"type":"string"}},{"name":"X-Nexus-Signature","in":"header","required":true,"description":"Hex HMAC-SHA256 of the string to sign","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePartnerOrderDto"}}}},"responses":{"201":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerOrderDto"}}}},"409":{"description":"`DUPLICATE_REFERENCE`, `REQUEST_IN_PROGRESS`"}},"security":[{"PartnerSignature":[]}],"summary":"Place an order paid from your USD wallet balance","tags":["Orders"]},"get":{"operationId":"PartnerOrdersController_list","parameters":[{"name":"cursor","required":false,"in":"query","description":"Opaque cursor from the previous page (`nextCursor`)","schema":{"type":"string"}},{"name":"limit","required":false,"in":"query","schema":{"minimum":1,"maximum":100,"default":25,"type":"number"}},{"name":"status","required":false,"in":"query","schema":{"type":"string","enum":["processing","under_review","partially_completed","completed","cancelled","failed","refunded","partially_refunded"]}},{"name":"createdFrom","required":false,"in":"query","description":"Orders created at or after this time (ISO 8601)","schema":{"format":"date-time","type":"string"}},{"name":"createdTo","required":false,"in":"query","description":"Orders created before this time (ISO 8601)","schema":{"format":"date-time","type":"string"}},{"name":"X-Nexus-Timestamp","in":"header","required":true,"description":"Unix time in seconds","schema":{"type":"string","example":"1760054400"}},{"name":"X-Nexus-Nonce","in":"header","required":true,"description":"Unique per request, 16-64 of A-Z a-z 0-9 _ -","schema":{"type":"string"}},{"name":"X-Nexus-Signature","in":"header","required":true,"description":"Hex HMAC-SHA256 of the string to sign","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerOrderPageDto"}}}}},"security":[{"PartnerSignature":[]}],"summary":"List orders placed through the API, newest first","tags":["Orders"]}},"/v1/partner/orders/by-reference/{externalReference}":{"get":{"operationId":"PartnerOrdersController_getByReference","parameters":[{"name":"externalReference","required":true,"in":"path","schema":{"type":"string"}},{"name":"X-Nexus-Timestamp","in":"header","required":true,"description":"Unix time in seconds","schema":{"type":"string","example":"1760054400"}},{"name":"X-Nexus-Nonce","in":"header","required":true,"description":"Unique per request, 16-64 of A-Z a-z 0-9 _ -","schema":{"type":"string"}},{"name":"X-Nexus-Signature","in":"header","required":true,"description":"Hex HMAC-SHA256 of the string to sign","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerOrderDto"}}}}},"security":[{"PartnerSignature":[]}],"summary":"Get an order by your own `externalReference`","tags":["Orders"]}},"/v1/partner/orders/{orderId}":{"get":{"operationId":"PartnerOrdersController_get","parameters":[{"name":"orderId","required":true,"in":"path","schema":{"type":"string"}},{"name":"X-Nexus-Timestamp","in":"header","required":true,"description":"Unix time in seconds","schema":{"type":"string","example":"1760054400"}},{"name":"X-Nexus-Nonce","in":"header","required":true,"description":"Unique per request, 16-64 of A-Z a-z 0-9 _ -","schema":{"type":"string"}},{"name":"X-Nexus-Signature","in":"header","required":true,"description":"Hex HMAC-SHA256 of the string to sign","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerOrderDto"}}}}},"security":[{"PartnerSignature":[]}],"summary":"Get an order","tags":["Orders"]}},"/v1/partner/orders/{orderId}/codes":{"get":{"description":"Returns every code delivered so far (call again for the rest of a partially completed order). Each fetch is recorded as proof of delivery.","operationId":"PartnerOrdersController_getCodes","parameters":[{"name":"orderId","required":true,"in":"path","schema":{"type":"string"}},{"name":"X-Nexus-Timestamp","in":"header","required":true,"description":"Unix time in seconds","schema":{"type":"string","example":"1760054400"}},{"name":"X-Nexus-Nonce","in":"header","required":true,"description":"Unique per request, 16-64 of A-Z a-z 0-9 _ -","schema":{"type":"string"}},{"name":"X-Nexus-Signature","in":"header","required":true,"description":"Hex HMAC-SHA256 of the string to sign","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerOrderCodesDto"}}}},"409":{"description":"`CODES_NOT_READY` while the order is processing or under review"}},"security":[{"PartnerSignature":[]}],"summary":"Get the delivered codes of an order","tags":["Orders"]}},"/v1/partner/wallet/balance":{"get":{"description":"Orders are paid from `available`. Top up your wallet from your account in the shop.","operationId":"PartnerWalletController_getBalance","parameters":[{"name":"X-Nexus-Timestamp","in":"header","required":true,"description":"Unix time in seconds","schema":{"type":"string","example":"1760054400"}},{"name":"X-Nexus-Nonce","in":"header","required":true,"description":"Unique per request, 16-64 of A-Z a-z 0-9 _ -","schema":{"type":"string"}},{"name":"X-Nexus-Signature","in":"header","required":true,"description":"Hex HMAC-SHA256 of the string to sign","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerWalletBalanceDto"}}}}},"security":[{"PartnerSignature":[]}],"summary":"USD wallet balance","tags":["Wallet"]}},"/v1/partner/wallet/transactions":{"get":{"operationId":"PartnerWalletController_getStatement","parameters":[{"name":"cursor","required":false,"in":"query","description":"Opaque cursor from the previous page (`nextCursor`)","schema":{"type":"string"}},{"name":"limit","required":false,"in":"query","schema":{"minimum":1,"maximum":100,"default":25,"type":"number"}},{"name":"type","required":false,"in":"query","schema":{"type":"string","enum":["purchase","refund","topup","withdrawal","adjustment","hold","release"]}},{"name":"from","required":false,"in":"query","description":"At or after (ISO 8601)","schema":{"format":"date-time","type":"string"}},{"name":"to","required":false,"in":"query","description":"Before (ISO 8601)","schema":{"format":"date-time","type":"string"}},{"name":"orderId","required":false,"in":"query","description":"Only entries for this order","schema":{"type":"string"}},{"name":"includeHolds","required":false,"in":"query","description":"Include temporary holds and their releases","schema":{"default":false,"type":"boolean"}},{"name":"X-Nexus-Timestamp","in":"header","required":true,"description":"Unix time in seconds","schema":{"type":"string","example":"1760054400"}},{"name":"X-Nexus-Nonce","in":"header","required":true,"description":"Unique per request, 16-64 of A-Z a-z 0-9 _ -","schema":{"type":"string"}},{"name":"X-Nexus-Signature","in":"header","required":true,"description":"Hex HMAC-SHA256 of the string to sign","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerStatementPageDto"}}}}},"security":[{"PartnerSignature":[]}],"summary":"USD wallet statement, newest first, for reconciliation","tags":["Wallet"]}}},"info":{"title":"Nexus Partner API","description":"\nServer-to-server API for approved partners: browse the catalog with your prices, place orders paid from your **USD wallet**, and collect codes.\n\nAll amounts are in **USD**. All responses are in **English**. Every endpoint lives under `/v1/partner` on the host serving this page.\n\n> Never call this API from a browser or a mobile app. Your API secret must stay on your servers.\n\n## Quick start\n\n1. Apply for API access from **Account → API Access** in the shop (identity verification is required).\n2. Once approved, reveal your **Key ID**, **API secret** and **webhook signing secret** in the same page. Each secret is shown **once**; store it in a secrets manager.\n3. Add the public IP addresses (or CIDR ranges) of your servers to the **IP allowlist**. Calls from any other address are rejected.\n4. Top up your wallet in the shop, then call `GET /v1/partner/wallet/balance`.\n5. Sync the catalog with `GET /v1/partner/catalog/products`, price a basket with `POST /v1/partner/orders/quote`, and place it with `POST /v1/partner/orders`.\n\n## Authentication\n\nEvery request carries four headers:\n\n| Header | Value |\n| --- | --- |\n| `X-Nexus-Key` | Your Key ID (`nxk_live_…`) |\n| `X-Nexus-Timestamp` | Current Unix time in seconds; must be within 5 minutes of server time |\n| `X-Nexus-Nonce` | A new random value per request (16–64 of `A-Z a-z 0-9 _ -`); reuse is rejected |\n| `X-Nexus-Signature` | Lowercase hex HMAC-SHA256 of the string to sign, keyed with your API secret |\n\nThe **string to sign** is five lines joined with `\\n` (no trailing newline):\n\n```\n<timestamp>\n<nonce>\n<HTTP method, uppercase>\n<path>[?<canonical query>]\n<lowercase hex SHA-256 of the raw request body; of the empty string when there is no body>\n```\n\n- **path** is exactly as sent, starting with `/v1/partner/…`.\n- **canonical query**: decode every `key=value` pair (`+` means space), sort by key then value, re-encode both with RFC 3986 percent-encoding (only `A-Z a-z 0-9 - _ . ~` stay unencoded) and join with `&`. Omit the `?` when there is no query.\n- Hash the **exact bytes** you send as the body.\n\n### Node.js\n\n```js\nimport crypto from 'node:crypto';\n\nconst BASE_URL = process.env.NEXUS_API_URL; // e.g. https://api.example.com\nconst KEY_ID = process.env.NEXUS_KEY_ID;\nconst SECRET = process.env.NEXUS_API_SECRET;\n\nconst encode = (value) =>\n  encodeURIComponent(value).replace(/[!'()*]/g, (c) => '%' + c.charCodeAt(0).toString(16).toUpperCase());\n\nfunction canonicalQuery(search) {\n  const pairs = [...new URLSearchParams(search)];\n  pairs.sort(([ak, av], [bk, bv]) => (ak === bk ? (av < bv ? -1 : av > bv ? 1 : 0) : ak < bk ? -1 : 1));\n  return pairs.map(([k, v]) => encode(k) + '=' + encode(v)).join('&');\n}\n\nexport async function nexus(method, pathAndQuery, body, extraHeaders = {}) {\n  const url = new URL(pathAndQuery, BASE_URL);\n  const payload = body === undefined ? '' : JSON.stringify(body);\n  const timestamp = Math.floor(Date.now() / 1000).toString();\n  const nonce = crypto.randomUUID().replace(/-/g, '');\n  const query = canonicalQuery(url.search);\n  const stringToSign = [\n    timestamp,\n    nonce,\n    method.toUpperCase(),\n    query ? url.pathname + '?' + query : url.pathname,\n    crypto.createHash('sha256').update(payload).digest('hex'),\n  ].join('\\n');\n  const signature = crypto.createHmac('sha256', SECRET).update(stringToSign).digest('hex');\n\n  const res = await fetch(url, {\n    method,\n    body: payload || undefined,\n    headers: {\n      'Content-Type': 'application/json',\n      'X-Nexus-Key': KEY_ID,\n      'X-Nexus-Timestamp': timestamp,\n      'X-Nexus-Nonce': nonce,\n      'X-Nexus-Signature': signature,\n      ...extraHeaders,\n    },\n  });\n  const data = await res.json();\n  if (!res.ok) throw Object.assign(new Error(data.error?.message), { status: res.status, error: data.error });\n  return data;\n}\n\n// const balance = await nexus('GET', '/v1/partner/wallet/balance');\n```\n\n### Python\n\n```python\nimport hashlib, hmac, json, os, time, uuid\nfrom urllib.parse import parse_qsl, quote, urlsplit\n\nimport requests\n\nBASE_URL = os.environ[\"NEXUS_API_URL\"]\nKEY_ID = os.environ[\"NEXUS_KEY_ID\"]\nSECRET = os.environ[\"NEXUS_API_SECRET\"].encode()\n\ndef canonical_query(query: str) -> str:\n    pairs = sorted(parse_qsl(query, keep_blank_values=True))\n    return \"&\".join(f\"{quote(k, safe='-_.~')}={quote(v, safe='-_.~')}\" for k, v in pairs)\n\ndef nexus(method: str, path_and_query: str, body=None, headers=None):\n    parts = urlsplit(path_and_query)\n    payload = b\"\" if body is None else json.dumps(body, separators=(\",\", \":\")).encode()\n    timestamp = str(int(time.time()))\n    nonce = uuid.uuid4().hex\n    query = canonical_query(parts.query)\n    target = f\"{parts.path}?{query}\" if query else parts.path\n    string_to_sign = \"\\n\".join([timestamp, nonce, method.upper(), target, hashlib.sha256(payload).hexdigest()])\n    signature = hmac.new(SECRET, string_to_sign.encode(), hashlib.sha256).hexdigest()\n    res = requests.request(method, BASE_URL + path_and_query, data=payload or None, headers={\n        \"Content-Type\": \"application/json\",\n        \"X-Nexus-Key\": KEY_ID,\n        \"X-Nexus-Timestamp\": timestamp,\n        \"X-Nexus-Nonce\": nonce,\n        \"X-Nexus-Signature\": signature,\n        **(headers or {}),\n    }, timeout=30)\n    data = res.json()\n    if not res.ok:\n        raise RuntimeError(f\"{res.status_code} {data['error']['code']}: {data['error']['message']}\")\n    return data\n```\n\n### PHP\n\n```php\n<?php\nfunction canonicalQuery(string $query): string {\n    $pairs = [];\n    foreach (explode('&', $query) as $part) {\n        if ($part === '') continue;\n        [$k, $v] = array_pad(explode('=', $part, 2), 2, '');\n        $pairs[] = [urldecode($k), urldecode($v)];\n    }\n    usort($pairs, fn($a, $b) => strcmp($a[0], $b[0]) ?: strcmp($a[1], $b[1]));\n    return implode('&', array_map(fn($p) => rawurlencode($p[0]) . '=' . rawurlencode($p[1]), $pairs));\n}\n\nfunction nexus(string $method, string $pathAndQuery, ?array $body = null, array $headers = []): array {\n    $parts = parse_url($pathAndQuery);\n    $payload = $body === null ? '' : json_encode($body, JSON_UNESCAPED_SLASHES);\n    $timestamp = (string) time();\n    $nonce = bin2hex(random_bytes(16));\n    $query = canonicalQuery($parts['query'] ?? '');\n    $target = $query === '' ? $parts['path'] : $parts['path'] . '?' . $query;\n    $stringToSign = implode(\"\\n\", [$timestamp, $nonce, strtoupper($method), $target, hash('sha256', $payload)]);\n    $signature = hash_hmac('sha256', $stringToSign, getenv('NEXUS_API_SECRET'));\n\n    $ch = curl_init(getenv('NEXUS_API_URL') . $pathAndQuery);\n    curl_setopt_array($ch, [\n        CURLOPT_CUSTOMREQUEST => strtoupper($method),\n        CURLOPT_RETURNTRANSFER => true,\n        CURLOPT_POSTFIELDS => $payload === '' ? null : $payload,\n        CURLOPT_HTTPHEADER => array_merge([\n            'Content-Type: application/json',\n            'X-Nexus-Key: ' . getenv('NEXUS_KEY_ID'),\n            'X-Nexus-Timestamp: ' . $timestamp,\n            'X-Nexus-Nonce: ' . $nonce,\n            'X-Nexus-Signature: ' . $signature,\n        ], $headers),\n    ]);\n    $data = json_decode(curl_exec($ch), true);\n    curl_close($ch);\n    return $data;\n}\n```\n\n## Catalog scope\n\n`GET /v1/partner/account` returns your `countryCode` and `catalogScope`:\n\n- `country`: the catalog lists only products and SKUs offered in `countryCode`.\n- `global`: every product is listed, whatever its country or region. Check each SKU's `countryCode` and `regionCode` to know where its codes can be redeemed.\n\nTax and payment rules always follow `countryCode`.\n\n## Placing orders\n\n1. Read SKUs from the catalog. Each SKU has your `price` (USD), `minQuantity`/`maxQuantity`, and for custom-amount SKUs a `customAmount` block (send `customAmount` in that unit; you pay `customAmount × unitPrice`). Products with `requiredInputs` (top-ups) need those values in `inputs`.\n2. Optional: `POST /orders/quote` returns the exact total for a basket without charging anything.\n3. `POST /orders` with an **`Idempotency-Key`** header. The total is debited from your **USD balance only**; other currency balances are never converted. You may pass your own `externalReference`, unique per client.\n4. The response is the order. Virtual stock is usually delivered within seconds: when `codesAvailable` is true, fetch codes with `GET /orders/{orderId}/codes`, or wait for the `order.completed` webhook.\n\n### Idempotency\n\nUse a new random `Idempotency-Key` (8–100 of `A-Z a-z 0-9 . _ : -`) for every order and **reuse it when retrying** that order after a timeout or network error:\n\n- same key and body: the original response is returned (header `Idempotent-Replayed: true`), no second order is placed;\n- same key, different body: `422 IDEMPOTENCY_KEY_REUSED`;\n- first request still running: `409 REQUEST_IN_PROGRESS`; retry shortly.\n\nKeys are remembered for 24 hours.\n\n### Order statuses\n\n| Status | Meaning |\n| --- | --- |\n| `processing` | Paid; codes are being delivered |\n| `partially_completed` | Some codes delivered, the rest are on the way |\n| `completed` | Everything delivered |\n| `under_review` | Held for a manual check; you are notified when it continues |\n| `cancelled` / `failed` | Not delivered; refunds, when due, appear in your wallet statement |\n| `refunded` / `partially_refunded` | Refunded to your wallet after delivery |\n\nCodes are only returned through `GET /orders/{orderId}/codes`. Every fetch is logged as proof of delivery.\n\n## Pagination\n\nList endpoints return `{ data, nextCursor }`. Pass `nextCursor` back as `cursor` to get the next page; it is `null` on the last page. `limit` is 1–100 (default 25).\n\n## Errors\n\nErrors always look like:\n\n```json\n{ \"error\": { \"code\": \"INSUFFICIENT_BALANCE\", \"message\": \"Insufficient wallet balance\", \"requestId\": \"req_…\", \"details\": { } } }\n```\n\nBranch on `code`, never on `message`. Include `requestId` when contacting support.\n\n| HTTP | Code | When |\n| --- | --- | --- |\n| 400 | `VALIDATION_FAILED` | Invalid body or query; see `details` |\n| 400 | `IDEMPOTENCY_KEY_REQUIRED` | `POST /orders` without `Idempotency-Key` |\n| 401 | `UNAUTHORIZED` | Missing or unknown credentials |\n| 401 | `INVALID_SIGNATURE` | Signature does not match |\n| 401 | `TIMESTAMP_OUT_OF_RANGE` | Clock skew over 5 minutes (`details.serverTime`) |\n| 401 | `NONCE_REUSED` | Nonce already used |\n| 403 | `IP_NOT_ALLOWED` | Caller IP is not on your allowlist |\n| 403 | `CLIENT_INACTIVE` | API access suspended or revoked |\n| 403 | `ACCOUNT_RESTRICTED` | The owning account cannot trade right now |\n| 403 | `WALLET_FROZEN` | Your wallet is frozen |\n| 404 | `NOT_FOUND` | Unknown order or product |\n| 409 | `DUPLICATE_REFERENCE` | `externalReference` already used (`details.orderId`) |\n| 409 | `REQUEST_IN_PROGRESS` | Same idempotency key still processing |\n| 409 | `PRICE_CHANGED` | Prices moved while the order was placed; quote again |\n| 409 | `CODES_NOT_READY` | Codes not delivered yet |\n| 400 | `INSUFFICIENT_BALANCE` | USD balance too low (`details.args`) |\n| 422 | `PRODUCT_UNAVAILABLE` | SKU not sellable or out of stock |\n| 422 | `LIMIT_EXCEEDED` | Over your max order amount or daily spend limit |\n| 422 | `ORDER_REJECTED` | Order declined by risk checks |\n| 422 | `IDEMPOTENCY_KEY_REUSED` | Key reused with a different request |\n| 429 | `RATE_LIMITED` | Too many requests; honour `Retry-After` |\n| 500 | `INTERNAL_ERROR` | Unexpected error; safe to retry with the same idempotency key |\n| 503 | `SERVICE_UNAVAILABLE` | The Partner API is temporarily switched off; your credentials stay valid, retry later |\n\n## Limits\n\nEach client has a per-minute request limit, a per-minute order limit, a maximum order amount and a daily spend limit (UTC day); see `GET /v1/partner/account`. Responses carry `X-RateLimit-Limit`, `X-RateLimit-Remaining` and `X-RateLimit-Reset` (seconds).\n\n## Webhooks\n\nSet an HTTPS webhook URL in **Account → API Access** to be notified of order changes: `order.completed`, `order.partially_fulfilled`, `order.under_review`, `order.failed`, `order.cancelled`, `order.refunded` (and `test.ping` on request).\n\nEach delivery is a `POST` with a JSON body `{ \"id\", \"type\", \"createdAt\", \"data\": { \"order\": { … } } }` and headers:\n\n- `X-Nexus-Event`: event type\n- `X-Nexus-Event-Id`: stable across retries; use it to ignore duplicates\n- `X-Nexus-Signature`: `t=<unix seconds>,v1=<hex HMAC-SHA256 of \"<t>.<raw body>\" keyed with your webhook signing secret>`\n\nRespond with any `2xx` within 10 seconds. Failed deliveries are retried up to 8 times with exponential backoff (starting at 1 minute). Webhooks never contain codes; fetch them with the API.\n\n```js\nimport crypto from 'node:crypto';\n\nexport function verifyNexusWebhook(rawBody, header, secret, toleranceSeconds = 300) {\n  const parts = Object.fromEntries(header.split(',').map((p) => p.trim().split('=')));\n  const t = Number(parts.t);\n  if (!t || Math.abs(Date.now() / 1000 - t) > toleranceSeconds) return false;\n  const expected = crypto.createHmac('sha256', secret).update(t + '.' + rawBody).digest('hex');\n  const a = Buffer.from(expected, 'hex');\n  const b = Buffer.from(parts.v1 ?? '', 'hex');\n  return a.length === b.length && crypto.timingSafeEqual(a, b);\n}\n```\n\n```python\nimport hashlib, hmac, time\n\ndef verify_nexus_webhook(raw_body: bytes, header: str, secret: str, tolerance: int = 300) -> bool:\n    parts = dict(p.strip().split(\"=\", 1) for p in header.split(\",\"))\n    t = int(parts.get(\"t\", \"0\"))\n    if abs(time.time() - t) > tolerance:\n        return False\n    expected = hmac.new(secret.encode(), f\"{t}.\".encode() + raw_body, hashlib.sha256).hexdigest()\n    return hmac.compare_digest(expected, parts.get(\"v1\", \"\"))\n```\n\nAlways verify against the **raw** body bytes, before parsing the JSON.\n","version":"1.0","contact":{}},"tags":[{"name":"Account","description":"Your API client"},{"name":"Wallet","description":"USD balance and statement"},{"name":"Catalog","description":"Products and your prices"},{"name":"Orders","description":"Quotes, orders and codes"}],"servers":[],"components":{"securitySchemes":{"PartnerSignature":{"type":"apiKey","in":"header","name":"X-Nexus-Key","description":"Send your Key ID in `X-Nexus-Key` together with `X-Nexus-Timestamp`, `X-Nexus-Nonce` and `X-Nexus-Signature`. See \"Authentication\" above."}},"schemas":{"PartnerStatementPageDto":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/PartnerStatementEntryDto"}},"nextCursor":{"type":"object","nullable":true}},"required":["data"]},"PartnerStatementEntryDto":{"type":"object","properties":{"id":{"type":"string"},"type":{"type":"string","enum":["purchase","refund","topup","withdrawal","adjustment","hold","release"]},"status":{"type":"string","enum":["pending","completed","failed","cancelled"]},"amount":{"type":"number","description":"Signed: negative for debits","example":-95},"currency":{"type":"string","example":"USD","enum":["USD"]},"balanceAfter":{"type":"number","description":"Available balance after this entry"},"description":{"type":"object","nullable":true},"reference":{"$ref":"#/components/schemas/PartnerStatementReferenceDto"},"createdAt":{"format":"date-time","type":"string"},"completedAt":{"type":"object","nullable":true}},"required":["id","type","status","amount","currency","balanceAfter","reference","createdAt"]},"PartnerStatementReferenceDto":{"type":"object","properties":{"orderId":{"type":"object","nullable":true},"orderNumber":{"type":"object","nullable":true},"externalReference":{"type":"object","nullable":true}}},"PartnerWalletBalanceDto":{"type":"object","properties":{"currency":{"type":"string","example":"USD","enum":["USD"]},"available":{"type":"number","description":"Spendable now","example":1250.4},"held":{"type":"number","description":"Reserved for orders being placed","example":0},"total":{"type":"number","description":"available + held","example":1250.4},"isFrozen":{"type":"boolean","description":"A frozen wallet cannot pay for orders"},"dailySpendLimit":{"type":"number","description":"Your daily API spend limit (UTC day)","example":10000},"spentToday":{"type":"number","example":320},"remainingToday":{"type":"number","example":9680},"updatedAt":{"type":"object","nullable":true}},"required":["currency","available","held","total","isFrozen","dailySpendLimit","spentToday","remainingToday"]},"PartnerOrderCodesDto":{"type":"object","properties":{"orderId":{"type":"string"},"orderNumber":{"type":"string"},"status":{"type":"string","enum":["processing","under_review","partially_completed","completed","cancelled","failed","refunded","partially_refunded"]},"codes":{"type":"array","items":{"$ref":"#/components/schemas/PartnerCodeDto"}},"withheldCount":{"type":"number","description":"Codes withheld while support reviews them"}},"required":["orderId","orderNumber","status","codes","withheldCount"]},"PartnerCodeDto":{"type":"object","properties":{"itemId":{"type":"string","description":"Order line the code belongs to"},"skuId":{"type":"string"},"code":{"type":"string","example":"XXXX-YYYY-ZZZZ"},"pin":{"type":"object","nullable":true},"serial":{"type":"object","nullable":true},"expiresAt":{"type":"object","nullable":true},"extra":{"type":"array","items":{"type":"object","properties":{"key":{"type":"string"},"value":{"type":"string"}}}}},"required":["itemId","skuId","code","extra"]},"PartnerOrderDto":{"type":"object","properties":{"id":{"type":"string"},"orderNumber":{"type":"string","example":"ORD-261010-0042"},"externalReference":{"type":"object","nullable":true},"status":{"type":"string","enum":["processing","under_review","partially_completed","completed","cancelled","failed","refunded","partially_refunded"]},"codesAvailable":{"type":"boolean","description":"True once at least one code can be fetched"},"amounts":{"$ref":"#/components/schemas/PartnerAmountsDto"},"items":{"type":"array","items":{"$ref":"#/components/schemas/PartnerOrderItemResponseDto"}},"createdAt":{"format":"date-time","type":"string"},"updatedAt":{"format":"date-time","type":"string"},"completedAt":{"type":"object","nullable":true}},"required":["id","orderNumber","status","codesAvailable","amounts","items","createdAt","updatedAt"]},"PartnerOrderItemResponseDto":{"type":"object","properties":{"skuId":{"type":"string"},"skuCode":{"type":"string"},"name":{"type":"string"},"quantity":{"type":"number"},"customAmount":{"type":"object","nullable":true},"unitPrice":{"type":"number"},"lineTotal":{"type":"number"},"id":{"type":"string","description":"Line ID, matches `itemId` on returned codes"},"productId":{"type":"string"},"status":{"type":"string","enum":["pending","processing","partially_delivered","delivered","cancelled","refunded"]}},"required":["skuId","skuCode","name","quantity","unitPrice","lineTotal","id","productId","status"]},"PartnerAmountsDto":{"type":"object","properties":{"currency":{"type":"string","example":"USD","enum":["USD"]},"subtotal":{"type":"number","example":95},"fees":{"type":"number","example":0,"description":"Wallet payment fee, if one is configured"},"tax":{"type":"number","example":0},"total":{"type":"number","example":95,"description":"Amount debited from your USD wallet balance"}},"required":["currency","subtotal","fees","tax","total"]},"PartnerOrderPageDto":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/PartnerOrderDto"}},"nextCursor":{"type":"object","nullable":true}},"required":["data"]},"CreatePartnerOrderDto":{"type":"object","properties":{"items":{"maxItems":20,"type":"array","items":{"$ref":"#/components/schemas/PartnerOrderItemDto"}},"externalReference":{"type":"string","description":"Your own order ID. Unique per client; a reused value is rejected with 409.","example":"SO-2026-000123"}},"required":["items"]},"PartnerOrderItemDto":{"type":"object","properties":{"skuId":{"type":"string","description":"SKU `id` from the catalog"},"quantity":{"type":"number","minimum":1,"maximum":1000,"example":2},"customAmount":{"type":"number","description":"Required for custom-amount SKUs: the amount, in the SKU `customAmount.unit`","example":25},"inputs":{"description":"Values for `requiredInputs`","type":"array","items":{"$ref":"#/components/schemas/PartnerOrderInputDto"}}},"required":["skuId","quantity"]},"PartnerOrderInputDto":{"type":"object","properties":{"name":{"type":"string","example":"playerId","description":"`name` of a required input from the catalog"},"value":{"type":"string","example":"5123456789"}},"required":["name","value"]},"PartnerQuoteDto":{"type":"object","properties":{"currency":{"type":"string","example":"USD","enum":["USD"]},"subtotal":{"type":"number","example":95},"fees":{"type":"number","example":0,"description":"Wallet payment fee, if one is configured"},"tax":{"type":"number","example":0},"total":{"type":"number","example":95,"description":"Amount debited from your USD wallet balance"},"items":{"type":"array","items":{"$ref":"#/components/schemas/PartnerQuoteItemDto"}}},"required":["currency","subtotal","fees","tax","total","items"]},"PartnerQuoteItemDto":{"type":"object","properties":{"skuId":{"type":"string"},"skuCode":{"type":"string"},"name":{"type":"string"},"quantity":{"type":"number"},"customAmount":{"type":"object","nullable":true},"unitPrice":{"type":"number"},"lineTotal":{"type":"number"}},"required":["skuId","skuCode","name","quantity","unitPrice","lineTotal"]},"QuotePartnerOrderDto":{"type":"object","properties":{"items":{"maxItems":20,"type":"array","items":{"$ref":"#/components/schemas/PartnerOrderItemDto"}}},"required":["items"]},"CatalogCategoryDto":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"},"parentId":{"type":"object","nullable":true}},"required":["id","name","slug"]},"CatalogProductDetailDto":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"},"type":{"type":"string","enum":["voucher","range","topup"]},"shortDescription":{"type":"object","nullable":true},"image":{"type":"object","nullable":true},"brand":{"nullable":true,"allOf":[{"$ref":"#/components/schemas/CatalogReferenceDto"}]},"categories":{"type":"array","items":{"$ref":"#/components/schemas/CatalogReferenceDto"}},"instantDelivery":{"type":"boolean"},"requiredInputs":{"description":"Inputs required when ordering","type":"array","items":{"$ref":"#/components/schemas/CatalogInputFieldDto"}},"skus":{"type":"array","items":{"$ref":"#/components/schemas/CatalogSkuDto"}},"updatedAt":{"format":"date-time","type":"string"},"description":{"type":"object","nullable":true,"description":"HTML"},"redemptionInstructions":{"type":"object","nullable":true,"description":"HTML"},"topUpInstructions":{"type":"object","nullable":true,"description":"HTML"},"images":{"type":"array","items":{"type":"string"}}},"required":["id","name","slug","type","categories","instantDelivery","requiredInputs","skus","updatedAt","images"]},"CatalogSkuDto":{"type":"object","properties":{"id":{"type":"string"},"code":{"type":"string","example":"PSN-US-USD-50"},"name":{"type":"string","example":"$50 USD"},"faceValue":{"type":"object","nullable":true,"example":50},"faceValueCurrency":{"type":"object","nullable":true,"example":"USD"},"countryCode":{"type":"object","nullable":true,"example":"US"},"regionCode":{"type":"object","nullable":true,"example":"GLOBAL"},"price":{"type":"number","description":"Your price in USD for one unit (per 1 amount unit for custom-amount SKUs)","example":47.5},"currency":{"type":"string","example":"USD","enum":["USD"]},"available":{"type":"boolean","description":"Whether the SKU can be ordered right now"},"minQuantity":{"type":"number"},"maxQuantity":{"type":"object","nullable":true},"customAmount":{"nullable":true,"allOf":[{"$ref":"#/components/schemas/CatalogCustomAmountDto"}]}},"required":["id","code","name","price","currency","available","minQuantity"]},"CatalogCustomAmountDto":{"type":"object","properties":{"min":{"type":"number","description":"Smallest amount that can be ordered"},"max":{"type":"object","nullable":true},"step":{"type":"number","description":"Amount must be a multiple of this step"},"unit":{"type":"string","example":"USD","description":"Unit the amount is expressed in"},"unitPrice":{"type":"number","description":"Price in USD per 1 unit of amount"}},"required":["min","step","unit","unitPrice"]},"CatalogInputFieldDto":{"type":"object","properties":{"name":{"type":"string","description":"Key to send in `inputs` when ordering","example":"playerId"},"label":{"type":"string","example":"Player ID"},"type":{"type":"string","enum":["text","email","number","phone","select","textarea"]},"required":{"type":"boolean"},"placeholder":{"type":"object","nullable":true},"minLength":{"type":"object","nullable":true},"maxLength":{"type":"object","nullable":true},"pattern":{"type":"object","nullable":true,"description":"Regular expression the value must match"},"min":{"type":"object","nullable":true},"max":{"type":"object","nullable":true},"options":{"description":"Allowed values for `select` fields","type":"array","items":{"type":"string"}}},"required":["name","label","type","required","options"]},"CatalogReferenceDto":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}},"required":["id","name"]},"CatalogProductPageDto":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/CatalogProductDto"}},"nextCursor":{"type":"object","nullable":true,"description":"Pass as `cursor` to get the next page"}},"required":["data"]},"CatalogProductDto":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"},"type":{"type":"string","enum":["voucher","range","topup"]},"shortDescription":{"type":"object","nullable":true},"image":{"type":"object","nullable":true},"brand":{"nullable":true,"allOf":[{"$ref":"#/components/schemas/CatalogReferenceDto"}]},"categories":{"type":"array","items":{"$ref":"#/components/schemas/CatalogReferenceDto"}},"instantDelivery":{"type":"boolean"},"requiredInputs":{"description":"Inputs required when ordering","type":"array","items":{"$ref":"#/components/schemas/CatalogInputFieldDto"}},"skus":{"type":"array","items":{"$ref":"#/components/schemas/CatalogSkuDto"}},"updatedAt":{"format":"date-time","type":"string"}},"required":["id","name","slug","type","categories","instantDelivery","requiredInputs","skus","updatedAt"]},"PartnerAccountDto":{"type":"object","properties":{"keyId":{"type":"string"},"status":{"type":"string","enum":["active"]},"countryCode":{"type":"string","example":"AE","description":"Billing country used for tax and payment rules, and for catalog availability when `catalogScope` is `country`"},"catalogScope":{"type":"string","enum":["country","global"],"description":"`country`: only products offered in `countryCode`. `global`: every product, whatever its country or region; check each SKU's `countryCode`/`regionCode` for where its codes work"},"currency":{"type":"string","example":"USD","enum":["USD"]},"limits":{"type":"object","properties":{"requestsPerMinute":{"type":"number"},"ordersPerMinute":{"type":"number"},"maxOrderAmountUSD":{"type":"number"},"dailySpendLimitUSD":{"type":"number"}}}},"required":["keyId","status","countryCode","catalogScope","currency","limits"]}}}}