{"info":{"_postman_id":"2445d6f9-6ae5-4249-9fa7-21f0fd89ecf6","name":"HOI eServices API","description":"<html><head></head><body><p>The HOI eServices API provides a unified interface for digital services including gift cards, eSIM provisioning, mobile top-ups, vouchers, bill payments, and travel insurance. Each service is organized as a separate folder within this collection.</p>\n<hr>\n<h2 id=\"base-urls\">Base URLs</h2>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Environment</th>\n<th>Base URL</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>Preproduction (PPD)</td>\n<td><code>https://eservicespre.hoicom.net</code></td>\n</tr>\n<tr>\n<td>Production (PRD)</td>\n<td><code>https://eservices.hoicom.net</code></td>\n</tr>\n</tbody>\n</table>\n</div><p>All endpoint paths are relative to the base URL for your target environment, e.g. <code>https://eservices.hoicom.net/api/v0/gifts/locations</code>.</p>\n<hr>\n<h2 id=\"api-architecture\">API Architecture</h2>\n<p>The API is structured around RESTful principles, utilizing standard HTTP methods and status codes. It communicates using JSON-formatted requests and responses, ensuring compatibility with a wide range of clients and platforms.</p>\n<ul>\n<li><p><strong>Content Type:</strong> All requests and responses use <code>application/json</code></p>\n</li>\n<li><p><strong>Base URL:</strong> Environment-specific — see the <strong>Base URLs</strong> section above. Paths follow the form <code>.../api/{version}/{service}</code></p>\n</li>\n<li><p><strong>Versioning:</strong> API versions are specified in the URL path (e.g., <code>v0</code>, <code>v1</code>)</p>\n</li>\n</ul>\n<hr>\n<h2 id=\"authentication\">Authentication</h2>\n<p>All API endpoints require proper authentication to ensure secure access. Authentication is handled via <strong>Basic Authentication</strong>, where clients provide their credentials with each request.</p>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Property</th>\n<th>Value</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><strong>Method</strong></td>\n<td>Basic Authentication</td>\n</tr>\n<tr>\n<td><strong>Header</strong></td>\n<td><code>Authorization: Basic {Base64EncodedCredentials}</code></td>\n</tr>\n</tbody>\n</table>\n</div><h3 id=\"how-to-encode-credentials\">How to encode credentials</h3>\n<ol>\n<li><p>Combine your username and password with a colon: <code>username:password</code></p>\n</li>\n<li><p>Encode the combined string using <strong>Base64</strong> encoding</p>\n</li>\n<li><p>Include the encoded string in the <code>Authorization</code> header:</p>\n</li>\n</ol>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code>Authorization: Basic xxxxxxxxx\n\n</code></pre><hr>\n<h2 id=\"security\">Security</h2>\n<h3 id=\"transport-security-tls\">Transport Security (TLS)</h3>\n<ul>\n<li>All API communication is served <strong>exclusively over HTTPS/TLS</strong>. Plain HTTP is not supported on any endpoint.</li>\n<li><strong>TLS 1.2 or higher</strong> is enforced.</li>\n<li>Our TLS server certificates are issued by a <strong>trusted public Certificate Authority (CA)</strong>.</li>\n</ul>\n<h3 id=\"certificates\">Certificates</h3>\n<ul>\n<li>Server certificates are renewed <strong>annually</strong>, ahead of expiry.</li>\n<li>Clients who validate or pin our certificate on their systems are <strong>notified in advance of each renewal</strong>, with the new certificate / public key provided beforehand so it can be pre-configured with <strong>no service interruption</strong>.</li>\n</ul>\n<h3 id=\"authentication-1\">Authentication</h3>\n<ul>\n<li>Every request must include valid client credentials in the <code>Authorization</code> header (HTTP <strong>Basic Authentication</strong>).</li>\n<li>Each client is issued <strong>unique credentials</strong>, with <strong>separate credentials per environment</strong> (Pre-Production and Production).</li>\n<li>Credentials are delivered through a <strong>secure channel during onboarding</strong> and can be <strong>rotated or revoked immediately</strong> upon request or suspicion of compromise.</li>\n</ul>\n<h3 id=\"input-validation\">Input Validation</h3>\n<ul>\n<li>Strict <strong>server-side validation</strong> is applied to request format and parameters, protecting the platform against malformed and injection-style payloads.</li>\n</ul>\n<h3 id=\"environment-segregation\">Environment Segregation</h3>\n<ul>\n<li><strong>Pre-Production</strong> (<code>eservicespre.hoicom.net</code>) and <strong>Production</strong> (<code>eservices.hoicom.net</code>) are <strong>fully segregated</strong> environments, with separate credentials and separate data.</li>\n<li>All integration testing must be completed in <strong>Pre-Production before Production access is granted</strong>.</li>\n</ul>\n<hr>\n<h2 id=\"response-format\">Response Format</h2>\n<p>All responses follow a standard JSON structure:</p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">{\n  \"code\": 1000,\n  \"message\": \"Success\",\n  \"data\": { }\n}\n\n</code></pre>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Field</th>\n<th>Type</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>code</code></td>\n<td><code>int</code></td>\n<td>Custom response code (see table below)</td>\n</tr>\n<tr>\n<td><code>message</code></td>\n<td><code>string</code></td>\n<td>Human-readable message</td>\n</tr>\n<tr>\n<td><code>data</code></td>\n<td><code>object</code></td>\n<td>Response payload (nullable on errors)</td>\n</tr>\n</tbody>\n</table>\n</div><hr>\n<h2 id=\"response-codes\">Response Codes</h2>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Code</th>\n<th>Name</th>\n<th>Message</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><strong>1000</strong></td>\n<td>Success</td>\n<td>Request processed successfully.</td>\n</tr>\n<tr>\n<td><strong>1101</strong></td>\n<td>InternalServerError</td>\n<td>Internal server error.</td>\n</tr>\n<tr>\n<td><strong>1102</strong></td>\n<td>InvalidRequestFormat</td>\n<td>Invalid request format.</td>\n</tr>\n<tr>\n<td><strong>1103</strong></td>\n<td>UnauthorizedAccess</td>\n<td>Unauthorized access.</td>\n</tr>\n<tr>\n<td><strong>1104</strong></td>\n<td>Forbidden</td>\n<td>Forbidden.</td>\n</tr>\n<tr>\n<td><strong>1105</strong></td>\n<td>ResourceNotFound</td>\n<td>Resource not found.</td>\n</tr>\n<tr>\n<td><strong>1106</strong></td>\n<td>MethodNotAllowed</td>\n<td>Method not allowed.</td>\n</tr>\n<tr>\n<td><strong>1107</strong></td>\n<td>ValidationError</td>\n<td>Validation error.</td>\n</tr>\n<tr>\n<td><strong>1108</strong></td>\n<td>InvalidCredentials</td>\n<td>Invalid credentials.</td>\n</tr>\n<tr>\n<td><strong>1109</strong></td>\n<td>RateLimitExceeded</td>\n<td>Rate limit exceeded.</td>\n</tr>\n<tr>\n<td><strong>1110</strong></td>\n<td>UnsupportedMediaType</td>\n<td>Unsupported media type.</td>\n</tr>\n<tr>\n<td><strong>1111</strong></td>\n<td>NotAcceptable</td>\n<td>Not acceptable.</td>\n</tr>\n<tr>\n<td><strong>1112</strong></td>\n<td>Conflict</td>\n<td>Conflict with current state.</td>\n</tr>\n<tr>\n<td><strong>1113</strong></td>\n<td>ServiceUnavailable</td>\n<td>Service unavailable.</td>\n</tr>\n<tr>\n<td><strong>1114</strong></td>\n<td>InvalidParameterValue</td>\n<td>Invalid parameter value.</td>\n</tr>\n<tr>\n<td><strong>1120</strong></td>\n<td>TooManyRequests</td>\n<td>Too many requests.</td>\n</tr>\n<tr>\n<td><strong>1201</strong></td>\n<td>PaginationErrorInvalidPage</td>\n<td>Invalid page number.</td>\n</tr>\n<tr>\n<td><strong>1202</strong></td>\n<td>PaginationErrorInvalidPageSize</td>\n<td>Invalid page size.</td>\n</tr>\n<tr>\n<td><strong>1301</strong></td>\n<td>SearchParameterErrorInvalidTerm</td>\n<td>Invalid search term.</td>\n</tr>\n<tr>\n<td><strong>1302</strong></td>\n<td>FilteringErrorInvalidCriteria</td>\n<td>Invalid filtering criteria.</td>\n</tr>\n<tr>\n<td><strong>1303</strong></td>\n<td>NoResultsFound</td>\n<td>No results found.</td>\n</tr>\n<tr>\n<td><strong>1401</strong></td>\n<td>InvalidNumberOrAccount</td>\n<td>Invalid number or account.</td>\n</tr>\n<tr>\n<td><strong>1402</strong></td>\n<td>LimitationExceeded</td>\n<td>Limitation exceeded.</td>\n</tr>\n<tr>\n<td><strong>1403</strong></td>\n<td>TransactionRejected</td>\n<td>Transaction rejected.</td>\n</tr>\n<tr>\n<td><strong>1404</strong></td>\n<td>DeclinedByProvider</td>\n<td>Declined by provider.</td>\n</tr>\n<tr>\n<td><strong>1405</strong></td>\n<td>ProviderDown</td>\n<td>Provider is down.</td>\n</tr>\n<tr>\n<td><strong>1406</strong></td>\n<td>NumberOrAccountIssueByProvider</td>\n<td>Number or account issue by provider.</td>\n</tr>\n<tr>\n<td><strong>1407</strong></td>\n<td>DuplicateTransaction</td>\n<td>Duplicate transaction.</td>\n</tr>\n<tr>\n<td><strong>1408</strong></td>\n<td>TransactionTimeout</td>\n<td>Transaction timeout.</td>\n</tr>\n<tr>\n<td><strong>1409</strong></td>\n<td>InvalidTransactionAmount</td>\n<td>Invalid transaction amount.</td>\n</tr>\n<tr>\n<td><strong>1410</strong></td>\n<td>ServiceTemporarilyUnavailable</td>\n<td>Service temporarily unavailable.</td>\n</tr>\n<tr>\n<td><strong>1411</strong></td>\n<td>InsufficientFunds</td>\n<td>Insufficient funds.</td>\n</tr>\n<tr>\n<td><strong>1412</strong></td>\n<td>ExceededTransactionLimit</td>\n<td>Exceeded transaction limit.</td>\n</tr>\n<tr>\n<td><strong>1413</strong></td>\n<td>InvalidProductId</td>\n<td>Invalid product ID.</td>\n</tr>\n<tr>\n<td><strong>1414</strong></td>\n<td>InvalidCurrencyCode</td>\n<td>Invalid currency code.</td>\n</tr>\n<tr>\n<td><strong>1415</strong></td>\n<td>InvalidAmountRange</td>\n<td>Invalid amount range.</td>\n</tr>\n<tr>\n<td><strong>1416</strong></td>\n<td>InvalidDestinationNumberFormat</td>\n<td>Invalid destination number format.</td>\n</tr>\n<tr>\n<td><strong>1417</strong></td>\n<td>DestinationNumberNotSupported</td>\n<td>Destination number not supported.</td>\n</tr>\n<tr>\n<td><strong>1418</strong></td>\n<td>InvalidExternalReference</td>\n<td>Invalid external reference.</td>\n</tr>\n<tr>\n<td><strong>1419</strong></td>\n<td>TransactionAlreadyProcessed</td>\n<td>Transaction already processed.</td>\n</tr>\n<tr>\n<td><strong>1420</strong></td>\n<td>UnsupportedCountry</td>\n<td>Unsupported country.</td>\n</tr>\n<tr>\n<td><strong>1421</strong></td>\n<td>UnsupportedOperator</td>\n<td>Unsupported operator.</td>\n</tr>\n<tr>\n<td><strong>1422</strong></td>\n<td>RefundNotEligible</td>\n<td>Refund not eligible.</td>\n</tr>\n<tr>\n<td><strong>1423</strong></td>\n<td>RefundRequestAlreadyOpen</td>\n<td>A refund request is already open for this transaction.</td>\n</tr>\n<tr>\n<td><strong>1424</strong></td>\n<td>InvalidRefundTransition</td>\n<td>This action is not valid for the refund request's current status.</td>\n</tr>\n<tr>\n<td><strong>1426</strong></td>\n<td>RefundServiceUnavailable</td>\n<td>Refund service unavailable.</td>\n</tr>\n<tr>\n<td><strong>1427</strong></td>\n<td>RegenerationNotEligible</td>\n<td>This eSIM is not eligible for regeneration.</td>\n</tr>\n<tr>\n<td><strong>1428</strong></td>\n<td>RegenerationLimitReached</td>\n<td>The regeneration limit for this eSIM has been reached.</td>\n</tr>\n<tr>\n<td><strong>1429</strong></td>\n<td>RegenerationInProgress</td>\n<td>A regeneration is already in progress for this eSIM.</td>\n</tr>\n</tbody>\n</table>\n</div><p><strong>Notes on specific codes</strong></p>\n<ul>\n<li><strong>HTTP status of the new codes:</strong> <code>1422</code> returns 400, <code>1423</code> 409, <code>1424</code> 409, <code>1426</code> 503, <code>1427</code> 400 (the <code>message</code> states the reason), <code>1428</code> 409, <code>1429</code> 409 (also returned for a top-up of an eSIM that is being regenerated).</li>\n<li><strong>1107</strong> — also returned (HTTP 400) for body validation on eSIM refund and regenerate requests.</li>\n<li><strong>1114</strong> — also returned with HTTP 409 when an <code>externalReference</code> is already used in your account (see <strong>External references</strong> below).</li>\n<li><strong>1303</strong> — also returned with HTTP 404 for an eSIM top-up whose target is not your own completed base plan, and for Gifts when delivery prices cannot be read.</li>\n<li><strong>1403</strong> — Gift Cards: \"This product is not available for purchase right now.\" (HTTP 400).</li>\n<li><strong>1407</strong> — the <code>externalReference</code> is already used by your account on the same service (Topup and Gift Cards; HTTP 200).</li>\n<li><strong>1413</strong> — Gift Cards: the product is unknown, inactive, or not offered to you.</li>\n<li><strong>1415</strong> — Gifts: <code>amount</code> must equal the availability total (within 0.01).</li>\n</ul>\n<hr>\n<h2 id=\"transaction-statuses\">Transaction Statuses</h2>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Status</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><strong>Submitted</strong></td>\n<td>The transaction has been received and is queued for processing.</td>\n</tr>\n<tr>\n<td><strong>Pending</strong></td>\n<td>The transaction is currently being processed by the system or service provider.</td>\n</tr>\n<tr>\n<td><strong>Completed</strong></td>\n<td>The transaction has been completed successfully.</td>\n</tr>\n<tr>\n<td><strong>Failed</strong></td>\n<td>The transaction failed during processing due to an error or issue.</td>\n</tr>\n<tr>\n<td><strong>Cancelled</strong></td>\n<td>The transaction was cancelled before completion.</td>\n</tr>\n<tr>\n<td><strong>Refunded</strong></td>\n<td>The transaction was completed and then refunded (for example, an eSIM whose refund completed).</td>\n</tr>\n</tbody>\n</table>\n</div><p>An eSIM regeneration does not change the transaction <code>status</code>; it stays <code>Completed</code>.</p>\n<hr>\n<h2 id=\"external-references\">External references</h2>\n<p><code>externalReference</code> must be unique within your account, across all services. Other clients' references never collide with yours. Using a prefix per service (for example <code>gifts-...</code>, <code>esim-...</code>) is recommended.</p>\n<p>Behaviour when a reference is reused:</p>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Service</th>\n<th>Same service, repeat</th>\n<th>Same reference used on another of your services</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>Topup, Gift Cards</td>\n<td>HTTP 200 / <code>1407</code></td>\n<td>HTTP 409 / <code>1114</code></td>\n</tr>\n<tr>\n<td>Ground Transport</td>\n<td>HTTP 200 / <code>1000</code> with the existing reservation</td>\n<td>HTTP 200 / <code>1102</code> (field <code>externalReference</code>)</td>\n</tr>\n<tr>\n<td>eSIM, Gifts, Utilities, Vouchers, Travel Insurance</td>\n<td>HTTP 409 / <code>1114</code></td>\n<td>HTTP 409 / <code>1114</code></td>\n</tr>\n</tbody>\n</table>\n</div></body></html>","schema":"https://schema.getpostman.com/json/collection/v2.0.0/collection.json","toc":[],"owner":"41813919","collectionId":"2445d6f9-6ae5-4249-9fa7-21f0fd89ecf6","publishedId":"2sBXigMZ13","public":true,"customColor":{"top-bar":"2671C5","right-sidebar":"303030","highlight":"2671C5"},"publishDate":"2026-07-02T09:11:58.000Z"},"item":[{"name":"eSIM","item":[{"name":"Catalogue","item":[{"name":"Get Regions","id":"d6082f91-3a8f-4120-ba62-de5128bb4a28","request":{"method":"GET","header":[],"url":"https://eservices.hoicom.net/api/v0/esim/regions?lang=en&sortBy=name&sortDescending=false","description":"<p>Returns the geographic <strong>regions</strong> eSIM plans are grouped into. Use a region <code>code</code> with <strong>Get Plans by Region</strong> to list its plans.</p>\n<hr />\n<h2 id=\"authorization\">Authorization</h2>\n<p>Requires Basic Authentication with your client credentials. Your account must be enabled for the eSIM service.</p>\n<hr />\n<h2 id=\"query-parameters\">Query Parameters</h2>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Parameter</th>\n<th>Type</th>\n<th>Required</th>\n<th>Default</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>lang</code></td>\n<td><code>string</code></td>\n<td>No</td>\n<td><code>en</code></td>\n<td>Language for text fields: <code>en</code> or <code>ar</code>.</td>\n</tr>\n<tr>\n<td><code>sortBy</code></td>\n<td><code>string</code></td>\n<td>No</td>\n<td><code>name</code></td>\n<td>Field to sort by.</td>\n</tr>\n<tr>\n<td><code>sortDescending</code></td>\n<td><code>bool</code></td>\n<td>No</td>\n<td><code>false</code></td>\n<td>Sort descending.</td>\n</tr>\n</tbody>\n</table>\n</div><hr />\n<h2 id=\"response\">Response</h2>\n<p>On success <code>code</code> is <code>1000</code> and <code>data</code> is a list of regions, each with <code>name</code>, <code>code</code>, and <code>countries</code>.</p>\n<hr />\n<h2 id=\"response-fields\">Response fields</h2>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Field</th>\n<th>Type</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>code</td>\n<td>int</td>\n<td>Response status code; <code>1000</code> on success (see the folder overview's error notes for others).</td>\n</tr>\n<tr>\n<td>message</td>\n<td>string</td>\n<td>Human-readable summary of the result.</td>\n</tr>\n<tr>\n<td>data</td>\n<td>array</td>\n<td>The list of regions eSIM plans are grouped into.</td>\n</tr>\n<tr>\n<td>data[].name</td>\n<td>string</td>\n<td>Region's display name (e.g. <code>Europe</code>).</td>\n</tr>\n<tr>\n<td>data[].code</td>\n<td>string</td>\n<td>Short region code — pass it to <strong>Get Plans by Region</strong>.</td>\n</tr>\n<tr>\n<td>data[].countries</td>\n<td>array of string</td>\n<td>ISO 3166-1 alpha-3 codes of the countries in this region.</td>\n</tr>\n</tbody>\n</table>\n</div>","urlObject":{"path":["api","v0","esim","regions"],"host":["https://eservices.hoicom.net"],"query":[{"description":{"content":"<p>Language for text fields: \"en\" or \"ar\".</p>\n","type":"text/plain"},"key":"lang","value":"en"},{"description":{"content":"<p>Field to sort by.</p>\n","type":"text/plain"},"key":"sortBy","value":"name"},{"description":{"content":"<p>Sort descending.</p>\n","type":"text/plain"},"key":"sortDescending","value":"false"}],"variable":[]}},"response":[{"id":"ff3e153b-cb7f-4232-9ea1-72c4326f874a","name":"OK","originalRequest":{"method":"GET","header":[],"url":{"raw":"https://eservices.hoicom.net/api/v0/esim/regions?lang=en&sortBy=name&sortDescending=false","host":["https://eservices.hoicom.net"],"path":["api","v0","esim","regions"],"query":[{"key":"lang","value":"en","description":"Language for text fields: \"en\" or \"ar\"."},{"key":"sortBy","value":"name","description":"Field to sort by."},{"key":"sortDescending","value":"false","description":"Sort descending."}]},"description":"Returns the geographic **regions** eSIM plans are grouped into. Use a region `code` with **Get Plans by Region** to list its plans.\n\n---\n\n## Authorization\n\nRequires Basic Authentication with your client credentials. Your account must be enabled for the eSIM service.\n\n---\n\n## Query Parameters\n\n| Parameter | Type | Required | Default | Description |\n| --- | --- | --- | --- | --- |\n| `lang` | `string` | No | `en` | Language for text fields: `en` or `ar`. |\n| `sortBy` | `string` | No | `name` | Field to sort by. |\n| `sortDescending` | `bool` | No | `false` | Sort descending. |\n\n---\n\n## Response\n\nOn success `code` is `1000` and `data` is a list of regions, each with `name`, `code`, and `countries`."},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"cookie":[],"responseTime":null,"body":"{\n  \"code\": 1000,\n  \"message\": \"Success\",\n  \"data\": [\n    {\n      \"name\": \"Europe\",\n      \"code\": \"EU\",\n      \"countries\": [\n        \"FRA\",\n        \"DEU\",\n        \"ESP\"\n      ]\n    },\n    {\n      \"name\": \"Asia Pacific\",\n      \"code\": \"AP\",\n      \"countries\": [\n        \"JPN\",\n        \"SGP\",\n        \"AUS\"\n      ]\n    }\n  ]\n}"}],"_postman_id":"d6082f91-3a8f-4120-ba62-de5128bb4a28"},{"name":"Get Countries","id":"5fd9197e-1d04-4805-aa9b-c7250896b37e","request":{"method":"GET","header":[],"url":"https://eservices.hoicom.net/api/v0/esim/countries?name=&isoCode=&continentName=&lang=en&sortBy=name&sortDescending=false&page=1&pageSize=300","description":"<p>Returns the <strong>countries</strong> eSIM plans are available for, with currency, calling codes, and dialing rules.</p>\n<hr />\n<h2 id=\"authorization\">Authorization</h2>\n<p>Requires Basic Authentication with your client credentials. Your account must be enabled for the eSIM service.</p>\n<hr />\n<h2 id=\"query-parameters\">Query Parameters</h2>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Parameter</th>\n<th>Type</th>\n<th>Required</th>\n<th>Default</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>name</code></td>\n<td><code>string</code></td>\n<td>No</td>\n<td>—</td>\n<td>Filter by country name.</td>\n</tr>\n<tr>\n<td><code>isoCode</code></td>\n<td><code>string</code></td>\n<td>No</td>\n<td>—</td>\n<td>Filter by ISO code.</td>\n</tr>\n<tr>\n<td><code>continentName</code></td>\n<td><code>string</code></td>\n<td>No</td>\n<td>—</td>\n<td>Filter by continent.</td>\n</tr>\n<tr>\n<td><code>lang</code></td>\n<td><code>string</code></td>\n<td>No</td>\n<td><code>en</code></td>\n<td>Language: <code>en</code> or <code>ar</code>.</td>\n</tr>\n<tr>\n<td><code>sortBy</code></td>\n<td><code>string</code></td>\n<td>No</td>\n<td><code>name</code></td>\n<td>Field to sort by.</td>\n</tr>\n<tr>\n<td><code>sortDescending</code></td>\n<td><code>bool</code></td>\n<td>No</td>\n<td><code>false</code></td>\n<td>Sort descending.</td>\n</tr>\n<tr>\n<td><code>page</code></td>\n<td><code>int</code></td>\n<td>No</td>\n<td><code>1</code></td>\n<td>Page number.</td>\n</tr>\n<tr>\n<td><code>pageSize</code></td>\n<td><code>int</code></td>\n<td>No</td>\n<td><code>300</code></td>\n<td>Items per page.</td>\n</tr>\n</tbody>\n</table>\n</div><hr />\n<h2 id=\"response\">Response</h2>\n<p>On success <code>code</code> is <code>1000</code> and <code>data</code> is a paginated list of countries.</p>\n<hr />\n<h2 id=\"response-fields\">Response fields</h2>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Field</th>\n<th>Type</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>code</td>\n<td>int</td>\n<td>Response status code; <code>1000</code> on success.</td>\n</tr>\n<tr>\n<td>message</td>\n<td>string</td>\n<td>Human-readable summary of the result.</td>\n</tr>\n<tr>\n<td>data</td>\n<td>object</td>\n<td>Paginated list of countries matching the filters.</td>\n</tr>\n<tr>\n<td>data.items</td>\n<td>array</td>\n<td>Countries for the current page.</td>\n</tr>\n<tr>\n<td>data.items[].name</td>\n<td>string</td>\n<td>Country's display name.</td>\n</tr>\n<tr>\n<td>data.items[].isoCode</td>\n<td>string</td>\n<td>Country's ISO 3166-1 alpha-3 code.</td>\n</tr>\n<tr>\n<td>data.items[].continentName</td>\n<td>string</td>\n<td>Continent the country belongs to.</td>\n</tr>\n<tr>\n<td>data.items[].currency</td>\n<td>object</td>\n<td>The country's local currency.</td>\n</tr>\n<tr>\n<td>data.items[].currency.code</td>\n<td>string</td>\n<td>3-letter ISO 4217 currency code.</td>\n</tr>\n<tr>\n<td>data.items[].currency.name</td>\n<td>string</td>\n<td>Currency's display name.</td>\n</tr>\n<tr>\n<td>data.items[].currency.symbol</td>\n<td>string</td>\n<td>Currency's symbol (e.g. <code>₺</code>).</td>\n</tr>\n<tr>\n<td>data.items[].flagUrl</td>\n<td>string</td>\n<td>URL of the country's flag image.</td>\n</tr>\n<tr>\n<td>data.items[].callingCodes</td>\n<td>array of string</td>\n<td>International dialing code(s) for the country (e.g. <code>+90</code>).</td>\n</tr>\n<tr>\n<td>data.items[].regions</td>\n<td>array</td>\n<td>Region(s) this country belongs to.</td>\n</tr>\n<tr>\n<td>data.items[].regions[].name</td>\n<td>string</td>\n<td>Region display name.</td>\n</tr>\n<tr>\n<td>data.items[].regions[].code</td>\n<td>string</td>\n<td>Region code — usable with <strong>Get Plans by Region</strong>.</td>\n</tr>\n<tr>\n<td>data.items[].dialingRules</td>\n<td>array</td>\n<td>Rules describing valid local mobile number formats for the country.</td>\n</tr>\n<tr>\n<td>data.items[].dialingRules[].prefix</td>\n<td>string</td>\n<td>Required leading digit(s) of a local mobile number.</td>\n</tr>\n<tr>\n<td>data.items[].dialingRules[].minimumLength</td>\n<td>int</td>\n<td>Minimum digit length of a local mobile number under this rule.</td>\n</tr>\n<tr>\n<td>data.items[].dialingRules[].maximumLength</td>\n<td>int</td>\n<td>Maximum digit length of a local mobile number under this rule.</td>\n</tr>\n<tr>\n<td>data.count</td>\n<td>int</td>\n<td>Number of items returned on this page (not the total across all pages).</td>\n</tr>\n<tr>\n<td>data.page</td>\n<td>int</td>\n<td>Current page number.</td>\n</tr>\n<tr>\n<td>data.pageSize</td>\n<td>int</td>\n<td>Number of items requested per page.</td>\n</tr>\n<tr>\n<td>data.totalPages</td>\n<td>int</td>\n<td>Total number of pages available for the current filters.</td>\n</tr>\n<tr>\n<td>data.totalItems</td>\n<td>int</td>\n<td>Total number of countries matching the filters, across all pages.</td>\n</tr>\n</tbody>\n</table>\n</div>","urlObject":{"path":["api","v0","esim","countries"],"host":["https://eservices.hoicom.net"],"query":[{"description":{"content":"<p>Filter by country name.</p>\n","type":"text/plain"},"key":"name","value":""},{"description":{"content":"<p>Filter by ISO code.</p>\n","type":"text/plain"},"key":"isoCode","value":""},{"description":{"content":"<p>Filter by continent.</p>\n","type":"text/plain"},"key":"continentName","value":""},{"description":{"content":"<p>Language: \"en\" or \"ar\".</p>\n","type":"text/plain"},"key":"lang","value":"en"},{"key":"sortBy","value":"name"},{"key":"sortDescending","value":"false"},{"key":"page","value":"1"},{"key":"pageSize","value":"300"}],"variable":[]}},"response":[{"id":"7cc47c73-06b9-47c2-9783-09d55c2fb94c","name":"OK","originalRequest":{"method":"GET","header":[],"url":{"raw":"https://eservices.hoicom.net/api/v0/esim/countries?name=&isoCode=&continentName=&lang=en&sortBy=name&sortDescending=false&page=1&pageSize=300","host":["https://eservices.hoicom.net"],"path":["api","v0","esim","countries"],"query":[{"key":"name","value":"","description":"Filter by country name."},{"key":"isoCode","value":"","description":"Filter by ISO code."},{"key":"continentName","value":"","description":"Filter by continent."},{"key":"lang","value":"en","description":"Language: \"en\" or \"ar\"."},{"key":"sortBy","value":"name"},{"key":"sortDescending","value":"false"},{"key":"page","value":"1"},{"key":"pageSize","value":"300"}]},"description":"Returns the **countries** eSIM plans are available for, with currency, calling codes, and dialing rules.\n\n---\n\n## Authorization\n\nRequires Basic Authentication with your client credentials. Your account must be enabled for the eSIM service.\n\n---\n\n## Query Parameters\n\n| Parameter | Type | Required | Default | Description |\n| --- | --- | --- | --- | --- |\n| `name` | `string` | No | — | Filter by country name. |\n| `isoCode` | `string` | No | — | Filter by ISO code. |\n| `continentName` | `string` | No | — | Filter by continent. |\n| `lang` | `string` | No | `en` | Language: `en` or `ar`. |\n| `sortBy` | `string` | No | `name` | Field to sort by. |\n| `sortDescending` | `bool` | No | `false` | Sort descending. |\n| `page` | `int` | No | `1` | Page number. |\n| `pageSize` | `int` | No | `300` | Items per page. |\n\n---\n\n## Response\n\nOn success `code` is `1000` and `data` is a paginated list of countries."},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"cookie":[],"responseTime":null,"body":"{\n  \"code\": 1000,\n  \"message\": \"Success\",\n  \"data\": {\n    \"items\": [\n      {\n        \"name\": \"Türkiye\",\n        \"isoCode\": \"TUR\",\n        \"continentName\": \"Asia\",\n        \"currency\": {\n          \"code\": \"TRY\",\n          \"name\": \"Turkish Lira\",\n          \"symbol\": \"₺\"\n        },\n        \"flagUrl\": \"https://cdn.example.com/flags/tr.svg\",\n        \"callingCodes\": [\n          \"+90\"\n        ],\n        \"regions\": [\n          {\n            \"name\": \"Europe\",\n            \"code\": \"EU\"\n          }\n        ],\n        \"dialingRules\": [\n          {\n            \"prefix\": \"5\",\n            \"minimumLength\": 10,\n            \"maximumLength\": 10\n          }\n        ]\n      }\n    ],\n    \"count\": 1,\n    \"page\": 1,\n    \"pageSize\": 50,\n    \"totalPages\": 1,\n    \"totalItems\": 1\n  }\n}"}],"_postman_id":"5fd9197e-1d04-4805-aa9b-c7250896b37e"},{"name":"Get Plans","id":"804e2310-d31b-4ef4-8e48-eb02dbec261f","request":{"method":"GET","header":[],"url":"https://eservices.hoicom.net/api/v0/esim/plans?coverageType=REGIONAL&supportsTopup=true&sortBy=minprice&sortDescending=false&page=1&pageSize=50&lang=en","description":"<p>Returns available <strong>eSIM plans</strong> with rich filtering. Each plan carries its <code>details</code>, <code>pricing</code> (see <strong>Pricing type</strong> in the folder overview), and <code>validities</code>.</p>\n<p><strong>Data units.</strong> Data amounts are normalised: allowances of 1 GB or more are shown in decimal GB (a 1024 MB plan reads <code>1 GB</code>, 512 MB reads <code>500 MB</code>), smaller ones in MB. Do not assume a fixed unit; always read <code>unit</code>. The catalogue is large and its size is not fixed, so do not hard-code plan counts. Arabic text is available with <code>lang=ar</code>.</p>\n<hr />\n<h2 id=\"authorization\">Authorization</h2>\n<p>Requires Basic Authentication with your client credentials. Your account must be enabled for the eSIM service.</p>\n<hr />\n<h2 id=\"query-parameters\">Query Parameters</h2>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Parameter</th>\n<th>Type</th>\n<th>Required</th>\n<th>Default</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>id</code></td>\n<td><code>string</code></td>\n<td>No</td>\n<td>—</td>\n<td>Filter by plan id.</td>\n</tr>\n<tr>\n<td><code>unlimited</code></td>\n<td><code>bool</code></td>\n<td>No</td>\n<td>—</td>\n<td>Only unlimited-data plans.</td>\n</tr>\n<tr>\n<td><code>supportsTopup</code></td>\n<td><code>bool</code></td>\n<td>No</td>\n<td>—</td>\n<td>Only plans that support top-ups.</td>\n</tr>\n<tr>\n<td><code>coverageType</code></td>\n<td><code>string</code></td>\n<td>No</td>\n<td>—</td>\n<td><code>LOCAL</code>, <code>REGIONAL</code>, or <code>GLOBAL</code>.</td>\n</tr>\n<tr>\n<td><code>countryIsoCodes</code></td>\n<td><code>string[]</code></td>\n<td>No</td>\n<td>—</td>\n<td>Filter by country ISO codes.</td>\n</tr>\n<tr>\n<td><code>operators</code></td>\n<td><code>string[]</code></td>\n<td>No</td>\n<td>—</td>\n<td>Filter by network operators.</td>\n</tr>\n<tr>\n<td><code>sortBy</code></td>\n<td><code>string</code></td>\n<td>No</td>\n<td><code>minprice</code></td>\n<td>Field to sort by.</td>\n</tr>\n<tr>\n<td><code>sortDescending</code></td>\n<td><code>bool</code></td>\n<td>No</td>\n<td><code>false</code></td>\n<td>Sort descending.</td>\n</tr>\n<tr>\n<td><code>page</code></td>\n<td><code>int</code></td>\n<td>No</td>\n<td><code>1</code></td>\n<td>Page number.</td>\n</tr>\n<tr>\n<td><code>pageSize</code></td>\n<td><code>int</code></td>\n<td>No</td>\n<td><code>50</code></td>\n<td>Items per page (max 50).</td>\n</tr>\n<tr>\n<td><code>lang</code></td>\n<td><code>string</code></td>\n<td>No</td>\n<td><code>en</code></td>\n<td>Language for text fields: <code>en</code> (English) or <code>ar</code> (Arabic).</td>\n</tr>\n</tbody>\n</table>\n</div><hr />\n<h2 id=\"response\">Response</h2>\n<p>On success <code>code</code> is <code>1000</code> and <code>data</code> is a paginated list of plans. <code>details.coverageType</code> uses the <strong>Coverage type</strong> values and <code>pricing.type</code> the <strong>Pricing type</strong> values (see folder overview).</p>\n<hr />\n<h2 id=\"response-fields\">Response fields</h2>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Field</th>\n<th>Type</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>code</td>\n<td>int</td>\n<td>Response status code; <code>1000</code> on success.</td>\n</tr>\n<tr>\n<td>message</td>\n<td>string</td>\n<td>Human-readable summary of the result.</td>\n</tr>\n<tr>\n<td>data</td>\n<td>object</td>\n<td>Paginated list of plans matching the filters.</td>\n</tr>\n<tr>\n<td>data.items</td>\n<td>array</td>\n<td>Plans for the current page.</td>\n</tr>\n<tr>\n<td>data.items[].id</td>\n<td>string</td>\n<td>Plan identifier — use it with <strong>Get Plan Networks</strong>, <strong>Get Plan Topups</strong>, and <strong>Create Transaction</strong>.</td>\n</tr>\n<tr>\n<td>data.items[].details</td>\n<td>object</td>\n<td>Descriptive information about the plan.</td>\n</tr>\n<tr>\n<td>data.items[].details.name</td>\n<td>string</td>\n<td>Plan's display name.</td>\n</tr>\n<tr>\n<td>data.items[].details.description</td>\n<td>string</td>\n<td>Longer description of what the plan includes.</td>\n</tr>\n<tr>\n<td>data.items[].details.coverageType</td>\n<td>string (values: LOCAL | REGIONAL | GLOBAL)</td>\n<td>Geographic coverage of the plan — see <strong>Coverage type</strong> in the folder overview.</td>\n</tr>\n<tr>\n<td>data.items[].details.termsAndConditions</td>\n<td>string</td>\n<td>Terms and conditions text for the plan.</td>\n</tr>\n<tr>\n<td>data.items[].details.usageInstructions</td>\n<td>string</td>\n<td>Instructions for activating and using the plan.</td>\n</tr>\n<tr>\n<td>data.items[].details.unlimited</td>\n<td>bool</td>\n<td><code>true</code> if the plan has unlimited data.</td>\n</tr>\n<tr>\n<td>data.items[].details.supportsTopup</td>\n<td>bool</td>\n<td><code>true</code> if this plan can later be topped up via <strong>Get Plan Topups</strong> / <strong>Create Transaction</strong>.</td>\n</tr>\n<tr>\n<td>data.items[].details.autoRenew</td>\n<td>bool</td>\n<td><code>true</code> if the plan renews automatically at expiry.</td>\n</tr>\n<tr>\n<td>data.items[].details.maxDownloadSpeed</td>\n<td>decimal</td>\n<td>Maximum download speed for the plan; <code>null</code> when unrestricted or not specified.</td>\n</tr>\n<tr>\n<td>data.items[].details.maxUploadSpeed</td>\n<td>decimal</td>\n<td>Maximum upload speed for the plan; <code>null</code> when unrestricted or not specified.</td>\n</tr>\n<tr>\n<td>data.items[].details.validCountries</td>\n<td>array</td>\n<td>Countries where the plan can be used.</td>\n</tr>\n<tr>\n<td>data.items[].details.validCountries[].name</td>\n<td>string</td>\n<td>Country display name.</td>\n</tr>\n<tr>\n<td>data.items[].details.validCountries[].isoCode3</td>\n<td>string</td>\n<td>Country's ISO 3166-1 alpha-3 code.</td>\n</tr>\n<tr>\n<td>data.items[].details.supportedOperators</td>\n<td>array of string</td>\n<td>Mobile network operators reachable on this plan.</td>\n</tr>\n<tr>\n<td>data.items[].pricing</td>\n<td>object</td>\n<td>Pricing details for the plan.</td>\n</tr>\n<tr>\n<td>data.items[].pricing.type</td>\n<td>string (values: FIXED | RANGED)</td>\n<td>Pricing model — see <strong>Pricing type</strong> in the folder overview.</td>\n</tr>\n<tr>\n<td>data.items[].pricing.currency</td>\n<td>string</td>\n<td>3-letter ISO 4217 currency code for the amounts below.</td>\n</tr>\n<tr>\n<td>data.items[].pricing.minAmount</td>\n<td>decimal</td>\n<td>Minimum price. Equal to <code>maxAmount</code> when <code>type</code> is <code>FIXED</code>.</td>\n</tr>\n<tr>\n<td>data.items[].pricing.maxAmount</td>\n<td>decimal</td>\n<td>Maximum price. Equal to <code>minAmount</code> when <code>type</code> is <code>FIXED</code>.</td>\n</tr>\n<tr>\n<td>data.items[].pricing.fees</td>\n<td>decimal</td>\n<td>Additional fixed fee added on top of the price, if any.</td>\n</tr>\n<tr>\n<td>data.items[].pricing.tax</td>\n<td>object</td>\n<td>Tax breakdown applied to the price; <code>null</code>/omitted where no tax applies to this plan.</td>\n</tr>\n<tr>\n<td>data.items[].pricing.tax.taxRate</td>\n<td>decimal</td>\n<td>Tax rate as a percentage (e.g. <code>15</code> means 15%).</td>\n</tr>\n<tr>\n<td>data.items[].pricing.tax.taxType</td>\n<td>string</td>\n<td>Name of the tax (e.g. <code>VAT</code>).</td>\n</tr>\n<tr>\n<td>data.items[].pricing.tax.taxAmount</td>\n<td>decimal</td>\n<td>Tax amount, in <code>pricing.currency</code>.</td>\n</tr>\n<tr>\n<td>data.items[].validities</td>\n<td>array</td>\n<td>The plan's data/duration allowances.</td>\n</tr>\n<tr>\n<td>data.items[].validities[].type</td>\n<td>string</td>\n<td>Kind of allowance, e.g. <code>DATA</code> or <code>DURATION</code>.</td>\n</tr>\n<tr>\n<td>data.items[].validities[].unit</td>\n<td>string</td>\n<td>Unit for <code>quantity</code>, e.g. <code>MB</code>, <code>GB</code> or <code>DAYS</code>.</td>\n</tr>\n<tr>\n<td>data.items[].validities[].quantity</td>\n<td>decimal</td>\n<td>Amount of the allowance, in <code>unit</code>.</td>\n</tr>\n<tr>\n<td>data.count</td>\n<td>int</td>\n<td>Number of items returned on this page (not the total across all pages).</td>\n</tr>\n<tr>\n<td>data.page</td>\n<td>int</td>\n<td>Current page number.</td>\n</tr>\n<tr>\n<td>data.pageSize</td>\n<td>int</td>\n<td>Number of items requested per page (max 50).</td>\n</tr>\n<tr>\n<td>data.totalPages</td>\n<td>int</td>\n<td>Total number of pages available for the current filters.</td>\n</tr>\n<tr>\n<td>data.totalItems</td>\n<td>int</td>\n<td>Total number of plans matching the filters, across all pages.</td>\n</tr>\n</tbody>\n</table>\n</div>","urlObject":{"path":["api","v0","esim","plans"],"host":["https://eservices.hoicom.net"],"query":[{"description":{"content":"<p>LOCAL, REGIONAL, or GLOBAL.</p>\n","type":"text/plain"},"key":"coverageType","value":"REGIONAL"},{"key":"supportsTopup","value":"true"},{"key":"sortBy","value":"minprice"},{"key":"sortDescending","value":"false"},{"key":"page","value":"1"},{"key":"pageSize","value":"50"},{"description":{"content":"<p>Language for text fields: en or ar.</p>\n","type":"text/plain"},"key":"lang","value":"en"}],"variable":[]}},"response":[{"id":"268a6c83-cf3a-4360-9469-442e5149f682","name":"OK","originalRequest":{"method":"GET","header":[],"url":{"raw":"https://eservices.hoicom.net/api/v0/esim/plans?coverageType=REGIONAL&supportsTopup=true&sortBy=minprice&sortDescending=false&page=1&pageSize=50&lang=en","host":["https://eservices.hoicom.net"],"path":["api","v0","esim","plans"],"query":[{"key":"coverageType","value":"REGIONAL","description":"LOCAL, REGIONAL, or GLOBAL."},{"key":"supportsTopup","value":"true"},{"key":"sortBy","value":"minprice"},{"key":"sortDescending","value":"false"},{"key":"page","value":"1"},{"key":"pageSize","value":"50"},{"key":"lang","value":"en","description":"Language for text fields: en or ar."}]},"description":"Returns available **eSIM plans** with rich filtering. Each plan carries its `details`, `pricing` (see **Pricing type** in the folder overview), and `validities`.\n\n**Data units.** Data amounts are normalised: allowances of 1 GB or more are shown in decimal GB (a 1024 MB plan reads `1 GB`, 512 MB reads `500 MB`), smaller ones in MB. Do not assume a fixed unit; always read `unit`. The catalogue is large and its size is not fixed, so do not hard-code plan counts. Arabic text is available with `lang=ar`.\n\n---\n\n## Authorization\n\nRequires Basic Authentication with your client credentials. Your account must be enabled for the eSIM service.\n\n---\n\n## Query Parameters\n\n| Parameter | Type | Required | Default | Description |\n| --- | --- | --- | --- | --- |\n| `id` | `string` | No | — | Filter by plan id. |\n| `unlimited` | `bool` | No | — | Only unlimited-data plans. |\n| `supportsTopup` | `bool` | No | — | Only plans that support top-ups. |\n| `coverageType` | `string` | No | — | `LOCAL`, `REGIONAL`, or `GLOBAL`. |\n| `countryIsoCodes` | `string[]` | No | — | Filter by country ISO codes. |\n| `operators` | `string[]` | No | — | Filter by network operators. |\n| `sortBy` | `string` | No | `minprice` | Field to sort by. |\n| `sortDescending` | `bool` | No | `false` | Sort descending. |\n| `page` | `int` | No | `1` | Page number. |\n| `pageSize` | `int` | No | `50` | Items per page (max 50). |\n| `lang` | `string` | No | `en` | Language for text fields: `en` (English) or `ar` (Arabic). |\n\n---\n\n## Response\n\nOn success `code` is `1000` and `data` is a paginated list of plans. `details.coverageType` uses the **Coverage type** values and `pricing.type` the **Pricing type** values (see folder overview).\n\n---\n\n## Response fields\n\n| Field | Type | Description |\n|---|---|---|\n| code | int | Response status code; `1000` on success. |\n| message | string | Human-readable summary of the result. |\n| data | object | Paginated list of plans matching the filters. |\n| data.items | array | Plans for the current page. |\n| data.items[].id | string | Plan identifier — use it with **Get Plan Networks**, **Get Plan Topups**, and **Create Transaction**. |\n| data.items[].details | object | Descriptive information about the plan. |\n| data.items[].details.name | string | Plan's display name. |\n| data.items[].details.description | string | Longer description of what the plan includes. |\n| data.items[].details.coverageType | string (values: LOCAL \\| REGIONAL \\| GLOBAL) | Geographic coverage of the plan — see **Coverage type** in the folder overview. |\n| data.items[].details.termsAndConditions | string | Terms and conditions text for the plan. |\n| data.items[].details.usageInstructions | string | Instructions for activating and using the plan. |\n| data.items[].details.unlimited | bool | `true` if the plan has unlimited data. |\n| data.items[].details.supportsTopup | bool | `true` if this plan can later be topped up via **Get Plan Topups** / **Create Transaction**. |\n| data.items[].details.autoRenew | bool | `true` if the plan renews automatically at expiry. |\n| data.items[].details.maxDownloadSpeed | decimal | Maximum download speed for the plan; `null` when unrestricted or not specified. |\n| data.items[].details.maxUploadSpeed | decimal | Maximum upload speed for the plan; `null` when unrestricted or not specified. |\n| data.items[].details.validCountries | array | Countries where the plan can be used. |\n| data.items[].details.validCountries[].name | string | Country display name. |\n| data.items[].details.validCountries[].isoCode3 | string | Country's ISO 3166-1 alpha-3 code. |\n| data.items[].details.supportedOperators | array of string | Mobile network operators reachable on this plan. |\n| data.items[].pricing | object | Pricing details for the plan. |\n| data.items[].pricing.type | string (values: FIXED \\| RANGED) | Pricing model — see **Pricing type** in the folder overview. |\n| data.items[].pricing.currency | string | 3-letter ISO 4217 currency code for the amounts below. |\n| data.items[].pricing.minAmount | decimal | Minimum price. Equal to `maxAmount` when `type` is `FIXED`. |\n| data.items[].pricing.maxAmount | decimal | Maximum price. Equal to `minAmount` when `type` is `FIXED`. |\n| data.items[].pricing.fees | decimal | Additional fixed fee added on top of the price, if any. |\n| data.items[].pricing.tax | object | Tax breakdown applied to the price; `null`/omitted where no tax applies to this plan. |\n| data.items[].pricing.tax.taxRate | decimal | Tax rate as a percentage (e.g. `15` means 15%). |\n| data.items[].pricing.tax.taxType | string | Name of the tax (e.g. `VAT`). |\n| data.items[].pricing.tax.taxAmount | decimal | Tax amount, in `pricing.currency`. |\n| data.items[].validities | array | The plan's data/duration allowances. |\n| data.items[].validities[].type | string | Kind of allowance, e.g. `DATA` or `DURATION`. |\n| data.items[].validities[].unit | string | Unit for `quantity`, e.g. `MB`, `GB` or `DAYS`. |\n| data.items[].validities[].quantity | decimal | Amount of the allowance, in `unit`. |\n| data.count | int | Number of items returned on this page (not the total across all pages). |\n| data.page | int | Current page number. |\n| data.pageSize | int | Number of items requested per page (max 50). |\n| data.totalPages | int | Total number of pages available for the current filters. |\n| data.totalItems | int | Total number of plans matching the filters, across all pages. |\n"},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"cookie":[],"responseTime":null,"body":"{\n  \"code\": 1000,\n  \"message\": \"Success\",\n  \"data\": {\n    \"items\": [\n      {\n        \"id\": \"plan_eu_5gb_30d\",\n        \"details\": {\n          \"name\": \"Europe 5GB - 30 Days\",\n          \"description\": \"5GB of data across Europe, valid for 30 days.\",\n          \"coverageType\": \"REGIONAL\",\n          \"termsAndConditions\": \"Standard eSIM terms apply.\",\n          \"usageInstructions\": \"Scan the QR code and enable data roaming.\",\n          \"unlimited\": false,\n          \"supportsTopup\": true,\n          \"autoRenew\": false,\n          \"maxDownloadSpeed\": null,\n          \"maxUploadSpeed\": null,\n          \"validCountries\": [\n            {\n              \"name\": \"France\",\n              \"isoCode3\": \"FRA\"\n            },\n            {\n              \"name\": \"Germany\",\n              \"isoCode3\": \"DEU\"\n            }\n          ],\n          \"supportedOperators\": [\n            \"Orange\",\n            \"Vodafone\"\n          ]\n        },\n        \"pricing\": {\n          \"type\": \"FIXED\",\n          \"currency\": \"INR\",\n          \"minAmount\": 75,\n          \"maxAmount\": 75,\n          \"fees\": 0,\n          \"tax\": {\n            \"taxRate\": 15,\n            \"taxType\": \"VAT\",\n            \"taxAmount\": 11.25\n          }\n        },\n        \"validities\": [\n          {\n            \"type\": \"DATA\",\n            \"unit\": \"GB\",\n            \"quantity\": 5\n          },\n          {\n            \"type\": \"DURATION\",\n            \"unit\": \"DAYS\",\n            \"quantity\": 30\n          }\n        ]\n      }\n    ],\n    \"count\": 1,\n    \"page\": 1,\n    \"pageSize\": 50,\n    \"totalPages\": 1,\n    \"totalItems\": 1\n  }\n}"}],"_postman_id":"804e2310-d31b-4ef4-8e48-eb02dbec261f"},{"name":"Get Plans by Country","id":"909568f4-3c0a-40e2-89a2-c36708a270ce","request":{"method":"GET","header":[],"url":"https://eservices.hoicom.net/api/v0/esim/plans/country/:countryIsoCode?page=1&pageSize=50&lang=en","description":"<p>Returns eSIM plans available for a specific country.</p>\n<p><strong>Data units.</strong> Data amounts are normalised: allowances of 1 GB or more are shown in decimal GB (a 1024 MB plan reads <code>1 GB</code>, 512 MB reads <code>500 MB</code>), smaller ones in MB. Do not assume a fixed unit; always read <code>unit</code>. The catalogue is large and its size is not fixed, so do not hard-code plan counts. Arabic text is available with <code>lang=ar</code>.</p>\n<hr />\n<h2 id=\"authorization\">Authorization</h2>\n<p>Requires Basic Authentication with your client credentials. Your account must be enabled for the eSIM service.</p>\n<hr />\n<h2 id=\"path-parameters\">Path Parameters</h2>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Parameter</th>\n<th>Type</th>\n<th>Required</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>countryIsoCode</code></td>\n<td><code>string</code></td>\n<td>Yes</td>\n<td>Country ISO code (2 or 3 letters).</td>\n</tr>\n</tbody>\n</table>\n</div><hr />\n<h2 id=\"query-parameters\">Query Parameters</h2>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Parameter</th>\n<th>Type</th>\n<th>Required</th>\n<th>Default</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>page</code></td>\n<td><code>int</code></td>\n<td>No</td>\n<td><code>1</code></td>\n<td>Page number.</td>\n</tr>\n<tr>\n<td><code>pageSize</code></td>\n<td><code>int</code></td>\n<td>No</td>\n<td><code>50</code></td>\n<td>Items per page.</td>\n</tr>\n<tr>\n<td><code>lang</code></td>\n<td><code>string</code></td>\n<td>No</td>\n<td><code>en</code></td>\n<td>Language for text fields: <code>en</code> (English) or <code>ar</code> (Arabic).</td>\n</tr>\n</tbody>\n</table>\n</div><hr />\n<h2 id=\"response\">Response</h2>\n<p>On success <code>code</code> is <code>1000</code> and <code>data</code> is a paginated list of plans.</p>\n<hr />\n<h2 id=\"response-fields\">Response fields</h2>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Field</th>\n<th>Type</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>code</td>\n<td>int</td>\n<td>Response status code; <code>1000</code> on success.</td>\n</tr>\n<tr>\n<td>message</td>\n<td>string</td>\n<td>Human-readable summary of the result.</td>\n</tr>\n<tr>\n<td>data</td>\n<td>object</td>\n<td>Paginated list of plans available for the requested country.</td>\n</tr>\n<tr>\n<td>data.items</td>\n<td>array</td>\n<td>Plans for the current page.</td>\n</tr>\n<tr>\n<td>data.items[].id</td>\n<td>string</td>\n<td>Plan identifier — use it with <strong>Get Plan Networks</strong>, <strong>Get Plan Topups</strong>, and <strong>Create Transaction</strong>.</td>\n</tr>\n<tr>\n<td>data.items[].details</td>\n<td>object</td>\n<td>Descriptive information about the plan.</td>\n</tr>\n<tr>\n<td>data.items[].details.name</td>\n<td>string</td>\n<td>Plan's display name.</td>\n</tr>\n<tr>\n<td>data.items[].details.description</td>\n<td>string</td>\n<td>Longer description of what the plan includes.</td>\n</tr>\n<tr>\n<td>data.items[].details.coverageType</td>\n<td>string (values: LOCAL | REGIONAL | GLOBAL)</td>\n<td>Geographic coverage of the plan — see <strong>Coverage type</strong> in the folder overview.</td>\n</tr>\n<tr>\n<td>data.items[].details.termsAndConditions</td>\n<td>string</td>\n<td>Terms and conditions text for the plan.</td>\n</tr>\n<tr>\n<td>data.items[].details.usageInstructions</td>\n<td>string</td>\n<td>Instructions for activating and using the plan.</td>\n</tr>\n<tr>\n<td>data.items[].details.unlimited</td>\n<td>bool</td>\n<td><code>true</code> if the plan has unlimited data.</td>\n</tr>\n<tr>\n<td>data.items[].details.supportsTopup</td>\n<td>bool</td>\n<td><code>true</code> if this plan can later be topped up via <strong>Get Plan Topups</strong> / <strong>Create Transaction</strong>.</td>\n</tr>\n<tr>\n<td>data.items[].details.autoRenew</td>\n<td>bool</td>\n<td><code>true</code> if the plan renews automatically at expiry.</td>\n</tr>\n<tr>\n<td>data.items[].details.maxDownloadSpeed</td>\n<td>decimal</td>\n<td>Maximum download speed for the plan; <code>null</code> when unrestricted or not specified.</td>\n</tr>\n<tr>\n<td>data.items[].details.maxUploadSpeed</td>\n<td>decimal</td>\n<td>Maximum upload speed for the plan; <code>null</code> when unrestricted or not specified.</td>\n</tr>\n<tr>\n<td>data.items[].details.validCountries</td>\n<td>array</td>\n<td>Countries where the plan can be used.</td>\n</tr>\n<tr>\n<td>data.items[].details.validCountries[].name</td>\n<td>string</td>\n<td>Country display name.</td>\n</tr>\n<tr>\n<td>data.items[].details.validCountries[].isoCode3</td>\n<td>string</td>\n<td>Country's ISO 3166-1 alpha-3 code.</td>\n</tr>\n<tr>\n<td>data.items[].details.supportedOperators</td>\n<td>array of string</td>\n<td>Mobile network operators reachable on this plan.</td>\n</tr>\n<tr>\n<td>data.items[].pricing</td>\n<td>object</td>\n<td>Pricing details for the plan.</td>\n</tr>\n<tr>\n<td>data.items[].pricing.type</td>\n<td>string (values: FIXED | RANGED)</td>\n<td>Pricing model — see <strong>Pricing type</strong> in the folder overview.</td>\n</tr>\n<tr>\n<td>data.items[].pricing.currency</td>\n<td>string</td>\n<td>3-letter ISO 4217 currency code for the amounts below.</td>\n</tr>\n<tr>\n<td>data.items[].pricing.minAmount</td>\n<td>decimal</td>\n<td>Minimum price. Equal to <code>maxAmount</code> when <code>type</code> is <code>FIXED</code>.</td>\n</tr>\n<tr>\n<td>data.items[].pricing.maxAmount</td>\n<td>decimal</td>\n<td>Maximum price. Equal to <code>minAmount</code> when <code>type</code> is <code>FIXED</code>.</td>\n</tr>\n<tr>\n<td>data.items[].pricing.fees</td>\n<td>decimal</td>\n<td>Additional fixed fee added on top of the price, if any.</td>\n</tr>\n<tr>\n<td>data.items[].pricing.tax</td>\n<td>object</td>\n<td>Tax breakdown applied to the price; <code>null</code>/omitted where no tax applies to this plan.</td>\n</tr>\n<tr>\n<td>data.items[].pricing.tax.taxRate</td>\n<td>decimal</td>\n<td>Tax rate as a percentage (e.g. <code>15</code> means 15%).</td>\n</tr>\n<tr>\n<td>data.items[].pricing.tax.taxType</td>\n<td>string</td>\n<td>Name of the tax (e.g. <code>VAT</code>).</td>\n</tr>\n<tr>\n<td>data.items[].pricing.tax.taxAmount</td>\n<td>decimal</td>\n<td>Tax amount, in <code>pricing.currency</code>.</td>\n</tr>\n<tr>\n<td>data.items[].validities</td>\n<td>array</td>\n<td>The plan's data/duration allowances.</td>\n</tr>\n<tr>\n<td>data.items[].validities[].type</td>\n<td>string</td>\n<td>Kind of allowance, e.g. <code>DATA</code> or <code>DURATION</code>.</td>\n</tr>\n<tr>\n<td>data.items[].validities[].unit</td>\n<td>string</td>\n<td>Unit for <code>quantity</code>, e.g. <code>MB</code>, <code>GB</code> or <code>DAYS</code>.</td>\n</tr>\n<tr>\n<td>data.items[].validities[].quantity</td>\n<td>decimal</td>\n<td>Amount of the allowance, in <code>unit</code>.</td>\n</tr>\n<tr>\n<td>data.count</td>\n<td>int</td>\n<td>Number of items returned on this page (not the total across all pages).</td>\n</tr>\n<tr>\n<td>data.page</td>\n<td>int</td>\n<td>Current page number.</td>\n</tr>\n<tr>\n<td>data.pageSize</td>\n<td>int</td>\n<td>Number of items requested per page.</td>\n</tr>\n<tr>\n<td>data.totalPages</td>\n<td>int</td>\n<td>Total number of pages available for the current filters.</td>\n</tr>\n<tr>\n<td>data.totalItems</td>\n<td>int</td>\n<td>Total number of plans available for this country, across all pages.</td>\n</tr>\n</tbody>\n</table>\n</div>","urlObject":{"path":["api","v0","esim","plans","country",":countryIsoCode"],"host":["https://eservices.hoicom.net"],"query":[{"key":"page","value":"1"},{"key":"pageSize","value":"50"},{"description":{"content":"<p>Language for text fields: en or ar.</p>\n","type":"text/plain"},"key":"lang","value":"en"}],"variable":[{"type":"any","value":"","key":"countryIsoCode"}]}},"response":[{"id":"539802c7-05bf-49a1-b422-431f20e4da5c","name":"OK","originalRequest":{"method":"GET","header":[],"url":{"raw":"https://eservices.hoicom.net/api/v0/esim/plans/country/:countryIsoCode?page=1&pageSize=50&lang=en","host":["https://eservices.hoicom.net"],"path":["api","v0","esim","plans","country",":countryIsoCode"],"query":[{"key":"page","value":"1"},{"key":"pageSize","value":"50"},{"key":"lang","value":"en","description":"Language for text fields: en or ar."}],"variable":[{"key":"countryIsoCode","value":""}]},"description":"Returns eSIM plans available for a specific country.\n\n**Data units.** Data amounts are normalised: allowances of 1 GB or more are shown in decimal GB (a 1024 MB plan reads `1 GB`, 512 MB reads `500 MB`), smaller ones in MB. Do not assume a fixed unit; always read `unit`. The catalogue is large and its size is not fixed, so do not hard-code plan counts. Arabic text is available with `lang=ar`.\n\n---\n\n## Authorization\n\nRequires Basic Authentication with your client credentials. Your account must be enabled for the eSIM service.\n\n---\n\n## Path Parameters\n\n| Parameter | Type | Required | Description |\n| --- | --- | --- | --- |\n| `countryIsoCode` | `string` | Yes | Country ISO code (2 or 3 letters). |\n\n---\n\n## Query Parameters\n\n| Parameter | Type | Required | Default | Description |\n| --- | --- | --- | --- | --- |\n| `page` | `int` | No | `1` | Page number. |\n| `pageSize` | `int` | No | `50` | Items per page. |\n| `lang` | `string` | No | `en` | Language for text fields: `en` (English) or `ar` (Arabic). |\n\n---\n\n## Response\n\nOn success `code` is `1000` and `data` is a paginated list of plans.\n\n---\n\n## Response fields\n\n| Field | Type | Description |\n|---|---|---|\n| code | int | Response status code; `1000` on success. |\n| message | string | Human-readable summary of the result. |\n| data | object | Paginated list of plans available for the requested country. |\n| data.items | array | Plans for the current page. |\n| data.items[].id | string | Plan identifier — use it with **Get Plan Networks**, **Get Plan Topups**, and **Create Transaction**. |\n| data.items[].details | object | Descriptive information about the plan. |\n| data.items[].details.name | string | Plan's display name. |\n| data.items[].details.description | string | Longer description of what the plan includes. |\n| data.items[].details.coverageType | string (values: LOCAL \\| REGIONAL \\| GLOBAL) | Geographic coverage of the plan — see **Coverage type** in the folder overview. |\n| data.items[].details.termsAndConditions | string | Terms and conditions text for the plan. |\n| data.items[].details.usageInstructions | string | Instructions for activating and using the plan. |\n| data.items[].details.unlimited | bool | `true` if the plan has unlimited data. |\n| data.items[].details.supportsTopup | bool | `true` if this plan can later be topped up via **Get Plan Topups** / **Create Transaction**. |\n| data.items[].details.autoRenew | bool | `true` if the plan renews automatically at expiry. |\n| data.items[].details.maxDownloadSpeed | decimal | Maximum download speed for the plan; `null` when unrestricted or not specified. |\n| data.items[].details.maxUploadSpeed | decimal | Maximum upload speed for the plan; `null` when unrestricted or not specified. |\n| data.items[].details.validCountries | array | Countries where the plan can be used. |\n| data.items[].details.validCountries[].name | string | Country display name. |\n| data.items[].details.validCountries[].isoCode3 | string | Country's ISO 3166-1 alpha-3 code. |\n| data.items[].details.supportedOperators | array of string | Mobile network operators reachable on this plan. |\n| data.items[].pricing | object | Pricing details for the plan. |\n| data.items[].pricing.type | string (values: FIXED \\| RANGED) | Pricing model — see **Pricing type** in the folder overview. |\n| data.items[].pricing.currency | string | 3-letter ISO 4217 currency code for the amounts below. |\n| data.items[].pricing.minAmount | decimal | Minimum price. Equal to `maxAmount` when `type` is `FIXED`. |\n| data.items[].pricing.maxAmount | decimal | Maximum price. Equal to `minAmount` when `type` is `FIXED`. |\n| data.items[].pricing.fees | decimal | Additional fixed fee added on top of the price, if any. |\n| data.items[].pricing.tax | object | Tax breakdown applied to the price; `null`/omitted where no tax applies to this plan. |\n| data.items[].pricing.tax.taxRate | decimal | Tax rate as a percentage (e.g. `15` means 15%). |\n| data.items[].pricing.tax.taxType | string | Name of the tax (e.g. `VAT`). |\n| data.items[].pricing.tax.taxAmount | decimal | Tax amount, in `pricing.currency`. |\n| data.items[].validities | array | The plan's data/duration allowances. |\n| data.items[].validities[].type | string | Kind of allowance, e.g. `DATA` or `DURATION`. |\n| data.items[].validities[].unit | string | Unit for `quantity`, e.g. `MB`, `GB` or `DAYS`. |\n| data.items[].validities[].quantity | decimal | Amount of the allowance, in `unit`. |\n| data.count | int | Number of items returned on this page (not the total across all pages). |\n| data.page | int | Current page number. |\n| data.pageSize | int | Number of items requested per page. |\n| data.totalPages | int | Total number of pages available for the current filters. |\n| data.totalItems | int | Total number of plans available for this country, across all pages. |\n"},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"cookie":[],"responseTime":null,"body":"{\n  \"code\": 1000,\n  \"message\": \"Success\",\n  \"data\": {\n    \"items\": [\n      {\n        \"id\": \"plan_eu_5gb_30d\",\n        \"details\": {\n          \"name\": \"Europe 5GB - 30 Days\",\n          \"description\": \"5GB of data across Europe, valid for 30 days.\",\n          \"coverageType\": \"REGIONAL\",\n          \"termsAndConditions\": \"Standard eSIM terms apply.\",\n          \"usageInstructions\": \"Scan the QR code and enable data roaming.\",\n          \"unlimited\": false,\n          \"supportsTopup\": true,\n          \"autoRenew\": false,\n          \"maxDownloadSpeed\": null,\n          \"maxUploadSpeed\": null,\n          \"validCountries\": [\n            {\n              \"name\": \"France\",\n              \"isoCode3\": \"FRA\"\n            },\n            {\n              \"name\": \"Germany\",\n              \"isoCode3\": \"DEU\"\n            }\n          ],\n          \"supportedOperators\": [\n            \"Orange\",\n            \"Vodafone\"\n          ]\n        },\n        \"pricing\": {\n          \"type\": \"FIXED\",\n          \"currency\": \"INR\",\n          \"minAmount\": 75,\n          \"maxAmount\": 75,\n          \"fees\": 0,\n          \"tax\": {\n            \"taxRate\": 15,\n            \"taxType\": \"VAT\",\n            \"taxAmount\": 11.25\n          }\n        },\n        \"validities\": [\n          {\n            \"type\": \"DATA\",\n            \"unit\": \"GB\",\n            \"quantity\": 5\n          },\n          {\n            \"type\": \"DURATION\",\n            \"unit\": \"DAYS\",\n            \"quantity\": 30\n          }\n        ]\n      }\n    ],\n    \"count\": 1,\n    \"page\": 1,\n    \"pageSize\": 50,\n    \"totalPages\": 1,\n    \"totalItems\": 1\n  }\n}"}],"_postman_id":"909568f4-3c0a-40e2-89a2-c36708a270ce"},{"name":"Get Plans by Region","id":"2cfc28ec-b663-4d73-a753-3f1589af2e2e","request":{"method":"GET","header":[],"url":"https://eservices.hoicom.net/api/v0/esim/plans/region/:regionCode?page=1&pageSize=50&lang=en","description":"<p>Returns eSIM plans available for a specific region (region <code>code</code> from <strong>Get Regions</strong>).</p>\n<p><strong>Data units.</strong> Data amounts are normalised: allowances of 1 GB or more are shown in decimal GB (a 1024 MB plan reads <code>1 GB</code>, 512 MB reads <code>500 MB</code>), smaller ones in MB. Do not assume a fixed unit; always read <code>unit</code>. The catalogue is large and its size is not fixed, so do not hard-code plan counts. Arabic text is available with <code>lang=ar</code>.</p>\n<hr />\n<h2 id=\"authorization\">Authorization</h2>\n<p>Requires Basic Authentication with your client credentials. Your account must be enabled for the eSIM service.</p>\n<hr />\n<h2 id=\"path-parameters\">Path Parameters</h2>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Parameter</th>\n<th>Type</th>\n<th>Required</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>regionCode</code></td>\n<td><code>string</code></td>\n<td>Yes</td>\n<td>Region code, e.g. <code>EU</code>.</td>\n</tr>\n</tbody>\n</table>\n</div><hr />\n<h2 id=\"query-parameters\">Query Parameters</h2>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Parameter</th>\n<th>Type</th>\n<th>Required</th>\n<th>Default</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>page</code></td>\n<td><code>int</code></td>\n<td>No</td>\n<td><code>1</code></td>\n<td>Page number.</td>\n</tr>\n<tr>\n<td><code>pageSize</code></td>\n<td><code>int</code></td>\n<td>No</td>\n<td><code>50</code></td>\n<td>Items per page.</td>\n</tr>\n<tr>\n<td><code>lang</code></td>\n<td><code>string</code></td>\n<td>No</td>\n<td><code>en</code></td>\n<td>Language for text fields: <code>en</code> (English) or <code>ar</code> (Arabic).</td>\n</tr>\n</tbody>\n</table>\n</div><hr />\n<h2 id=\"response\">Response</h2>\n<p>On success <code>code</code> is <code>1000</code> and <code>data</code> is a paginated list of plans.</p>\n<hr />\n<h2 id=\"response-fields\">Response fields</h2>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Field</th>\n<th>Type</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>code</td>\n<td>int</td>\n<td>Response status code; <code>1000</code> on success.</td>\n</tr>\n<tr>\n<td>message</td>\n<td>string</td>\n<td>Human-readable summary of the result.</td>\n</tr>\n<tr>\n<td>data</td>\n<td>object</td>\n<td>Paginated list of plans available for the requested region.</td>\n</tr>\n<tr>\n<td>data.items</td>\n<td>array</td>\n<td>Plans for the current page.</td>\n</tr>\n<tr>\n<td>data.items[].id</td>\n<td>string</td>\n<td>Plan identifier — use it with <strong>Get Plan Networks</strong>, <strong>Get Plan Topups</strong>, and <strong>Create Transaction</strong>.</td>\n</tr>\n<tr>\n<td>data.items[].details</td>\n<td>object</td>\n<td>Descriptive information about the plan.</td>\n</tr>\n<tr>\n<td>data.items[].details.name</td>\n<td>string</td>\n<td>Plan's display name.</td>\n</tr>\n<tr>\n<td>data.items[].details.description</td>\n<td>string</td>\n<td>Longer description of what the plan includes.</td>\n</tr>\n<tr>\n<td>data.items[].details.coverageType</td>\n<td>string (values: LOCAL | REGIONAL | GLOBAL)</td>\n<td>Geographic coverage of the plan — see <strong>Coverage type</strong> in the folder overview.</td>\n</tr>\n<tr>\n<td>data.items[].details.termsAndConditions</td>\n<td>string</td>\n<td>Terms and conditions text for the plan.</td>\n</tr>\n<tr>\n<td>data.items[].details.usageInstructions</td>\n<td>string</td>\n<td>Instructions for activating and using the plan.</td>\n</tr>\n<tr>\n<td>data.items[].details.unlimited</td>\n<td>bool</td>\n<td><code>true</code> if the plan has unlimited data.</td>\n</tr>\n<tr>\n<td>data.items[].details.supportsTopup</td>\n<td>bool</td>\n<td><code>true</code> if this plan can later be topped up via <strong>Get Plan Topups</strong> / <strong>Create Transaction</strong>.</td>\n</tr>\n<tr>\n<td>data.items[].details.autoRenew</td>\n<td>bool</td>\n<td><code>true</code> if the plan renews automatically at expiry.</td>\n</tr>\n<tr>\n<td>data.items[].details.maxDownloadSpeed</td>\n<td>decimal</td>\n<td>Maximum download speed for the plan; <code>null</code> when unrestricted or not specified.</td>\n</tr>\n<tr>\n<td>data.items[].details.maxUploadSpeed</td>\n<td>decimal</td>\n<td>Maximum upload speed for the plan; <code>null</code> when unrestricted or not specified.</td>\n</tr>\n<tr>\n<td>data.items[].details.validCountries</td>\n<td>array</td>\n<td>Countries where the plan can be used.</td>\n</tr>\n<tr>\n<td>data.items[].details.validCountries[].name</td>\n<td>string</td>\n<td>Country display name.</td>\n</tr>\n<tr>\n<td>data.items[].details.validCountries[].isoCode3</td>\n<td>string</td>\n<td>Country's ISO 3166-1 alpha-3 code.</td>\n</tr>\n<tr>\n<td>data.items[].details.supportedOperators</td>\n<td>array of string</td>\n<td>Mobile network operators reachable on this plan.</td>\n</tr>\n<tr>\n<td>data.items[].pricing</td>\n<td>object</td>\n<td>Pricing details for the plan.</td>\n</tr>\n<tr>\n<td>data.items[].pricing.type</td>\n<td>string (values: FIXED | RANGED)</td>\n<td>Pricing model — see <strong>Pricing type</strong> in the folder overview.</td>\n</tr>\n<tr>\n<td>data.items[].pricing.currency</td>\n<td>string</td>\n<td>3-letter ISO 4217 currency code for the amounts below.</td>\n</tr>\n<tr>\n<td>data.items[].pricing.minAmount</td>\n<td>decimal</td>\n<td>Minimum price. Equal to <code>maxAmount</code> when <code>type</code> is <code>FIXED</code>.</td>\n</tr>\n<tr>\n<td>data.items[].pricing.maxAmount</td>\n<td>decimal</td>\n<td>Maximum price. Equal to <code>minAmount</code> when <code>type</code> is <code>FIXED</code>.</td>\n</tr>\n<tr>\n<td>data.items[].pricing.fees</td>\n<td>decimal</td>\n<td>Additional fixed fee added on top of the price, if any.</td>\n</tr>\n<tr>\n<td>data.items[].pricing.tax</td>\n<td>object</td>\n<td>Tax breakdown applied to the price; <code>null</code>/omitted where no tax applies to this plan.</td>\n</tr>\n<tr>\n<td>data.items[].pricing.tax.taxRate</td>\n<td>decimal</td>\n<td>Tax rate as a percentage (e.g. <code>15</code> means 15%).</td>\n</tr>\n<tr>\n<td>data.items[].pricing.tax.taxType</td>\n<td>string</td>\n<td>Name of the tax (e.g. <code>VAT</code>).</td>\n</tr>\n<tr>\n<td>data.items[].pricing.tax.taxAmount</td>\n<td>decimal</td>\n<td>Tax amount, in <code>pricing.currency</code>.</td>\n</tr>\n<tr>\n<td>data.items[].validities</td>\n<td>array</td>\n<td>The plan's data/duration allowances.</td>\n</tr>\n<tr>\n<td>data.items[].validities[].type</td>\n<td>string</td>\n<td>Kind of allowance, e.g. <code>DATA</code> or <code>DURATION</code>.</td>\n</tr>\n<tr>\n<td>data.items[].validities[].unit</td>\n<td>string</td>\n<td>Unit for <code>quantity</code>, e.g. <code>MB</code>, <code>GB</code> or <code>DAYS</code>.</td>\n</tr>\n<tr>\n<td>data.items[].validities[].quantity</td>\n<td>decimal</td>\n<td>Amount of the allowance, in <code>unit</code>.</td>\n</tr>\n<tr>\n<td>data.count</td>\n<td>int</td>\n<td>Number of items returned on this page (not the total across all pages).</td>\n</tr>\n<tr>\n<td>data.page</td>\n<td>int</td>\n<td>Current page number.</td>\n</tr>\n<tr>\n<td>data.pageSize</td>\n<td>int</td>\n<td>Number of items requested per page.</td>\n</tr>\n<tr>\n<td>data.totalPages</td>\n<td>int</td>\n<td>Total number of pages available for the current filters.</td>\n</tr>\n<tr>\n<td>data.totalItems</td>\n<td>int</td>\n<td>Total number of plans available for this region, across all pages.</td>\n</tr>\n</tbody>\n</table>\n</div>","urlObject":{"path":["api","v0","esim","plans","region",":regionCode"],"host":["https://eservices.hoicom.net"],"query":[{"key":"page","value":"1"},{"key":"pageSize","value":"50"},{"description":{"content":"<p>Language for text fields: en or ar.</p>\n","type":"text/plain"},"key":"lang","value":"en"}],"variable":[{"type":"any","value":"","key":"regionCode"}]}},"response":[{"id":"48d29976-52a2-4135-9b0d-48598a7bc5ae","name":"OK","originalRequest":{"method":"GET","header":[],"url":{"raw":"https://eservices.hoicom.net/api/v0/esim/plans/region/:regionCode?page=1&pageSize=50&lang=en","host":["https://eservices.hoicom.net"],"path":["api","v0","esim","plans","region",":regionCode"],"query":[{"key":"page","value":"1"},{"key":"pageSize","value":"50"},{"key":"lang","value":"en","description":"Language for text fields: en or ar."}],"variable":[{"key":"regionCode","value":""}]},"description":"Returns eSIM plans available for a specific region (region `code` from **Get Regions**).\n\n**Data units.** Data amounts are normalised: allowances of 1 GB or more are shown in decimal GB (a 1024 MB plan reads `1 GB`, 512 MB reads `500 MB`), smaller ones in MB. Do not assume a fixed unit; always read `unit`. The catalogue is large and its size is not fixed, so do not hard-code plan counts. Arabic text is available with `lang=ar`.\n\n---\n\n## Authorization\n\nRequires Basic Authentication with your client credentials. Your account must be enabled for the eSIM service.\n\n---\n\n## Path Parameters\n\n| Parameter | Type | Required | Description |\n| --- | --- | --- | --- |\n| `regionCode` | `string` | Yes | Region code, e.g. `EU`. |\n\n---\n\n## Query Parameters\n\n| Parameter | Type | Required | Default | Description |\n| --- | --- | --- | --- | --- |\n| `page` | `int` | No | `1` | Page number. |\n| `pageSize` | `int` | No | `50` | Items per page. |\n| `lang` | `string` | No | `en` | Language for text fields: `en` (English) or `ar` (Arabic). |\n\n---\n\n## Response\n\nOn success `code` is `1000` and `data` is a paginated list of plans.\n\n---\n\n## Response fields\n\n| Field | Type | Description |\n|---|---|---|\n| code | int | Response status code; `1000` on success. |\n| message | string | Human-readable summary of the result. |\n| data | object | Paginated list of plans available for the requested region. |\n| data.items | array | Plans for the current page. |\n| data.items[].id | string | Plan identifier — use it with **Get Plan Networks**, **Get Plan Topups**, and **Create Transaction**. |\n| data.items[].details | object | Descriptive information about the plan. |\n| data.items[].details.name | string | Plan's display name. |\n| data.items[].details.description | string | Longer description of what the plan includes. |\n| data.items[].details.coverageType | string (values: LOCAL \\| REGIONAL \\| GLOBAL) | Geographic coverage of the plan — see **Coverage type** in the folder overview. |\n| data.items[].details.termsAndConditions | string | Terms and conditions text for the plan. |\n| data.items[].details.usageInstructions | string | Instructions for activating and using the plan. |\n| data.items[].details.unlimited | bool | `true` if the plan has unlimited data. |\n| data.items[].details.supportsTopup | bool | `true` if this plan can later be topped up via **Get Plan Topups** / **Create Transaction**. |\n| data.items[].details.autoRenew | bool | `true` if the plan renews automatically at expiry. |\n| data.items[].details.maxDownloadSpeed | decimal | Maximum download speed for the plan; `null` when unrestricted or not specified. |\n| data.items[].details.maxUploadSpeed | decimal | Maximum upload speed for the plan; `null` when unrestricted or not specified. |\n| data.items[].details.validCountries | array | Countries where the plan can be used. |\n| data.items[].details.validCountries[].name | string | Country display name. |\n| data.items[].details.validCountries[].isoCode3 | string | Country's ISO 3166-1 alpha-3 code. |\n| data.items[].details.supportedOperators | array of string | Mobile network operators reachable on this plan. |\n| data.items[].pricing | object | Pricing details for the plan. |\n| data.items[].pricing.type | string (values: FIXED \\| RANGED) | Pricing model — see **Pricing type** in the folder overview. |\n| data.items[].pricing.currency | string | 3-letter ISO 4217 currency code for the amounts below. |\n| data.items[].pricing.minAmount | decimal | Minimum price. Equal to `maxAmount` when `type` is `FIXED`. |\n| data.items[].pricing.maxAmount | decimal | Maximum price. Equal to `minAmount` when `type` is `FIXED`. |\n| data.items[].pricing.fees | decimal | Additional fixed fee added on top of the price, if any. |\n| data.items[].pricing.tax | object | Tax breakdown applied to the price; `null`/omitted where no tax applies to this plan. |\n| data.items[].pricing.tax.taxRate | decimal | Tax rate as a percentage (e.g. `15` means 15%). |\n| data.items[].pricing.tax.taxType | string | Name of the tax (e.g. `VAT`). |\n| data.items[].pricing.tax.taxAmount | decimal | Tax amount, in `pricing.currency`. |\n| data.items[].validities | array | The plan's data/duration allowances. |\n| data.items[].validities[].type | string | Kind of allowance, e.g. `DATA` or `DURATION`. |\n| data.items[].validities[].unit | string | Unit for `quantity`, e.g. `MB`, `GB` or `DAYS`. |\n| data.items[].validities[].quantity | decimal | Amount of the allowance, in `unit`. |\n| data.count | int | Number of items returned on this page (not the total across all pages). |\n| data.page | int | Current page number. |\n| data.pageSize | int | Number of items requested per page. |\n| data.totalPages | int | Total number of pages available for the current filters. |\n| data.totalItems | int | Total number of plans available for this region, across all pages. |\n"},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"cookie":[],"responseTime":null,"body":"{\n  \"code\": 1000,\n  \"message\": \"Success\",\n  \"data\": {\n    \"items\": [\n      {\n        \"id\": \"plan_eu_5gb_30d\",\n        \"details\": {\n          \"name\": \"Europe 5GB - 30 Days\",\n          \"description\": \"5GB of data across Europe, valid for 30 days.\",\n          \"coverageType\": \"REGIONAL\",\n          \"termsAndConditions\": \"Standard eSIM terms apply.\",\n          \"usageInstructions\": \"Scan the QR code and enable data roaming.\",\n          \"unlimited\": false,\n          \"supportsTopup\": true,\n          \"autoRenew\": false,\n          \"maxDownloadSpeed\": null,\n          \"maxUploadSpeed\": null,\n          \"validCountries\": [\n            {\n              \"name\": \"France\",\n              \"isoCode3\": \"FRA\"\n            },\n            {\n              \"name\": \"Germany\",\n              \"isoCode3\": \"DEU\"\n            }\n          ],\n          \"supportedOperators\": [\n            \"Orange\",\n            \"Vodafone\"\n          ]\n        },\n        \"pricing\": {\n          \"type\": \"FIXED\",\n          \"currency\": \"INR\",\n          \"minAmount\": 75,\n          \"maxAmount\": 75,\n          \"fees\": 0,\n          \"tax\": {\n            \"taxRate\": 15,\n            \"taxType\": \"VAT\",\n            \"taxAmount\": 11.25\n          }\n        },\n        \"validities\": [\n          {\n            \"type\": \"DATA\",\n            \"unit\": \"GB\",\n            \"quantity\": 5\n          },\n          {\n            \"type\": \"DURATION\",\n            \"unit\": \"DAYS\",\n            \"quantity\": 30\n          }\n        ]\n      }\n    ],\n    \"count\": 1,\n    \"page\": 1,\n    \"pageSize\": 50,\n    \"totalPages\": 1,\n    \"totalItems\": 1\n  }\n}"}],"_postman_id":"2cfc28ec-b663-4d73-a753-3f1589af2e2e"},{"name":"Get Plan Networks","id":"95efda1a-ebfc-4550-aa5a-3af94ef57f6f","request":{"method":"GET","header":[],"url":"https://eservices.hoicom.net/api/v0/esim/plans/:id/networks","description":"<p>Returns the network operators reachable on a plan, grouped by country.</p>\n<hr />\n<h2 id=\"authorization\">Authorization</h2>\n<p>Requires Basic Authentication with your client credentials. Your account must be enabled for the eSIM service.</p>\n<hr />\n<h2 id=\"path-parameters\">Path Parameters</h2>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Parameter</th>\n<th>Type</th>\n<th>Required</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>id</code></td>\n<td><code>string</code></td>\n<td>Yes</td>\n<td>Plan identifier.</td>\n</tr>\n</tbody>\n</table>\n</div><hr />\n<h2 id=\"response\">Response</h2>\n<p>On success <code>code</code> is <code>1000</code> and <code>data</code> is a list of <code>{ countryIsoCode, operators[] }</code>.</p>\n<hr />\n<h2 id=\"response-fields\">Response fields</h2>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Field</th>\n<th>Type</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>code</td>\n<td>int</td>\n<td>Response status code; <code>1000</code> on success.</td>\n</tr>\n<tr>\n<td>message</td>\n<td>string</td>\n<td>Human-readable summary of the result.</td>\n</tr>\n<tr>\n<td>data</td>\n<td>array</td>\n<td>Network operators reachable on the plan, grouped by country.</td>\n</tr>\n<tr>\n<td>data[].countryIsoCode</td>\n<td>string</td>\n<td>ISO 3166-1 alpha-3 code of the country.</td>\n</tr>\n<tr>\n<td>data[].operators</td>\n<td>array of string</td>\n<td>Mobile network operators reachable in that country on this plan.</td>\n</tr>\n</tbody>\n</table>\n</div>","urlObject":{"path":["api","v0","esim","plans",":id","networks"],"host":["https://eservices.hoicom.net"],"query":[],"variable":[{"type":"any","value":"","key":"id"}]}},"response":[{"id":"d420746f-f58a-4dbb-8711-d23880c540ef","name":"OK","originalRequest":{"method":"GET","header":[],"url":{"raw":"https://eservices.hoicom.net/api/v0/esim/plans/:id/networks","host":["https://eservices.hoicom.net"],"path":["api","v0","esim","plans",":id","networks"],"variable":[{"key":"id","value":""}]},"description":"Returns the network operators reachable on a plan, grouped by country.\n\n---\n\n## Authorization\n\nRequires Basic Authentication with your client credentials. Your account must be enabled for the eSIM service.\n\n---\n\n## Path Parameters\n\n| Parameter | Type | Required | Description |\n| --- | --- | --- | --- |\n| `id` | `string` | Yes | Plan identifier. |\n\n---\n\n## Response\n\nOn success `code` is `1000` and `data` is a list of `{ countryIsoCode, operators[] }`."},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"cookie":[],"responseTime":null,"body":"{\n  \"code\": 1000,\n  \"message\": \"Success\",\n  \"data\": [\n    {\n      \"countryIsoCode\": \"FRA\",\n      \"operators\": [\n        \"Orange\",\n        \"SFR\",\n        \"Bouygues\"\n      ]\n    },\n    {\n      \"countryIsoCode\": \"DEU\",\n      \"operators\": [\n        \"Telekom\",\n        \"Vodafone\"\n      ]\n    }\n  ]\n}"}],"_postman_id":"95efda1a-ebfc-4550-aa5a-3af94ef57f6f"},{"name":"Get Plan Topups","id":"49c1eb38-bda9-4530-a944-ca005603a386","request":{"method":"GET","header":[],"url":"https://eservices.hoicom.net/api/v0/esim/plans/:id/topups?page=1&pageSize=50&lang=en","description":"<p>Returns the top-up add-ons available for a plan. To buy one, call <strong>Create Transaction</strong> with <code>mainTransactionId</code> set to the original transaction.</p>\n<p><strong>Data units.</strong> Data amounts are normalised: allowances of 1 GB or more are shown in decimal GB (a 1024 MB plan reads <code>1 GB</code>, 512 MB reads <code>500 MB</code>), smaller ones in MB. Do not assume a fixed unit; always read <code>unit</code>. The catalogue is large and its size is not fixed, so do not hard-code plan counts. Arabic text is available with <code>lang=ar</code>.</p>\n<hr />\n<h2 id=\"authorization\">Authorization</h2>\n<p>Requires Basic Authentication with your client credentials. Your account must be enabled for the eSIM service.</p>\n<hr />\n<h2 id=\"path-parameters\">Path Parameters</h2>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Parameter</th>\n<th>Type</th>\n<th>Required</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>id</code></td>\n<td><code>string</code></td>\n<td>Yes</td>\n<td>Plan identifier.</td>\n</tr>\n</tbody>\n</table>\n</div><hr />\n<h2 id=\"query-parameters\">Query Parameters</h2>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Parameter</th>\n<th>Type</th>\n<th>Required</th>\n<th>Default</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>page</code></td>\n<td><code>int</code></td>\n<td>No</td>\n<td><code>1</code></td>\n<td>Page number.</td>\n</tr>\n<tr>\n<td><code>pageSize</code></td>\n<td><code>int</code></td>\n<td>No</td>\n<td><code>50</code></td>\n<td>Items per page.</td>\n</tr>\n<tr>\n<td><code>lang</code></td>\n<td><code>string</code></td>\n<td>No</td>\n<td><code>en</code></td>\n<td>Language for text fields: <code>en</code> (English) or <code>ar</code> (Arabic).</td>\n</tr>\n</tbody>\n</table>\n</div><hr />\n<h2 id=\"response\">Response</h2>\n<p>On success <code>code</code> is <code>1000</code> and <code>data</code> is a paginated list of top-up plans.</p>\n<hr />\n<h2 id=\"response-fields\">Response fields</h2>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Field</th>\n<th>Type</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>code</td>\n<td>int</td>\n<td>Response status code; <code>1000</code> on success.</td>\n</tr>\n<tr>\n<td>message</td>\n<td>string</td>\n<td>Human-readable summary of the result.</td>\n</tr>\n<tr>\n<td>data</td>\n<td>object</td>\n<td>Paginated list of top-up add-ons available for the plan.</td>\n</tr>\n<tr>\n<td>data.items</td>\n<td>array</td>\n<td>Top-ups for the current page.</td>\n</tr>\n<tr>\n<td>data.items[].id</td>\n<td>string</td>\n<td>Top-up identifier — pass it as <code>planId</code> on <strong>Create Transaction</strong>, with <code>mainTransactionId</code> set to the original transaction.</td>\n</tr>\n<tr>\n<td>data.items[].details</td>\n<td>object</td>\n<td>Descriptive information about the top-up.</td>\n</tr>\n<tr>\n<td>data.items[].details.name</td>\n<td>string</td>\n<td>Top-up's display name.</td>\n</tr>\n<tr>\n<td>data.items[].details.description</td>\n<td>string</td>\n<td>Longer description of what the top-up adds.</td>\n</tr>\n<tr>\n<td>data.items[].details.coverageType</td>\n<td>string (values: LOCAL | REGIONAL | GLOBAL)</td>\n<td>Geographic coverage the top-up applies to — see <strong>Coverage type</strong> in the folder overview.</td>\n</tr>\n<tr>\n<td>data.items[].details.termsAndConditions</td>\n<td>string</td>\n<td>Terms and conditions text for the top-up.</td>\n</tr>\n<tr>\n<td>data.items[].details.usageInstructions</td>\n<td>string</td>\n<td>Instructions for how the top-up is applied.</td>\n</tr>\n<tr>\n<td>data.items[].details.unlimited</td>\n<td>bool</td>\n<td><code>true</code> if the top-up grants unlimited data.</td>\n</tr>\n<tr>\n<td>data.items[].details.autoRenew</td>\n<td>bool</td>\n<td><code>true</code> if the top-up renews automatically at expiry.</td>\n</tr>\n<tr>\n<td>data.items[].details.maxDownloadSpeed</td>\n<td>decimal</td>\n<td>Maximum download speed for the top-up; <code>null</code> when unrestricted or not specified.</td>\n</tr>\n<tr>\n<td>data.items[].details.maxUploadSpeed</td>\n<td>decimal</td>\n<td>Maximum upload speed for the top-up; <code>null</code> when unrestricted or not specified.</td>\n</tr>\n<tr>\n<td>data.items[].details.validCountries</td>\n<td>array</td>\n<td>Countries where the top-up can be used.</td>\n</tr>\n<tr>\n<td>data.items[].details.validCountries[].name</td>\n<td>string</td>\n<td>Country display name.</td>\n</tr>\n<tr>\n<td>data.items[].details.validCountries[].isoCode3</td>\n<td>string</td>\n<td>Country's ISO 3166-1 alpha-3 code.</td>\n</tr>\n<tr>\n<td>data.items[].details.supportedOperators</td>\n<td>array of string</td>\n<td>Mobile network operators reachable on this top-up.</td>\n</tr>\n<tr>\n<td>data.items[].pricing</td>\n<td>object</td>\n<td>Pricing details for the top-up.</td>\n</tr>\n<tr>\n<td>data.items[].pricing.type</td>\n<td>string (values: FIXED | RANGED)</td>\n<td>Pricing model — see <strong>Pricing type</strong> in the folder overview.</td>\n</tr>\n<tr>\n<td>data.items[].pricing.currency</td>\n<td>string</td>\n<td>3-letter ISO 4217 currency code for the amounts below.</td>\n</tr>\n<tr>\n<td>data.items[].pricing.minAmount</td>\n<td>decimal</td>\n<td>Minimum price. Equal to <code>maxAmount</code> when <code>type</code> is <code>FIXED</code>.</td>\n</tr>\n<tr>\n<td>data.items[].pricing.maxAmount</td>\n<td>decimal</td>\n<td>Maximum price. Equal to <code>minAmount</code> when <code>type</code> is <code>FIXED</code>.</td>\n</tr>\n<tr>\n<td>data.items[].pricing.fees</td>\n<td>decimal</td>\n<td>Additional fixed fee added on top of the price, if any.</td>\n</tr>\n<tr>\n<td>data.items[].pricing.tax</td>\n<td>object</td>\n<td>Tax breakdown applied to the price; <code>null</code>/omitted where no tax applies to this top-up.</td>\n</tr>\n<tr>\n<td>data.items[].pricing.tax.taxRate</td>\n<td>decimal</td>\n<td>Tax rate as a percentage (e.g. <code>15</code> means 15%).</td>\n</tr>\n<tr>\n<td>data.items[].pricing.tax.taxType</td>\n<td>string</td>\n<td>Name of the tax (e.g. <code>VAT</code>).</td>\n</tr>\n<tr>\n<td>data.items[].pricing.tax.taxAmount</td>\n<td>decimal</td>\n<td>Tax amount, in <code>pricing.currency</code>.</td>\n</tr>\n<tr>\n<td>data.items[].validities</td>\n<td>array</td>\n<td>The top-up's data/duration allowances.</td>\n</tr>\n<tr>\n<td>data.items[].validities[].type</td>\n<td>string</td>\n<td>Kind of allowance, e.g. <code>DATA</code> or <code>DURATION</code>.</td>\n</tr>\n<tr>\n<td>data.items[].validities[].unit</td>\n<td>string</td>\n<td>Unit for <code>quantity</code>, e.g. <code>MB</code> or <code>GB</code>.</td>\n</tr>\n<tr>\n<td>data.items[].validities[].quantity</td>\n<td>decimal</td>\n<td>Amount of the allowance, in <code>unit</code>.</td>\n</tr>\n<tr>\n<td>data.count</td>\n<td>int</td>\n<td>Number of items returned on this page (not the total across all pages).</td>\n</tr>\n<tr>\n<td>data.page</td>\n<td>int</td>\n<td>Current page number.</td>\n</tr>\n<tr>\n<td>data.pageSize</td>\n<td>int</td>\n<td>Number of items requested per page.</td>\n</tr>\n<tr>\n<td>data.totalPages</td>\n<td>int</td>\n<td>Total number of pages available for the current filters.</td>\n</tr>\n<tr>\n<td>data.totalItems</td>\n<td>int</td>\n<td>Total number of top-ups available for this plan, across all pages.</td>\n</tr>\n</tbody>\n</table>\n</div>","urlObject":{"path":["api","v0","esim","plans",":id","topups"],"host":["https://eservices.hoicom.net"],"query":[{"key":"page","value":"1"},{"key":"pageSize","value":"50"},{"description":{"content":"<p>Language for text fields: en or ar.</p>\n","type":"text/plain"},"key":"lang","value":"en"}],"variable":[{"type":"any","value":"","key":"id"}]}},"response":[{"id":"86d11a22-62f8-4b93-b138-8970be35e63f","name":"OK","originalRequest":{"method":"GET","header":[],"url":{"raw":"https://eservices.hoicom.net/api/v0/esim/plans/:id/topups?page=1&pageSize=50&lang=en","host":["https://eservices.hoicom.net"],"path":["api","v0","esim","plans",":id","topups"],"query":[{"key":"page","value":"1"},{"key":"pageSize","value":"50"},{"key":"lang","value":"en","description":"Language for text fields: en or ar."}],"variable":[{"key":"id","value":""}]},"description":"Returns the top-up add-ons available for a plan. To buy one, call **Create Transaction** with `mainTransactionId` set to the original transaction.\n\n**Data units.** Data amounts are normalised: allowances of 1 GB or more are shown in decimal GB (a 1024 MB plan reads `1 GB`, 512 MB reads `500 MB`), smaller ones in MB. Do not assume a fixed unit; always read `unit`. The catalogue is large and its size is not fixed, so do not hard-code plan counts. Arabic text is available with `lang=ar`.\n\n---\n\n## Authorization\n\nRequires Basic Authentication with your client credentials. Your account must be enabled for the eSIM service.\n\n---\n\n## Path Parameters\n\n| Parameter | Type | Required | Description |\n| --- | --- | --- | --- |\n| `id` | `string` | Yes | Plan identifier. |\n\n---\n\n## Query Parameters\n\n| Parameter | Type | Required | Default | Description |\n| --- | --- | --- | --- | --- |\n| `page` | `int` | No | `1` | Page number. |\n| `pageSize` | `int` | No | `50` | Items per page. |\n| `lang` | `string` | No | `en` | Language for text fields: `en` (English) or `ar` (Arabic). |\n\n---\n\n## Response\n\nOn success `code` is `1000` and `data` is a paginated list of top-up plans.\n\n---\n\n## Response fields\n\n| Field | Type | Description |\n|---|---|---|\n| code | int | Response status code; `1000` on success. |\n| message | string | Human-readable summary of the result. |\n| data | object | Paginated list of top-up add-ons available for the plan. |\n| data.items | array | Top-ups for the current page. |\n| data.items[].id | string | Top-up identifier — pass it as `planId` on **Create Transaction**, with `mainTransactionId` set to the original transaction. |\n| data.items[].details | object | Descriptive information about the top-up. |\n| data.items[].details.name | string | Top-up's display name. |\n| data.items[].details.description | string | Longer description of what the top-up adds. |\n| data.items[].details.coverageType | string (values: LOCAL \\| REGIONAL \\| GLOBAL) | Geographic coverage the top-up applies to — see **Coverage type** in the folder overview. |\n| data.items[].details.termsAndConditions | string | Terms and conditions text for the top-up. |\n| data.items[].details.usageInstructions | string | Instructions for how the top-up is applied. |\n| data.items[].details.unlimited | bool | `true` if the top-up grants unlimited data. |\n| data.items[].details.autoRenew | bool | `true` if the top-up renews automatically at expiry. |\n| data.items[].details.maxDownloadSpeed | decimal | Maximum download speed for the top-up; `null` when unrestricted or not specified. |\n| data.items[].details.maxUploadSpeed | decimal | Maximum upload speed for the top-up; `null` when unrestricted or not specified. |\n| data.items[].details.validCountries | array | Countries where the top-up can be used. |\n| data.items[].details.validCountries[].name | string | Country display name. |\n| data.items[].details.validCountries[].isoCode3 | string | Country's ISO 3166-1 alpha-3 code. |\n| data.items[].details.supportedOperators | array of string | Mobile network operators reachable on this top-up. |\n| data.items[].pricing | object | Pricing details for the top-up. |\n| data.items[].pricing.type | string (values: FIXED \\| RANGED) | Pricing model — see **Pricing type** in the folder overview. |\n| data.items[].pricing.currency | string | 3-letter ISO 4217 currency code for the amounts below. |\n| data.items[].pricing.minAmount | decimal | Minimum price. Equal to `maxAmount` when `type` is `FIXED`. |\n| data.items[].pricing.maxAmount | decimal | Maximum price. Equal to `minAmount` when `type` is `FIXED`. |\n| data.items[].pricing.fees | decimal | Additional fixed fee added on top of the price, if any. |\n| data.items[].pricing.tax | object | Tax breakdown applied to the price; `null`/omitted where no tax applies to this top-up. |\n| data.items[].pricing.tax.taxRate | decimal | Tax rate as a percentage (e.g. `15` means 15%). |\n| data.items[].pricing.tax.taxType | string | Name of the tax (e.g. `VAT`). |\n| data.items[].pricing.tax.taxAmount | decimal | Tax amount, in `pricing.currency`. |\n| data.items[].validities | array | The top-up's data/duration allowances. |\n| data.items[].validities[].type | string | Kind of allowance, e.g. `DATA` or `DURATION`. |\n| data.items[].validities[].unit | string | Unit for `quantity`, e.g. `MB` or `GB`. |\n| data.items[].validities[].quantity | decimal | Amount of the allowance, in `unit`. |\n| data.count | int | Number of items returned on this page (not the total across all pages). |\n| data.page | int | Current page number. |\n| data.pageSize | int | Number of items requested per page. |\n| data.totalPages | int | Total number of pages available for the current filters. |\n| data.totalItems | int | Total number of top-ups available for this plan, across all pages. |\n"},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"cookie":[],"responseTime":null,"body":"{\n  \"code\": 1000,\n  \"message\": \"Success\",\n  \"data\": {\n    \"items\": [\n      {\n        \"id\": \"topup_eu_2gb\",\n        \"details\": {\n          \"name\": \"Europe 2GB Add-on\",\n          \"description\": \"Add 2GB to an active Europe plan.\",\n          \"coverageType\": \"REGIONAL\",\n          \"termsAndConditions\": \"Standard eSIM terms apply.\",\n          \"usageInstructions\": \"Applied automatically to your active eSIM.\",\n          \"unlimited\": false,\n          \"autoRenew\": false,\n          \"maxDownloadSpeed\": null,\n          \"maxUploadSpeed\": null,\n          \"validCountries\": [\n            {\n              \"name\": \"France\",\n              \"isoCode3\": \"FRA\"\n            }\n          ],\n          \"supportedOperators\": [\n            \"Orange\"\n          ]\n        },\n        \"pricing\": {\n          \"type\": \"FIXED\",\n          \"currency\": \"INR\",\n          \"minAmount\": 30,\n          \"maxAmount\": 30,\n          \"fees\": 0,\n          \"tax\": {\n            \"taxRate\": 15,\n            \"taxType\": \"VAT\",\n            \"taxAmount\": 4.5\n          }\n        },\n        \"validities\": [\n          {\n            \"type\": \"DATA\",\n            \"unit\": \"GB\",\n            \"quantity\": 2\n          }\n        ]\n      }\n    ],\n    \"count\": 1,\n    \"page\": 1,\n    \"pageSize\": 50,\n    \"totalPages\": 1,\n    \"totalItems\": 1\n  }\n}"}],"_postman_id":"49c1eb38-bda9-4530-a944-ca005603a386"}],"id":"23bf129e-f8b6-4181-a4a8-8e0b1e8f9a69","description":"<p>Browse what you can sell: regions, countries, plans, the networks a plan covers, and the top-up add-ons for a plan. Start here before buying.</p>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Method</th>\n<th>Endpoint</th>\n<th>Request</th>\n<th>Purpose</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>GET</code></td>\n<td><code>/api/v0/esim/regions</code></td>\n<td><strong>Get Regions</strong></td>\n<td>Regions that plans are grouped into.</td>\n</tr>\n<tr>\n<td><code>GET</code></td>\n<td><code>/api/v0/esim/countries</code></td>\n<td><strong>Get Countries</strong></td>\n<td>Countries that plans are available for.</td>\n</tr>\n<tr>\n<td><code>GET</code></td>\n<td><code>/api/v0/esim/plans</code></td>\n<td><strong>Get Plans</strong></td>\n<td>All plans, with filtering, sorting and paging.</td>\n</tr>\n<tr>\n<td><code>GET</code></td>\n<td><code>/api/v0/esim/plans/country/{countryIsoCode}</code></td>\n<td><strong>Get Plans by Country</strong></td>\n<td>Plans for one country.</td>\n</tr>\n<tr>\n<td><code>GET</code></td>\n<td><code>/api/v0/esim/plans/region/{regionCode}</code></td>\n<td><strong>Get Plans by Region</strong></td>\n<td>Plans for one region.</td>\n</tr>\n<tr>\n<td><code>GET</code></td>\n<td><code>/api/v0/esim/plans/{id}/networks</code></td>\n<td><strong>Get Plan Networks</strong></td>\n<td>Network operators reachable on a plan, by country.</td>\n</tr>\n<tr>\n<td><code>GET</code></td>\n<td><code>/api/v0/esim/plans/{id}/topups</code></td>\n<td><strong>Get Plan Topups</strong></td>\n<td>Top-up add-ons available for a plan.</td>\n</tr>\n</tbody>\n</table>\n</div>","_postman_id":"23bf129e-f8b6-4181-a4a8-8e0b1e8f9a69"},{"name":"Transactions","item":[{"name":"Create Transaction","id":"edd3d7aa-e43f-4195-9d80-ef5df533571b","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"body":{"mode":"raw","raw":"{\n  \"externalReference\": \"client-ref-2001\",\n  \"planId\": \"plan_eu_5gb_30d\",\n  \"mainTransactionId\": null,\n  \"amount\": 75,\n  \"currency\": \"SAR\"\n}","options":{"raw":{"language":"json"}}},"url":"https://eservices.hoicom.net/api/v0/esim/transactions/async","description":"<p>Buys an eSIM plan <strong>asynchronously</strong>. Returns immediately with a <code>transactionId</code>; poll <strong>Get Transaction by ID</strong> until <code>status</code> is <code>Completed</code> to retrieve the eSIM details (ICCID, activation code, QR).</p>\n<p>To buy a <strong>top-up</strong> for an existing eSIM, set <code>mainTransactionId</code> to the original transaction id. The target must be <strong>your own <code>Completed</code> base plan</strong>; a top-up on any other transaction (another account's, unknown, not yet <code>Completed</code>, or itself a top-up) is refused with HTTP 404 / <code>1303</code>. If the target eSIM is being replaced (see <strong>Regenerate Transaction</strong>) the top-up is refused with HTTP 409 / <code>1429</code>; nothing is created or charged, and a retry after the regeneration completes lands on the new eSIM.</p>\n<p><code>externalReference</code> must be unique within your account across all your services; re-using one returns HTTP 409 / <code>1114</code>.</p>\n<hr />\n<h2 id=\"authorization\">Authorization</h2>\n<p>Requires Basic Authentication with your client credentials. Your account must be enabled for the eSIM service.</p>\n<hr />\n<h2 id=\"request-body\">Request Body</h2>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Field</th>\n<th>Type</th>\n<th>Required</th>\n<th>Constraints</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>externalReference</code></td>\n<td><code>string</code></td>\n<td>Yes</td>\n<td>Your unique id, unique within your account across all services. Max 50 chars.</td>\n</tr>\n<tr>\n<td><code>planId</code></td>\n<td><code>string</code></td>\n<td>Yes</td>\n<td>Plan (or top-up plan) id.</td>\n</tr>\n<tr>\n<td><code>mainTransactionId</code></td>\n<td><code>string</code></td>\n<td>No</td>\n<td>For top-ups: the original transaction id (your own <code>Completed</code> base plan). Max 50 chars, numeric.</td>\n</tr>\n<tr>\n<td><code>amount</code></td>\n<td><code>decimal</code></td>\n<td>Yes</td>\n<td>Must be greater than <code>0</code>.</td>\n</tr>\n<tr>\n<td><code>currency</code></td>\n<td><code>string</code></td>\n<td>No</td>\n<td>3-letter ISO code.</td>\n</tr>\n</tbody>\n</table>\n</div><hr />\n<h2 id=\"response\">Response</h2>\n<p>On acceptance <code>code</code> is <code>1000</code> and <code>data</code> contains the <code>transactionId</code>.</p>\n<h3 id=\"common-error-codes\">Common error codes</h3>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Code</th>\n<th>Meaning</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>1107</code></td>\n<td>Validation error.</td>\n</tr>\n<tr>\n<td><code>1413</code></td>\n<td>Invalid product/plan id.</td>\n</tr>\n<tr>\n<td><code>1414</code></td>\n<td>Invalid currency code.</td>\n</tr>\n<tr>\n<td><code>1114</code></td>\n<td>HTTP 409. <code>externalReference</code> already used by your account.</td>\n</tr>\n<tr>\n<td><code>1303</code></td>\n<td>HTTP 404. Top-up target is not your own <code>Completed</code> base plan.</td>\n</tr>\n<tr>\n<td><code>1429</code></td>\n<td>HTTP 409. The target eSIM is being replaced: \"The eSIM is being replaced; please retry the top-up shortly.\"</td>\n</tr>\n</tbody>\n</table>\n</div><p>A plan id that was only just created, or has just been withdrawn, may take up to ~15 seconds before it is reported as not found.</p>\n<hr />\n<h2 id=\"response-fields\">Response fields</h2>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Field</th>\n<th>Type</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>code</td>\n<td>int</td>\n<td>Response status code; <code>1000</code> when the order was accepted for processing (see <strong>Common error codes</strong> below for others).</td>\n</tr>\n<tr>\n<td>message</td>\n<td>string</td>\n<td>Human-readable summary of the result.</td>\n</tr>\n<tr>\n<td>data</td>\n<td>object</td>\n<td>The created transaction reference.</td>\n</tr>\n<tr>\n<td>data.transactionId</td>\n<td>string</td>\n<td>Id of the newly created transaction. Poll <strong>Get Transaction by ID</strong> with this id to track provisioning.</td>\n</tr>\n</tbody>\n</table>\n</div>","urlObject":{"path":["api","v0","esim","transactions","async"],"host":["https://eservices.hoicom.net"],"query":[],"variable":[]}},"response":[{"id":"5f8283a4-dbd3-4a85-bdbf-fcbc65071e4b","name":"OK","originalRequest":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"body":{"mode":"raw","raw":"{\n  \"externalReference\": \"client-ref-2001\",\n  \"planId\": \"plan_eu_5gb_30d\",\n  \"mainTransactionId\": null,\n  \"amount\": 75,\n  \"currency\": \"SAR\"\n}","options":{"raw":{"language":"json"}}},"url":"https://eservices.hoicom.net/api/v0/esim/transactions/async","description":"Buys an eSIM plan **asynchronously**. Returns immediately with a `transactionId`; poll **Get Transaction by ID** until `status` is `Completed` to retrieve the eSIM details (ICCID, activation code, QR).\n\nTo buy a **top-up** for an existing eSIM, set `mainTransactionId` to the original transaction id. The target must be **your own `Completed` base plan**; a top-up on any other transaction (another account's, unknown, not yet `Completed`, or itself a top-up) is refused with HTTP 404 / `1303`. If the target eSIM is being replaced (see **Regenerate Transaction**) the top-up is refused with HTTP 409 / `1429`; nothing is created or charged, and a retry after the regeneration completes lands on the new eSIM.\n\n`externalReference` must be unique within your account across all your services; re-using one returns HTTP 409 / `1114`.\n\n---\n\n## Authorization\n\nRequires Basic Authentication with your client credentials. Your account must be enabled for the eSIM service.\n\n---\n\n## Request Body\n\n| Field | Type | Required | Constraints |\n| --- | --- | --- | --- |\n| `externalReference` | `string` | Yes | Your unique id, unique within your account across all services. Max 50 chars. |\n| `planId` | `string` | Yes | Plan (or top-up plan) id. |\n| `mainTransactionId` | `string` | No | For top-ups: the original transaction id (your own `Completed` base plan). Max 50 chars, numeric. |\n| `amount` | `decimal` | Yes | Must be greater than `0`. |\n| `currency` | `string` | No | 3-letter ISO code. |\n\n---\n\n## Response\n\nOn acceptance `code` is `1000` and `data` contains the `transactionId`.\n\n### Common error codes\n\n| Code | Meaning |\n| --- | --- |\n| `1107` | Validation error. |\n| `1413` | Invalid product/plan id. |\n| `1414` | Invalid currency code. |\n| `1114` | HTTP 409. `externalReference` already used by your account. |\n| `1303` | HTTP 404. Top-up target is not your own `Completed` base plan. |\n| `1429` | HTTP 409. The target eSIM is being replaced: \"The eSIM is being replaced; please retry the top-up shortly.\" |\n\nA plan id that was only just created, or has just been withdrawn, may take up to ~15 seconds before it is reported as not found.\n\n---\n\n## Response fields\n\n| Field | Type | Description |\n|---|---|---|\n| code | int | Response status code; `1000` when the order was accepted for processing (see **Common error codes** below for others). |\n| message | string | Human-readable summary of the result. |\n| data | object | The created transaction reference. |\n| data.transactionId | string | Id of the newly created transaction. Poll **Get Transaction by ID** with this id to track provisioning. |\n"},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"cookie":[],"responseTime":null,"body":"{\n  \"code\": 1000,\n  \"message\": \"Success\",\n  \"data\": {\n    \"transactionId\": \"esim_txn_5a1b2c3d\"\n  }\n}"},{"id":"96b1ab87-e70b-4568-a722-4e8a69fad8f9","name":"Top-up target not found","originalRequest":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"body":{"mode":"raw","raw":"{\n  \"externalReference\": \"client-ref-2002\",\n  \"planId\": \"plan_eu_1gb_7d_topup\",\n  \"mainTransactionId\": \"23038\",\n  \"amount\": 20,\n  \"currency\": \"SAR\"\n}","options":{"raw":{"language":"json"}}},"url":"https://eservices.hoicom.net/api/v0/esim/transactions/async","description":"Buys an eSIM plan **asynchronously**. Returns immediately with a `transactionId`; poll **Get Transaction by ID** until `status` is `Completed` to retrieve the eSIM details (ICCID, activation code, QR).\n\nTo buy a **top-up** for an existing eSIM, set `mainTransactionId` to the original transaction id. The target must be **your own `Completed` base plan**; a top-up on any other transaction (another account's, unknown, not yet `Completed`, or itself a top-up) is refused with HTTP 404 / `1303`. If the target eSIM is being replaced (see **Regenerate Transaction**) the top-up is refused with HTTP 409 / `1429`; nothing is created or charged, and a retry after the regeneration completes lands on the new eSIM.\n\n`externalReference` must be unique within your account across all your services; re-using one returns HTTP 409 / `1114`.\n\n---\n\n## Authorization\n\nRequires Basic Authentication with your client credentials. Your account must be enabled for the eSIM service.\n\n---\n\n## Request Body\n\n| Field | Type | Required | Constraints |\n| --- | --- | --- | --- |\n| `externalReference` | `string` | Yes | Your unique id, unique within your account across all services. Max 50 chars. |\n| `planId` | `string` | Yes | Plan (or top-up plan) id. |\n| `mainTransactionId` | `string` | No | For top-ups: the original transaction id (your own `Completed` base plan). Max 50 chars, numeric. |\n| `amount` | `decimal` | Yes | Must be greater than `0`. |\n| `currency` | `string` | No | 3-letter ISO code. |\n\n---\n\n## Response\n\nOn acceptance `code` is `1000` and `data` contains the `transactionId`.\n\n### Common error codes\n\n| Code | Meaning |\n| --- | --- |\n| `1107` | Validation error. |\n| `1413` | Invalid product/plan id. |\n| `1414` | Invalid currency code. |\n| `1114` | HTTP 409. `externalReference` already used by your account. |\n| `1303` | HTTP 404. Top-up target is not your own `Completed` base plan. |\n| `1429` | HTTP 409. The target eSIM is being replaced: \"The eSIM is being replaced; please retry the top-up shortly.\" |\n\nA plan id that was only just created, or has just been withdrawn, may take up to ~15 seconds before it is reported as not found.\n\n---\n\n## Response fields\n\n| Field | Type | Description |\n|---|---|---|\n| code | int | Response status code; `1000` when the order was accepted for processing (see **Common error codes** below for others). |\n| message | string | Human-readable summary of the result. |\n| data | object | The created transaction reference. |\n| data.transactionId | string | Id of the newly created transaction. Poll **Get Transaction by ID** with this id to track provisioning. |\n"},"status":"Not Found","code":404,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"cookie":[],"responseTime":null,"body":"{\n  \"code\": 1303,\n  \"message\": \"No results found.\",\n  \"data\": null\n}"},{"id":"ccdd08bd-c93d-4226-9723-716c9ec59c4a","name":"Top-up while eSIM is being replaced","originalRequest":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"body":{"mode":"raw","raw":"{\n  \"externalReference\": \"client-ref-2002\",\n  \"planId\": \"plan_eu_1gb_7d_topup\",\n  \"mainTransactionId\": \"23038\",\n  \"amount\": 20,\n  \"currency\": \"SAR\"\n}","options":{"raw":{"language":"json"}}},"url":"https://eservices.hoicom.net/api/v0/esim/transactions/async","description":"Buys an eSIM plan **asynchronously**. Returns immediately with a `transactionId`; poll **Get Transaction by ID** until `status` is `Completed` to retrieve the eSIM details (ICCID, activation code, QR).\n\nTo buy a **top-up** for an existing eSIM, set `mainTransactionId` to the original transaction id. The target must be **your own `Completed` base plan**; a top-up on any other transaction (another account's, unknown, not yet `Completed`, or itself a top-up) is refused with HTTP 404 / `1303`. If the target eSIM is being replaced (see **Regenerate Transaction**) the top-up is refused with HTTP 409 / `1429`; nothing is created or charged, and a retry after the regeneration completes lands on the new eSIM.\n\n`externalReference` must be unique within your account across all your services; re-using one returns HTTP 409 / `1114`.\n\n---\n\n## Authorization\n\nRequires Basic Authentication with your client credentials. Your account must be enabled for the eSIM service.\n\n---\n\n## Request Body\n\n| Field | Type | Required | Constraints |\n| --- | --- | --- | --- |\n| `externalReference` | `string` | Yes | Your unique id, unique within your account across all services. Max 50 chars. |\n| `planId` | `string` | Yes | Plan (or top-up plan) id. |\n| `mainTransactionId` | `string` | No | For top-ups: the original transaction id (your own `Completed` base plan). Max 50 chars, numeric. |\n| `amount` | `decimal` | Yes | Must be greater than `0`. |\n| `currency` | `string` | No | 3-letter ISO code. |\n\n---\n\n## Response\n\nOn acceptance `code` is `1000` and `data` contains the `transactionId`.\n\n### Common error codes\n\n| Code | Meaning |\n| --- | --- |\n| `1107` | Validation error. |\n| `1413` | Invalid product/plan id. |\n| `1414` | Invalid currency code. |\n| `1114` | HTTP 409. `externalReference` already used by your account. |\n| `1303` | HTTP 404. Top-up target is not your own `Completed` base plan. |\n| `1429` | HTTP 409. The target eSIM is being replaced: \"The eSIM is being replaced; please retry the top-up shortly.\" |\n\nA plan id that was only just created, or has just been withdrawn, may take up to ~15 seconds before it is reported as not found.\n\n---\n\n## Response fields\n\n| Field | Type | Description |\n|---|---|---|\n| code | int | Response status code; `1000` when the order was accepted for processing (see **Common error codes** below for others). |\n| message | string | Human-readable summary of the result. |\n| data | object | The created transaction reference. |\n| data.transactionId | string | Id of the newly created transaction. Poll **Get Transaction by ID** with this id to track provisioning. |\n"},"status":"Conflict","code":409,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"cookie":[],"responseTime":null,"body":"{\n  \"code\": 1429,\n  \"message\": \"The eSIM is being replaced; please retry the top-up shortly.\",\n  \"data\": null\n}"}],"_postman_id":"edd3d7aa-e43f-4195-9d80-ef5df533571b"},{"name":"Get Transaction by ID","id":"8ae8e082-1554-421d-b57e-7cdf515db59f","request":{"method":"GET","header":[],"url":"https://eservices.hoicom.net/api/v0/esim/transactions/:id","description":"<p>Returns a single eSIM transaction, including its <code>status</code> and — once <code>Completed</code> — the eSIM <code>product</code> (ICCID, activation code, SM-DP+ address, matching id, and a base64 <code>qrCode</code>).</p>\n<hr />\n<h2 id=\"authorization\">Authorization</h2>\n<p>Requires Basic Authentication with your client credentials. Your account must be enabled for the eSIM service.</p>\n<hr />\n<h2 id=\"path-parameters\">Path Parameters</h2>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Parameter</th>\n<th>Type</th>\n<th>Required</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>id</code></td>\n<td><code>string</code></td>\n<td>Yes</td>\n<td>Transaction identifier.</td>\n</tr>\n</tbody>\n</table>\n</div><h2 id=\"query-parameters\">Query Parameters</h2>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Parameter</th>\n<th>Type</th>\n<th>Required</th>\n<th>Default</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>include</code></td>\n<td><code>string</code></td>\n<td>No</td>\n<td>—</td>\n<td><code>regenerations</code>: also return the eSIM's regeneration history.</td>\n</tr>\n</tbody>\n</table>\n</div><hr />\n<h2 id=\"response\">Response</h2>\n<p>On success <code>code</code> is <code>1000</code>. <code>status</code> uses the <strong>Transaction status</strong> values and <code>product.planType</code> / <code>product.coverageType</code> the <strong>Product type</strong> / <strong>Coverage type</strong> values (see folder overview).</p>\n<p>Optional <code>include=regenerations</code> adds a <code>regenerations</code> object (see <strong>Regenerate Transaction</strong>). Without it the response is unchanged. After a regeneration completes, <code>product.iccid</code>, <code>activationCode</code>, <code>smdpAddress</code>, <code>matchingId</code>, <code>otp</code> and <code>qrCode</code> carry the <strong>new</strong> eSIM; <code>transactionId</code>, <code>externalReference</code>, <code>amounts</code> and <code>status</code> do not change.</p>\n<hr />\n<h2 id=\"response-fields\">Response fields</h2>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Field</th>\n<th>Type</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>code</td>\n<td>int</td>\n<td>Response status code; <code>1000</code> on success.</td>\n</tr>\n<tr>\n<td>message</td>\n<td>string</td>\n<td>Human-readable summary of the result.</td>\n</tr>\n<tr>\n<td>data</td>\n<td>object</td>\n<td>The transaction.</td>\n</tr>\n<tr>\n<td>data.transactionId</td>\n<td>string</td>\n<td>Transaction identifier.</td>\n</tr>\n<tr>\n<td>data.externalReference</td>\n<td>string</td>\n<td>Your <code>externalReference</code> for the order, if one was supplied.</td>\n</tr>\n<tr>\n<td>data.status</td>\n<td>string (values: Submitted | Pending | Completed | Failed | Cancelled | Refunded)</td>\n<td>Transaction lifecycle status — see <strong>Transaction status</strong> in the folder overview.</td>\n</tr>\n<tr>\n<td>data.timestamp</td>\n<td>object</td>\n<td>Key timestamps for the transaction.</td>\n</tr>\n<tr>\n<td>data.timestamp.requestedAt</td>\n<td>datetime</td>\n<td>When the order was placed.</td>\n</tr>\n<tr>\n<td>data.timestamp.completedAt</td>\n<td>datetime</td>\n<td>When the transaction last changed state; only meaningful once <code>status</code> is a terminal value.</td>\n</tr>\n<tr>\n<td>data.product</td>\n<td>object</td>\n<td>The eSIM product purchased. The identity fields below (<code>iccid</code>, <code>activationCode</code>, <code>smdpAddress</code>, <code>matchingId</code>, <code>qrCode</code>) are blank until <code>status</code> is <code>Completed</code>.</td>\n</tr>\n<tr>\n<td>data.product.id</td>\n<td>string</td>\n<td>Plan (or top-up) id that was purchased.</td>\n</tr>\n<tr>\n<td>data.product.name</td>\n<td>string</td>\n<td>Display name of the plan/top-up.</td>\n</tr>\n<tr>\n<td>data.product.planType</td>\n<td>string (values: Plan | Topup)</td>\n<td>Whether this transaction purchased a primary plan or a top-up — see <strong>Product type</strong> in the folder overview.</td>\n</tr>\n<tr>\n<td>data.product.coverageType</td>\n<td>string (values: LOCAL | REGIONAL | GLOBAL)</td>\n<td>Geographic coverage of the plan — see <strong>Coverage type</strong> in the folder overview.</td>\n</tr>\n<tr>\n<td>data.product.iccid</td>\n<td>string</td>\n<td>The provisioned eSIM's ICCID (SIM serial number). Blank until <code>status</code> is <code>Completed</code>.</td>\n</tr>\n<tr>\n<td>data.product.activationCode</td>\n<td>string</td>\n<td>Activation code for the eSIM profile. Blank until <code>status</code> is <code>Completed</code>.</td>\n</tr>\n<tr>\n<td>data.product.smdpAddress</td>\n<td>string</td>\n<td>SM-DP+ server address, for manual eSIM installation. Blank until <code>status</code> is <code>Completed</code>.</td>\n</tr>\n<tr>\n<td>data.product.matchingId</td>\n<td>string</td>\n<td>Matching id used together with <code>smdpAddress</code> for manual installation. Blank until <code>status</code> is <code>Completed</code>.</td>\n</tr>\n<tr>\n<td>data.product.otp</td>\n<td>string</td>\n<td>One-time passcode required to install the profile, when the network requires one; blank otherwise.</td>\n</tr>\n<tr>\n<td>data.product.qrCode</td>\n<td>string</td>\n<td>Base64-encoded PNG of the QR code the traveller scans to install the eSIM (encodes <code>activationCode</code>/<code>smdpAddress</code> in LPA format). Blank until <code>status</code> is <code>Completed</code>.</td>\n</tr>\n<tr>\n<td>data.amounts</td>\n<td>object</td>\n<td>Amounts for the order.</td>\n</tr>\n<tr>\n<td>data.amounts.requestedAmount</td>\n<td>object</td>\n<td>Amount requested at order time.</td>\n</tr>\n<tr>\n<td>data.amounts.requestedAmount.amount</td>\n<td>decimal</td>\n<td>Requested amount.</td>\n</tr>\n<tr>\n<td>data.amounts.requestedAmount.currency</td>\n<td>string</td>\n<td>3-letter ISO 4217 currency code for <code>requestedAmount.amount</code>.</td>\n</tr>\n<tr>\n<td>data.amounts.deliveredAmount</td>\n<td>object</td>\n<td>Amount actually charged for the order.</td>\n</tr>\n<tr>\n<td>data.amounts.deliveredAmount.amount</td>\n<td>decimal</td>\n<td>Delivered amount.</td>\n</tr>\n<tr>\n<td>data.amounts.deliveredAmount.currency</td>\n<td>string</td>\n<td>3-letter ISO 4217 currency code for <code>deliveredAmount.amount</code>.</td>\n</tr>\n<tr>\n<td>data.amounts.fees</td>\n<td>object</td>\n<td>Additional fee charged on top of the amount, if any.</td>\n</tr>\n<tr>\n<td>data.amounts.fees.totalFee</td>\n<td>decimal</td>\n<td>Total fee amount.</td>\n</tr>\n<tr>\n<td>data.amounts.fees.currency</td>\n<td>string</td>\n<td>3-letter ISO 4217 currency code for <code>fees.totalFee</code>.</td>\n</tr>\n<tr>\n<td>data.pinDetails</td>\n<td>object</td>\n<td>Not used for eSIM orders — always blank; present for response-shape consistency with other Hoi services.</td>\n</tr>\n<tr>\n<td>data.pinDetails.code</td>\n<td>string</td>\n<td>Always blank for eSIM.</td>\n</tr>\n<tr>\n<td>data.pinDetails.serial</td>\n<td>string</td>\n<td>Always blank for eSIM.</td>\n</tr>\n<tr>\n<td>data.pinDetails.validity</td>\n<td>string</td>\n<td>Always blank for eSIM.</td>\n</tr>\n<tr>\n<td>data.pinDetails.additionalInfo</td>\n<td>array of string</td>\n<td>Always empty for eSIM.</td>\n</tr>\n<tr>\n<td>data.receipt</td>\n<td>string</td>\n<td>A receipt summary for the transaction.</td>\n</tr>\n<tr>\n<td>data.regenerations</td>\n<td>object</td>\n<td>Present <strong>only</strong> when <code>include=regenerations</code> was requested.</td>\n</tr>\n<tr>\n<td>data.regenerations.count</td>\n<td>int</td>\n<td>Number of regenerations of this eSIM.</td>\n</tr>\n<tr>\n<td>data.regenerations.inProgress</td>\n<td>bool</td>\n<td><code>true</code> while a regeneration is in progress.</td>\n</tr>\n<tr>\n<td>data.regenerations.items</td>\n<td>array</td>\n<td>The regenerations, ordered by <code>number</code>.</td>\n</tr>\n<tr>\n<td>data.regenerations.items[].number</td>\n<td>int</td>\n<td>1, 2 or 3.</td>\n</tr>\n<tr>\n<td>data.regenerations.items[].reason</td>\n<td>string (values: NotActivated | NotWorking | Other)</td>\n<td>Reason supplied with the request.</td>\n</tr>\n<tr>\n<td>data.regenerations.items[].requestedAt</td>\n<td>datetime</td>\n<td>When the regeneration was requested.</td>\n</tr>\n<tr>\n<td>data.regenerations.items[].completedAt</td>\n<td>datetime</td>\n<td>When it finished; <code>null</code> while in progress.</td>\n</tr>\n<tr>\n<td>data.regenerations.items[].previousIccid</td>\n<td>string</td>\n<td>The replaced eSIM's ICCID, masked (<code>****</code> + last 4 digits).</td>\n</tr>\n<tr>\n<td>data.regenerations.items[].status</td>\n<td>string (values: InProgress | Completed | Failed)</td>\n<td>Outcome of this regeneration.</td>\n</tr>\n</tbody>\n</table>\n</div>","urlObject":{"path":["api","v0","esim","transactions",":id"],"host":["https://eservices.hoicom.net"],"query":[{"disabled":true,"description":{"content":"<p>Optional. <code>regenerations</code> adds the regeneration history.</p>\n","type":"text/plain"},"key":"include","value":""}],"variable":[{"type":"any","value":"","key":"id"}]}},"response":[{"id":"34cffbd6-dc5c-4c81-9652-e40d7c6f1e94","name":"OK","originalRequest":{"method":"GET","header":[],"url":{"raw":"https://eservices.hoicom.net/api/v0/esim/transactions/:id","host":["https://eservices.hoicom.net"],"path":["api","v0","esim","transactions",":id"],"query":[{"key":"include","value":"","description":"Optional. `regenerations` adds the regeneration history.","disabled":true}],"variable":[{"key":"id","value":""}]},"description":"Returns a single eSIM transaction, including its `status` and — once `Completed` — the eSIM `product` (ICCID, activation code, SM-DP+ address, matching id, and a base64 `qrCode`).\n\n---\n\n## Authorization\n\nRequires Basic Authentication with your client credentials. Your account must be enabled for the eSIM service.\n\n---\n\n## Path Parameters\n\n| Parameter | Type | Required | Description |\n| --- | --- | --- | --- |\n| `id` | `string` | Yes | Transaction identifier. |\n\n## Query Parameters\n\n| Parameter | Type | Required | Default | Description |\n| --- | --- | --- | --- | --- |\n| `include` | `string` | No | — | `regenerations`: also return the eSIM's regeneration history. |\n\n---\n\n## Response\n\nOn success `code` is `1000`. `status` uses the **Transaction status** values and `product.planType` / `product.coverageType` the **Product type** / **Coverage type** values (see folder overview).\n\nOptional `include=regenerations` adds a `regenerations` object (see **Regenerate Transaction**). Without it the response is unchanged. After a regeneration completes, `product.iccid`, `activationCode`, `smdpAddress`, `matchingId`, `otp` and `qrCode` carry the **new** eSIM; `transactionId`, `externalReference`, `amounts` and `status` do not change.\n\n---\n\n## Response fields\n\n| Field | Type | Description |\n|---|---|---|\n| code | int | Response status code; `1000` on success. |\n| message | string | Human-readable summary of the result. |\n| data | object | The transaction. |\n| data.transactionId | string | Transaction identifier. |\n| data.externalReference | string | Your `externalReference` for the order, if one was supplied. |\n| data.status | string (values: Submitted \\| Pending \\| Completed \\| Failed \\| Cancelled \\| Refunded) | Transaction lifecycle status — see **Transaction status** in the folder overview. |\n| data.timestamp | object | Key timestamps for the transaction. |\n| data.timestamp.requestedAt | datetime | When the order was placed. |\n| data.timestamp.completedAt | datetime | When the transaction last changed state; only meaningful once `status` is a terminal value. |\n| data.product | object | The eSIM product purchased. The identity fields below (`iccid`, `activationCode`, `smdpAddress`, `matchingId`, `qrCode`) are blank until `status` is `Completed`. |\n| data.product.id | string | Plan (or top-up) id that was purchased. |\n| data.product.name | string | Display name of the plan/top-up. |\n| data.product.planType | string (values: Plan \\| Topup) | Whether this transaction purchased a primary plan or a top-up — see **Product type** in the folder overview. |\n| data.product.coverageType | string (values: LOCAL \\| REGIONAL \\| GLOBAL) | Geographic coverage of the plan — see **Coverage type** in the folder overview. |\n| data.product.iccid | string | The provisioned eSIM's ICCID (SIM serial number). Blank until `status` is `Completed`. |\n| data.product.activationCode | string | Activation code for the eSIM profile. Blank until `status` is `Completed`. |\n| data.product.smdpAddress | string | SM-DP+ server address, for manual eSIM installation. Blank until `status` is `Completed`. |\n| data.product.matchingId | string | Matching id used together with `smdpAddress` for manual installation. Blank until `status` is `Completed`. |\n| data.product.otp | string | One-time passcode required to install the profile, when the network requires one; blank otherwise. |\n| data.product.qrCode | string | Base64-encoded PNG of the QR code the traveller scans to install the eSIM (encodes `activationCode`/`smdpAddress` in LPA format). Blank until `status` is `Completed`. |\n| data.amounts | object | Amounts for the order. |\n| data.amounts.requestedAmount | object | Amount requested at order time. |\n| data.amounts.requestedAmount.amount | decimal | Requested amount. |\n| data.amounts.requestedAmount.currency | string | 3-letter ISO 4217 currency code for `requestedAmount.amount`. |\n| data.amounts.deliveredAmount | object | Amount actually charged for the order. |\n| data.amounts.deliveredAmount.amount | decimal | Delivered amount. |\n| data.amounts.deliveredAmount.currency | string | 3-letter ISO 4217 currency code for `deliveredAmount.amount`. |\n| data.amounts.fees | object | Additional fee charged on top of the amount, if any. |\n| data.amounts.fees.totalFee | decimal | Total fee amount. |\n| data.amounts.fees.currency | string | 3-letter ISO 4217 currency code for `fees.totalFee`. |\n| data.pinDetails | object | Not used for eSIM orders — always blank; present for response-shape consistency with other Hoi services. |\n| data.pinDetails.code | string | Always blank for eSIM. |\n| data.pinDetails.serial | string | Always blank for eSIM. |\n| data.pinDetails.validity | string | Always blank for eSIM. |\n| data.pinDetails.additionalInfo | array of string | Always empty for eSIM. |\n| data.receipt | string | A receipt summary for the transaction. |\n| data.regenerations | object | Present **only** when `include=regenerations` was requested. |\n| data.regenerations.count | int | Number of regenerations of this eSIM. |\n| data.regenerations.inProgress | bool | `true` while a regeneration is in progress. |\n| data.regenerations.items | array | The regenerations, ordered by `number`. |\n| data.regenerations.items[].number | int | 1, 2 or 3. |\n| data.regenerations.items[].reason | string (values: NotActivated \\| NotWorking \\| Other) | Reason supplied with the request. |\n| data.regenerations.items[].requestedAt | datetime | When the regeneration was requested. |\n| data.regenerations.items[].completedAt | datetime | When it finished; `null` while in progress. |\n| data.regenerations.items[].previousIccid | string | The replaced eSIM's ICCID, masked (`****` + last 4 digits). |\n| data.regenerations.items[].status | string (values: InProgress \\| Completed \\| Failed) | Outcome of this regeneration. |\n"},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"cookie":[],"responseTime":null,"body":"{\n  \"code\": 1000,\n  \"message\": \"Success\",\n  \"data\": {\n    \"transactionId\": \"esim_txn_5a1b2c3d\",\n    \"externalReference\": \"client-ref-2001\",\n    \"status\": \"Completed\",\n    \"timestamp\": {\n      \"requestedAt\": \"2026-07-01T09:30:00Z\",\n      \"completedAt\": \"2026-07-01T09:31:12Z\"\n    },\n    \"product\": {\n      \"id\": \"plan_eu_5gb_30d\",\n      \"name\": \"Europe 5GB - 30 Days\",\n      \"planType\": \"Plan\",\n      \"coverageType\": \"REGIONAL\",\n      \"iccid\": \"8944000000000000000\",\n      \"activationCode\": \"LPA:1$smdp.example.com$ABC123\",\n      \"smdpAddress\": \"smdp.example.com\",\n      \"matchingId\": \"ABC123\",\n      \"otp\": \"\",\n      \"qrCode\": \"iVBORw0KGgoAAAANSUhEUgAA...(base64-encoded PNG)\"\n    },\n    \"amounts\": {\n      \"requestedAmount\": {\n        \"amount\": 75,\n        \"currency\": \"INR\"\n      },\n      \"deliveredAmount\": {\n        \"amount\": 75,\n        \"currency\": \"INR\"\n      },\n      \"fees\": {\n        \"totalFee\": 0,\n        \"currency\": \"INR\"\n      }\n    },\n    \"pinDetails\": {\n      \"code\": \"\",\n      \"serial\": \"\",\n      \"validity\": \"\",\n      \"additionalInfo\": []\n    },\n    \"receipt\": \"https://cdn.example.com/receipts/esim_txn_5a1b2c3d.pdf\"\n  }\n}"},{"id":"33658610-4cfd-4895-9d6b-4571851dbf63","name":"OK (include=regenerations)","originalRequest":{"method":"GET","header":[],"url":{"raw":"https://eservices.hoicom.net/api/v0/esim/transactions/:id?include=regenerations","host":["https://eservices.hoicom.net"],"path":["api","v0","esim","transactions",":id"],"query":[{"key":"include","value":"regenerations"}],"variable":[{"key":"id","value":""}]},"description":"Returns a single eSIM transaction, including its `status` and — once `Completed` — the eSIM `product` (ICCID, activation code, SM-DP+ address, matching id, and a base64 `qrCode`).\n\n---\n\n## Authorization\n\nRequires Basic Authentication with your client credentials. Your account must be enabled for the eSIM service.\n\n---\n\n## Path Parameters\n\n| Parameter | Type | Required | Description |\n| --- | --- | --- | --- |\n| `id` | `string` | Yes | Transaction identifier. |\n\n## Query Parameters\n\n| Parameter | Type | Required | Default | Description |\n| --- | --- | --- | --- | --- |\n| `include` | `string` | No | — | `regenerations`: also return the eSIM's regeneration history. |\n\n---\n\n## Response\n\nOn success `code` is `1000`. `status` uses the **Transaction status** values and `product.planType` / `product.coverageType` the **Product type** / **Coverage type** values (see folder overview).\n\nOptional `include=regenerations` adds a `regenerations` object (see **Regenerate Transaction**). Without it the response is unchanged. After a regeneration completes, `product.iccid`, `activationCode`, `smdpAddress`, `matchingId`, `otp` and `qrCode` carry the **new** eSIM; `transactionId`, `externalReference`, `amounts` and `status` do not change.\n\n---\n\n## Response fields\n\n| Field | Type | Description |\n|---|---|---|\n| code | int | Response status code; `1000` on success. |\n| message | string | Human-readable summary of the result. |\n| data | object | The transaction. |\n| data.transactionId | string | Transaction identifier. |\n| data.externalReference | string | Your `externalReference` for the order, if one was supplied. |\n| data.status | string (values: Submitted \\| Pending \\| Completed \\| Failed \\| Cancelled \\| Refunded) | Transaction lifecycle status — see **Transaction status** in the folder overview. |\n| data.timestamp | object | Key timestamps for the transaction. |\n| data.timestamp.requestedAt | datetime | When the order was placed. |\n| data.timestamp.completedAt | datetime | When the transaction last changed state; only meaningful once `status` is a terminal value. |\n| data.product | object | The eSIM product purchased. The identity fields below (`iccid`, `activationCode`, `smdpAddress`, `matchingId`, `qrCode`) are blank until `status` is `Completed`. |\n| data.product.id | string | Plan (or top-up) id that was purchased. |\n| data.product.name | string | Display name of the plan/top-up. |\n| data.product.planType | string (values: Plan \\| Topup) | Whether this transaction purchased a primary plan or a top-up — see **Product type** in the folder overview. |\n| data.product.coverageType | string (values: LOCAL \\| REGIONAL \\| GLOBAL) | Geographic coverage of the plan — see **Coverage type** in the folder overview. |\n| data.product.iccid | string | The provisioned eSIM's ICCID (SIM serial number). Blank until `status` is `Completed`. |\n| data.product.activationCode | string | Activation code for the eSIM profile. Blank until `status` is `Completed`. |\n| data.product.smdpAddress | string | SM-DP+ server address, for manual eSIM installation. Blank until `status` is `Completed`. |\n| data.product.matchingId | string | Matching id used together with `smdpAddress` for manual installation. Blank until `status` is `Completed`. |\n| data.product.otp | string | One-time passcode required to install the profile, when the network requires one; blank otherwise. |\n| data.product.qrCode | string | Base64-encoded PNG of the QR code the traveller scans to install the eSIM (encodes `activationCode`/`smdpAddress` in LPA format). Blank until `status` is `Completed`. |\n| data.amounts | object | Amounts for the order. |\n| data.amounts.requestedAmount | object | Amount requested at order time. |\n| data.amounts.requestedAmount.amount | decimal | Requested amount. |\n| data.amounts.requestedAmount.currency | string | 3-letter ISO 4217 currency code for `requestedAmount.amount`. |\n| data.amounts.deliveredAmount | object | Amount actually charged for the order. |\n| data.amounts.deliveredAmount.amount | decimal | Delivered amount. |\n| data.amounts.deliveredAmount.currency | string | 3-letter ISO 4217 currency code for `deliveredAmount.amount`. |\n| data.amounts.fees | object | Additional fee charged on top of the amount, if any. |\n| data.amounts.fees.totalFee | decimal | Total fee amount. |\n| data.amounts.fees.currency | string | 3-letter ISO 4217 currency code for `fees.totalFee`. |\n| data.pinDetails | object | Not used for eSIM orders — always blank; present for response-shape consistency with other Hoi services. |\n| data.pinDetails.code | string | Always blank for eSIM. |\n| data.pinDetails.serial | string | Always blank for eSIM. |\n| data.pinDetails.validity | string | Always blank for eSIM. |\n| data.pinDetails.additionalInfo | array of string | Always empty for eSIM. |\n| data.receipt | string | A receipt summary for the transaction. |\n| data.regenerations | object | Present **only** when `include=regenerations` was requested. |\n| data.regenerations.count | int | Number of regenerations of this eSIM. |\n| data.regenerations.inProgress | bool | `true` while a regeneration is in progress. |\n| data.regenerations.items | array | The regenerations, ordered by `number`. |\n| data.regenerations.items[].number | int | 1, 2 or 3. |\n| data.regenerations.items[].reason | string (values: NotActivated \\| NotWorking \\| Other) | Reason supplied with the request. |\n| data.regenerations.items[].requestedAt | datetime | When the regeneration was requested. |\n| data.regenerations.items[].completedAt | datetime | When it finished; `null` while in progress. |\n| data.regenerations.items[].previousIccid | string | The replaced eSIM's ICCID, masked (`****` + last 4 digits). |\n| data.regenerations.items[].status | string (values: InProgress \\| Completed \\| Failed) | Outcome of this regeneration. |\n"},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"cookie":[],"responseTime":null,"body":"{\n  \"code\": 1000,\n  \"message\": \"Success\",\n  \"data\": {\n    \"transactionId\": \"esim_txn_5a1b2c3d\",\n    \"externalReference\": \"client-ref-2001\",\n    \"status\": \"Completed\",\n    \"timestamp\": {\n      \"requestedAt\": \"2026-07-01T09:30:00Z\",\n      \"completedAt\": \"2026-07-01T09:31:12Z\"\n    },\n    \"product\": {\n      \"id\": \"plan_eu_5gb_30d\",\n      \"name\": \"Europe 5GB - 30 Days\",\n      \"planType\": \"Plan\",\n      \"coverageType\": \"REGIONAL\",\n      \"iccid\": \"8944000000000000000\",\n      \"activationCode\": \"LPA:1$smdp.example.com$ABC123\",\n      \"smdpAddress\": \"smdp.example.com\",\n      \"matchingId\": \"ABC123\",\n      \"otp\": \"\",\n      \"qrCode\": \"iVBORw0KGgoAAAANSUhEUgAA...(base64-encoded PNG)\"\n    },\n    \"amounts\": {\n      \"requestedAmount\": {\n        \"amount\": 75,\n        \"currency\": \"INR\"\n      },\n      \"deliveredAmount\": {\n        \"amount\": 75,\n        \"currency\": \"INR\"\n      },\n      \"fees\": {\n        \"totalFee\": 0,\n        \"currency\": \"INR\"\n      }\n    },\n    \"pinDetails\": {\n      \"code\": \"\",\n      \"serial\": \"\",\n      \"validity\": \"\",\n      \"additionalInfo\": []\n    },\n    \"receipt\": \"https://cdn.example.com/receipts/esim_txn_5a1b2c3d.pdf\",\n    \"regenerations\": {\n      \"count\": 1,\n      \"inProgress\": false,\n      \"items\": [\n        {\n          \"number\": 1,\n          \"reason\": \"NotWorking\",\n          \"requestedAt\": \"2026-09-30T08:57:55Z\",\n          \"completedAt\": \"2026-09-30T08:57:57Z\",\n          \"previousIccid\": \"****9910\",\n          \"status\": \"Completed\"\n        }\n      ]\n    }\n  }\n}"}],"_postman_id":"8ae8e082-1554-421d-b57e-7cdf515db59f"},{"name":"Get Transactions","id":"9b03fe91-e462-43e3-9e2e-733f1b943983","request":{"method":"GET","header":[],"url":"https://eservices.hoicom.net/api/v0/esim/Transactions?transactionId=&externalReference=&status=Completed&fromDate=&toDate=&page=1&pageSize=50","description":"<p>Returns a paginated, filterable list of your eSIM transactions.</p>\n<hr />\n<h2 id=\"authorization\">Authorization</h2>\n<p>Requires Basic Authentication with your client credentials. Your account must be enabled for the eSIM service.</p>\n<hr />\n<h2 id=\"query-parameters\">Query Parameters</h2>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Parameter</th>\n<th>Type</th>\n<th>Required</th>\n<th>Default</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>transactionId</code></td>\n<td><code>string</code></td>\n<td>No</td>\n<td>—</td>\n<td>Filter by transaction id.</td>\n</tr>\n<tr>\n<td><code>externalReference</code></td>\n<td><code>string</code></td>\n<td>No</td>\n<td>—</td>\n<td>Filter by your external reference.</td>\n</tr>\n<tr>\n<td><code>status</code></td>\n<td><code>string</code></td>\n<td>No</td>\n<td>—</td>\n<td>Filter by status: <code>Submitted</code>, <code>Pending</code>, <code>Completed</code>, <code>Failed</code>, <code>Cancelled</code> or <code>Refunded</code>.</td>\n</tr>\n<tr>\n<td><code>fromDate</code></td>\n<td><code>datetime</code></td>\n<td>No</td>\n<td>—</td>\n<td>Start of creation-date range.</td>\n</tr>\n<tr>\n<td><code>toDate</code></td>\n<td><code>datetime</code></td>\n<td>No</td>\n<td>—</td>\n<td>End of creation-date range.</td>\n</tr>\n<tr>\n<td><code>page</code></td>\n<td><code>int</code></td>\n<td>No</td>\n<td><code>1</code></td>\n<td>Page number.</td>\n</tr>\n<tr>\n<td><code>pageSize</code></td>\n<td><code>int</code></td>\n<td>No</td>\n<td><code>50</code></td>\n<td>Items per page.</td>\n</tr>\n<tr>\n<td><code>include</code></td>\n<td><code>string</code></td>\n<td>No</td>\n<td>—</td>\n<td><code>regenerations</code>: add each eSIM's regeneration history to every item.</td>\n</tr>\n</tbody>\n</table>\n</div><hr />\n<h2 id=\"response\">Response</h2>\n<p>On success <code>code</code> is <code>1000</code> and <code>data</code> is a paginated list of transactions. Valid <code>status</code> values: <code>Submitted</code>, <code>Pending</code>, <code>Completed</code>, <code>Failed</code>, <code>Cancelled</code>, <code>Refunded</code>.</p>\n<p>Optional <code>include=regenerations</code> adds a <code>regenerations</code> object (see <strong>Regenerate Transaction</strong>). Without it the response is unchanged. After a regeneration completes, <code>product.iccid</code>, <code>activationCode</code>, <code>smdpAddress</code>, <code>matchingId</code>, <code>otp</code> and <code>qrCode</code> carry the <strong>new</strong> eSIM; <code>transactionId</code>, <code>externalReference</code>, <code>amounts</code> and <code>status</code> do not change. With <code>include</code>, the <code>regenerations</code> object is added to every item (<code>data.items[].regenerations</code>, same shape).</p>\n<hr />\n<h2 id=\"response-fields\">Response fields</h2>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Field</th>\n<th>Type</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>code</td>\n<td>int</td>\n<td>Response status code; <code>1000</code> on success.</td>\n</tr>\n<tr>\n<td>message</td>\n<td>string</td>\n<td>Human-readable summary of the result.</td>\n</tr>\n<tr>\n<td>data</td>\n<td>object</td>\n<td>Paginated, filtered list of your eSIM transactions.</td>\n</tr>\n<tr>\n<td>data.items</td>\n<td>array</td>\n<td>Transactions for the current page.</td>\n</tr>\n<tr>\n<td>data.items[].transactionId</td>\n<td>string</td>\n<td>Transaction identifier.</td>\n</tr>\n<tr>\n<td>data.items[].externalReference</td>\n<td>string</td>\n<td>Your <code>externalReference</code> for the order, if one was supplied.</td>\n</tr>\n<tr>\n<td>data.items[].status</td>\n<td>string (values: Submitted | Pending | Completed | Failed | Cancelled | Refunded)</td>\n<td>Transaction lifecycle status — see <strong>Transaction status</strong> in the folder overview.</td>\n</tr>\n<tr>\n<td>data.items[].timestamp</td>\n<td>object</td>\n<td>Key timestamps for the transaction.</td>\n</tr>\n<tr>\n<td>data.items[].timestamp.requestedAt</td>\n<td>datetime</td>\n<td>When the order was placed.</td>\n</tr>\n<tr>\n<td>data.items[].timestamp.completedAt</td>\n<td>datetime</td>\n<td>When the transaction last changed state; only meaningful once <code>status</code> is a terminal value.</td>\n</tr>\n<tr>\n<td>data.items[].product</td>\n<td>object</td>\n<td>The eSIM product purchased. The identity fields below are blank until <code>status</code> is <code>Completed</code>.</td>\n</tr>\n<tr>\n<td>data.items[].product.id</td>\n<td>string</td>\n<td>Plan (or top-up) id that was purchased.</td>\n</tr>\n<tr>\n<td>data.items[].product.name</td>\n<td>string</td>\n<td>Display name of the plan/top-up.</td>\n</tr>\n<tr>\n<td>data.items[].product.planType</td>\n<td>string (values: Plan | Topup)</td>\n<td>Whether this transaction purchased a primary plan or a top-up — see <strong>Product type</strong> in the folder overview.</td>\n</tr>\n<tr>\n<td>data.items[].product.coverageType</td>\n<td>string (values: LOCAL | REGIONAL | GLOBAL)</td>\n<td>Geographic coverage of the plan — see <strong>Coverage type</strong> in the folder overview.</td>\n</tr>\n<tr>\n<td>data.items[].product.iccid</td>\n<td>string</td>\n<td>The provisioned eSIM's ICCID (SIM serial number). Blank until <code>status</code> is <code>Completed</code>.</td>\n</tr>\n<tr>\n<td>data.items[].product.activationCode</td>\n<td>string</td>\n<td>Activation code for the eSIM profile. Blank until <code>status</code> is <code>Completed</code>.</td>\n</tr>\n<tr>\n<td>data.items[].product.smdpAddress</td>\n<td>string</td>\n<td>SM-DP+ server address, for manual eSIM installation. Blank until <code>status</code> is <code>Completed</code>.</td>\n</tr>\n<tr>\n<td>data.items[].product.matchingId</td>\n<td>string</td>\n<td>Matching id used together with <code>smdpAddress</code> for manual installation. Blank until <code>status</code> is <code>Completed</code>.</td>\n</tr>\n<tr>\n<td>data.items[].product.otp</td>\n<td>string</td>\n<td>One-time passcode required to install the profile, when the network requires one; blank otherwise.</td>\n</tr>\n<tr>\n<td>data.items[].product.qrCode</td>\n<td>string</td>\n<td>Base64-encoded PNG of the QR code the traveller scans to install the eSIM. Blank until <code>status</code> is <code>Completed</code>.</td>\n</tr>\n<tr>\n<td>data.items[].amounts</td>\n<td>object</td>\n<td>Amounts for the order.</td>\n</tr>\n<tr>\n<td>data.items[].amounts.requestedAmount</td>\n<td>object</td>\n<td>Amount requested at order time.</td>\n</tr>\n<tr>\n<td>data.items[].amounts.requestedAmount.amount</td>\n<td>decimal</td>\n<td>Requested amount.</td>\n</tr>\n<tr>\n<td>data.items[].amounts.requestedAmount.currency</td>\n<td>string</td>\n<td>3-letter ISO 4217 currency code for <code>requestedAmount.amount</code>.</td>\n</tr>\n<tr>\n<td>data.items[].amounts.deliveredAmount</td>\n<td>object</td>\n<td>Amount actually charged for the order.</td>\n</tr>\n<tr>\n<td>data.items[].amounts.deliveredAmount.amount</td>\n<td>decimal</td>\n<td>Delivered amount.</td>\n</tr>\n<tr>\n<td>data.items[].amounts.deliveredAmount.currency</td>\n<td>string</td>\n<td>3-letter ISO 4217 currency code for <code>deliveredAmount.amount</code>.</td>\n</tr>\n<tr>\n<td>data.items[].amounts.fees</td>\n<td>object</td>\n<td>Additional fee charged on top of the amount, if any.</td>\n</tr>\n<tr>\n<td>data.items[].amounts.fees.totalFee</td>\n<td>decimal</td>\n<td>Total fee amount.</td>\n</tr>\n<tr>\n<td>data.items[].amounts.fees.currency</td>\n<td>string</td>\n<td>3-letter ISO 4217 currency code for <code>fees.totalFee</code>.</td>\n</tr>\n<tr>\n<td>data.items[].pinDetails</td>\n<td>object</td>\n<td>Not used for eSIM orders — always blank; present for response-shape consistency with other Hoi services.</td>\n</tr>\n<tr>\n<td>data.items[].pinDetails.code</td>\n<td>string</td>\n<td>Always blank for eSIM.</td>\n</tr>\n<tr>\n<td>data.items[].pinDetails.serial</td>\n<td>string</td>\n<td>Always blank for eSIM.</td>\n</tr>\n<tr>\n<td>data.items[].pinDetails.validity</td>\n<td>string</td>\n<td>Always blank for eSIM.</td>\n</tr>\n<tr>\n<td>data.items[].pinDetails.additionalInfo</td>\n<td>array of string</td>\n<td>Always empty for eSIM.</td>\n</tr>\n<tr>\n<td>data.items[].receipt</td>\n<td>string</td>\n<td>A receipt summary for the transaction.</td>\n</tr>\n<tr>\n<td>data.items[].regenerations</td>\n<td>object</td>\n<td>Present <strong>only</strong> when <code>include=regenerations</code> was requested.</td>\n</tr>\n<tr>\n<td>data.items[].regenerations.count</td>\n<td>int</td>\n<td>Number of regenerations of this eSIM.</td>\n</tr>\n<tr>\n<td>data.items[].regenerations.inProgress</td>\n<td>bool</td>\n<td><code>true</code> while a regeneration is in progress.</td>\n</tr>\n<tr>\n<td>data.items[].regenerations.items</td>\n<td>array</td>\n<td>The regenerations, ordered by <code>number</code>.</td>\n</tr>\n<tr>\n<td>data.items[].regenerations.items[].number</td>\n<td>int</td>\n<td>1, 2 or 3.</td>\n</tr>\n<tr>\n<td>data.items[].regenerations.items[].reason</td>\n<td>string (values: NotActivated | NotWorking | Other)</td>\n<td>Reason supplied with the request.</td>\n</tr>\n<tr>\n<td>data.items[].regenerations.items[].requestedAt</td>\n<td>datetime</td>\n<td>When the regeneration was requested.</td>\n</tr>\n<tr>\n<td>data.items[].regenerations.items[].completedAt</td>\n<td>datetime</td>\n<td>When it finished; <code>null</code> while in progress.</td>\n</tr>\n<tr>\n<td>data.items[].regenerations.items[].previousIccid</td>\n<td>string</td>\n<td>The replaced eSIM's ICCID, masked (<code>****</code> + last 4 digits).</td>\n</tr>\n<tr>\n<td>data.items[].regenerations.items[].status</td>\n<td>string (values: InProgress | Completed | Failed)</td>\n<td>Outcome of this regeneration.</td>\n</tr>\n<tr>\n<td>data.count</td>\n<td>int</td>\n<td>Number of items returned on this page (not the total across all pages).</td>\n</tr>\n<tr>\n<td>data.page</td>\n<td>int</td>\n<td>Current page number.</td>\n</tr>\n<tr>\n<td>data.pageSize</td>\n<td>int</td>\n<td>Number of items requested per page.</td>\n</tr>\n<tr>\n<td>data.totalPages</td>\n<td>int</td>\n<td>Total number of pages available for the current filters.</td>\n</tr>\n<tr>\n<td>data.totalItems</td>\n<td>int</td>\n<td>Total number of transactions matching the filters, across all pages.</td>\n</tr>\n</tbody>\n</table>\n</div>","urlObject":{"path":["api","v0","esim","Transactions"],"host":["https://eservices.hoicom.net"],"query":[{"key":"transactionId","value":""},{"key":"externalReference","value":""},{"description":{"content":"<p>Enum name, e.g. Completed.</p>\n","type":"text/plain"},"key":"status","value":"Completed"},{"key":"fromDate","value":""},{"key":"toDate","value":""},{"key":"page","value":"1"},{"key":"pageSize","value":"50"},{"disabled":true,"description":{"content":"<p>Optional. <code>regenerations</code> adds the regeneration history.</p>\n","type":"text/plain"},"key":"include","value":""}],"variable":[]}},"response":[{"id":"bde2f812-5cad-4a7e-8d95-00c341667d14","name":"OK","originalRequest":{"method":"GET","header":[],"url":{"raw":"https://eservices.hoicom.net/api/v0/esim/Transactions?transactionId=&externalReference=&status=Completed&fromDate=&toDate=&page=1&pageSize=50","host":["https://eservices.hoicom.net"],"path":["api","v0","esim","Transactions"],"query":[{"key":"transactionId","value":""},{"key":"externalReference","value":""},{"key":"status","value":"Completed","description":"Enum name, e.g. Completed."},{"key":"fromDate","value":""},{"key":"toDate","value":""},{"key":"page","value":"1"},{"key":"pageSize","value":"50"},{"key":"include","value":"","description":"Optional. `regenerations` adds the regeneration history.","disabled":true}]},"description":"Returns a paginated, filterable list of your eSIM transactions.\n\n---\n\n## Authorization\n\nRequires Basic Authentication with your client credentials. Your account must be enabled for the eSIM service.\n\n---\n\n## Query Parameters\n\n| Parameter | Type | Required | Default | Description |\n| --- | --- | --- | --- | --- |\n| `transactionId` | `string` | No | — | Filter by transaction id. |\n| `externalReference` | `string` | No | — | Filter by your external reference. |\n| `status` | `string` | No | — | Filter by status: `Submitted`, `Pending`, `Completed`, `Failed`, `Cancelled` or `Refunded`. |\n| `fromDate` | `datetime` | No | — | Start of creation-date range. |\n| `toDate` | `datetime` | No | — | End of creation-date range. |\n| `page` | `int` | No | `1` | Page number. |\n| `pageSize` | `int` | No | `50` | Items per page. |\n| `include` | `string` | No | — | `regenerations`: add each eSIM's regeneration history to every item. |\n\n---\n\n## Response\n\nOn success `code` is `1000` and `data` is a paginated list of transactions. Valid `status` values: `Submitted`, `Pending`, `Completed`, `Failed`, `Cancelled`, `Refunded`.\n\nOptional `include=regenerations` adds a `regenerations` object (see **Regenerate Transaction**). Without it the response is unchanged. After a regeneration completes, `product.iccid`, `activationCode`, `smdpAddress`, `matchingId`, `otp` and `qrCode` carry the **new** eSIM; `transactionId`, `externalReference`, `amounts` and `status` do not change. With `include`, the `regenerations` object is added to every item (`data.items[].regenerations`, same shape).\n\n---\n\n## Response fields\n\n| Field | Type | Description |\n|---|---|---|\n| code | int | Response status code; `1000` on success. |\n| message | string | Human-readable summary of the result. |\n| data | object | Paginated, filtered list of your eSIM transactions. |\n| data.items | array | Transactions for the current page. |\n| data.items[].transactionId | string | Transaction identifier. |\n| data.items[].externalReference | string | Your `externalReference` for the order, if one was supplied. |\n| data.items[].status | string (values: Submitted \\| Pending \\| Completed \\| Failed \\| Cancelled \\| Refunded) | Transaction lifecycle status — see **Transaction status** in the folder overview. |\n| data.items[].timestamp | object | Key timestamps for the transaction. |\n| data.items[].timestamp.requestedAt | datetime | When the order was placed. |\n| data.items[].timestamp.completedAt | datetime | When the transaction last changed state; only meaningful once `status` is a terminal value. |\n| data.items[].product | object | The eSIM product purchased. The identity fields below are blank until `status` is `Completed`. |\n| data.items[].product.id | string | Plan (or top-up) id that was purchased. |\n| data.items[].product.name | string | Display name of the plan/top-up. |\n| data.items[].product.planType | string (values: Plan \\| Topup) | Whether this transaction purchased a primary plan or a top-up — see **Product type** in the folder overview. |\n| data.items[].product.coverageType | string (values: LOCAL \\| REGIONAL \\| GLOBAL) | Geographic coverage of the plan — see **Coverage type** in the folder overview. |\n| data.items[].product.iccid | string | The provisioned eSIM's ICCID (SIM serial number). Blank until `status` is `Completed`. |\n| data.items[].product.activationCode | string | Activation code for the eSIM profile. Blank until `status` is `Completed`. |\n| data.items[].product.smdpAddress | string | SM-DP+ server address, for manual eSIM installation. Blank until `status` is `Completed`. |\n| data.items[].product.matchingId | string | Matching id used together with `smdpAddress` for manual installation. Blank until `status` is `Completed`. |\n| data.items[].product.otp | string | One-time passcode required to install the profile, when the network requires one; blank otherwise. |\n| data.items[].product.qrCode | string | Base64-encoded PNG of the QR code the traveller scans to install the eSIM. Blank until `status` is `Completed`. |\n| data.items[].amounts | object | Amounts for the order. |\n| data.items[].amounts.requestedAmount | object | Amount requested at order time. |\n| data.items[].amounts.requestedAmount.amount | decimal | Requested amount. |\n| data.items[].amounts.requestedAmount.currency | string | 3-letter ISO 4217 currency code for `requestedAmount.amount`. |\n| data.items[].amounts.deliveredAmount | object | Amount actually charged for the order. |\n| data.items[].amounts.deliveredAmount.amount | decimal | Delivered amount. |\n| data.items[].amounts.deliveredAmount.currency | string | 3-letter ISO 4217 currency code for `deliveredAmount.amount`. |\n| data.items[].amounts.fees | object | Additional fee charged on top of the amount, if any. |\n| data.items[].amounts.fees.totalFee | decimal | Total fee amount. |\n| data.items[].amounts.fees.currency | string | 3-letter ISO 4217 currency code for `fees.totalFee`. |\n| data.items[].pinDetails | object | Not used for eSIM orders — always blank; present for response-shape consistency with other Hoi services. |\n| data.items[].pinDetails.code | string | Always blank for eSIM. |\n| data.items[].pinDetails.serial | string | Always blank for eSIM. |\n| data.items[].pinDetails.validity | string | Always blank for eSIM. |\n| data.items[].pinDetails.additionalInfo | array of string | Always empty for eSIM. |\n| data.items[].receipt | string | A receipt summary for the transaction. |\n| data.items[].regenerations | object | Present **only** when `include=regenerations` was requested. |\n| data.items[].regenerations.count | int | Number of regenerations of this eSIM. |\n| data.items[].regenerations.inProgress | bool | `true` while a regeneration is in progress. |\n| data.items[].regenerations.items | array | The regenerations, ordered by `number`. |\n| data.items[].regenerations.items[].number | int | 1, 2 or 3. |\n| data.items[].regenerations.items[].reason | string (values: NotActivated \\| NotWorking \\| Other) | Reason supplied with the request. |\n| data.items[].regenerations.items[].requestedAt | datetime | When the regeneration was requested. |\n| data.items[].regenerations.items[].completedAt | datetime | When it finished; `null` while in progress. |\n| data.items[].regenerations.items[].previousIccid | string | The replaced eSIM's ICCID, masked (`****` + last 4 digits). |\n| data.items[].regenerations.items[].status | string (values: InProgress \\| Completed \\| Failed) | Outcome of this regeneration. |\n| data.count | int | Number of items returned on this page (not the total across all pages). |\n| data.page | int | Current page number. |\n| data.pageSize | int | Number of items requested per page. |\n| data.totalPages | int | Total number of pages available for the current filters. |\n| data.totalItems | int | Total number of transactions matching the filters, across all pages. |\n"},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"cookie":[],"responseTime":null,"body":"{\n  \"code\": 1000,\n  \"message\": \"Success\",\n  \"data\": {\n    \"items\": [\n      {\n        \"transactionId\": \"esim_txn_5a1b2c3d\",\n        \"externalReference\": \"client-ref-2001\",\n        \"status\": \"Completed\",\n        \"timestamp\": {\n          \"requestedAt\": \"2026-07-01T09:30:00Z\",\n          \"completedAt\": \"2026-07-01T09:31:12Z\"\n        },\n        \"product\": {\n          \"id\": \"plan_eu_5gb_30d\",\n          \"name\": \"Europe 5GB - 30 Days\",\n          \"planType\": \"Plan\",\n          \"coverageType\": \"REGIONAL\",\n          \"iccid\": \"8944000000000000000\",\n          \"activationCode\": \"LPA:1$smdp.example.com$ABC123\",\n          \"smdpAddress\": \"smdp.example.com\",\n          \"matchingId\": \"ABC123\",\n          \"otp\": \"\",\n          \"qrCode\": \"iVBORw0KGgoAAAANSUhEUgAA...(base64-encoded PNG)\"\n        },\n        \"amounts\": {\n          \"requestedAmount\": {\n            \"amount\": 75,\n            \"currency\": \"INR\"\n          },\n          \"deliveredAmount\": {\n            \"amount\": 75,\n            \"currency\": \"INR\"\n          },\n          \"fees\": {\n            \"totalFee\": 0,\n            \"currency\": \"INR\"\n          }\n        },\n        \"pinDetails\": {\n          \"code\": \"\",\n          \"serial\": \"\",\n          \"validity\": \"\",\n          \"additionalInfo\": []\n        },\n        \"receipt\": \"https://cdn.example.com/receipts/esim_txn_5a1b2c3d.pdf\"\n      }\n    ],\n    \"count\": 1,\n    \"page\": 1,\n    \"pageSize\": 50,\n    \"totalPages\": 1,\n    \"totalItems\": 1\n  }\n}"}],"_postman_id":"9b03fe91-e462-43e3-9e2e-733f1b943983"}],"id":"42638444-3bb2-4cec-bb14-328ad5fbc94e","description":"<p>Buy an eSIM plan or a top-up, then look up your purchases. Purchases are asynchronous: poll <strong>Get Transaction by ID</strong> until <code>status</code> is <code>Completed</code> to get the eSIM details.</p>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Method</th>\n<th>Endpoint</th>\n<th>Request</th>\n<th>Purpose</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>POST</code></td>\n<td><code>/api/v0/esim/transactions/async</code></td>\n<td><strong>Create Transaction</strong></td>\n<td>Buy a plan, or a top-up (set <code>mainTransactionId</code>).</td>\n</tr>\n<tr>\n<td><code>GET</code></td>\n<td><code>/api/v0/esim/transactions/{id}</code></td>\n<td><strong>Get Transaction by ID</strong></td>\n<td>One transaction, with the eSIM details once <code>Completed</code>.</td>\n</tr>\n<tr>\n<td><code>GET</code></td>\n<td><code>/api/v0/esim/Transactions</code></td>\n<td><strong>Get Transactions</strong></td>\n<td>Your transactions, filtered and paged.</td>\n</tr>\n</tbody>\n</table>\n</div>","_postman_id":"42638444-3bb2-4cec-bb14-328ad5fbc94e"},{"name":"Consumption","item":[{"name":"Get Plan Usage by Transaction","id":"11f4d60a-0381-439f-95d0-0951693a6d4f","request":{"method":"GET","header":[],"url":"https://eservices.hoicom.net/api/v0/esim/transactions/:id/plans/usage","description":"<p>Returns live data-usage details for the plan attached to a transaction.</p>\n<p><strong>Data units.</strong> Data amounts are normalised: allowances of 1 GB or more are shown in decimal GB (a 1024 MB plan reads <code>1 GB</code>, 512 MB reads <code>500 MB</code>), smaller ones in MB. Do not assume a fixed unit; always read <code>unit</code>. <code>dataUnit</code> tells you which unit the data fields use.</p>\n<hr />\n<h2 id=\"authorization\">Authorization</h2>\n<p>Requires Basic Authentication with your client credentials. Your account must be enabled for the eSIM service.</p>\n<hr />\n<h2 id=\"path-parameters\">Path Parameters</h2>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Parameter</th>\n<th>Type</th>\n<th>Required</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>id</code></td>\n<td><code>string</code></td>\n<td>Yes</td>\n<td>Transaction identifier.</td>\n</tr>\n</tbody>\n</table>\n</div><hr />\n<h2 id=\"response\">Response</h2>\n<p>On success <code>code</code> is <code>1000</code>. <code>planStatus</code> uses the <strong>Plan status</strong> values and <code>esimStatus</code> the <strong>eSIM status</strong> values (see folder overview).</p>\n<hr />\n<h2 id=\"response-fields\">Response fields</h2>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Field</th>\n<th>Type</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>code</td>\n<td>int</td>\n<td>Response status code; <code>1000</code> on success.</td>\n</tr>\n<tr>\n<td>message</td>\n<td>string</td>\n<td>Human-readable summary of the result.</td>\n</tr>\n<tr>\n<td>data</td>\n<td>object</td>\n<td>Live usage details for the plan attached to the transaction.</td>\n</tr>\n<tr>\n<td>data.planId</td>\n<td>string</td>\n<td>Id of the plan/top-up whose usage is reported.</td>\n</tr>\n<tr>\n<td>data.planName</td>\n<td>string</td>\n<td>Display name of the plan.</td>\n</tr>\n<tr>\n<td>data.totalDataAllocation</td>\n<td>decimal</td>\n<td>Total data allowance for the plan, in <code>dataUnit</code>. Not meaningful when <code>unlimited</code> is <code>true</code>.</td>\n</tr>\n<tr>\n<td>data.dataUnit</td>\n<td>string</td>\n<td>Unit for the data fields (<code>MB</code> or <code>GB</code>).</td>\n</tr>\n<tr>\n<td>data.dataConsumed</td>\n<td>decimal</td>\n<td>Data used so far, in <code>dataUnit</code>.</td>\n</tr>\n<tr>\n<td>data.dataRemaining</td>\n<td>decimal</td>\n<td>Data left to use, in <code>dataUnit</code>. Not meaningful when <code>unlimited</code> is <code>true</code>.</td>\n</tr>\n<tr>\n<td>data.usagePercentage</td>\n<td>decimal</td>\n<td>Percentage of the allowance consumed (<code>0</code>-<code>100</code>); always <code>0</code> when <code>unlimited</code> is <code>true</code>.</td>\n</tr>\n<tr>\n<td>data.unlimited</td>\n<td>bool</td>\n<td><code>true</code> if the plan has unlimited data.</td>\n</tr>\n<tr>\n<td>data.expirationDate</td>\n<td>string (date-time)</td>\n<td>When the plan's data allowance expires.</td>\n</tr>\n<tr>\n<td>data.planStatus</td>\n<td>string (values: NotStarted | Active | Pending | Expired)</td>\n<td>Lifecycle status of the data plan itself — see <strong>Plan status</strong> in the folder overview.</td>\n</tr>\n<tr>\n<td>data.esimExpirationDate</td>\n<td>string (date-time)</td>\n<td>When the eSIM profile itself expires.</td>\n</tr>\n<tr>\n<td>data.esimStatus</td>\n<td>string (values: NotInstalled | Installed | Unavailable)</td>\n<td>Provisioning state of the eSIM profile on the traveller's device — see <strong>eSIM status</strong> in the folder overview.</td>\n</tr>\n</tbody>\n</table>\n</div>","urlObject":{"path":["api","v0","esim","transactions",":id","plans","usage"],"host":["https://eservices.hoicom.net"],"query":[],"variable":[{"type":"any","value":"","key":"id"}]}},"response":[{"id":"d3441c9d-458f-4f3a-af89-eff7a33ce619","name":"OK","originalRequest":{"method":"GET","header":[],"url":{"raw":"https://eservices.hoicom.net/api/v0/esim/transactions/:id/plans/usage","host":["https://eservices.hoicom.net"],"path":["api","v0","esim","transactions",":id","plans","usage"],"variable":[{"key":"id","value":""}]},"description":"Returns live data-usage details for the plan attached to a transaction.\n\n**Data units.** Data amounts are normalised: allowances of 1 GB or more are shown in decimal GB (a 1024 MB plan reads `1 GB`, 512 MB reads `500 MB`), smaller ones in MB. Do not assume a fixed unit; always read `unit`. `dataUnit` tells you which unit the data fields use.\n\n---\n\n## Authorization\n\nRequires Basic Authentication with your client credentials. Your account must be enabled for the eSIM service.\n\n---\n\n## Path Parameters\n\n| Parameter | Type | Required | Description |\n| --- | --- | --- | --- |\n| `id` | `string` | Yes | Transaction identifier. |\n\n---\n\n## Response\n\nOn success `code` is `1000`. `planStatus` uses the **Plan status** values and `esimStatus` the **eSIM status** values (see folder overview).\n\n---\n\n## Response fields\n\n| Field | Type | Description |\n|---|---|---|\n| code | int | Response status code; `1000` on success. |\n| message | string | Human-readable summary of the result. |\n| data | object | Live usage details for the plan attached to the transaction. |\n| data.planId | string | Id of the plan/top-up whose usage is reported. |\n| data.planName | string | Display name of the plan. |\n| data.totalDataAllocation | decimal | Total data allowance for the plan, in `dataUnit`. Not meaningful when `unlimited` is `true`. |\n| data.dataUnit | string | Unit for the data fields (`MB` or `GB`). |\n| data.dataConsumed | decimal | Data used so far, in `dataUnit`. |\n| data.dataRemaining | decimal | Data left to use, in `dataUnit`. Not meaningful when `unlimited` is `true`. |\n| data.usagePercentage | decimal | Percentage of the allowance consumed (`0`-`100`); always `0` when `unlimited` is `true`. |\n| data.unlimited | bool | `true` if the plan has unlimited data. |\n| data.expirationDate | string (date-time) | When the plan's data allowance expires. |\n| data.planStatus | string (values: NotStarted \\| Active \\| Pending \\| Expired) | Lifecycle status of the data plan itself — see **Plan status** in the folder overview. |\n| data.esimExpirationDate | string (date-time) | When the eSIM profile itself expires. |\n| data.esimStatus | string (values: NotInstalled \\| Installed \\| Unavailable) | Provisioning state of the eSIM profile on the traveller's device — see **eSIM status** in the folder overview. |\n"},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"cookie":[],"responseTime":null,"body":"{\n  \"code\": 1000,\n  \"message\": \"Success\",\n  \"data\": {\n    \"planId\": \"plan_eu_5gb_30d\",\n    \"planName\": \"Europe 5GB - 30 Days\",\n    \"totalDataAllocation\": 5,\n    \"dataUnit\": \"GB\",\n    \"dataConsumed\": 1.25,\n    \"dataRemaining\": 3.75,\n    \"usagePercentage\": 25,\n    \"unlimited\": false,\n    \"expirationDate\": \"2026-07-31T09:31:12.000\",\n    \"planStatus\": \"Active\",\n    \"esimExpirationDate\": \"2026-07-31T09:31:12.000\",\n    \"esimStatus\": \"Installed\"\n  }\n}"}],"_postman_id":"11f4d60a-0381-439f-95d0-0951693a6d4f"},{"name":"Get Plan Usage by Reference","id":"a6f05fd6-471e-49aa-ad22-171438869fa1","request":{"method":"GET","header":[],"url":"https://eservices.hoicom.net/api/v0/esim/transactions/reference/:externalReference/plans/usage","description":"<p>Same as <strong>Get Plan Usage by Transaction</strong>, but looked up by your <code>externalReference</code> instead of the transaction id.</p>\n<p><strong>Data units.</strong> Data amounts are normalised: allowances of 1 GB or more are shown in decimal GB (a 1024 MB plan reads <code>1 GB</code>, 512 MB reads <code>500 MB</code>), smaller ones in MB. Do not assume a fixed unit; always read <code>unit</code>. <code>dataUnit</code> tells you which unit the data fields use.</p>\n<hr />\n<h2 id=\"authorization\">Authorization</h2>\n<p>Requires Basic Authentication with your client credentials. Your account must be enabled for the eSIM service.</p>\n<hr />\n<h2 id=\"path-parameters\">Path Parameters</h2>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Parameter</th>\n<th>Type</th>\n<th>Required</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>externalReference</code></td>\n<td><code>string</code></td>\n<td>Yes</td>\n<td>Your external reference for the transaction.</td>\n</tr>\n</tbody>\n</table>\n</div><hr />\n<h2 id=\"response\">Response</h2>\n<p>On success <code>code</code> is <code>1000</code> and <code>data</code> is the usage object (see <strong>Get Plan Usage by Transaction</strong>).</p>\n<hr />\n<h2 id=\"response-fields\">Response fields</h2>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Field</th>\n<th>Type</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>code</td>\n<td>int</td>\n<td>Response status code; <code>1000</code> on success.</td>\n</tr>\n<tr>\n<td>message</td>\n<td>string</td>\n<td>Human-readable summary of the result.</td>\n</tr>\n<tr>\n<td>data</td>\n<td>object</td>\n<td>Live usage details for the plan attached to the transaction (same shape as <strong>Get Plan Usage by Transaction</strong>).</td>\n</tr>\n<tr>\n<td>data.planId</td>\n<td>string</td>\n<td>Id of the plan/top-up whose usage is reported.</td>\n</tr>\n<tr>\n<td>data.planName</td>\n<td>string</td>\n<td>Display name of the plan.</td>\n</tr>\n<tr>\n<td>data.totalDataAllocation</td>\n<td>decimal</td>\n<td>Total data allowance for the plan, in <code>dataUnit</code>. Not meaningful when <code>unlimited</code> is <code>true</code>.</td>\n</tr>\n<tr>\n<td>data.dataUnit</td>\n<td>string</td>\n<td>Unit for the data fields (<code>MB</code> or <code>GB</code>).</td>\n</tr>\n<tr>\n<td>data.dataConsumed</td>\n<td>decimal</td>\n<td>Data used so far, in <code>dataUnit</code>.</td>\n</tr>\n<tr>\n<td>data.dataRemaining</td>\n<td>decimal</td>\n<td>Data left to use, in <code>dataUnit</code>. Not meaningful when <code>unlimited</code> is <code>true</code>.</td>\n</tr>\n<tr>\n<td>data.usagePercentage</td>\n<td>decimal</td>\n<td>Percentage of the allowance consumed (<code>0</code>-<code>100</code>); always <code>0</code> when <code>unlimited</code> is <code>true</code>.</td>\n</tr>\n<tr>\n<td>data.unlimited</td>\n<td>bool</td>\n<td><code>true</code> if the plan has unlimited data.</td>\n</tr>\n<tr>\n<td>data.expirationDate</td>\n<td>string (date-time)</td>\n<td>When the plan's data allowance expires.</td>\n</tr>\n<tr>\n<td>data.planStatus</td>\n<td>string (values: NotStarted | Active | Pending | Expired)</td>\n<td>Lifecycle status of the data plan itself — see <strong>Plan status</strong> in the folder overview.</td>\n</tr>\n<tr>\n<td>data.esimExpirationDate</td>\n<td>string (date-time)</td>\n<td>When the eSIM profile itself expires.</td>\n</tr>\n<tr>\n<td>data.esimStatus</td>\n<td>string (values: NotInstalled | Installed | Unavailable)</td>\n<td>Provisioning state of the eSIM profile on the traveller's device — see <strong>eSIM status</strong> in the folder overview.</td>\n</tr>\n</tbody>\n</table>\n</div>","urlObject":{"path":["api","v0","esim","transactions","reference",":externalReference","plans","usage"],"host":["https://eservices.hoicom.net"],"query":[],"variable":[{"type":"any","value":"","key":"externalReference"}]}},"response":[{"id":"71e162bb-c2ff-4674-9a9f-8266fe08dc56","name":"OK","originalRequest":{"method":"GET","header":[],"url":{"raw":"https://eservices.hoicom.net/api/v0/esim/transactions/reference/:externalReference/plans/usage","host":["https://eservices.hoicom.net"],"path":["api","v0","esim","transactions","reference",":externalReference","plans","usage"],"variable":[{"key":"externalReference","value":""}]},"description":"Same as **Get Plan Usage by Transaction**, but looked up by your `externalReference` instead of the transaction id.\n\n**Data units.** Data amounts are normalised: allowances of 1 GB or more are shown in decimal GB (a 1024 MB plan reads `1 GB`, 512 MB reads `500 MB`), smaller ones in MB. Do not assume a fixed unit; always read `unit`. `dataUnit` tells you which unit the data fields use.\n\n---\n\n## Authorization\n\nRequires Basic Authentication with your client credentials. Your account must be enabled for the eSIM service.\n\n---\n\n## Path Parameters\n\n| Parameter | Type | Required | Description |\n| --- | --- | --- | --- |\n| `externalReference` | `string` | Yes | Your external reference for the transaction. |\n\n---\n\n## Response\n\nOn success `code` is `1000` and `data` is the usage object (see **Get Plan Usage by Transaction**).\n\n---\n\n## Response fields\n\n| Field | Type | Description |\n|---|---|---|\n| code | int | Response status code; `1000` on success. |\n| message | string | Human-readable summary of the result. |\n| data | object | Live usage details for the plan attached to the transaction (same shape as **Get Plan Usage by Transaction**). |\n| data.planId | string | Id of the plan/top-up whose usage is reported. |\n| data.planName | string | Display name of the plan. |\n| data.totalDataAllocation | decimal | Total data allowance for the plan, in `dataUnit`. Not meaningful when `unlimited` is `true`. |\n| data.dataUnit | string | Unit for the data fields (`MB` or `GB`). |\n| data.dataConsumed | decimal | Data used so far, in `dataUnit`. |\n| data.dataRemaining | decimal | Data left to use, in `dataUnit`. Not meaningful when `unlimited` is `true`. |\n| data.usagePercentage | decimal | Percentage of the allowance consumed (`0`-`100`); always `0` when `unlimited` is `true`. |\n| data.unlimited | bool | `true` if the plan has unlimited data. |\n| data.expirationDate | string (date-time) | When the plan's data allowance expires. |\n| data.planStatus | string (values: NotStarted \\| Active \\| Pending \\| Expired) | Lifecycle status of the data plan itself — see **Plan status** in the folder overview. |\n| data.esimExpirationDate | string (date-time) | When the eSIM profile itself expires. |\n| data.esimStatus | string (values: NotInstalled \\| Installed \\| Unavailable) | Provisioning state of the eSIM profile on the traveller's device — see **eSIM status** in the folder overview. |\n"},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"cookie":[],"responseTime":null,"body":"{\n  \"code\": 1000,\n  \"message\": \"Success\",\n  \"data\": {\n    \"planId\": \"plan_eu_5gb_30d\",\n    \"planName\": \"Europe 5GB - 30 Days\",\n    \"totalDataAllocation\": 5,\n    \"dataUnit\": \"GB\",\n    \"dataConsumed\": 1.25,\n    \"dataRemaining\": 3.75,\n    \"usagePercentage\": 25,\n    \"unlimited\": false,\n    \"expirationDate\": \"2026-07-31T09:31:12.000\",\n    \"planStatus\": \"Active\",\n    \"esimExpirationDate\": \"2026-07-31T09:31:12.000\",\n    \"esimStatus\": \"Installed\"\n  }\n}"}],"_postman_id":"a6f05fd6-471e-49aa-ad22-171438869fa1"}],"id":"fec1d676-49c8-4df7-a68e-47883f14e5e7","description":"<p>Check live data usage of a purchased eSIM, by transaction id or by your own <code>externalReference</code>.</p>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Method</th>\n<th>Endpoint</th>\n<th>Request</th>\n<th>Purpose</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>GET</code></td>\n<td><code>/api/v0/esim/transactions/{id}/plans/usage</code></td>\n<td><strong>Get Plan Usage by Transaction</strong></td>\n<td>Usage of the plan on a transaction.</td>\n</tr>\n<tr>\n<td><code>GET</code></td>\n<td><code>/api/v0/esim/transactions/reference/{externalReference}/plans/usage</code></td>\n<td><strong>Get Plan Usage by Reference</strong></td>\n<td>Same, looked up by <code>externalReference</code>.</td>\n</tr>\n</tbody>\n</table>\n</div>","_postman_id":"fec1d676-49c8-4df7-a68e-47883f14e5e7"},{"name":"Regenerate","item":[{"name":"Regenerate Transaction","id":"9468c1e4-7ef6-4514-a46b-e4229e08a55d","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"body":{"mode":"raw","raw":"{\n  \"reasonCode\": \"NotWorking\",\n  \"reasonText\": \"eSIM profile installs but never connects to a network.\"\n}","options":{"raw":{"language":"json"}}},"url":"https://eservices.hoicom.net/api/v0/esim/transactions/:id/regenerate","description":"<p>Replaces a faulty eSIM with a <strong>new</strong> one, looked up by transaction id. No charge. The <strong>same transaction</strong> is updated in place: it gets a new ICCID, activation code and QR code, while <code>transactionId</code>, <code>externalReference</code>, amounts and <code>status</code> do not change.</p>\n<p>The response is returned immediately with <code>regeneration.status</code> = <code>InProgress</code>. Regeneration runs in the background. Poll <code>GET /transactions/{id}?include=regenerations</code> until <code>regenerations.inProgress</code> is <code>false</code>, then check the <code>status</code> of the latest entry in <code>regenerations.items[]</code>. Only when it is <code>Completed</code> does the transaction carry the new eSIM; on <code>Failed</code> it still shows the previous eSIM details.</p>\n<hr />\n<h2 id=\"authorization\">Authorization</h2>\n<p>Requires Basic Authentication with your client credentials. Your account must be enabled for the eSIM service.</p>\n<hr />\n<h2 id=\"path-parameters\">Path Parameters</h2>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Parameter</th>\n<th>Type</th>\n<th>Required</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>id</code></td>\n<td><code>string</code></td>\n<td>Yes</td>\n<td>Transaction identifier of the eSIM to regenerate.</td>\n</tr>\n</tbody>\n</table>\n</div><hr />\n<h2 id=\"request-body\">Request Body</h2>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Field</th>\n<th>Type</th>\n<th>Required</th>\n<th>Constraints</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>reasonCode</code></td>\n<td><code>string</code></td>\n<td>Yes</td>\n<td><code>NotActivated</code> or <code>NotWorking</code> (case-insensitive).</td>\n</tr>\n<tr>\n<td><code>reasonText</code></td>\n<td><code>string</code></td>\n<td>No</td>\n<td>Free text, max 500 characters.</td>\n</tr>\n</tbody>\n</table>\n</div><hr />\n<h2 id=\"limits\">Limits</h2>\n<ul>\n<li>Only a <code>Completed</code> <strong>base plan</strong> can be regenerated (not a top-up).</li>\n<li>Within <strong>59 days</strong> of purchase.</li>\n<li>At most <strong>3</strong> regenerations per eSIM.</li>\n<li>The eSIM must have used no more than <strong>49 MB</strong> of data, and must not be refunded or have an open refund request.</li>\n<li>Neither the eSIM plan nor the eSIM profile has expired</li>\n<li>No active top-up</li>\n</ul>\n<hr />\n<h2 id=\"response\">Response</h2>\n<p>On acceptance <code>code</code> is <code>1000</code> and <code>data</code> contains the <code>transactionId</code> and the <code>regeneration</code> that was started.</p>\n<h3 id=\"error-codes\">Error codes</h3>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Code</th>\n<th>HTTP</th>\n<th>Meaning</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>1000</code></td>\n<td>200</td>\n<td>Accepted; regeneration started.</td>\n</tr>\n<tr>\n<td><code>1107</code></td>\n<td>400</td>\n<td>Validation error (missing or unsupported <code>reasonCode</code>, <code>reasonText</code> too long, bad id).</td>\n</tr>\n<tr>\n<td><code>1427</code></td>\n<td>400</td>\n<td>1427 is returned when the eSIM plan or the eSIM profile has expired. This eSIM is not eligible for regeneration; the reason is in <code>message</code> (e.g. window passed, data usage above the limit, plan or profile expired, active top-up, open refund, not completed, top-up).</td>\n</tr>\n<tr>\n<td><code>1105</code></td>\n<td>404</td>\n<td>Transaction not found (or not yours / not an eSIM transaction).</td>\n</tr>\n<tr>\n<td><code>1428</code></td>\n<td>409</td>\n<td>\"This eSIM has reached the limit of 3 regenerations.\"</td>\n</tr>\n<tr>\n<td><code>1429</code></td>\n<td>409</td>\n<td>A regeneration is already in progress for this eSIM.</td>\n</tr>\n<tr>\n<td><code>1410</code></td>\n<td>503</td>\n<td>Eligibility could not be verified right now; retry shortly.</td>\n</tr>\n</tbody>\n</table>\n</div><hr />\n<h2 id=\"response-fields\">Response fields</h2>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Field</th>\n<th>Type</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>code</td>\n<td>int</td>\n<td>Response status code; <code>1000</code> on success.</td>\n</tr>\n<tr>\n<td>message</td>\n<td>string</td>\n<td>Human-readable summary of the result.</td>\n</tr>\n<tr>\n<td>data</td>\n<td>object</td>\n<td>The regeneration that was started.</td>\n</tr>\n<tr>\n<td>data.transactionId</td>\n<td>string</td>\n<td>The eSIM transaction (unchanged).</td>\n</tr>\n<tr>\n<td>data.regeneration</td>\n<td>object</td>\n<td>The regeneration that was started.</td>\n</tr>\n<tr>\n<td>data.regeneration.number</td>\n<td>int</td>\n<td>Which regeneration this is for the eSIM (1, 2 or 3).</td>\n</tr>\n<tr>\n<td>data.regeneration.status</td>\n<td>string</td>\n<td><code>InProgress</code> at response time.</td>\n</tr>\n</tbody>\n</table>\n</div>","urlObject":{"path":["api","v0","esim","transactions",":id","regenerate"],"host":["https://eservices.hoicom.net"],"query":[],"variable":[{"description":{"content":"<p>Transaction identifier of the eSIM to regenerate.</p>\n","type":"text/plain"},"type":"any","value":"","key":"id"}]}},"response":[{"id":"95d9aef2-1934-4faa-9c52-12e27cd9c7b6","name":"OK","originalRequest":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"body":{"mode":"raw","raw":"{\n  \"reasonCode\": \"NotWorking\",\n  \"reasonText\": \"eSIM profile installs but never connects to a network.\"\n}","options":{"raw":{"language":"json"}}},"url":{"raw":"https://eservices.hoicom.net/api/v0/esim/transactions/:id/regenerate","host":["https://eservices.hoicom.net"],"path":["api","v0","esim","transactions",":id","regenerate"],"variable":[{"key":"id","value":"","description":"Transaction identifier of the eSIM to regenerate."}]},"description":"Replaces a faulty eSIM with a **new** one, looked up by transaction id. No charge. The **same transaction** is updated in place: it gets a new ICCID, activation code and QR code, while `transactionId`, `externalReference`, amounts and `status` do not change.\n\nRegeneration runs in the background; the response is returned immediately with `regeneration.status` = `InProgress`. Poll **Get Transaction by ID** with `include=regenerations` until `regenerations.inProgress` is `false`, then read the new eSIM details from `product`.\n\n---\n\n## Authorization\n\nRequires Basic Authentication with your client credentials. Your account must be enabled for the eSIM service.\n\n---\n\n## Path Parameters\n\n| Parameter | Type | Required | Description |\n| --- | --- | --- | --- |\n| `id` | `string` | Yes | Transaction identifier of the eSIM to regenerate. |\n\n---\n\n## Request Body\n\n| Field | Type | Required | Constraints |\n| --- | --- | --- | --- |\n| `reasonCode` | `string` | Yes | `NotActivated` or `NotWorking` (case-insensitive). |\n| `reasonText` | `string` | No | Free text, max 500 characters. |\n\n---\n\n## Limits\n\n- Only a `Completed` **base plan** can be regenerated (not a top-up).\n- Within **59 days** of purchase.\n- At most **3** regenerations per eSIM.\n- The eSIM must have used no more than **49 MB** of data, and must not be expired, refunded or have an open refund request.\n\n---\n\n## Response\n\nOn acceptance `code` is `1000` and `data` contains the `transactionId` and the `regeneration` that was started.\n\n### Error codes\n\n| Code | HTTP | Meaning |\n| --- | --- | --- |\n| `1000` | 200 | Accepted; regeneration started. |\n| `1107` | 400 | Validation error (missing or unsupported `reasonCode`, `reasonText` too long, bad id). |\n| `1427` | 400 | This eSIM is not eligible for regeneration; the reason is in `message` (e.g. window passed, data usage above the limit, plan expired, open refund, not completed, top-up). |\n| `1105` | 404 | Transaction not found (or not yours / not an eSIM transaction). |\n| `1428` | 409 | \"This eSIM has reached the limit of 3 regenerations.\" |\n| `1429` | 409 | A regeneration is already in progress for this eSIM. |\n| `1410` | 503 | Eligibility could not be verified right now; retry shortly. |\n\n---\n\n## Response fields\n\n| Field | Type | Description |\n|---|---|---|\n| code | int | Response status code; `1000` on success. |\n| message | string | Human-readable summary of the result. |\n| data | object | The regeneration that was started. |\n| data.transactionId | string | The eSIM transaction (unchanged). |\n| data.regeneration | object | The regeneration that was started. |\n| data.regeneration.number | int | Which regeneration this is for the eSIM (1, 2 or 3). |\n| data.regeneration.status | string | `InProgress` at response time. |\n"},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"cookie":[],"responseTime":null,"body":"{\n  \"code\": 1000,\n  \"message\": \"Request processed successfully.\",\n  \"data\": {\n    \"transactionId\": \"23038\",\n    \"regeneration\": {\n      \"number\": 1,\n      \"status\": \"InProgress\"\n    }\n  }\n}"},{"id":"4ba4b1da-6996-42da-92a3-6197f1665d55","name":"Not eligible","originalRequest":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"body":{"mode":"raw","raw":"{\n  \"reasonCode\": \"NotWorking\",\n  \"reasonText\": \"eSIM profile installs but never connects to a network.\"\n}","options":{"raw":{"language":"json"}}},"url":{"raw":"https://eservices.hoicom.net/api/v0/esim/transactions/:id/regenerate","host":["https://eservices.hoicom.net"],"path":["api","v0","esim","transactions",":id","regenerate"],"variable":[{"key":"id","value":"","description":"Transaction identifier of the eSIM to regenerate."}]}},"status":"Bad Request","code":400,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"cookie":[],"responseTime":null,"body":"{\n  \"code\": 1427,\n  \"message\": \"The regeneration window (59 days from purchase) has passed.\",\n  \"data\": null\n}"},{"id":"a962922a-8630-4c9e-918e-1a51e0b79399","name":"Transaction not found","originalRequest":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"body":{"mode":"raw","raw":"{\n  \"reasonCode\": \"NotWorking\",\n  \"reasonText\": \"eSIM profile installs but never connects to a network.\"\n}","options":{"raw":{"language":"json"}}},"url":{"raw":"https://eservices.hoicom.net/api/v0/esim/transactions/:id/regenerate","host":["https://eservices.hoicom.net"],"path":["api","v0","esim","transactions",":id","regenerate"],"variable":[{"key":"id","value":"","description":"Transaction identifier of the eSIM to regenerate."}]}},"status":"Not Found","code":404,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"cookie":[],"responseTime":null,"body":"{\n  \"code\": 1105,\n  \"message\": \"Transaction not found.\",\n  \"data\": null\n}"},{"id":"cb3123e9-9afd-4b71-b111-1d98fa18eda1","name":"Regeneration limit reached","originalRequest":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"body":{"mode":"raw","raw":"{\n  \"reasonCode\": \"NotWorking\",\n  \"reasonText\": \"eSIM profile installs but never connects to a network.\"\n}","options":{"raw":{"language":"json"}}},"url":{"raw":"https://eservices.hoicom.net/api/v0/esim/transactions/:id/regenerate","host":["https://eservices.hoicom.net"],"path":["api","v0","esim","transactions",":id","regenerate"],"variable":[{"key":"id","value":"","description":"Transaction identifier of the eSIM to regenerate."}]}},"status":"Conflict","code":409,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"cookie":[],"responseTime":null,"body":"{\n  \"code\": 1428,\n  \"message\": \"This eSIM has reached the limit of 3 regenerations.\",\n  \"data\": null\n}"},{"id":"ef9ff0e5-4d8f-4f00-ad76-ae161a194a16","name":"Regeneration in progress","originalRequest":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"body":{"mode":"raw","raw":"{\n  \"reasonCode\": \"NotWorking\",\n  \"reasonText\": \"eSIM profile installs but never connects to a network.\"\n}","options":{"raw":{"language":"json"}}},"url":{"raw":"https://eservices.hoicom.net/api/v0/esim/transactions/:id/regenerate","host":["https://eservices.hoicom.net"],"path":["api","v0","esim","transactions",":id","regenerate"],"variable":[{"key":"id","value":"","description":"Transaction identifier of the eSIM to regenerate."}]}},"status":"Conflict","code":409,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"cookie":[],"responseTime":null,"body":"{\n  \"code\": 1429,\n  \"message\": \"A regeneration is already in progress for this eSIM.\",\n  \"data\": null\n}"}],"_postman_id":"9468c1e4-7ef6-4514-a46b-e4229e08a55d"},{"name":"Regenerate Transaction by Reference","id":"631bd023-d323-4af0-9b6a-e67e47ab292e","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"body":{"mode":"raw","raw":"{\n  \"reasonCode\": \"NotWorking\",\n  \"reasonText\": \"eSIM profile installs but never connects to a network.\"\n}","options":{"raw":{"language":"json"}}},"url":"https://eservices.hoicom.net/api/v0/esim/transactions/reference/:externalReference/regenerate","description":"<p>Replaces a faulty eSIM with a <strong>new</strong> one, looked up by your <code>externalReference</code>. No charge. The <strong>same transaction</strong> is updated in place: it gets a new ICCID, activation code and QR code, while <code>transactionId</code>, <code>externalReference</code>, amounts and <code>status</code> do not change.</p>\n<p>The response is returned immediately with <code>regeneration.status</code> = <code>InProgress</code>. Regeneration runs in the background. Poll <code>GET /transactions/{id}?include=regenerations</code> until <code>regenerations.inProgress</code> is <code>false</code>, then check the <code>status</code> of the latest entry in <code>regenerations.items[]</code>. Only when it is <code>Completed</code> does the transaction carry the new eSIM; on <code>Failed</code> it still shows the previous eSIM details.</p>\n<hr />\n<h2 id=\"authorization\">Authorization</h2>\n<p>Requires Basic Authentication with your client credentials. Your account must be enabled for the eSIM service.</p>\n<hr />\n<h2 id=\"path-parameters\">Path Parameters</h2>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Parameter</th>\n<th>Type</th>\n<th>Required</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>externalReference</code></td>\n<td><code>string</code></td>\n<td>Yes</td>\n<td>Your external reference for the eSIM transaction.</td>\n</tr>\n</tbody>\n</table>\n</div><hr />\n<h2 id=\"request-body\">Request Body</h2>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Field</th>\n<th>Type</th>\n<th>Required</th>\n<th>Constraints</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>reasonCode</code></td>\n<td><code>string</code></td>\n<td>Yes</td>\n<td><code>NotActivated</code> or <code>NotWorking</code> (case-insensitive).</td>\n</tr>\n<tr>\n<td><code>reasonText</code></td>\n<td><code>string</code></td>\n<td>No</td>\n<td>Free text, max 500 characters.</td>\n</tr>\n</tbody>\n</table>\n</div><hr />\n<h2 id=\"limits\">Limits</h2>\n<ul>\n<li>Only a <code>Completed</code> <strong>base plan</strong> can be regenerated (not a top-up).</li>\n<li>Within <strong>59 days</strong> of purchase.</li>\n<li>At most <strong>3</strong> regenerations per eSIM.</li>\n<li>The eSIM must have used no more than <strong>49 MB</strong> of data, and must not be refunded or have an open refund request.</li>\n<li>Neither the eSIM plan nor the eSIM profile has expired</li>\n<li>No active top-up</li>\n</ul>\n<hr />\n<h2 id=\"response\">Response</h2>\n<p>On acceptance <code>code</code> is <code>1000</code> and <code>data</code> contains the <code>transactionId</code> and the <code>regeneration</code> that was started.</p>\n<h3 id=\"error-codes\">Error codes</h3>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Code</th>\n<th>HTTP</th>\n<th>Meaning</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>1000</code></td>\n<td>200</td>\n<td>Accepted; regeneration started.</td>\n</tr>\n<tr>\n<td><code>1107</code></td>\n<td>400</td>\n<td>Validation error (missing or unsupported <code>reasonCode</code>, <code>reasonText</code> too long, bad id).</td>\n</tr>\n<tr>\n<td><code>1427</code></td>\n<td>400</td>\n<td>1427 is returned when the eSIM plan or the eSIM profile has expired. This eSIM is not eligible for regeneration; the reason is in <code>message</code> (e.g. window passed, data usage above the limit, plan or profile expired, active top-up, open refund, not completed, top-up).</td>\n</tr>\n<tr>\n<td><code>1105</code></td>\n<td>404</td>\n<td>Transaction not found (or not yours / not an eSIM transaction).</td>\n</tr>\n<tr>\n<td><code>1428</code></td>\n<td>409</td>\n<td>\"This eSIM has reached the limit of 3 regenerations.\"</td>\n</tr>\n<tr>\n<td><code>1429</code></td>\n<td>409</td>\n<td>A regeneration is already in progress for this eSIM.</td>\n</tr>\n<tr>\n<td><code>1410</code></td>\n<td>503</td>\n<td>Eligibility could not be verified right now; retry shortly.</td>\n</tr>\n</tbody>\n</table>\n</div><hr />\n<h2 id=\"response-fields\">Response fields</h2>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Field</th>\n<th>Type</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>code</td>\n<td>int</td>\n<td>Response status code; <code>1000</code> on success.</td>\n</tr>\n<tr>\n<td>message</td>\n<td>string</td>\n<td>Human-readable summary of the result.</td>\n</tr>\n<tr>\n<td>data</td>\n<td>object</td>\n<td>The regeneration that was started.</td>\n</tr>\n<tr>\n<td>data.transactionId</td>\n<td>string</td>\n<td>The eSIM transaction (unchanged).</td>\n</tr>\n<tr>\n<td>data.regeneration</td>\n<td>object</td>\n<td>The regeneration that was started.</td>\n</tr>\n<tr>\n<td>data.regeneration.number</td>\n<td>int</td>\n<td>Which regeneration this is for the eSIM (1, 2 or 3).</td>\n</tr>\n<tr>\n<td>data.regeneration.status</td>\n<td>string</td>\n<td><code>InProgress</code> at response time.</td>\n</tr>\n</tbody>\n</table>\n</div>","urlObject":{"path":["api","v0","esim","transactions","reference",":externalReference","regenerate"],"host":["https://eservices.hoicom.net"],"query":[],"variable":[{"description":{"content":"<p>Your external reference for the eSIM transaction.</p>\n","type":"text/plain"},"type":"any","value":"","key":"externalReference"}]}},"response":[{"id":"20ea3026-c6fd-4d4e-a1e0-5285bcc313aa","name":"OK","originalRequest":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"body":{"mode":"raw","raw":"{\n  \"reasonCode\": \"NotWorking\",\n  \"reasonText\": \"eSIM profile installs but never connects to a network.\"\n}","options":{"raw":{"language":"json"}}},"url":{"raw":"https://eservices.hoicom.net/api/v0/esim/transactions/reference/:externalReference/regenerate","host":["https://eservices.hoicom.net"],"path":["api","v0","esim","transactions","reference",":externalReference","regenerate"],"variable":[{"key":"externalReference","value":"","description":"Your external reference for the eSIM transaction."}]},"description":"Replaces a faulty eSIM with a **new** one, looked up by your `externalReference`. No charge. The **same transaction** is updated in place: it gets a new ICCID, activation code and QR code, while `transactionId`, `externalReference`, amounts and `status` do not change.\n\nRegeneration runs in the background; the response is returned immediately with `regeneration.status` = `InProgress`. Poll **Get Transaction by ID** with `include=regenerations` until `regenerations.inProgress` is `false`, then read the new eSIM details from `product`.\n\n---\n\n## Authorization\n\nRequires Basic Authentication with your client credentials. Your account must be enabled for the eSIM service.\n\n---\n\n## Path Parameters\n\n| Parameter | Type | Required | Description |\n| --- | --- | --- | --- |\n| `externalReference` | `string` | Yes | Your external reference for the eSIM transaction. |\n\n---\n\n## Request Body\n\n| Field | Type | Required | Constraints |\n| --- | --- | --- | --- |\n| `reasonCode` | `string` | Yes | `NotActivated` or `NotWorking` (case-insensitive). |\n| `reasonText` | `string` | No | Free text, max 500 characters. |\n\n---\n\n## Limits\n\n- Only a `Completed` **base plan** can be regenerated (not a top-up).\n- Within **59 days** of purchase.\n- At most **3** regenerations per eSIM.\n- The eSIM must have used no more than **49 MB** of data, and must not be expired, refunded or have an open refund request.\n\n---\n\n## Response\n\nOn acceptance `code` is `1000` and `data` contains the `transactionId` and the `regeneration` that was started.\n\n### Error codes\n\n| Code | HTTP | Meaning |\n| --- | --- | --- |\n| `1000` | 200 | Accepted; regeneration started. |\n| `1107` | 400 | Validation error (missing or unsupported `reasonCode`, `reasonText` too long, bad id). |\n| `1427` | 400 | This eSIM is not eligible for regeneration; the reason is in `message` (e.g. window passed, data usage above the limit, plan expired, open refund, not completed, top-up). |\n| `1105` | 404 | Transaction not found (or not yours / not an eSIM transaction). |\n| `1428` | 409 | \"This eSIM has reached the limit of 3 regenerations.\" |\n| `1429` | 409 | A regeneration is already in progress for this eSIM. |\n| `1410` | 503 | Eligibility could not be verified right now; retry shortly. |\n\n---\n\n## Response fields\n\n| Field | Type | Description |\n|---|---|---|\n| code | int | Response status code; `1000` on success. |\n| message | string | Human-readable summary of the result. |\n| data | object | The regeneration that was started. |\n| data.transactionId | string | The eSIM transaction (unchanged). |\n| data.regeneration | object | The regeneration that was started. |\n| data.regeneration.number | int | Which regeneration this is for the eSIM (1, 2 or 3). |\n| data.regeneration.status | string | `InProgress` at response time. |\n"},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"cookie":[],"responseTime":null,"body":"{\n  \"code\": 1000,\n  \"message\": \"Request processed successfully.\",\n  \"data\": {\n    \"transactionId\": \"23038\",\n    \"regeneration\": {\n      \"number\": 1,\n      \"status\": \"InProgress\"\n    }\n  }\n}"},{"id":"b3d01726-4603-4c89-89f4-cfbe1f31e27b","name":"Not eligible","originalRequest":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"body":{"mode":"raw","raw":"{\n  \"reasonCode\": \"NotWorking\",\n  \"reasonText\": \"eSIM profile installs but never connects to a network.\"\n}","options":{"raw":{"language":"json"}}},"url":{"raw":"https://eservices.hoicom.net/api/v0/esim/transactions/reference/:externalReference/regenerate","host":["https://eservices.hoicom.net"],"path":["api","v0","esim","transactions","reference",":externalReference","regenerate"],"variable":[{"key":"externalReference","value":"","description":"The externalReference you sent when buying the eSIM."}]}},"status":"Bad Request","code":400,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"cookie":[],"responseTime":null,"body":"{\n  \"code\": 1427,\n  \"message\": \"The regeneration window (59 days from purchase) has passed.\",\n  \"data\": null\n}"},{"id":"782045a9-5cd0-4fd0-9820-67b32e8ba54c","name":"Transaction not found","originalRequest":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"body":{"mode":"raw","raw":"{\n  \"reasonCode\": \"NotWorking\",\n  \"reasonText\": \"eSIM profile installs but never connects to a network.\"\n}","options":{"raw":{"language":"json"}}},"url":{"raw":"https://eservices.hoicom.net/api/v0/esim/transactions/reference/:externalReference/regenerate","host":["https://eservices.hoicom.net"],"path":["api","v0","esim","transactions","reference",":externalReference","regenerate"],"variable":[{"key":"externalReference","value":"","description":"The externalReference you sent when buying the eSIM."}]}},"status":"Not Found","code":404,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"cookie":[],"responseTime":null,"body":"{\n  \"code\": 1105,\n  \"message\": \"Transaction not found.\",\n  \"data\": null\n}"},{"id":"1fb6f3b2-ab52-4bbb-9cc7-9f491804d701","name":"Regeneration limit reached","originalRequest":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"body":{"mode":"raw","raw":"{\n  \"reasonCode\": \"NotWorking\",\n  \"reasonText\": \"eSIM profile installs but never connects to a network.\"\n}","options":{"raw":{"language":"json"}}},"url":{"raw":"https://eservices.hoicom.net/api/v0/esim/transactions/reference/:externalReference/regenerate","host":["https://eservices.hoicom.net"],"path":["api","v0","esim","transactions","reference",":externalReference","regenerate"],"variable":[{"key":"externalReference","value":"","description":"The externalReference you sent when buying the eSIM."}]}},"status":"Conflict","code":409,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"cookie":[],"responseTime":null,"body":"{\n  \"code\": 1428,\n  \"message\": \"This eSIM has reached the limit of 3 regenerations.\",\n  \"data\": null\n}"},{"id":"758d143d-818f-446b-a781-edbeb372966a","name":"Regeneration in progress","originalRequest":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"body":{"mode":"raw","raw":"{\n  \"reasonCode\": \"NotWorking\",\n  \"reasonText\": \"eSIM profile installs but never connects to a network.\"\n}","options":{"raw":{"language":"json"}}},"url":{"raw":"https://eservices.hoicom.net/api/v0/esim/transactions/reference/:externalReference/regenerate","host":["https://eservices.hoicom.net"],"path":["api","v0","esim","transactions","reference",":externalReference","regenerate"],"variable":[{"key":"externalReference","value":"","description":"The externalReference you sent when buying the eSIM."}]}},"status":"Conflict","code":409,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"cookie":[],"responseTime":null,"body":"{\n  \"code\": 1429,\n  \"message\": \"A regeneration is already in progress for this eSIM.\",\n  \"data\": null\n}"}],"_postman_id":"631bd023-d323-4af0-9b6a-e67e47ab292e"}],"id":"ba8e18a8-1770-4868-9a30-0a29c5f8c805","description":"<p>Replace a faulty eSIM with a new one at no charge. The same transaction is updated in place; regeneration runs in the background. Limits and rules: see <strong>Regenerating an eSIM</strong> in the eSIM folder description.</p>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Method</th>\n<th>Endpoint</th>\n<th>Request</th>\n<th>Purpose</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>POST</code></td>\n<td><code>/api/v0/esim/transactions/{id}/regenerate</code></td>\n<td><strong>Regenerate Transaction</strong></td>\n<td>Regenerate by transaction id.</td>\n</tr>\n<tr>\n<td><code>POST</code></td>\n<td><code>/api/v0/esim/transactions/reference/{externalReference}/regenerate</code></td>\n<td><strong>Regenerate Transaction by Reference</strong></td>\n<td>Regenerate by <code>externalReference</code>.</td>\n</tr>\n</tbody>\n</table>\n</div>","_postman_id":"ba8e18a8-1770-4868-9a30-0a29c5f8c805"},{"name":"Refunds","item":[{"name":"Request Refund","id":"733802a0-78f3-45b8-8c72-bdc091e451a5","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"body":{"mode":"raw","raw":"{\n  \"reasonCode\": \"NotWorking\",\n  \"reasonText\": \"Data plan never connected after activation.\",\n  \"clientReference\": \"SUPPORT-CASE-4821\"\n}","options":{"raw":{"language":"json"}}},"url":"https://eservices.hoicom.net/api/v0/esim/transactions/:id/refund","description":"<p>Opens a refund request for a <code>Completed</code> eSIM transaction you own. The decision is made in the background: the response returns the new request with <code>status</code> = <code>Submitted</code>. Poll <strong>Get Refund</strong> (or <strong>Get Refund by Transaction</strong>) until <code>status</code> is terminal.</p>\n<p>Only one refund request can be open per transaction at a time.</p>\n<hr />\n<h2 id=\"authorization\">Authorization</h2>\n<p>Requires Basic Authentication with your client credentials. Your account must be enabled for the eSIM service. You can only see and act on refunds for your own transactions.</p>\n<hr />\n<h2 id=\"path-parameters\">Path Parameters</h2>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Parameter</th>\n<th>Type</th>\n<th>Required</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>id</code></td>\n<td><code>int</code></td>\n<td>Yes</td>\n<td>Transaction identifier of the eSIM purchase.</td>\n</tr>\n</tbody>\n</table>\n</div><hr />\n<h2 id=\"request-body\">Request Body</h2>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Field</th>\n<th>Type</th>\n<th>Required</th>\n<th>Constraints</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>reasonCode</code></td>\n<td><code>string</code></td>\n<td>Yes</td>\n<td><code>NotActivated</code>, <code>NotWorking</code>, <code>WrongPurchase</code>, <code>Duplicate</code> or <code>Other</code> (case-insensitive).</td>\n</tr>\n<tr>\n<td><code>reasonText</code></td>\n<td><code>string</code></td>\n<td>No</td>\n<td>Free text, max 1000 characters.</td>\n</tr>\n<tr>\n<td><code>clientReference</code></td>\n<td><code>string</code></td>\n<td>No</td>\n<td>Your own reference for the request, max 100 characters.</td>\n</tr>\n</tbody>\n</table>\n</div><p>Eligibility rules (59-day window, installed/used checks per reason) are listed in the eSIM folder description.</p>\n<hr />\n<h2 id=\"response\">Response</h2>\n<p>On success <code>code</code> is <code>1000</code> and <code>data</code> is the new refund request.</p>\n<h3 id=\"error-codes\">Error codes</h3>\n<p>1104 / 403: your account is not permitted to perform this refund action. 1105 / 404: the transaction or refund request was not found, or does not belong to your account (another client's records always return 1105).</p>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Code</th>\n<th>HTTP</th>\n<th>Meaning</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>1000</code></td>\n<td>200</td>\n<td>Refund request opened.</td>\n</tr>\n<tr>\n<td>—</td>\n<td>400</td>\n<td>Missing or empty <code>reasonCode</code>, empty body or malformed JSON. Returned as a standard validation problem body (<code>title</code>, <code>status</code>, <code>errors</code>; <code>application/problem+json</code>), <strong>not</strong> the usual <code>code</code>/<code>message</code> envelope.</td>\n</tr>\n<tr>\n<td><code>1107</code></td>\n<td>400</td>\n<td>Validation error: unsupported <code>reasonCode</code> value, or a field over its length limit.</td>\n</tr>\n<tr>\n<td><code>1422</code></td>\n<td>400</td>\n<td>The transaction is not eligible for a refund (e.g. not <code>Completed</code>, outside the 59-day window, or a cooldown after a recent rejection). Refused immediately — no refund request is created; <code>message</code> names the reason, e.g. <code>Refund not eligible: OutsideWindow.</code></td>\n</tr>\n<tr>\n<td><code>1104</code></td>\n<td>403</td>\n<td>Your account is not permitted to perform this refund action.</td>\n</tr>\n<tr>\n<td><code>1105</code></td>\n<td>404</td>\n<td>The transaction or refund request was not found, or does not belong to your account (another client's records always return 1105).</td>\n</tr>\n<tr>\n<td><code>1423</code></td>\n<td>409</td>\n<td>A refund request is already open for this transaction — <code>data</code> carries it. Also returned with <code>data: null</code> while an eSIM regeneration is in progress; retry once it has finished.</td>\n</tr>\n<tr>\n<td><code>1101</code></td>\n<td>503</td>\n<td>Internal error while handling the request — retry after a short delay.</td>\n</tr>\n<tr>\n<td><code>1426</code></td>\n<td>503</td>\n<td>The refund service is temporarily unavailable — retry after a short delay.</td>\n</tr>\n</tbody>\n</table>\n</div><hr />\n<h2 id=\"response-fields\">Response fields</h2>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Field</th>\n<th>Type</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>code</td>\n<td>int</td>\n<td>Response status code; <code>1000</code> on success.</td>\n</tr>\n<tr>\n<td>message</td>\n<td>string</td>\n<td>Human-readable summary of the result.</td>\n</tr>\n<tr>\n<td>data</td>\n<td>object</td>\n<td>The refund request (<code>null</code> on most errors).</td>\n</tr>\n<tr>\n<td>data.refundId</td>\n<td>int</td>\n<td>The refund request's own id — use it with <strong>Get Refund</strong> and <strong>Withdraw Refund</strong>.</td>\n</tr>\n<tr>\n<td>data.transactionId</td>\n<td>int</td>\n<td>The eSIM transaction the refund was requested against.</td>\n</tr>\n<tr>\n<td>data.hoiReference</td>\n<td>string</td>\n<td>The Hoi reference of the refunded transaction.</td>\n</tr>\n<tr>\n<td>data.clientExternalReference</td>\n<td>string</td>\n<td>The <code>externalReference</code> you sent when buying the eSIM, if any.</td>\n</tr>\n<tr>\n<td>data.status</td>\n<td>string</td>\n<td>Refund status — see <strong>Status vocabulary</strong> in the eSIM folder description.</td>\n</tr>\n<tr>\n<td>data.reasonCode</td>\n<td>string</td>\n<td>The reason code you submitted.</td>\n</tr>\n<tr>\n<td>data.reasonText</td>\n<td>string</td>\n<td>The free text you submitted, if any.</td>\n</tr>\n<tr>\n<td>data.clientReference</td>\n<td>string</td>\n<td>Your own reference for the refund request, if any.</td>\n</tr>\n<tr>\n<td>data.requestedAt</td>\n<td>datetime</td>\n<td>When the refund was requested (UTC).</td>\n</tr>\n<tr>\n<td>data.decidedAt</td>\n<td>datetime</td>\n<td>When a decision was made, if any (UTC).</td>\n</tr>\n<tr>\n<td>data.decisionReasonCode</td>\n<td>string</td>\n<td>Short code explaining the decision, when available.</td>\n</tr>\n<tr>\n<td>data.clientMessage</td>\n<td>string</td>\n<td>Short human-readable sentence explaining the decision, when available.</td>\n</tr>\n<tr>\n<td>data.approvedAmount</td>\n<td>decimal</td>\n<td>Amount approved, once decided.</td>\n</tr>\n<tr>\n<td>data.refundedAmount</td>\n<td>decimal</td>\n<td>Amount actually refunded, once processed.</td>\n</tr>\n<tr>\n<td>data.currency</td>\n<td>string</td>\n<td>Currency of the amounts.</td>\n</tr>\n</tbody>\n</table>\n</div>","urlObject":{"path":["api","v0","esim","transactions",":id","refund"],"host":["https://eservices.hoicom.net"],"query":[],"variable":[{"description":{"content":"<p>Transaction identifier of the eSIM purchase.</p>\n","type":"text/plain"},"type":"any","value":"","key":"id"}]}},"response":[{"id":"44bf6fa6-9d86-47ba-9509-01eb3d0e745a","name":"OK","originalRequest":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"body":{"mode":"raw","raw":"{\n  \"reasonCode\": \"NotWorking\",\n  \"reasonText\": \"Data plan never connected after activation.\",\n  \"clientReference\": \"SUPPORT-CASE-4821\"\n}","options":{"raw":{"language":"json"}}},"url":{"raw":"https://eservices.hoicom.net/api/v0/esim/transactions/:id/refund","host":["https://eservices.hoicom.net"],"path":["api","v0","esim","transactions",":id","refund"],"variable":[{"key":"id","value":"","description":"Transaction identifier of the eSIM purchase."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"cookie":[],"responseTime":null,"body":"{\n  \"code\": 1000,\n  \"message\": \"Request processed successfully.\",\n  \"data\": {\n    \"refundId\": 501,\n    \"transactionId\": 23038,\n    \"hoiReference\": \"3f2b9c7e41d04a6b9e8f1c2d3a4b5c6d\",\n    \"clientExternalReference\": \"client-ref-2001\",\n    \"status\": \"Submitted\",\n    \"reasonCode\": \"NotWorking\",\n    \"reasonText\": \"Data plan never connected after activation.\",\n    \"clientReference\": \"SUPPORT-CASE-4821\",\n    \"requestedAt\": \"2026-08-30T09:12:41Z\",\n    \"decidedAt\": null,\n    \"decisionReasonCode\": null,\n    \"clientMessage\": null,\n    \"approvedAmount\": null,\n    \"refundedAmount\": null,\n    \"currency\": \"USD\"\n  }\n}"},{"id":"54b9976b-6bda-4d98-a5c3-0463558527f0","name":"Missing reasonCode","originalRequest":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"body":{"mode":"raw","raw":"{\n  \"reasonText\": \"Data plan never connected after activation.\"\n}","options":{"raw":{"language":"json"}}},"url":{"raw":"https://eservices.hoicom.net/api/v0/esim/transactions/:id/refund","host":["https://eservices.hoicom.net"],"path":["api","v0","esim","transactions",":id","refund"],"variable":[{"key":"id","value":"","description":"Transaction identifier of the eSIM purchase."}]}},"status":"Bad Request","code":400,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/problem+json"}],"cookie":[],"responseTime":null,"body":"{\n  \"type\": \"https://tools.ietf.org/html/rfc9110#section-15.5.1\",\n  \"title\": \"One or more validation errors occurred.\",\n  \"status\": 400,\n  \"errors\": {\n    \"ReasonCode\": [\n      \"The ReasonCode field is required.\"\n    ]\n  },\n  \"traceId\": \"00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-00\"\n}"},{"id":"e7ade17a-a081-4210-bba4-a6b3c76b2a82","name":"Unsupported reasonCode","originalRequest":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"body":{"mode":"raw","raw":"{\n  \"reasonCode\": \"Lost\"\n}","options":{"raw":{"language":"json"}}},"url":{"raw":"https://eservices.hoicom.net/api/v0/esim/transactions/:id/refund","host":["https://eservices.hoicom.net"],"path":["api","v0","esim","transactions",":id","refund"],"variable":[{"key":"id","value":"","description":"Transaction identifier of the eSIM purchase."}]}},"status":"Bad Request","code":400,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"cookie":[],"responseTime":null,"body":"{\n  \"code\": 1107,\n  \"message\": \"ReasonCode must be one of: NotActivated, NotWorking, WrongPurchase, Duplicate, Other.\",\n  \"data\": null\n}"},{"id":"148e0ae6-bcbb-4c75-b19c-05ed3ee91bd4","name":"Not eligible","originalRequest":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"body":{"mode":"raw","raw":"{\n  \"reasonCode\": \"NotWorking\",\n  \"reasonText\": \"Data plan never connected after activation.\",\n  \"clientReference\": \"SUPPORT-CASE-4821\"\n}","options":{"raw":{"language":"json"}}},"url":{"raw":"https://eservices.hoicom.net/api/v0/esim/transactions/:id/refund","host":["https://eservices.hoicom.net"],"path":["api","v0","esim","transactions",":id","refund"],"variable":[{"key":"id","value":"","description":"Transaction identifier of the eSIM purchase."}]}},"status":"Bad Request","code":400,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"cookie":[],"responseTime":null,"body":"{\n  \"code\": 1422,\n  \"message\": \"This transaction is not eligible for a refund\",\n  \"data\": null\n}"},{"id":"68e39c05-4932-4486-ab18-c42b143ca4e2","name":"Transaction not found","originalRequest":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"body":{"mode":"raw","raw":"{\n  \"reasonCode\": \"NotWorking\",\n  \"reasonText\": \"Data plan never connected after activation.\",\n  \"clientReference\": \"SUPPORT-CASE-4821\"\n}","options":{"raw":{"language":"json"}}},"url":{"raw":"https://eservices.hoicom.net/api/v0/esim/transactions/:id/refund","host":["https://eservices.hoicom.net"],"path":["api","v0","esim","transactions",":id","refund"],"variable":[{"key":"id","value":"","description":"Transaction identifier of the eSIM purchase."}]}},"status":"Not Found","code":404,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"cookie":[],"responseTime":null,"body":"{\n  \"code\": 1105,\n  \"message\": \"Resource not found.\",\n  \"data\": null\n}"},{"id":"767040bc-0f3b-4ab5-b306-6a7e39dcb738","name":"Refund already open","originalRequest":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"body":{"mode":"raw","raw":"{\n  \"reasonCode\": \"NotWorking\",\n  \"reasonText\": \"Data plan never connected after activation.\",\n  \"clientReference\": \"SUPPORT-CASE-4821\"\n}","options":{"raw":{"language":"json"}}},"url":{"raw":"https://eservices.hoicom.net/api/v0/esim/transactions/:id/refund","host":["https://eservices.hoicom.net"],"path":["api","v0","esim","transactions",":id","refund"],"variable":[{"key":"id","value":"","description":"Transaction identifier of the eSIM purchase."}]}},"status":"Conflict","code":409,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"cookie":[],"responseTime":null,"body":"{\n  \"code\": 1423,\n  \"message\": \"Refund not eligible: RequestAlreadyOpen.\",\n  \"data\": {\n    \"refundId\": 501,\n    \"transactionId\": 23038,\n    \"hoiReference\": \"3f2b9c7e41d04a6b9e8f1c2d3a4b5c6d\",\n    \"clientExternalReference\": \"client-ref-2001\",\n    \"status\": \"Submitted\",\n    \"reasonCode\": \"NotWorking\",\n    \"reasonText\": \"Data plan never connected after activation.\",\n    \"clientReference\": \"SUPPORT-CASE-4821\",\n    \"requestedAt\": \"2026-08-30T09:12:41Z\",\n    \"decidedAt\": null,\n    \"decisionReasonCode\": null,\n    \"clientMessage\": null,\n    \"approvedAmount\": null,\n    \"refundedAmount\": null,\n    \"currency\": \"USD\"\n  }\n}"},{"id":"e36195fe-a441-4188-a09f-9616905c7d7e","name":"Refund service unavailable","originalRequest":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"body":{"mode":"raw","raw":"{\n  \"reasonCode\": \"NotWorking\",\n  \"reasonText\": \"Data plan never connected after activation.\",\n  \"clientReference\": \"SUPPORT-CASE-4821\"\n}","options":{"raw":{"language":"json"}}},"url":{"raw":"https://eservices.hoicom.net/api/v0/esim/transactions/:id/refund","host":["https://eservices.hoicom.net"],"path":["api","v0","esim","transactions",":id","refund"],"variable":[{"key":"id","value":"","description":"Transaction identifier of the eSIM purchase."}]}},"status":"Service Unavailable","code":503,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"cookie":[],"responseTime":null,"body":"{\n  \"code\": 1426,\n  \"message\": \"Refund service unavailable.\",\n  \"data\": null\n}"}],"_postman_id":"733802a0-78f3-45b8-8c72-bdc091e451a5"},{"name":"Get Refund by Transaction","id":"bc6f958e-ffdc-4e4e-8f10-f722ab5e5196","request":{"method":"GET","header":[],"url":"https://eservices.hoicom.net/api/v0/esim/transactions/:id/refund","description":"<p>Returns the most recent refund request opened against an eSIM transaction. Use it when you know the transaction id but not the refund id, or to check whether a refund was ever requested for a transaction.</p>\n<hr />\n<h2 id=\"authorization\">Authorization</h2>\n<p>Requires Basic Authentication with your client credentials. Your account must be enabled for the eSIM service. You can only see and act on refunds for your own transactions.</p>\n<hr />\n<h2 id=\"path-parameters\">Path Parameters</h2>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Parameter</th>\n<th>Type</th>\n<th>Required</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>id</code></td>\n<td><code>int</code></td>\n<td>Yes</td>\n<td>Transaction identifier of the eSIM purchase.</td>\n</tr>\n</tbody>\n</table>\n</div><hr />\n<h2 id=\"response\">Response</h2>\n<p>On success <code>code</code> is <code>1000</code> and <code>data</code> is the refund request.</p>\n<h3 id=\"error-codes\">Error codes</h3>\n<p>1104 / 403: your account is not permitted to perform this refund action. 1105 / 404: the transaction or refund request was not found, or does not belong to your account (another client's records always return 1105).</p>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Code</th>\n<th>HTTP</th>\n<th>Meaning</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>1000</code></td>\n<td>200</td>\n<td>Refund request returned.</td>\n</tr>\n<tr>\n<td><code>1107</code></td>\n<td>400</td>\n<td>Validation error.</td>\n</tr>\n<tr>\n<td><code>1104</code></td>\n<td>403</td>\n<td>Your account is not permitted to perform this refund action.</td>\n</tr>\n<tr>\n<td><code>1105</code></td>\n<td>404</td>\n<td>The transaction or refund request was not found, or does not belong to your account (another client's records always return 1105).</td>\n</tr>\n<tr>\n<td><code>1101</code></td>\n<td>503</td>\n<td>Internal error while handling the request — retry after a short delay.</td>\n</tr>\n<tr>\n<td><code>1426</code></td>\n<td>503</td>\n<td>The refund service is temporarily unavailable — retry after a short delay.</td>\n</tr>\n</tbody>\n</table>\n</div><hr />\n<h2 id=\"response-fields\">Response fields</h2>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Field</th>\n<th>Type</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>code</td>\n<td>int</td>\n<td>Response status code; <code>1000</code> on success.</td>\n</tr>\n<tr>\n<td>message</td>\n<td>string</td>\n<td>Human-readable summary of the result.</td>\n</tr>\n<tr>\n<td>data</td>\n<td>object</td>\n<td>The refund request (<code>null</code> on most errors).</td>\n</tr>\n<tr>\n<td>data.refundId</td>\n<td>int</td>\n<td>The refund request's own id — use it with <strong>Get Refund</strong> and <strong>Withdraw Refund</strong>.</td>\n</tr>\n<tr>\n<td>data.transactionId</td>\n<td>int</td>\n<td>The eSIM transaction the refund was requested against.</td>\n</tr>\n<tr>\n<td>data.hoiReference</td>\n<td>string</td>\n<td>The Hoi reference of the refunded transaction.</td>\n</tr>\n<tr>\n<td>data.clientExternalReference</td>\n<td>string</td>\n<td>The <code>externalReference</code> you sent when buying the eSIM, if any.</td>\n</tr>\n<tr>\n<td>data.status</td>\n<td>string</td>\n<td>Refund status — see <strong>Status vocabulary</strong> in the eSIM folder description.</td>\n</tr>\n<tr>\n<td>data.reasonCode</td>\n<td>string</td>\n<td>The reason code you submitted.</td>\n</tr>\n<tr>\n<td>data.reasonText</td>\n<td>string</td>\n<td>The free text you submitted, if any.</td>\n</tr>\n<tr>\n<td>data.clientReference</td>\n<td>string</td>\n<td>Your own reference for the refund request, if any.</td>\n</tr>\n<tr>\n<td>data.requestedAt</td>\n<td>datetime</td>\n<td>When the refund was requested (UTC).</td>\n</tr>\n<tr>\n<td>data.decidedAt</td>\n<td>datetime</td>\n<td>When a decision was made, if any (UTC).</td>\n</tr>\n<tr>\n<td>data.decisionReasonCode</td>\n<td>string</td>\n<td>Short code explaining the decision, when available.</td>\n</tr>\n<tr>\n<td>data.clientMessage</td>\n<td>string</td>\n<td>Short human-readable sentence explaining the decision, when available.</td>\n</tr>\n<tr>\n<td>data.approvedAmount</td>\n<td>decimal</td>\n<td>Amount approved, once decided.</td>\n</tr>\n<tr>\n<td>data.refundedAmount</td>\n<td>decimal</td>\n<td>Amount actually refunded, once processed.</td>\n</tr>\n<tr>\n<td>data.currency</td>\n<td>string</td>\n<td>Currency of the amounts.</td>\n</tr>\n</tbody>\n</table>\n</div>","urlObject":{"path":["api","v0","esim","transactions",":id","refund"],"host":["https://eservices.hoicom.net"],"query":[],"variable":[{"description":{"content":"<p>Transaction identifier of the eSIM purchase.</p>\n","type":"text/plain"},"type":"any","value":"","key":"id"}]}},"response":[{"id":"9bd1f234-6f6e-4171-bae7-3b45042c4945","name":"OK","originalRequest":{"method":"GET","header":[],"url":{"raw":"https://eservices.hoicom.net/api/v0/esim/transactions/:id/refund","host":["https://eservices.hoicom.net"],"path":["api","v0","esim","transactions",":id","refund"],"variable":[{"key":"id","value":"","description":"Transaction identifier of the eSIM purchase."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"cookie":[],"responseTime":null,"body":"{\n  \"code\": 1000,\n  \"message\": \"Request processed successfully.\",\n  \"data\": {\n    \"refundId\": 501,\n    \"transactionId\": 23038,\n    \"hoiReference\": \"3f2b9c7e41d04a6b9e8f1c2d3a4b5c6d\",\n    \"clientExternalReference\": \"client-ref-2001\",\n    \"status\": \"UnderReview\",\n    \"reasonCode\": \"NotWorking\",\n    \"reasonText\": \"Data plan never connected after activation.\",\n    \"clientReference\": \"SUPPORT-CASE-4821\",\n    \"requestedAt\": \"2026-08-30T09:12:41Z\",\n    \"decidedAt\": null,\n    \"decisionReasonCode\": null,\n    \"clientMessage\": null,\n    \"approvedAmount\": null,\n    \"refundedAmount\": null,\n    \"currency\": \"USD\"\n  }\n}"},{"id":"cbadbd66-fc32-464b-8acd-1d8379a85e1b","name":"Not found","originalRequest":{"method":"GET","header":[],"url":{"raw":"https://eservices.hoicom.net/api/v0/esim/transactions/:id/refund","host":["https://eservices.hoicom.net"],"path":["api","v0","esim","transactions",":id","refund"],"variable":[{"key":"id","value":"","description":"Transaction identifier of the eSIM purchase."}]}},"status":"Not Found","code":404,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"cookie":[],"responseTime":null,"body":"{\n  \"code\": 1105,\n  \"message\": \"Resource not found.\",\n  \"data\": null\n}"},{"id":"72865549-fda6-4997-a500-5254d1bfefd5","name":"Refund service unavailable","originalRequest":{"method":"GET","header":[],"url":{"raw":"https://eservices.hoicom.net/api/v0/esim/transactions/:id/refund","host":["https://eservices.hoicom.net"],"path":["api","v0","esim","transactions",":id","refund"],"variable":[{"key":"id","value":"","description":"Transaction identifier of the eSIM purchase."}]}},"status":"Service Unavailable","code":503,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"cookie":[],"responseTime":null,"body":"{\n  \"code\": 1426,\n  \"message\": \"Refund service unavailable.\",\n  \"data\": null\n}"}],"_postman_id":"bc6f958e-ffdc-4e4e-8f10-f722ab5e5196"},{"name":"Get Refund","id":"17b65539-9c9d-4761-9e38-cc9ca550c76f","request":{"method":"GET","header":[],"url":"https://eservices.hoicom.net/api/v0/esim/refunds/:refundId","description":"<p>Returns one refund request by its own id. This is the endpoint to poll after <strong>Request Refund</strong> until <code>status</code> is terminal (<code>Refunded</code>, <code>AutoRejected</code>, <code>Rejected</code> or <code>Withdrawn</code>). Poll every 30–60 seconds; refunds have no callbacks or webhooks.</p>\n<hr />\n<h2 id=\"authorization\">Authorization</h2>\n<p>Requires Basic Authentication with your client credentials. Your account must be enabled for the eSIM service. You can only see and act on refunds for your own transactions.</p>\n<hr />\n<h2 id=\"path-parameters\">Path Parameters</h2>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Parameter</th>\n<th>Type</th>\n<th>Required</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>refundId</code></td>\n<td><code>int</code></td>\n<td>Yes</td>\n<td>The refund request id (<code>data.refundId</code>).</td>\n</tr>\n</tbody>\n</table>\n</div><hr />\n<h2 id=\"response\">Response</h2>\n<p>On success <code>code</code> is <code>1000</code> and <code>data</code> is the refund request.</p>\n<h3 id=\"error-codes\">Error codes</h3>\n<p>1104 / 403: your account is not permitted to perform this refund action. 1105 / 404: the transaction or refund request was not found, or does not belong to your account (another client's records always return 1105).</p>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Code</th>\n<th>HTTP</th>\n<th>Meaning</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>1000</code></td>\n<td>200</td>\n<td>Refund request returned.</td>\n</tr>\n<tr>\n<td><code>1107</code></td>\n<td>400</td>\n<td>Validation error (invalid <code>refundId</code>).</td>\n</tr>\n<tr>\n<td><code>1104</code></td>\n<td>403</td>\n<td>Your account is not permitted to perform this refund action.</td>\n</tr>\n<tr>\n<td><code>1105</code></td>\n<td>404</td>\n<td>The transaction or refund request was not found, or does not belong to your account (another client's records always return 1105).</td>\n</tr>\n<tr>\n<td><code>1101</code></td>\n<td>503</td>\n<td>Internal error while handling the request — retry after a short delay.</td>\n</tr>\n<tr>\n<td><code>1426</code></td>\n<td>503</td>\n<td>The refund service is temporarily unavailable — retry after a short delay.</td>\n</tr>\n</tbody>\n</table>\n</div><hr />\n<h2 id=\"response-fields\">Response fields</h2>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Field</th>\n<th>Type</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>code</td>\n<td>int</td>\n<td>Response status code; <code>1000</code> on success.</td>\n</tr>\n<tr>\n<td>message</td>\n<td>string</td>\n<td>Human-readable summary of the result.</td>\n</tr>\n<tr>\n<td>data</td>\n<td>object</td>\n<td>The refund request (<code>null</code> on most errors).</td>\n</tr>\n<tr>\n<td>data.refundId</td>\n<td>int</td>\n<td>The refund request's own id — use it with <strong>Get Refund</strong> and <strong>Withdraw Refund</strong>.</td>\n</tr>\n<tr>\n<td>data.transactionId</td>\n<td>int</td>\n<td>The eSIM transaction the refund was requested against.</td>\n</tr>\n<tr>\n<td>data.hoiReference</td>\n<td>string</td>\n<td>The Hoi reference of the refunded transaction.</td>\n</tr>\n<tr>\n<td>data.clientExternalReference</td>\n<td>string</td>\n<td>The <code>externalReference</code> you sent when buying the eSIM, if any.</td>\n</tr>\n<tr>\n<td>data.status</td>\n<td>string</td>\n<td>Refund status — see <strong>Status vocabulary</strong> in the eSIM folder description.</td>\n</tr>\n<tr>\n<td>data.reasonCode</td>\n<td>string</td>\n<td>The reason code you submitted.</td>\n</tr>\n<tr>\n<td>data.reasonText</td>\n<td>string</td>\n<td>The free text you submitted, if any.</td>\n</tr>\n<tr>\n<td>data.clientReference</td>\n<td>string</td>\n<td>Your own reference for the refund request, if any.</td>\n</tr>\n<tr>\n<td>data.requestedAt</td>\n<td>datetime</td>\n<td>When the refund was requested (UTC).</td>\n</tr>\n<tr>\n<td>data.decidedAt</td>\n<td>datetime</td>\n<td>When a decision was made, if any (UTC).</td>\n</tr>\n<tr>\n<td>data.decisionReasonCode</td>\n<td>string</td>\n<td>Short code explaining the decision, when available.</td>\n</tr>\n<tr>\n<td>data.clientMessage</td>\n<td>string</td>\n<td>Short human-readable sentence explaining the decision, when available.</td>\n</tr>\n<tr>\n<td>data.approvedAmount</td>\n<td>decimal</td>\n<td>Amount approved, once decided.</td>\n</tr>\n<tr>\n<td>data.refundedAmount</td>\n<td>decimal</td>\n<td>Amount actually refunded, once processed.</td>\n</tr>\n<tr>\n<td>data.currency</td>\n<td>string</td>\n<td>Currency of the amounts.</td>\n</tr>\n</tbody>\n</table>\n</div>","urlObject":{"path":["api","v0","esim","refunds",":refundId"],"host":["https://eservices.hoicom.net"],"query":[],"variable":[{"description":{"content":"<p>The refund request id (<code>data.refundId</code>).</p>\n","type":"text/plain"},"type":"any","value":"","key":"refundId"}]}},"response":[{"id":"029e98d6-03ca-470c-b5d7-b8ee97d52df4","name":"OK","originalRequest":{"method":"GET","header":[],"url":{"raw":"https://eservices.hoicom.net/api/v0/esim/refunds/:refundId","host":["https://eservices.hoicom.net"],"path":["api","v0","esim","refunds",":refundId"],"variable":[{"key":"refundId","value":"","description":"The refund request id (`data.refundId`)."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"cookie":[],"responseTime":null,"body":"{\n  \"code\": 1000,\n  \"message\": \"Request processed successfully.\",\n  \"data\": {\n    \"refundId\": 501,\n    \"transactionId\": 23038,\n    \"hoiReference\": \"3f2b9c7e41d04a6b9e8f1c2d3a4b5c6d\",\n    \"clientExternalReference\": \"client-ref-2001\",\n    \"status\": \"Refunded\",\n    \"reasonCode\": \"NotWorking\",\n    \"reasonText\": \"Data plan never connected after activation.\",\n    \"clientReference\": \"SUPPORT-CASE-4821\",\n    \"requestedAt\": \"2026-08-30T09:12:41Z\",\n    \"decidedAt\": \"2026-08-30T09:14:05Z\",\n    \"decisionReasonCode\": \"ProfileNotInstalled\",\n    \"clientMessage\": \"Your refund has been approved.\",\n    \"approvedAmount\": 12.5,\n    \"refundedAmount\": 12.5,\n    \"currency\": \"USD\"\n  }\n}"},{"id":"6eb5869a-3544-4f79-b42b-607ccc03811b","name":"Not found","originalRequest":{"method":"GET","header":[],"url":{"raw":"https://eservices.hoicom.net/api/v0/esim/refunds/:refundId","host":["https://eservices.hoicom.net"],"path":["api","v0","esim","refunds",":refundId"],"variable":[{"key":"refundId","value":"","description":"The refund request id (`data.refundId`)."}]}},"status":"Not Found","code":404,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"cookie":[],"responseTime":null,"body":"{\n  \"code\": 1105,\n  \"message\": \"Resource not found.\",\n  \"data\": null\n}"},{"id":"45f7ea79-e688-4ca4-83dc-b80586f9b4f4","name":"Refund service unavailable","originalRequest":{"method":"GET","header":[],"url":{"raw":"https://eservices.hoicom.net/api/v0/esim/refunds/:refundId","host":["https://eservices.hoicom.net"],"path":["api","v0","esim","refunds",":refundId"],"variable":[{"key":"refundId","value":"","description":"The refund request id (`data.refundId`)."}]}},"status":"Service Unavailable","code":503,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"cookie":[],"responseTime":null,"body":"{\n  \"code\": 1426,\n  \"message\": \"Refund service unavailable.\",\n  \"data\": null\n}"}],"_postman_id":"17b65539-9c9d-4761-9e38-cc9ca550c76f"},{"name":"Withdraw Refund","id":"78fe42b4-1d42-469c-bb81-2b6be42e02d1","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"body":{"mode":"raw","raw":"{\n  \"note\": \"Customer resolved the issue directly, no longer needed.\"\n}","options":{"raw":{"language":"json"}}},"url":"https://eservices.hoicom.net/api/v0/esim/refunds/:refundId/withdraw","description":"<p>Withdraws an open refund request. Only possible while the request is still open (<code>Submitted</code> or <code>UnderReview</code>); once a decision has been made it returns <code>1424</code>. On success the request's <code>status</code> becomes <code>Withdrawn</code>.</p>\n<hr />\n<h2 id=\"authorization\">Authorization</h2>\n<p>Requires Basic Authentication with your client credentials. Your account must be enabled for the eSIM service. You can only see and act on refunds for your own transactions.</p>\n<hr />\n<h2 id=\"path-parameters\">Path Parameters</h2>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Parameter</th>\n<th>Type</th>\n<th>Required</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>refundId</code></td>\n<td><code>int</code></td>\n<td>Yes</td>\n<td>The refund request id (<code>data.refundId</code>).</td>\n</tr>\n</tbody>\n</table>\n</div><hr />\n<h2 id=\"request-body\">Request Body</h2>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Field</th>\n<th>Type</th>\n<th>Required</th>\n<th>Constraints</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>note</code></td>\n<td><code>string</code></td>\n<td>No</td>\n<td>Free text, max 1000 characters.</td>\n</tr>\n</tbody>\n</table>\n</div><p>Body: required JSON object. <code>note</code> is optional (max 1000 characters); send <code>{}</code> if you have no note. An empty body or malformed JSON returns HTTP 400 with a standard validation problem body (not the <code>code</code>/<code>message</code> envelope).</p>\n<hr />\n<h2 id=\"response\">Response</h2>\n<p>On success <code>code</code> is <code>1000</code> and <code>data</code> is the refund request with <code>status</code> = <code>Withdrawn</code>.</p>\n<h3 id=\"error-codes\">Error codes</h3>\n<p>1104 / 403: your account is not permitted to perform this refund action. 1105 / 404: the transaction or refund request was not found, or does not belong to your account (another client's records always return 1105).</p>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Code</th>\n<th>HTTP</th>\n<th>Meaning</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>1000</code></td>\n<td>200</td>\n<td>Refund request withdrawn.</td>\n</tr>\n<tr>\n<td><code>1107</code></td>\n<td>400</td>\n<td>Validation error (invalid <code>refundId</code>, <code>note</code> too long).</td>\n</tr>\n<tr>\n<td><code>1104</code></td>\n<td>403</td>\n<td>Your account is not permitted to perform this refund action.</td>\n</tr>\n<tr>\n<td><code>1105</code></td>\n<td>404</td>\n<td>The transaction or refund request was not found, or does not belong to your account (another client's records always return 1105).</td>\n</tr>\n<tr>\n<td><code>1424</code></td>\n<td>409</td>\n<td>The request can no longer be withdrawn (a decision has already been made) — message <code>This refund request can no longer be withdrawn.</code> Also returned, with message <code>This refund request was just updated. Please refresh and try again.</code>, if the request changed at the same moment: fetch it with <strong>Get Refund</strong> and retry only if it is still open.</td>\n</tr>\n<tr>\n<td><code>1101</code></td>\n<td>503</td>\n<td>Internal error while handling the request — retry after a short delay.</td>\n</tr>\n<tr>\n<td><code>1426</code></td>\n<td>503</td>\n<td>The refund service is temporarily unavailable — retry after a short delay.</td>\n</tr>\n</tbody>\n</table>\n</div><hr />\n<h2 id=\"response-fields\">Response fields</h2>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Field</th>\n<th>Type</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>code</td>\n<td>int</td>\n<td>Response status code; <code>1000</code> on success.</td>\n</tr>\n<tr>\n<td>message</td>\n<td>string</td>\n<td>Human-readable summary of the result.</td>\n</tr>\n<tr>\n<td>data</td>\n<td>object</td>\n<td>The refund request (<code>null</code> on most errors).</td>\n</tr>\n<tr>\n<td>data.refundId</td>\n<td>int</td>\n<td>The refund request's own id — use it with <strong>Get Refund</strong> and <strong>Withdraw Refund</strong>.</td>\n</tr>\n<tr>\n<td>data.transactionId</td>\n<td>int</td>\n<td>The eSIM transaction the refund was requested against.</td>\n</tr>\n<tr>\n<td>data.hoiReference</td>\n<td>string</td>\n<td>The Hoi reference of the refunded transaction.</td>\n</tr>\n<tr>\n<td>data.clientExternalReference</td>\n<td>string</td>\n<td>The <code>externalReference</code> you sent when buying the eSIM, if any.</td>\n</tr>\n<tr>\n<td>data.status</td>\n<td>string</td>\n<td>Refund status — see <strong>Status vocabulary</strong> in the eSIM folder description.</td>\n</tr>\n<tr>\n<td>data.reasonCode</td>\n<td>string</td>\n<td>The reason code you submitted.</td>\n</tr>\n<tr>\n<td>data.reasonText</td>\n<td>string</td>\n<td>The free text you submitted, if any.</td>\n</tr>\n<tr>\n<td>data.clientReference</td>\n<td>string</td>\n<td>Your own reference for the refund request, if any.</td>\n</tr>\n<tr>\n<td>data.requestedAt</td>\n<td>datetime</td>\n<td>When the refund was requested (UTC).</td>\n</tr>\n<tr>\n<td>data.decidedAt</td>\n<td>datetime</td>\n<td>When a decision was made, if any (UTC).</td>\n</tr>\n<tr>\n<td>data.decisionReasonCode</td>\n<td>string</td>\n<td>Short code explaining the decision, when available.</td>\n</tr>\n<tr>\n<td>data.clientMessage</td>\n<td>string</td>\n<td>Short human-readable sentence explaining the decision, when available.</td>\n</tr>\n<tr>\n<td>data.approvedAmount</td>\n<td>decimal</td>\n<td>Amount approved, once decided.</td>\n</tr>\n<tr>\n<td>data.refundedAmount</td>\n<td>decimal</td>\n<td>Amount actually refunded, once processed.</td>\n</tr>\n<tr>\n<td>data.currency</td>\n<td>string</td>\n<td>Currency of the amounts.</td>\n</tr>\n</tbody>\n</table>\n</div>","urlObject":{"path":["api","v0","esim","refunds",":refundId","withdraw"],"host":["https://eservices.hoicom.net"],"query":[],"variable":[{"description":{"content":"<p>The refund request id (<code>data.refundId</code>).</p>\n","type":"text/plain"},"type":"any","value":"","key":"refundId"}]}},"response":[{"id":"8d40732c-1902-4a76-843c-1b360a520165","name":"OK","originalRequest":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"body":{"mode":"raw","raw":"{\n  \"note\": \"Customer resolved the issue directly, no longer needed.\"\n}","options":{"raw":{"language":"json"}}},"url":{"raw":"https://eservices.hoicom.net/api/v0/esim/refunds/:refundId/withdraw","host":["https://eservices.hoicom.net"],"path":["api","v0","esim","refunds",":refundId","withdraw"],"variable":[{"key":"refundId","value":"","description":"The refund request id (`data.refundId`)."}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"cookie":[],"responseTime":null,"body":"{\n  \"code\": 1000,\n  \"message\": \"Request processed successfully.\",\n  \"data\": {\n    \"refundId\": 501,\n    \"transactionId\": 23038,\n    \"hoiReference\": \"3f2b9c7e41d04a6b9e8f1c2d3a4b5c6d\",\n    \"clientExternalReference\": \"client-ref-2001\",\n    \"status\": \"Withdrawn\",\n    \"reasonCode\": \"NotWorking\",\n    \"reasonText\": \"Data plan never connected after activation.\",\n    \"clientReference\": \"SUPPORT-CASE-4821\",\n    \"requestedAt\": \"2026-08-30T09:12:41Z\",\n    \"decidedAt\": null,\n    \"decisionReasonCode\": null,\n    \"clientMessage\": null,\n    \"approvedAmount\": null,\n    \"refundedAmount\": null,\n    \"currency\": \"USD\"\n  }\n}"},{"id":"9912219e-0bf8-4640-9ce8-aaae13a025e3","name":"Not found","originalRequest":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"body":{"mode":"raw","raw":"{\n  \"note\": \"Customer resolved the issue directly, no longer needed.\"\n}","options":{"raw":{"language":"json"}}},"url":{"raw":"https://eservices.hoicom.net/api/v0/esim/refunds/:refundId/withdraw","host":["https://eservices.hoicom.net"],"path":["api","v0","esim","refunds",":refundId","withdraw"],"variable":[{"key":"refundId","value":"","description":"The refund request id (`data.refundId`)."}]}},"status":"Not Found","code":404,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"cookie":[],"responseTime":null,"body":"{\n  \"code\": 1105,\n  \"message\": \"Resource not found.\",\n  \"data\": null\n}"},{"id":"0b4161a6-c53b-4857-a42b-da0524ffac48","name":"Already decided","originalRequest":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"body":{"mode":"raw","raw":"{\n  \"note\": \"Customer resolved the issue directly, no longer needed.\"\n}","options":{"raw":{"language":"json"}}},"url":{"raw":"https://eservices.hoicom.net/api/v0/esim/refunds/:refundId/withdraw","host":["https://eservices.hoicom.net"],"path":["api","v0","esim","refunds",":refundId","withdraw"],"variable":[{"key":"refundId","value":"","description":"The refund request id (`data.refundId`)."}]}},"status":"Conflict","code":409,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"cookie":[],"responseTime":null,"body":"{\n  \"code\": 1424,\n  \"message\": \"This refund request can no longer be withdrawn.\",\n  \"data\": null\n}"},{"id":"db46d6b6-ede9-41bc-b4be-177ee5d58bf9","name":"Just updated","originalRequest":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"body":{"mode":"raw","raw":"{\n  \"note\": \"Customer resolved the issue directly, no longer needed.\"\n}","options":{"raw":{"language":"json"}}},"url":{"raw":"https://eservices.hoicom.net/api/v0/esim/refunds/:refundId/withdraw","host":["https://eservices.hoicom.net"],"path":["api","v0","esim","refunds",":refundId","withdraw"],"variable":[{"key":"refundId","value":"","description":"The refund request id (`data.refundId`)."}]}},"status":"Conflict","code":409,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"cookie":[],"responseTime":null,"body":"{\n  \"code\": 1424,\n  \"message\": \"This refund request was just updated. Please refresh and try again.\",\n  \"data\": null\n}"},{"id":"fa59ebd6-d5a3-4911-9354-ff2637989c85","name":"Refund service unavailable","originalRequest":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"body":{"mode":"raw","raw":"{\n  \"note\": \"Customer resolved the issue directly, no longer needed.\"\n}","options":{"raw":{"language":"json"}}},"url":{"raw":"https://eservices.hoicom.net/api/v0/esim/refunds/:refundId/withdraw","host":["https://eservices.hoicom.net"],"path":["api","v0","esim","refunds",":refundId","withdraw"],"variable":[{"key":"refundId","value":"","description":"The refund request id (`data.refundId`)."}]}},"status":"Service Unavailable","code":503,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"cookie":[],"responseTime":null,"body":"{\n  \"code\": 1426,\n  \"message\": \"Refund service unavailable.\",\n  \"data\": null\n}"}],"_postman_id":"78fe42b4-1d42-469c-bb81-2b6be42e02d1"}],"id":"c0e910a2-b327-4a3d-b85c-5e4dcd27b52e","description":"<p>Request, track and withdraw refunds for completed eSIM purchases. Decisions are made in the background, so poll until the status is final. Full guide (request/response examples, <code>decisionReasonCode</code> values, errors): see <strong>eSIM Refunds</strong> in the eSIM folder description.</p>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Method</th>\n<th>Endpoint</th>\n<th>Request</th>\n<th>Purpose</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>POST</code></td>\n<td><code>/api/v0/esim/transactions/{id}/refund</code></td>\n<td><strong>Request Refund</strong></td>\n<td>Open a refund request for a <code>Completed</code> transaction.</td>\n</tr>\n<tr>\n<td><code>GET</code></td>\n<td><code>/api/v0/esim/transactions/{id}/refund</code></td>\n<td><strong>Get Refund by Transaction</strong></td>\n<td>Most recent refund request for a transaction.</td>\n</tr>\n<tr>\n<td><code>GET</code></td>\n<td><code>/api/v0/esim/refunds/{refundId}</code></td>\n<td><strong>Get Refund</strong></td>\n<td>One refund request by id — poll this.</td>\n</tr>\n<tr>\n<td><code>POST</code></td>\n<td><code>/api/v0/esim/refunds/{refundId}/withdraw</code></td>\n<td><strong>Withdraw Refund</strong></td>\n<td>Withdraw a request that is still open.</td>\n</tr>\n</tbody>\n</table>\n</div><h3 id=\"refund-status-status\">Refund status (<code>status</code>)</h3>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Status</th>\n<th>What it means for you</th>\n<th>Final?</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>Submitted</code></td>\n<td>Received and awaiting a decision. You can still withdraw it.</td>\n<td>No</td>\n</tr>\n<tr>\n<td><code>AutoApproved</code></td>\n<td>Approved automatically; moving on to be processed.</td>\n<td>No</td>\n</tr>\n<tr>\n<td><code>UnderReview</code></td>\n<td>Needs a closer look by our support team before a decision is made. You can still withdraw it.</td>\n<td>No</td>\n</tr>\n<tr>\n<td><code>Approved</code></td>\n<td>Approved after review; moving on to be processed.</td>\n<td>No</td>\n</tr>\n<tr>\n<td><code>Processing</code></td>\n<td>Approved and currently being carried out.</td>\n<td>No</td>\n</tr>\n<tr>\n<td><code>Refunded</code></td>\n<td>Done — the amount has been refunded and the transaction is excluded from your settlement totals.</td>\n<td><strong>Yes</strong></td>\n</tr>\n<tr>\n<td><code>AutoRejected</code></td>\n<td>Rejected automatically (see the limitations below). You may submit a new request after the 7-day cooldown, if the transaction is still eligible.</td>\n<td><strong>Yes</strong></td>\n</tr>\n<tr>\n<td><code>Rejected</code></td>\n<td>Rejected after review.</td>\n<td><strong>Yes</strong></td>\n</tr>\n<tr>\n<td><code>Failed</code></td>\n<td>Could not be completed yet and is being resolved — keep polling; it may move to <code>UnderReview</code> or <code>Refunded</code>.</td>\n<td>No</td>\n</tr>\n<tr>\n<td><code>Withdrawn</code></td>\n<td>You withdrew the request before a decision was made.</td>\n<td><strong>Yes</strong></td>\n</tr>\n</tbody>\n</table>\n</div><h3 id=\"refund-reasons-reasoncode\">Refund reasons (<code>reasonCode</code>)</h3>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Reason</th>\n<th>Use it when</th>\n<th>How it is assessed</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>NotActivated</code></td>\n<td>The eSIM/plan was never activated.</td>\n<td>Up to 49 MB of usage is tolerated.</td>\n</tr>\n<tr>\n<td><code>NotWorking</code></td>\n<td>The eSIM/plan was activated but did not work as expected.</td>\n<td>Up to 49 MB of usage is tolerated.</td>\n</tr>\n<tr>\n<td><code>WrongPurchase</code></td>\n<td>The wrong product was purchased (e.g. wrong country or plan).</td>\n<td>Strict: the eSIM must not have been installed or activated and must have used no data.</td>\n</tr>\n<tr>\n<td><code>Duplicate</code></td>\n<td>The same purchase was made more than once in error.</td>\n<td>Strict: the eSIM must not have been installed or activated and must have used no data.</td>\n</tr>\n<tr>\n<td><code>Other</code></td>\n<td>Any reason not covered above — explain it in <code>reasonText</code>.</td>\n<td>Up to 49 MB of usage is tolerated.</td>\n</tr>\n</tbody>\n</table>\n</div><h3 id=\"limitations\">Limitations</h3>\n<p><strong>Refused immediately</strong> — 400 / <code>1422</code>, no refund request is created and <code>message</code> names the reason:</p>\n<ul>\n<li>Only a <code>Completed</code> transaction can be refunded.</li>\n<li>The request must be made within <strong>59 days</strong> of the purchase's completion (<code>OutsideWindow</code>).</li>\n<li>After a refund request for a transaction is rejected, a new request for it can't be made for <strong>7 days</strong> (<code>CooldownActive</code>).</li>\n</ul>\n<p><strong>One request at a time</strong> — 409 / <code>1423</code>:</p>\n<ul>\n<li>Only one refund request can be open per transaction; <code>data</code> carries the open request.</li>\n<li>While an eSIM regeneration is in progress, a refund request is refused (<code>data</code> is <code>null</code>) — retry once it has finished. Likewise, an eSIM with an open refund can't be regenerated.</li>\n</ul>\n<p><strong>Decided in the background</strong> — the request is created, then ends as shown:</p>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Situation</th>\n<th>Outcome</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>The plan has expired.</td>\n<td><code>AutoRejected</code> (<code>BundleExpired</code>)</td>\n</tr>\n<tr>\n<td>More than 49 MB used (<code>NotActivated</code> / <code>NotWorking</code> / <code>Other</code>).</td>\n<td><code>AutoRejected</code> (<code>DataConsumed</code>)</td>\n</tr>\n<tr>\n<td><code>WrongPurchase</code> / <code>Duplicate</code> on an eSIM that was installed, activated or used any data.</td>\n<td><code>AutoRejected</code> (<code>InstalledUnused</code> / <code>DataConsumed</code>)</td>\n</tr>\n<tr>\n<td>Never installed, never activated, no data used.</td>\n<td><code>AutoApproved</code> → <code>Refunded</code></td>\n</tr>\n<tr>\n<td>Installed but unused, 1–49 MB used, a top-up, or an eSIM with active top-ups.</td>\n<td><code>UnderReview</code> — decided by our support team</td>\n</tr>\n</tbody>\n</table>\n</div><p>A withdrawal is only possible while the request is <code>Submitted</code> or <code>UnderReview</code>; after a decision it returns 409 / <code>1424</code>.</p>\n<p>1104 / 403: your account is not permitted to perform this refund action. 1105 / 404: the transaction or refund request was not found, or does not belong to your account (another client's records always return 1105).</p>\n<p>Body: required JSON object. <code>note</code> is optional (max 1000 characters); send <code>{}</code> if you have no note.</p>\n","_postman_id":"c0e910a2-b327-4a3d-b85c-5e4dcd27b52e"}],"id":"b165bde1-7c03-4ce2-97ec-0269bf94fe43","description":"<p>The <strong>eSIM</strong> service lets you browse and provision data eSIM plans for travellers — discover coverage by country or region, buy a plan, receive the eSIM (QR / activation details), track the order, monitor data usage, and top up an active plan.</p>\n<hr />\n<h2 id=\"client-flow\">Client Flow</h2>\n<ol>\n<li><strong>Browse coverage</strong> — <code>GET /regions</code>, <code>GET /countries</code>, <code>GET /plans</code> (or <code>GET /plans/country/{iso}</code> / <code>GET /plans/region/{code}</code>).</li>\n<li><strong>Inspect a plan</strong> — <code>GET /plans/{id}/networks</code> (operators) and <code>GET /plans/{id}/topups</code> (add-ons).</li>\n<li><strong>Buy</strong> — <code>POST /transactions/async</code>; returns a <code>transactionId</code>, provisioning happens in the background.</li>\n<li><strong>Track</strong> — poll <code>GET /transactions/{id}</code> until <code>status</code> is <code>Completed</code>; the response then carries the eSIM <code>product</code> (ICCID, activation code, QR code).</li>\n<li><strong>Monitor usage</strong> — <code>GET /transactions/{id}/plans/usage</code> (or <code>.../reference/{externalReference}/plans/usage</code>).</li>\n<li><strong>Top up (optional)</strong> — <code>POST /transactions/async</code> again with <code>mainTransactionId</code> set to the original transaction id. The target must be <strong>your own <code>Completed</code> base plan</strong>; anything else returns HTTP 404 / <code>1303</code>. If that eSIM is being replaced at that moment you get HTTP 409 / <code>1429</code>; retry shortly.</li>\n<li><strong>Replace a faulty eSIM (optional)</strong> — <code>POST /transactions/{id}/regenerate</code> (or <code>.../reference/{externalReference}/regenerate</code>), then poll <code>GET /transactions/{id}?include=regenerations</code> until <code>regenerations.inProgress</code> is <code>false</code>, then check the latest <code>regenerations.items[]</code> status. Only <code>Completed</code> provides new eSIM details; <code>Failed</code> retains the previous details.</li>\n</ol>\n<p><code>externalReference</code> must be <strong>unique within your account across all your services</strong>. Re-using one returns HTTP 409 / <code>1114</code>. Other clients' references never collide with yours.</p>\n<p><strong>Data units.</strong> Data allowances are normalised: 1 GB and above are shown in decimal GB (a 1024 MB plan reads <code>1 GB</code>), smaller amounts in MB. The plan catalogue is large and its size is not fixed; do not hard-code counts. <code>lang=ar</code> (Arabic) is supported on the plans and top-ups endpoints.</p>\n<hr />\n<h2 id=\"regenerating-an-esim\">Regenerating an eSIM</h2>\n<p>If an eSIM does not install or work, you can have it replaced by a new one at no charge.</p>\n<ul>\n<li><code>POST /api/v0/esim/transactions/{id}/regenerate</code> or <code>POST /api/v0/esim/transactions/reference/{externalReference}/regenerate</code>.</li>\n<li>Body: <code>reasonCode</code> (<code>NotActivated</code> or <code>NotWorking</code>), optional <code>reasonText</code> (max 500 characters).</li>\n<li>The <strong>same transaction</strong> is updated in place: it gets a new ICCID, activation code and QR code; the <code>transactionId</code>, <code>externalReference</code>, amounts and <code>status</code> do not change. Nothing is charged.</li>\n<li>Regeneration runs in the background. Poll <code>GET /transactions/{id}?include=regenerations</code> until <code>regenerations.inProgress</code> is <code>false</code>, then check the <code>status</code> of the latest entry in <code>regenerations.items[]</code>. Only when it is <code>Completed</code> does the transaction carry the new eSIM; on <code>Failed</code> it still shows the previous eSIM details.</li>\n<li>Only a <code>Completed</code> base plan can be regenerated (not a top-up).</li>\n<li>While a regeneration is in progress, a top-up on that eSIM returns 409 / <code>1429</code>, and a refund request returns 409 / <code>1423</code>.</li>\n</ul>\n<p><strong>Conditions (all must be true)</strong></p>\n<ul>\n<li>A base plan (not a top-up)</li>\n<li>Status <code>Completed</code></li>\n<li>Within 59 days of purchase</li>\n<li>No more than 49 MB used</li>\n<li>Neither the eSIM plan nor the eSIM profile has expired.</li>\n<li>No active top-up</li>\n<li>Fewer than 3 regenerations so far</li>\n<li>No open refund request, and not refunded</li>\n<li>This eSIM is eligible for regeneration</li>\n</ul>\n<p><strong>Refused requests</strong></p>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>HTTP</th>\n<th>Code</th>\n<th>Meaning</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>400</td>\n<td><code>1107</code></td>\n<td>Invalid request.</td>\n</tr>\n<tr>\n<td>400</td>\n<td><code>1427</code></td>\n<td>1427 is returned when the eSIM plan or the eSIM profile has expired. Other eligibility conditions can also cause this code; read <code>message</code> for the reason.</td>\n</tr>\n<tr>\n<td>409</td>\n<td><code>1428</code></td>\n<td>The limit of 3 regenerations has been reached.</td>\n</tr>\n<tr>\n<td>409</td>\n<td><code>1429</code></td>\n<td>A regeneration is already in progress.</td>\n</tr>\n<tr>\n<td>503</td>\n<td><code>1410</code></td>\n<td>Service temporarily unavailable; retry.</td>\n</tr>\n</tbody>\n</table>\n</div><hr />\n<h2 id=\"reference-values\">Reference values</h2>\n<h3 id=\"transaction-status-status\">Transaction status (<code>status</code>)</h3>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Value</th>\n<th>Meaning</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>Submitted</code></td>\n<td>Received and queued for processing.</td>\n</tr>\n<tr>\n<td><code>Pending</code></td>\n<td>Being processed / provisioned.</td>\n</tr>\n<tr>\n<td><code>Completed</code></td>\n<td>Completed successfully; eSIM details available.</td>\n</tr>\n<tr>\n<td><code>Failed</code></td>\n<td>Processing failed.</td>\n</tr>\n<tr>\n<td><code>Cancelled</code></td>\n<td>Cancelled before completion.</td>\n</tr>\n<tr>\n<td><code>Refunded</code></td>\n<td>The completed purchase was refunded — see <strong>eSIM Refunds</strong> below.</td>\n</tr>\n</tbody>\n</table>\n</div><h3 id=\"coverage-type-coveragetype\">Coverage type (<code>coverageType</code>)</h3>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Value</th>\n<th>Meaning</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>LOCAL</code></td>\n<td>Covers a single country.</td>\n</tr>\n<tr>\n<td><code>REGIONAL</code></td>\n<td>Covers a region (e.g. Europe).</td>\n</tr>\n<tr>\n<td><code>GLOBAL</code></td>\n<td>Worldwide coverage.</td>\n</tr>\n</tbody>\n</table>\n</div><h3 id=\"pricing-type-pricingtype\">Pricing type (<code>pricing.type</code>)</h3>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Value</th>\n<th>Meaning</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>FIXED</code></td>\n<td>Single fixed price (<code>minAmount</code> = <code>maxAmount</code>).</td>\n</tr>\n<tr>\n<td><code>RANGED</code></td>\n<td>Any amount between <code>minAmount</code> and <code>maxAmount</code>.</td>\n</tr>\n</tbody>\n</table>\n</div><h3 id=\"product-type-productplantype\">Product type (<code>product.planType</code>)</h3>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Value</th>\n<th>Meaning</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>Plan</code></td>\n<td>A primary data plan.</td>\n</tr>\n<tr>\n<td><code>Topup</code></td>\n<td>A top-up / add-on for an existing plan.</td>\n</tr>\n</tbody>\n</table>\n</div><h3 id=\"plan-status-planstatus--usage\">Plan status (<code>planStatus</code> — usage)</h3>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Value</th>\n<th>Meaning</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>NotStarted</code></td>\n<td>Plan not started yet.</td>\n</tr>\n<tr>\n<td><code>Active</code></td>\n<td>Plan active and usable.</td>\n</tr>\n<tr>\n<td><code>Pending</code></td>\n<td>Plan pending activation.</td>\n</tr>\n<tr>\n<td><code>Expired</code></td>\n<td>Plan expired or data exhausted.</td>\n</tr>\n</tbody>\n</table>\n</div><h3 id=\"esim-status-esimstatus--usage\">eSIM status (<code>esimStatus</code> — usage)</h3>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Value</th>\n<th>Meaning</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>NotInstalled</code></td>\n<td>eSIM profile not yet installed on the device.</td>\n</tr>\n<tr>\n<td><code>Installed</code></td>\n<td>eSIM profile installed.</td>\n</tr>\n<tr>\n<td><code>Unavailable</code></td>\n<td>eSIM profile unavailable.</td>\n</tr>\n</tbody>\n</table>\n</div><hr />\n<h1 id=\"esim-refunds\">eSIM Refunds</h1>\n<p>Refunds let you ask Hoi to reverse a completed eSIM purchase on a client's behalf. A refund is opened\nagainst a specific transaction, is decided in the background (the decision is not instant), and can be\ntracked by polling until it reaches a final state. There are no callbacks or webhooks for refunds today —\nyour integration is responsible for polling.</p>\n<hr />\n<h2 id=\"journey\">Journey</h2>\n<ol>\n<li><strong>Request a refund</strong> — <code>POST /transactions/{id}/refund</code> on a <code>Completed</code> transaction you own.</li>\n<li><strong>Poll for a decision</strong> — <code>GET /transactions/{id}/refund</code> (or <code>GET /refunds/{refundId}</code> once you have\nthe id) until <code>status</code> reaches a terminal value (see the table below).</li>\n<li><strong>Withdraw</strong>, if you change your mind — <code>POST /refunds/{refundId}/withdraw</code>, only while the request is\nstill open.</li>\n</ol>\n<hr />\n<h2 id=\"authentication\">Authentication</h2>\n<p>Same <strong>Basic Authentication</strong> as every other eSIM endpoint — no separate credential is needed for refunds.</p>\n<hr />\n<h2 id=\"endpoints\">Endpoints</h2>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Method</th>\n<th>Path</th>\n<th>Purpose</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>POST</code></td>\n<td><code>/api/v0/esim/transactions/{id}/refund</code></td>\n<td>Open a refund request for transaction <code>{id}</code></td>\n</tr>\n<tr>\n<td><code>GET</code></td>\n<td><code>/api/v0/esim/transactions/{id}/refund</code></td>\n<td>Get the most recent refund request for transaction <code>{id}</code></td>\n</tr>\n<tr>\n<td><code>GET</code></td>\n<td><code>/api/v0/esim/refunds/{refundId}</code></td>\n<td>Get one refund request by its own id</td>\n</tr>\n<tr>\n<td><code>POST</code></td>\n<td><code>/api/v0/esim/refunds/{refundId}/withdraw</code></td>\n<td>Withdraw an open refund request</td>\n</tr>\n</tbody>\n</table>\n</div><hr />\n<h2 id=\"1-request-a-refund\">1. Request a refund</h2>\n<p><code>POST /api/v0/esim/transactions/{id}/refund</code></p>\n<p><strong>Route parameter</strong></p>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Field</th>\n<th>Meaning</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>id</code></td>\n<td>The eSIM transaction id you are requesting a refund for. Must belong to your account and be <code>Completed</code>.</td>\n</tr>\n</tbody>\n</table>\n</div><p><strong>Body</strong></p>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Field</th>\n<th>Required</th>\n<th>Rules</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>reasonCode</code></td>\n<td>Yes</td>\n<td>One of: <code>NotActivated</code>, <code>NotWorking</code>, <code>WrongPurchase</code>, <code>Duplicate</code>, <code>Other</code>.</td>\n</tr>\n<tr>\n<td><code>reasonText</code></td>\n<td>No</td>\n<td>Free text, max 1000 characters.</td>\n</tr>\n<tr>\n<td><code>clientReference</code></td>\n<td>No</td>\n<td>Your own reference for the request, max 100 characters.</td>\n</tr>\n</tbody>\n</table>\n</div><pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">{\n  \"reasonCode\": \"NotWorking\",\n  \"reasonText\": \"Data plan never connected after activation.\",\n  \"clientReference\": \"SUPPORT-CASE-4821\"\n}\n</code></pre>\n<p><strong>Response — 200, <code>code: 1000</code></strong></p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">{\n  \"code\": 1000,\n  \"message\": \"Request processed successfully.\",\n  \"data\": {\n    \"refundId\": 501,\n    \"transactionId\": 90210,\n    \"hoiReference\": \"3f2b9c7e41d04a6b9e8f1c2d3a4b5c6d\",\n    \"clientExternalReference\": \"ORDER-77341\",\n    \"status\": \"Submitted\",\n    \"reasonCode\": \"NotWorking\",\n    \"reasonText\": \"Data plan never connected after activation.\",\n    \"clientReference\": \"SUPPORT-CASE-4821\",\n    \"requestedAt\": \"2026-08-30T09:12:41Z\",\n    \"decidedAt\": null,\n    \"decisionReasonCode\": null,\n    \"clientMessage\": null,\n    \"approvedAmount\": null,\n    \"refundedAmount\": null,\n    \"currency\": \"USD\"\n  }\n}\n</code></pre>\n<p>Only one refund request can be open per transaction at a time — see error <code>1423</code> below.</p>\n<hr />\n<h2 id=\"2-get-the-current-refund-for-a-transaction\">2. Get the current refund for a transaction</h2>\n<p><code>GET /api/v0/esim/transactions/{id}/refund</code></p>\n<p>Returns the most recent refund request opened against transaction <code>{id}</code>, in the same shape as above.\nUse this when you know the transaction id but not the refund id (e.g. right after step 1, or to check\nwhether a given transaction has ever had a refund requested).</p>\n<hr />\n<h2 id=\"3-get-a-refund-by-id\">3. Get a refund by id</h2>\n<p><code>GET /api/v0/esim/refunds/{refundId}</code></p>\n<p>Returns one refund request by its own <code>refundId</code>. This is the endpoint to poll once you have the id from\nstep 1's response.</p>\n<hr />\n<h2 id=\"4-withdraw-a-refund\">4. Withdraw a refund</h2>\n<p><code>POST /api/v0/esim/refunds/{refundId}/withdraw</code></p>\n<p>Body: required JSON object. <code>note</code> is optional (max 1000 characters); send <code>{}</code> if you have no note.</p>\n<p>An empty body or malformed JSON returns HTTP 400 with a standard validation problem body (not the <code>code</code>/<code>message</code> envelope).</p>\n<p><strong>Body</strong></p>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Field</th>\n<th>Required</th>\n<th>Rules</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>note</code></td>\n<td>No</td>\n<td>Free text, max 1000 characters.</td>\n</tr>\n</tbody>\n</table>\n</div><pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">{\n  \"note\": \"Customer resolved the issue directly, no longer needed.\"\n}\n</code></pre>\n<p>Withdrawing is only valid while the request is still open (<code>Submitted</code> or <code>UnderReview</code>, see below) — once\na decision has been made, withdrawal is no longer possible and the call returns <code>1424</code>.</p>\n<hr />\n<h2 id=\"response-envelope\">Response envelope</h2>\n<p>Every refund endpoint returns the standard <code>BaseResponse&lt;T&gt;</code> envelope with <code>data</code> shaped as above:</p>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Field</th>\n<th>Meaning</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>refundId</code></td>\n<td>The refund request's own id — use it with <code>GET /refunds/{refundId}</code> and the withdraw endpoint.</td>\n</tr>\n<tr>\n<td><code>transactionId</code></td>\n<td>The eSIM transaction the refund was requested against.</td>\n</tr>\n<tr>\n<td><code>hoiReference</code></td>\n<td>The Hoi reference of the refunded transaction.</td>\n</tr>\n<tr>\n<td><code>clientExternalReference</code></td>\n<td>The <code>externalReference</code> you originally supplied for the transaction, if any.</td>\n</tr>\n<tr>\n<td><code>status</code></td>\n<td>Current lifecycle status — see the table below.</td>\n</tr>\n<tr>\n<td><code>reasonCode</code> / <code>reasonText</code></td>\n<td>What you submitted when requesting the refund.</td>\n</tr>\n<tr>\n<td><code>clientReference</code></td>\n<td>What you submitted when requesting the refund.</td>\n</tr>\n<tr>\n<td><code>requestedAt</code></td>\n<td>When the refund was requested.</td>\n</tr>\n<tr>\n<td><code>decidedAt</code></td>\n<td>When a decision was made, if any.</td>\n</tr>\n<tr>\n<td><code>decisionReasonCode</code></td>\n<td>A short code identifying why the request was decided the way it was, when available.</td>\n</tr>\n<tr>\n<td><code>clientMessage</code></td>\n<td>A short, human-readable sentence explaining the decision, when available.</td>\n</tr>\n<tr>\n<td><code>approvedAmount</code> / <code>refundedAmount</code></td>\n<td>The amount approved and, once processed, actually refunded.</td>\n</tr>\n<tr>\n<td><code>currency</code></td>\n<td>Currency for the amounts above.</td>\n</tr>\n</tbody>\n</table>\n</div><hr />\n<h2 id=\"status-vocabulary\">Status vocabulary</h2>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Status</th>\n<th>What it means for you</th>\n<th>Terminal?</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>Submitted</code></td>\n<td>Received and awaiting a decision.</td>\n<td>No</td>\n</tr>\n<tr>\n<td><code>AutoApproved</code></td>\n<td>Approved automatically; moving on to be processed.</td>\n<td>No</td>\n</tr>\n<tr>\n<td><code>UnderReview</code></td>\n<td>Needs a closer look before a decision is made.</td>\n<td>No</td>\n</tr>\n<tr>\n<td><code>Approved</code></td>\n<td>Approved after review; moving on to be processed.</td>\n<td>No</td>\n</tr>\n<tr>\n<td><code>Processing</code></td>\n<td>Approved and currently being carried out.</td>\n<td>No</td>\n</tr>\n<tr>\n<td><code>Refunded</code></td>\n<td>Completed — the amount has been refunded and the transaction is excluded from your settlement totals.</td>\n<td><strong>Yes</strong></td>\n</tr>\n<tr>\n<td><code>AutoRejected</code></td>\n<td>Rejected automatically; you may be able to submit a new request after a cooldown period.</td>\n<td><strong>Yes</strong></td>\n</tr>\n<tr>\n<td><code>Rejected</code></td>\n<td>Rejected after review.</td>\n<td><strong>Yes</strong></td>\n</tr>\n<tr>\n<td><code>Failed</code></td>\n<td>Could not be completed; being retried/resolved — keep polling, it may move to <code>UnderReview</code> or eventually <code>Refunded</code>.</td>\n<td>No</td>\n</tr>\n<tr>\n<td><code>Withdrawn</code></td>\n<td>You withdrew the request before a decision was made.</td>\n<td><strong>Yes</strong></td>\n</tr>\n</tbody>\n</table>\n</div><hr />\n<h2 id=\"reason-codes\">Reason codes</h2>\n<p>The <code>reasonCode</code> you submit when opening a refund must be one of:</p>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Code</th>\n<th>Use it when</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>NotActivated</code></td>\n<td>The eSIM/plan was never activated.</td>\n</tr>\n<tr>\n<td><code>NotWorking</code></td>\n<td>The eSIM/plan was activated but did not work as expected.</td>\n</tr>\n<tr>\n<td><code>WrongPurchase</code></td>\n<td>The wrong product was purchased (e.g. wrong country/plan).</td>\n</tr>\n<tr>\n<td><code>Duplicate</code></td>\n<td>The same purchase was made more than once in error.</td>\n</tr>\n<tr>\n<td><code>Other</code></td>\n<td>Any reason not covered above — use <code>reasonText</code> to explain.</td>\n</tr>\n</tbody>\n</table>\n</div><hr />\n<h2 id=\"scenarios\">Scenarios</h2>\n<p>A refund request ends in one of four ways. The overview shows the split; each scenario below has its own diagram.</p>\n<h3 id=\"scenario-1--approved-automatically\">Scenario 1 — Approved automatically</h3>\n<p><strong>Triggers:</strong> the eSIM was never installed, never activated and used no data.\n<strong>You see:</strong> <code>POST</code> returns 200 / <code>1000</code> with <code>status: Submitted</code>. Later polls show <code>AutoApproved</code>, then <code>Processing</code>, then <code>Refunded</code> (terminal).\n<strong>Next:</strong> poll <code>GET /transactions/{id}/refund</code> or <code>GET /refunds/{refundId}</code> every 30-60 seconds until <code>Refunded</code>.</p>\n<h3 id=\"scenario-2--reviewed-by-our-support-team\">Scenario 2 — Reviewed by our support team</h3>\n<p><strong>Triggers:</strong> the outcome depends on the refund <code>reasonCode</code> (see \"How the decision is made\" below). Our support team reviews the request when: the eSIM is installed with no data used and the reason is <code>NotActivated</code>, <code>NotWorking</code> or <code>Other</code>; 1-49 MB was used and the reason is <code>NotActivated</code>, <code>NotWorking</code> or <code>Other</code>; the transaction is a top-up; the eSIM has active top-ups (<code>TopupPresent</code>); or we could not read the eSIM's current state. With <code>WrongPurchase</code> / <code>Duplicate</code>, an installed or used eSIM is rejected automatically instead (Scenario 3).\n<strong>You see:</strong> 200 / <code>1000</code> with <code>status: Submitted</code>, then <code>UnderReview</code>. After the review: <code>Approved</code> then <code>Processing</code> then <code>Refunded</code>, or <code>Rejected</code> (<code>decisionReasonCode: ManualRejection</code>, with <code>clientMessage</code>).\n<strong>Next:</strong> keep polling. You can still withdraw while the request is <code>UnderReview</code> (<code>POST /refunds/{refundId}/withdraw</code>); after a decision, withdrawing returns 409 / <code>1424</code>.</p>\n<h3 id=\"scenario-3--rejected-automatically\">Scenario 3 — Rejected automatically</h3>\n<p><strong>Triggers:</strong> the eSIM plan or the eSIM profile has expired (<code>BundleExpired</code>); more than 49 MB was used with <code>NotActivated</code>, <code>NotWorking</code> or <code>Other</code>, or any data was used with <code>WrongPurchase</code> / <code>Duplicate</code> (<code>DataConsumed</code>); or <code>WrongPurchase</code> / <code>Duplicate</code> on an eSIM that was installed or started (<code>InstalledUnused</code>).\n<strong>You see:</strong> 200 / <code>1000</code> with <code>status: Submitted</code>, then <code>AutoRejected</code> (terminal), with <code>decisionReasonCode</code> and <code>clientMessage</code> saying why.\n<strong>Next:</strong> read <code>decisionReasonCode</code> and <code>clientMessage</code>. A new request for the same transaction is possible after 7 days, if it is still eligible.</p>\n<h3 id=\"scenario-4--refused-at-request-time-no-refund-is-created\">Scenario 4 — Refused at request time (no refund is created)</h3>\n<p>The request is refused immediately. There is no refund id and nothing to poll. There are three distinct exits:</p>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>HTTP / <code>code</code></th>\n<th>Meaning</th>\n<th>What to do</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><strong>400 / <code>1107</code></strong></td>\n<td>The request is invalid: an unrecognized <code>reasonCode</code> value, or a field over its length limit. Nothing is created.</td>\n<td>Correct the request and send it again.</td>\n</tr>\n<tr>\n<td><strong>400 / <code>1422</code></strong></td>\n<td>The transaction is not eligible: not <code>Completed</code>, outside the 59-day window, or rejected less than 7 days ago (<code>CooldownActive</code>). <code>message</code> names the reason, e.g. <code>Refund not eligible: OutsideWindow.</code></td>\n<td>Read <code>message</code>. Retry only once the cause is gone (for a cooldown, after 7 days).</td>\n</tr>\n<tr>\n<td><strong>409 / <code>1423</code></strong></td>\n<td>A refund request is already open for this transaction (<code>data</code> carries it), or an eSIM regeneration is running (<code>data</code> is <code>null</code>).</td>\n<td>Track the open refund, or retry after the regeneration has finished.</td>\n</tr>\n</tbody>\n</table>\n</div><p>See the Errors table below for every code.</p>\n<hr />\n<h2 id=\"eligibility-rules\">Eligibility rules</h2>\n<ul>\n<li><strong>Window:</strong> a refund can be requested within <strong>59 days</strong> of the purchase's completion. A later request is refused immediately with 400 / <code>1422</code> (<code>Refund not eligible: OutsideWindow.</code>) and no refund request is created.</li>\n<li><code>WrongPurchase</code> and <code>Duplicate</code> are <strong>rejected automatically</strong> if the eSIM was installed, started or has used any data (<code>InstalledUnused</code> / <code>DataConsumed</code>).</li>\n<li><code>NotActivated</code>, <code>NotWorking</code> and <code>Other</code> tolerate up to <strong>49 MB</strong> of usage; more than that is rejected (<code>DataConsumed</code>). For these three reasons, an installed profile with no data used, or 1-49 MB of usage, goes to manual review (<code>UnderReview</code>) rather than being approved automatically.</li>\n<li>An eSIM whose <strong>plan or profile has expired</strong> is rejected (<code>BundleExpired</code>).</li>\n<li>Top-ups are reviewed manually.</li>\n<li>While an eSIM <strong>regeneration</strong> is in progress, a refund request returns 409 / <code>1423</code> with <code>data: null</code>. Likewise, an eSIM with an open refund cannot be regenerated.</li>\n</ul>\n<h3 id=\"how-the-decision-is-made\">How the decision is made</h3>\n<p>The checks run top to bottom; the first one that applies decides. \"Strict\" reasons are <code>WrongPurchase</code> and <code>Duplicate</code>; \"other\" reasons are <code>NotActivated</code>, <code>NotWorking</code> and <code>Other</code>.</p>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>#</th>\n<th>Condition</th>\n<th>Strict reason</th>\n<th>Other reason</th>\n<th><code>decisionReasonCode</code></th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>1</td>\n<td>We cannot read the eSIM's current state</td>\n<td>Support review</td>\n<td>Support review</td>\n<td><code>Other</code></td>\n</tr>\n<tr>\n<td>2</td>\n<td>The eSIM plan <strong>or</strong> the eSIM profile has expired</td>\n<td>Auto-rejected</td>\n<td>Auto-rejected</td>\n<td><code>BundleExpired</code></td>\n</tr>\n<tr>\n<td>3</td>\n<td>Data used is unknown</td>\n<td>Support review</td>\n<td>Support review</td>\n<td><code>Other</code></td>\n</tr>\n<tr>\n<td>4</td>\n<td>Data used above the limit (strict: any data; other: over 49 MB)</td>\n<td>Auto-rejected</td>\n<td>Auto-rejected</td>\n<td><code>DataConsumed</code></td>\n</tr>\n<tr>\n<td>5</td>\n<td>Base plan installed or started (strict reasons only)</td>\n<td>Auto-rejected</td>\n<td>(not applied)</td>\n<td><code>InstalledUnused</code></td>\n</tr>\n<tr>\n<td>6</td>\n<td>Base plan, install or start state unknown (strict reasons only)</td>\n<td>Support review</td>\n<td>(not applied)</td>\n<td><code>Other</code></td>\n</tr>\n<tr>\n<td>7</td>\n<td>The transaction is a top-up, or the eSIM has active top-ups</td>\n<td>Support review</td>\n<td>Support review</td>\n<td><code>TopupPresent</code></td>\n</tr>\n<tr>\n<td>8</td>\n<td>Not installed, not started, 0 MB used</td>\n<td>Auto-approved</td>\n<td>Auto-approved</td>\n<td><code>ProfileNotInstalled</code></td>\n</tr>\n<tr>\n<td>9</td>\n<td>Installed, 0 MB used</td>\n<td>(rejected at 5)</td>\n<td>Support review</td>\n<td><code>InstalledUnused</code></td>\n</tr>\n<tr>\n<td>10</td>\n<td>Anything else (for example 1-49 MB used)</td>\n<td>(rejected at 4)</td>\n<td>Support review</td>\n<td><code>Other</code></td>\n</tr>\n</tbody>\n</table>\n</div><h3 id=\"decisionreasoncode-values\"><code>decisionReasonCode</code> values</h3>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Value</th>\n<th>Meaning</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>ProfileNotInstalled</code></td>\n<td>The eSIM profile was never installed.</td>\n</tr>\n<tr>\n<td><code>DataConsumed</code></td>\n<td>The eSIM has used more data than the reason allows.</td>\n</tr>\n<tr>\n<td><code>BundleExpired</code></td>\n<td>The eSIM plan or the eSIM profile has expired.</td>\n</tr>\n<tr>\n<td><code>TopupPresent</code></td>\n<td>A top-up exists on this eSIM.</td>\n</tr>\n<tr>\n<td><code>InstalledUnused</code></td>\n<td>The eSIM was installed, which a <code>WrongPurchase</code> / <code>Duplicate</code> refund does not allow.</td>\n</tr>\n<tr>\n<td><code>AmountAboveAutoCeiling</code></td>\n<td>Sent to review — amount above the automatic limit.</td>\n</tr>\n<tr>\n<td><code>ManualApproval</code></td>\n<td>Approved after manual review.</td>\n</tr>\n<tr>\n<td><code>ManualRejection</code></td>\n<td>Rejected after manual review.</td>\n</tr>\n<tr>\n<td><code>Other</code></td>\n<td>Any other decision basis.</td>\n</tr>\n</tbody>\n</table>\n</div><p>Checks made <strong>before</strong> a refund request is created — e.g. <code>OutsideWindow</code>, <code>CooldownActive</code> (a previous request was recently rejected), <code>RequestAlreadyOpen</code> — normally don't appear in <code>decisionReasonCode</code>: they are returned synchronously as 400 / <code>1422</code> (or 409 / <code>1423</code> for <code>RequestAlreadyOpen</code>), with the reason in <code>message</code> (e.g. <code>Refund not eligible: CooldownActive.</code>), and no refund request is created. The same checks run again when the request is evaluated, so in rare cases (e.g. the window ends between creation and evaluation) a request can end <code>AutoRejected</code> with <code>OutsideWindow</code> or <code>CooldownActive</code> as its <code>decisionReasonCode</code>.</p>\n<hr />\n<h2 id=\"inquiry-and-polling\">Inquiry and polling</h2>\n<p>Refund decisions are made <strong>asynchronously</strong> in the background — there are no push notifications or\nwebhooks today. Poll <code>GET /transactions/{id}/refund</code> or <code>GET /refunds/{refundId}</code> to track progress, and\nstop once <code>status</code> is one of the terminal values above.</p>\n<p>A sensible polling cadence is <strong>once every 30–60 seconds</strong> while a request is non-terminal, backing off if\nyou don't need near-real-time updates. Avoid tight polling loops (sub-second intervals) — decisions do not\nresolve that quickly and it adds unnecessary load.</p>\n<hr />\n<h2 id=\"errors\">Errors</h2>\n<p>1104 / 403: your account is not permitted to perform this refund action. 1105 / 404: the transaction or refund request was not found, or does not belong to your account (another client's records always return 1105).</p>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Code</th>\n<th>HTTP status</th>\n<th>Meaning</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>—</td>\n<td>400</td>\n<td>Missing or empty <code>reasonCode</code>, empty body or malformed JSON. Returned as a standard validation problem body (<code>title</code>, <code>status</code>, <code>errors</code>; <code>application/problem+json</code>), <strong>not</strong> the usual <code>code</code>/<code>message</code> envelope.</td>\n</tr>\n<tr>\n<td><code>1107</code></td>\n<td>400</td>\n<td>The request failed validation: an unrecognized <code>reasonCode</code> value, or a field over its length limit. See Scenario 4.</td>\n</tr>\n<tr>\n<td><code>1104</code></td>\n<td>403</td>\n<td>You are not permitted to perform this refund action.</td>\n</tr>\n<tr>\n<td><code>1105</code></td>\n<td>404</td>\n<td>The transaction or refund request was not found, or does not belong to your account (another client's records always return 1105).</td>\n</tr>\n<tr>\n<td><code>1422</code></td>\n<td>400</td>\n<td>The transaction is not eligible for a refund (e.g. not <code>Completed</code>, outside the 59-day window, or a cooldown after a recent rejection). Refused immediately — no refund request is created; <code>message</code> names the reason, e.g. <code>Refund not eligible: OutsideWindow.</code></td>\n</tr>\n<tr>\n<td><code>1423</code></td>\n<td>409</td>\n<td>A refund request is already open for this transaction (<code>data</code> carries it), <strong>or</strong> an eSIM regeneration is in progress for the transaction. In the regeneration case <code>data</code> is <code>null</code>; retry once the regeneration has finished.</td>\n</tr>\n<tr>\n<td><code>1424</code></td>\n<td>409</td>\n<td>The action is not valid for the refund request's current status (e.g. trying to withdraw a request that has already been decided).</td>\n</tr>\n<tr>\n<td><code>1426</code></td>\n<td>503</td>\n<td>The refund service is temporarily unavailable — retry after a short delay.</td>\n</tr>\n<tr>\n<td><code>1101</code></td>\n<td>503</td>\n<td>An internal error occurred while handling the refund request — retry after a short delay.</td>\n</tr>\n</tbody>\n</table>\n</div><p>On any <code>503</code>, retry with backoff; the request has not been lost, it simply could not be evaluated at that\nmoment.</p>\n","_postman_id":"b165bde1-7c03-4ce2-97ec-0269bf94fe43"},{"name":"Topup","item":[{"name":"Get Countries","id":"8b270f77-b2a5-483a-9519-6f917b63a3b9","request":{"method":"GET","header":[],"url":"https://eservices.hoicom.net/api/v0/Topup/countries?Name=&IsoCode=&ContinentName=&Page=1&PageSize=300","description":"<p>Returns the <strong>countries</strong> top-ups are supported for, with currency, calling codes, and dialing rules.</p>\n<hr />\n<h2 id=\"authorization\">Authorization</h2>\n<p>Requires Basic Authentication with your client credentials. Your account must be enabled for the Topup service.</p>\n<hr />\n<h2 id=\"query-parameters\">Query Parameters</h2>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Parameter</th>\n<th>Type</th>\n<th>Required</th>\n<th>Default</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>Name</code></td>\n<td><code>string[]</code></td>\n<td>No</td>\n<td>—</td>\n<td>Filter by country name(s).</td>\n</tr>\n<tr>\n<td><code>IsoCode</code></td>\n<td><code>string[]</code></td>\n<td>No</td>\n<td>—</td>\n<td>Filter by ISO code(s).</td>\n</tr>\n<tr>\n<td><code>ContinentName</code></td>\n<td><code>string[]</code></td>\n<td>No</td>\n<td>—</td>\n<td>Filter by continent(s).</td>\n</tr>\n<tr>\n<td><code>Page</code></td>\n<td><code>int</code></td>\n<td>No</td>\n<td><code>1</code></td>\n<td>Page number.</td>\n</tr>\n<tr>\n<td><code>PageSize</code></td>\n<td><code>int</code></td>\n<td>No</td>\n<td><code>300</code></td>\n<td>Items per page.</td>\n</tr>\n</tbody>\n</table>\n</div><hr />\n<h2 id=\"response\">Response</h2>\n<p>On success <code>code</code> is <code>1000</code> and <code>data</code> is a paginated list of countries.</p>\n<hr />\n<h2 id=\"response-fields\">Response fields</h2>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Field</th>\n<th>Type</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>code</code></td>\n<td>int</td>\n<td>Response status code; <code>1000</code> on success (see Reference values).</td>\n</tr>\n<tr>\n<td><code>message</code></td>\n<td>string</td>\n<td>Human-readable status message.</td>\n</tr>\n<tr>\n<td><code>data</code></td>\n<td>object</td>\n<td>Paginated list of countries.</td>\n</tr>\n<tr>\n<td><code>data.items</code></td>\n<td>array</td>\n<td>Countries on this page.</td>\n</tr>\n<tr>\n<td><code>data.items[].name</code></td>\n<td>string</td>\n<td>Country name.</td>\n</tr>\n<tr>\n<td><code>data.items[].isoCode</code></td>\n<td>string</td>\n<td>Country ISO code.</td>\n</tr>\n<tr>\n<td><code>data.items[].continentName</code></td>\n<td>string</td>\n<td>Continent the country belongs to.</td>\n</tr>\n<tr>\n<td><code>data.items[].currency.code</code></td>\n<td>string</td>\n<td>Currency code used in this country.</td>\n</tr>\n<tr>\n<td><code>data.items[].currency.name</code></td>\n<td>string</td>\n<td>Currency name.</td>\n</tr>\n<tr>\n<td><code>data.items[].currency.symbol</code></td>\n<td>string</td>\n<td>Currency symbol.</td>\n</tr>\n<tr>\n<td><code>data.items[].flagUrl</code></td>\n<td>string</td>\n<td>URL of the country's flag image; <code>null</code> if none is available.</td>\n</tr>\n<tr>\n<td><code>data.items[].callingCodes</code></td>\n<td>array of string</td>\n<td>International dialing code(s) for the country.</td>\n</tr>\n<tr>\n<td><code>data.items[].regions</code></td>\n<td>array</td>\n<td>Region groupings the country belongs to.</td>\n</tr>\n<tr>\n<td><code>data.items[].regions[].name</code></td>\n<td>string</td>\n<td>Region name.</td>\n</tr>\n<tr>\n<td><code>data.items[].regions[].code</code></td>\n<td>string</td>\n<td>Region code.</td>\n</tr>\n<tr>\n<td><code>data.items[].dialingRules</code></td>\n<td>array</td>\n<td>Destination-number length rules used to validate numbers for this country.</td>\n</tr>\n<tr>\n<td><code>data.items[].dialingRules[].prefix</code></td>\n<td>string</td>\n<td>Leading digit(s) the rule applies to.</td>\n</tr>\n<tr>\n<td><code>data.items[].dialingRules[].minimumLength</code></td>\n<td>int</td>\n<td>Minimum national number length for numbers starting with <code>prefix</code>.</td>\n</tr>\n<tr>\n<td><code>data.items[].dialingRules[].maximumLength</code></td>\n<td>int</td>\n<td>Maximum national number length for numbers starting with <code>prefix</code>.</td>\n</tr>\n<tr>\n<td><code>data.count</code></td>\n<td>int</td>\n<td>Number of items on this page.</td>\n</tr>\n<tr>\n<td><code>data.page</code></td>\n<td>int</td>\n<td>Current page number.</td>\n</tr>\n<tr>\n<td><code>data.pageSize</code></td>\n<td>int</td>\n<td>Items per page.</td>\n</tr>\n<tr>\n<td><code>data.totalPages</code></td>\n<td>int</td>\n<td>Total number of pages available.</td>\n</tr>\n<tr>\n<td><code>data.totalItems</code></td>\n<td>int</td>\n<td>Total number of countries matching the filter.</td>\n</tr>\n</tbody>\n</table>\n</div>","urlObject":{"path":["api","v0","Topup","countries"],"host":["https://eservices.hoicom.net"],"query":[{"key":"Name","value":""},{"key":"IsoCode","value":""},{"key":"ContinentName","value":""},{"key":"Page","value":"1"},{"key":"PageSize","value":"300"}],"variable":[]}},"response":[{"id":"301e8dd7-90fc-4eef-8ef4-eae7c1a988a5","name":"OK","originalRequest":{"method":"GET","header":[],"url":{"raw":"https://eservices.hoicom.net/api/v0/Topup/countries?Name=&IsoCode=&ContinentName=&Page=1&PageSize=300","host":["https://eservices.hoicom.net"],"path":["api","v0","Topup","countries"],"query":[{"key":"Name","value":""},{"key":"IsoCode","value":""},{"key":"ContinentName","value":""},{"key":"Page","value":"1"},{"key":"PageSize","value":"300"}]},"description":"Returns the **countries** top-ups are supported for, with currency, calling codes, and dialing rules.\n\n---\n\n## Authorization\n\nRequires Basic Authentication with your client credentials. Your account must be enabled for the Topup service.\n\n---\n\n## Query Parameters\n\n| Parameter | Type | Required | Default | Description |\n| --- | --- | --- | --- | --- |\n| `Name` | `string[]` | No | — | Filter by country name(s). |\n| `IsoCode` | `string[]` | No | — | Filter by ISO code(s). |\n| `ContinentName` | `string[]` | No | — | Filter by continent(s). |\n| `Page` | `int` | No | `1` | Page number. |\n| `PageSize` | `int` | No | `300` | Items per page. |\n\n---\n\n## Response\n\nOn success `code` is `1000` and `data` is a paginated list of countries."},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"cookie":[],"responseTime":null,"body":"{\n  \"code\": 1000,\n  \"message\": \"Success\",\n  \"data\": {\n    \"items\": [\n      {\n        \"name\": \"India\",\n        \"isoCode\": \"IN\",\n        \"continentName\": \"Asia\",\n        \"currency\": {\n          \"code\": \"INR\",\n          \"name\": \"Indian Rupee\",\n          \"symbol\": \"₹\"\n        },\n        \"flagUrl\": \"https://cdn.example.com/flags/in.svg\",\n        \"callingCodes\": [\n          \"+91\"\n        ],\n        \"regions\": [\n          {\n            \"name\": \"Asia\",\n            \"code\": \"AS\"\n          }\n        ],\n        \"dialingRules\": [\n          {\n            \"prefix\": \"5\",\n            \"minimumLength\": 9,\n            \"maximumLength\": 9\n          }\n        ]\n      }\n    ],\n    \"count\": 1,\n    \"page\": 1,\n    \"pageSize\": 50,\n    \"totalPages\": 1,\n    \"totalItems\": 1\n  }\n}"}],"_postman_id":"8b270f77-b2a5-483a-9519-6f917b63a3b9"},{"name":"Get Operators","id":"2d5dd362-98cb-4538-9e60-a2513020d5cc","request":{"method":"GET","header":[],"url":"https://eservices.hoicom.net/api/v0/Topup/operators?CountryIsoCode=SA&Id=&Name=&Page=1&PageSize=50","description":"<p>Returns mobile <strong>operators</strong> (carriers), optionally filtered by country. Use an operator <code>id</code> to list its products.</p>\n<hr />\n<h2 id=\"authorization\">Authorization</h2>\n<p>Requires Basic Authentication with your client credentials. Your account must be enabled for the Topup service.</p>\n<hr />\n<h2 id=\"query-parameters\">Query Parameters</h2>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Parameter</th>\n<th>Type</th>\n<th>Required</th>\n<th>Default</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>CountryIsoCode</code></td>\n<td><code>string</code></td>\n<td>No</td>\n<td>—</td>\n<td>Filter by country ISO code.</td>\n</tr>\n<tr>\n<td><code>Id</code></td>\n<td><code>string</code></td>\n<td>No</td>\n<td>—</td>\n<td>Filter by operator id.</td>\n</tr>\n<tr>\n<td><code>Name</code></td>\n<td><code>string</code></td>\n<td>No</td>\n<td>—</td>\n<td>Filter by operator name.</td>\n</tr>\n<tr>\n<td><code>Page</code></td>\n<td><code>int</code></td>\n<td>No</td>\n<td><code>1</code></td>\n<td>Page number.</td>\n</tr>\n<tr>\n<td><code>PageSize</code></td>\n<td><code>int</code></td>\n<td>No</td>\n<td><code>50</code></td>\n<td>Items per page.</td>\n</tr>\n</tbody>\n</table>\n</div><hr />\n<h2 id=\"response\">Response</h2>\n<p>On success <code>code</code> is <code>1000</code> and <code>data</code> is a paginated list of operators (with <code>logoUrls</code>).</p>\n<hr />\n<h2 id=\"response-fields\">Response fields</h2>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Field</th>\n<th>Type</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>code</code></td>\n<td>int</td>\n<td>Response status code; <code>1000</code> on success (see Reference values).</td>\n</tr>\n<tr>\n<td><code>message</code></td>\n<td>string</td>\n<td>Human-readable status message.</td>\n</tr>\n<tr>\n<td><code>data</code></td>\n<td>object</td>\n<td>Paginated list of operators.</td>\n</tr>\n<tr>\n<td><code>data.items</code></td>\n<td>array</td>\n<td>Operators on this page.</td>\n</tr>\n<tr>\n<td><code>data.items[].id</code></td>\n<td>string</td>\n<td>Operator identifier; use it to filter Get Products / Get Products by Number results.</td>\n</tr>\n<tr>\n<td><code>data.items[].name</code></td>\n<td>string</td>\n<td>Operator (telco) name.</td>\n</tr>\n<tr>\n<td><code>data.items[].country.name</code></td>\n<td>string</td>\n<td>Country the operator serves.</td>\n</tr>\n<tr>\n<td><code>data.items[].country.isoCode</code></td>\n<td>string</td>\n<td>Country ISO code.</td>\n</tr>\n<tr>\n<td><code>data.items[].country.regions</code></td>\n<td>array</td>\n<td>Region groupings for the country.</td>\n</tr>\n<tr>\n<td><code>data.items[].country.regions[].name</code></td>\n<td>string</td>\n<td>Region name.</td>\n</tr>\n<tr>\n<td><code>data.items[].country.regions[].code</code></td>\n<td>string</td>\n<td>Region code.</td>\n</tr>\n<tr>\n<td><code>data.items[].logoUrls</code></td>\n<td>array of string</td>\n<td>Operator logo image URL(s).</td>\n</tr>\n<tr>\n<td><code>data.count</code></td>\n<td>int</td>\n<td>Number of items on this page.</td>\n</tr>\n<tr>\n<td><code>data.page</code></td>\n<td>int</td>\n<td>Current page number.</td>\n</tr>\n<tr>\n<td><code>data.pageSize</code></td>\n<td>int</td>\n<td>Items per page.</td>\n</tr>\n<tr>\n<td><code>data.totalPages</code></td>\n<td>int</td>\n<td>Total number of pages available.</td>\n</tr>\n<tr>\n<td><code>data.totalItems</code></td>\n<td>int</td>\n<td>Total number of operators matching the filter.</td>\n</tr>\n</tbody>\n</table>\n</div>","urlObject":{"path":["api","v0","Topup","operators"],"host":["https://eservices.hoicom.net"],"query":[{"description":{"content":"<p>Filter operators by country ISO code.</p>\n","type":"text/plain"},"key":"CountryIsoCode","value":"SA"},{"key":"Id","value":""},{"key":"Name","value":""},{"key":"Page","value":"1"},{"key":"PageSize","value":"50"}],"variable":[]}},"response":[{"id":"74dac85b-d842-4507-96fd-91359948f18a","name":"OK","originalRequest":{"method":"GET","header":[],"url":{"raw":"https://eservices.hoicom.net/api/v0/Topup/operators?CountryIsoCode=SA&Id=&Name=&Page=1&PageSize=50","host":["https://eservices.hoicom.net"],"path":["api","v0","Topup","operators"],"query":[{"key":"CountryIsoCode","value":"SA","description":"Filter operators by country ISO code."},{"key":"Id","value":""},{"key":"Name","value":""},{"key":"Page","value":"1"},{"key":"PageSize","value":"50"}]},"description":"Returns mobile **operators** (carriers), optionally filtered by country. Use an operator `id` to list its products.\n\n---\n\n## Authorization\n\nRequires Basic Authentication with your client credentials. Your account must be enabled for the Topup service.\n\n---\n\n## Query Parameters\n\n| Parameter | Type | Required | Default | Description |\n| --- | --- | --- | --- | --- |\n| `CountryIsoCode` | `string` | No | — | Filter by country ISO code. |\n| `Id` | `string` | No | — | Filter by operator id. |\n| `Name` | `string` | No | — | Filter by operator name. |\n| `Page` | `int` | No | `1` | Page number. |\n| `PageSize` | `int` | No | `50` | Items per page. |\n\n---\n\n## Response\n\nOn success `code` is `1000` and `data` is a paginated list of operators (with `logoUrls`)."},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"cookie":[],"responseTime":null,"body":"{\n  \"code\": 1000,\n  \"message\": \"Success\",\n  \"data\": {\n    \"items\": [\n      {\n        \"id\": \"341\",\n        \"name\": \"Airtel\",\n        \"country\": {\n          \"name\": \"India\",\n          \"isoCode\": \"IN\",\n          \"regions\": [\n            {\n              \"name\": \"Asia\",\n              \"code\": \"AS\"\n            }\n          ]\n        },\n        \"logoUrls\": [\n          \"https://cdn.example.com/operators/airtel.png\"\n        ]\n      }\n    ],\n    \"count\": 1,\n    \"page\": 1,\n    \"pageSize\": 50,\n    \"totalPages\": 1,\n    \"totalItems\": 1\n  }\n}"}],"_postman_id":"2d5dd362-98cb-4538-9e60-a2513020d5cc"},{"name":"Get Products","id":"f162dd52-a368-4c09-8798-520d2d2a8982","request":{"method":"GET","header":[],"url":"https://eservices.hoicom.net/api/v0/Topup/products?Id=&OperatorId=341&CountryIso=&Type=&Page=1&PageSize=50","description":"<p>Returns top-up <strong>products</strong> (denominations/bundles), filterable by operator, country, or type. Each product carries <code>pricing</code>, <code>validities</code>, and <code>classification</code>.</p>\n<hr />\n<h2 id=\"authorization\">Authorization</h2>\n<p>Requires Basic Authentication with your client credentials. Your account must be enabled for the Topup service.</p>\n<hr />\n<h2 id=\"query-parameters\">Query Parameters</h2>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Parameter</th>\n<th>Type</th>\n<th>Required</th>\n<th>Default</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>Id</code></td>\n<td><code>string</code></td>\n<td>No</td>\n<td>—</td>\n<td>Filter by product id.</td>\n</tr>\n<tr>\n<td><code>OperatorId</code></td>\n<td><code>string</code></td>\n<td>No</td>\n<td>—</td>\n<td>Filter by operator id.</td>\n</tr>\n<tr>\n<td><code>CountryIso</code></td>\n<td><code>string</code></td>\n<td>No</td>\n<td>—</td>\n<td>Filter by country ISO code.</td>\n</tr>\n<tr>\n<td><code>Type</code></td>\n<td><code>string</code></td>\n<td>No</td>\n<td>—</td>\n<td>Filter by product type: <code>INSTANT_FIXED</code>, <code>INSTANT_VARIABLE</code>, <code>PIN_BASED</code>.</td>\n</tr>\n<tr>\n<td><code>Page</code></td>\n<td><code>int</code></td>\n<td>No</td>\n<td><code>1</code></td>\n<td>Page number.</td>\n</tr>\n<tr>\n<td><code>PageSize</code></td>\n<td><code>int</code></td>\n<td>No</td>\n<td><code>50</code></td>\n<td>Items per page.</td>\n</tr>\n</tbody>\n</table>\n</div><hr />\n<h2 id=\"response\">Response</h2>\n<p>On success <code>code</code> is <code>1000</code> and <code>data</code> is a paginated list of products. <code>type</code>, <code>validities[].type</code>/<code>unit</code>, and <code>classification.categories</code> use the reference values in the folder overview.</p>\n<hr />\n<h2 id=\"response-fields\">Response fields</h2>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Field</th>\n<th>Type</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>code</code></td>\n<td>int</td>\n<td>Response status code; <code>1000</code> on success (see Reference values).</td>\n</tr>\n<tr>\n<td><code>message</code></td>\n<td>string</td>\n<td>Human-readable status message.</td>\n</tr>\n<tr>\n<td><code>data</code></td>\n<td>object</td>\n<td>Paginated list of products.</td>\n</tr>\n<tr>\n<td><code>data.items</code></td>\n<td>array</td>\n<td>Products on this page.</td>\n</tr>\n<tr>\n<td><code>data.items[].id</code></td>\n<td>string</td>\n<td>Product identifier; pass as <code>productId</code> when creating a transaction.</td>\n</tr>\n<tr>\n<td><code>data.items[].type</code></td>\n<td>string (see Reference values)</td>\n<td>Product type — <code>INSTANT_FIXED</code>, <code>INSTANT_VARIABLE</code>, or <code>PIN_BASED</code>.</td>\n</tr>\n<tr>\n<td><code>data.items[].details.name</code></td>\n<td>string</td>\n<td>Product display name.</td>\n</tr>\n<tr>\n<td><code>data.items[].details.description</code></td>\n<td>string</td>\n<td>Product description.</td>\n</tr>\n<tr>\n<td><code>data.items[].details.termsAndConditions</code></td>\n<td>string</td>\n<td>Terms and conditions text.</td>\n</tr>\n<tr>\n<td><code>data.items[].details.usageInstructions</code></td>\n<td>string</td>\n<td>Instructions for how the top-up is used once delivered.</td>\n</tr>\n<tr>\n<td><code>data.items[].pricing.currency</code></td>\n<td>string</td>\n<td>Currency you are charged in.</td>\n</tr>\n<tr>\n<td><code>data.items[].pricing.minAmount</code></td>\n<td>decimal</td>\n<td>Minimum chargeable amount, in <code>currency</code>. Equal to <code>maxAmount</code> for a fixed-price product.</td>\n</tr>\n<tr>\n<td><code>data.items[].pricing.maxAmount</code></td>\n<td>decimal</td>\n<td>Maximum chargeable amount, in <code>currency</code>.</td>\n</tr>\n<tr>\n<td><code>data.items[].pricing.destinationCurrency</code></td>\n<td>string</td>\n<td>Currency the value is delivered in at the destination.</td>\n</tr>\n<tr>\n<td><code>data.items[].pricing.minDestinationAmount</code></td>\n<td>decimal</td>\n<td>Minimum delivered amount, in <code>destinationCurrency</code>.</td>\n</tr>\n<tr>\n<td><code>data.items[].pricing.maxDestinationAmount</code></td>\n<td>decimal</td>\n<td>Maximum delivered amount, in <code>destinationCurrency</code>.</td>\n</tr>\n<tr>\n<td><code>data.items[].pricing.tax.taxRate</code></td>\n<td>decimal</td>\n<td>Tax rate applied, as a percentage.</td>\n</tr>\n<tr>\n<td><code>data.items[].pricing.tax.taxType</code></td>\n<td>string</td>\n<td>Tax type/name (e.g. <code>VAT</code>).</td>\n</tr>\n<tr>\n<td><code>data.items[].pricing.tax.taxAmount</code></td>\n<td>decimal</td>\n<td>Tax amount included in the price.</td>\n</tr>\n<tr>\n<td><code>data.items[].validities</code></td>\n<td>array</td>\n<td>Validity period(s) for the delivered value.</td>\n</tr>\n<tr>\n<td><code>data.items[].validities[].type</code></td>\n<td>string (see Reference values)</td>\n<td><code>TIME_BASED</code>, <code>VOLUME_BASED</code>, or <code>UNLIMITED</code>.</td>\n</tr>\n<tr>\n<td><code>data.items[].validities[].unit</code></td>\n<td>string (see Reference values)</td>\n<td>Unit for <code>quantity</code>; time units when <code>type</code> is <code>TIME_BASED</code>, volume units when <code>VOLUME_BASED</code>, absent/irrelevant when <code>UNLIMITED</code>.</td>\n</tr>\n<tr>\n<td><code>data.items[].validities[].quantity</code></td>\n<td>decimal</td>\n<td>Number of <code>unit</code>s the validity lasts.</td>\n</tr>\n<tr>\n<td><code>data.items[].classification.isPromotional</code></td>\n<td>bool</td>\n<td><code>true</code> if this is a limited-time/promotional product.</td>\n</tr>\n<tr>\n<td><code>data.items[].classification.categories</code></td>\n<td>array of string (see Reference values)</td>\n<td>One or more of <code>AIRTIME</code>, <code>DATA</code>, <code>BUNDLES</code>.</td>\n</tr>\n<tr>\n<td><code>data.items[].availableRegions</code></td>\n<td>array</td>\n<td>Regions this product can be purchased from.</td>\n</tr>\n<tr>\n<td><code>data.items[].availableRegions[].name</code></td>\n<td>string</td>\n<td>Region name.</td>\n</tr>\n<tr>\n<td><code>data.items[].availableRegions[].code</code></td>\n<td>string</td>\n<td>Region code.</td>\n</tr>\n<tr>\n<td><code>data.items[].operator.id</code></td>\n<td>string</td>\n<td>Operator identifier.</td>\n</tr>\n<tr>\n<td><code>data.items[].operator.name</code></td>\n<td>string</td>\n<td>Operator (telco) name.</td>\n</tr>\n<tr>\n<td><code>data.items[].operator.country.name</code></td>\n<td>string</td>\n<td>Country the operator serves.</td>\n</tr>\n<tr>\n<td><code>data.items[].operator.country.isoCode</code></td>\n<td>string</td>\n<td>Country ISO code.</td>\n</tr>\n<tr>\n<td><code>data.items[].operator.country.regions</code></td>\n<td>array</td>\n<td>Region groupings for the country.</td>\n</tr>\n<tr>\n<td><code>data.items[].operator.country.regions[].name</code></td>\n<td>string</td>\n<td>Region name.</td>\n</tr>\n<tr>\n<td><code>data.items[].operator.country.regions[].code</code></td>\n<td>string</td>\n<td>Region code.</td>\n</tr>\n<tr>\n<td><code>data.items[].operator.logoUrls</code></td>\n<td>array of string</td>\n<td>Operator logo image URL(s).</td>\n</tr>\n<tr>\n<td><code>data.count</code></td>\n<td>int</td>\n<td>Number of items on this page.</td>\n</tr>\n<tr>\n<td><code>data.page</code></td>\n<td>int</td>\n<td>Current page number.</td>\n</tr>\n<tr>\n<td><code>data.pageSize</code></td>\n<td>int</td>\n<td>Items per page.</td>\n</tr>\n<tr>\n<td><code>data.totalPages</code></td>\n<td>int</td>\n<td>Total number of pages available.</td>\n</tr>\n<tr>\n<td><code>data.totalItems</code></td>\n<td>int</td>\n<td>Total number of products matching the filter.</td>\n</tr>\n</tbody>\n</table>\n</div>","urlObject":{"path":["api","v0","Topup","products"],"host":["https://eservices.hoicom.net"],"query":[{"key":"Id","value":""},{"description":{"content":"<p>Filter by operator id.</p>\n","type":"text/plain"},"key":"OperatorId","value":"341"},{"key":"CountryIso","value":""},{"description":{"content":"<p>Filter by product type (see folder overview).</p>\n","type":"text/plain"},"key":"Type","value":""},{"key":"Page","value":"1"},{"key":"PageSize","value":"50"}],"variable":[]}},"response":[{"id":"b4c7b0e8-2254-40b9-8322-4a235548f0f2","name":"OK","originalRequest":{"method":"GET","header":[],"url":{"raw":"https://eservices.hoicom.net/api/v0/Topup/products?Id=&OperatorId=341&CountryIso=&Type=&Page=1&PageSize=50","host":["https://eservices.hoicom.net"],"path":["api","v0","Topup","products"],"query":[{"key":"Id","value":""},{"key":"OperatorId","value":"341","description":"Filter by operator id."},{"key":"CountryIso","value":""},{"key":"Type","value":"","description":"Filter by product type (see folder overview)."},{"key":"Page","value":"1"},{"key":"PageSize","value":"50"}]},"description":"Returns top-up **products** (denominations/bundles), filterable by operator, country, or type. Each product carries `pricing`, `validities`, and `classification`.\n\n---\n\n## Authorization\n\nRequires Basic Authentication with your client credentials. Your account must be enabled for the Topup service.\n\n---\n\n## Query Parameters\n\n| Parameter | Type | Required | Default | Description |\n| --- | --- | --- | --- | --- |\n| `Id` | `string` | No | — | Filter by product id. |\n| `OperatorId` | `string` | No | — | Filter by operator id. |\n| `CountryIso` | `string` | No | — | Filter by country ISO code. |\n| `Type` | `string` | No | — | Filter by product type: `INSTANT_FIXED`, `INSTANT_VARIABLE`, `PIN_BASED`. |\n| `Page` | `int` | No | `1` | Page number. |\n| `PageSize` | `int` | No | `50` | Items per page. |\n\n---\n\n## Response\n\nOn success `code` is `1000` and `data` is a paginated list of products. `type`, `validities[].type`/`unit`, and `classification.categories` use the enums in the folder overview."},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"cookie":[],"responseTime":null,"body":"{\n  \"code\": 1000,\n  \"message\": \"Success\",\n  \"data\": {\n    \"items\": [\n      {\n        \"id\": \"6601\",\n        \"type\": \"INSTANT_FIXED\",\n        \"details\": {\n          \"name\": \"Airtel 50 INR\",\n          \"description\": \"INR 50 airtime top-up.\",\n          \"termsAndConditions\": \"Standard top-up terms apply.\",\n          \"usageInstructions\": \"Credited instantly to the mobile number.\"\n        },\n        \"pricing\": {\n          \"currency\": \"INR\",\n          \"minAmount\": 50,\n          \"maxAmount\": 50,\n          \"destinationCurrency\": \"INR\",\n          \"minDestinationAmount\": 50,\n          \"maxDestinationAmount\": 50,\n          \"tax\": {\n            \"taxRate\": 15,\n            \"taxType\": \"VAT\",\n            \"taxAmount\": 7.5\n          }\n        },\n        \"validities\": [\n          {\n            \"type\": \"TIME_BASED\",\n            \"unit\": \"DAYS\",\n            \"quantity\": 30\n          }\n        ],\n        \"classification\": {\n          \"isPromotional\": false,\n          \"categories\": [\n            \"AIRTIME\"\n          ]\n        },\n        \"availableRegions\": [\n          {\n            \"name\": \"Asia\",\n            \"code\": \"AS\"\n          }\n        ],\n        \"operator\": {\n          \"id\": \"341\",\n          \"name\": \"Airtel\",\n          \"country\": {\n            \"name\": \"India\",\n            \"isoCode\": \"IN\",\n            \"regions\": [\n              {\n                \"name\": \"Asia\",\n                \"code\": \"AS\"\n              }\n            ]\n          },\n          \"logoUrls\": [\n            \"https://cdn.example.com/operators/airtel.png\"\n          ]\n        }\n      }\n    ],\n    \"count\": 1,\n    \"page\": 1,\n    \"pageSize\": 50,\n    \"totalPages\": 1,\n    \"totalItems\": 1\n  }\n}"}],"_postman_id":"f162dd52-a368-4c09-8798-520d2d2a8982"},{"name":"Look Up Products by Number","id":"4d41a86c-b500-4bbc-9963-d1c3ddcada5c","request":{"method":"GET","header":[],"url":"https://eservices.hoicom.net/api/v0/Topup/products/lookup/:number?page=1&pageSize=300","description":"<p>Auto-detects the country and operator from a destination <strong>phone number</strong> and returns the matching top-up products — a shortcut for the countries → operators → products browse flow.</p>\n<hr />\n<h2 id=\"authorization\">Authorization</h2>\n<p>Requires Basic Authentication with your client credentials. Your account must be enabled for the Topup service.</p>\n<hr />\n<h2 id=\"path-parameters\">Path Parameters</h2>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Parameter</th>\n<th>Type</th>\n<th>Required</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>number</code></td>\n<td><code>string</code></td>\n<td>Yes</td>\n<td>Destination phone number (international format).</td>\n</tr>\n</tbody>\n</table>\n</div><hr />\n<h2 id=\"query-parameters\">Query Parameters</h2>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Parameter</th>\n<th>Type</th>\n<th>Required</th>\n<th>Default</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>page</code></td>\n<td><code>int</code></td>\n<td>No</td>\n<td><code>1</code></td>\n<td>Page number.</td>\n</tr>\n<tr>\n<td><code>pageSize</code></td>\n<td><code>int</code></td>\n<td>No</td>\n<td><code>300</code></td>\n<td>Items per page.</td>\n</tr>\n</tbody>\n</table>\n</div><hr />\n<h2 id=\"response\">Response</h2>\n<p>On success <code>code</code> is <code>1000</code> and <code>data</code> contains the detected <code>phoneNumber</code>, <code>country</code>, <code>operator</code>, and a paginated <code>products</code> list.</p>\n<hr />\n<h2 id=\"response-fields\">Response fields</h2>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Field</th>\n<th>Type</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>code</code></td>\n<td>int</td>\n<td>Response status code; <code>1000</code> on success (see Reference values).</td>\n</tr>\n<tr>\n<td><code>message</code></td>\n<td>string</td>\n<td>Human-readable status message.</td>\n</tr>\n<tr>\n<td><code>data</code></td>\n<td>object</td>\n<td>The detected country/operator and matching products.</td>\n</tr>\n<tr>\n<td><code>data.phoneNumber</code></td>\n<td>string</td>\n<td>The <code>number</code> you supplied, normalized to international format.</td>\n</tr>\n<tr>\n<td><code>data.country.name</code></td>\n<td>string</td>\n<td>Detected country name.</td>\n</tr>\n<tr>\n<td><code>data.country.isoCode</code></td>\n<td>string</td>\n<td>Detected country ISO code.</td>\n</tr>\n<tr>\n<td><code>data.operator.id</code></td>\n<td>string</td>\n<td>Detected operator identifier.</td>\n</tr>\n<tr>\n<td><code>data.operator.name</code></td>\n<td>string</td>\n<td>Detected operator (telco) name.</td>\n</tr>\n<tr>\n<td><code>data.operator.logoUrls</code></td>\n<td>array of string</td>\n<td>Operator logo image URL(s).</td>\n</tr>\n<tr>\n<td><code>data.products</code></td>\n<td>object</td>\n<td>Paginated list of products for the detected operator — same shape as <strong>Get Products</strong>' <code>data</code>.</td>\n</tr>\n<tr>\n<td><code>data.products.items</code></td>\n<td>array</td>\n<td>Products on this page; see <strong>Get Products</strong> response fields for the full item shape (<code>id</code>, <code>type</code>, <code>details</code>, <code>pricing</code>, <code>validities</code>, <code>classification</code>, <code>availableRegions</code>, <code>operator</code>).</td>\n</tr>\n<tr>\n<td><code>data.products.count</code></td>\n<td>int</td>\n<td>Number of items on this page.</td>\n</tr>\n<tr>\n<td><code>data.products.page</code></td>\n<td>int</td>\n<td>Current page number.</td>\n</tr>\n<tr>\n<td><code>data.products.pageSize</code></td>\n<td>int</td>\n<td>Items per page.</td>\n</tr>\n<tr>\n<td><code>data.products.totalPages</code></td>\n<td>int</td>\n<td>Total number of pages available.</td>\n</tr>\n<tr>\n<td><code>data.products.totalItems</code></td>\n<td>int</td>\n<td>Total number of products for this operator.</td>\n</tr>\n</tbody>\n</table>\n</div>","urlObject":{"path":["api","v0","Topup","products","lookup",":number"],"host":["https://eservices.hoicom.net"],"query":[{"key":"page","value":"1"},{"key":"pageSize","value":"300"}],"variable":[{"type":"any","value":"","key":"number"}]}},"response":[{"id":"e1fe5aca-a5cb-4de5-a19d-c343bdb25415","name":"OK","originalRequest":{"method":"GET","header":[],"url":{"raw":"https://eservices.hoicom.net/api/v0/Topup/products/lookup/:number?page=1&pageSize=300","host":["https://eservices.hoicom.net"],"path":["api","v0","Topup","products","lookup",":number"],"query":[{"key":"page","value":"1"},{"key":"pageSize","value":"300"}],"variable":[{"key":"number","value":""}]},"description":"Auto-detects the country and operator from a destination **phone number** and returns the matching top-up products — a shortcut for the countries → operators → products browse flow.\n\n---\n\n## Authorization\n\nRequires Basic Authentication with your client credentials. Your account must be enabled for the Topup service.\n\n---\n\n## Path Parameters\n\n| Parameter | Type | Required | Description |\n| --- | --- | --- | --- |\n| `number` | `string` | Yes | Destination phone number (international format). |\n\n---\n\n## Query Parameters\n\n| Parameter | Type | Required | Default | Description |\n| --- | --- | --- | --- | --- |\n| `page` | `int` | No | `1` | Page number. |\n| `pageSize` | `int` | No | `300` | Items per page. |\n\n---\n\n## Response\n\nOn success `code` is `1000` and `data` contains the detected `phoneNumber`, `country`, `operator`, and a paginated `products` list."},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"cookie":[],"responseTime":null,"body":"{\n  \"code\": 1000,\n  \"message\": \"Success\",\n  \"data\": {\n    \"phoneNumber\": \"+919812345678\",\n    \"country\": {\n      \"name\": \"India\",\n      \"isoCode\": \"IN\"\n    },\n    \"operator\": {\n      \"id\": \"341\",\n      \"name\": \"Airtel\",\n      \"logoUrls\": [\n        \"https://cdn.example.com/operators/airtel.png\"\n      ]\n    },\n    \"products\": {\n      \"items\": [\n        {\n          \"id\": \"6601\",\n          \"type\": \"INSTANT_FIXED\",\n          \"details\": {\n            \"name\": \"Airtel 50 INR\",\n            \"description\": \"INR 50 airtime top-up.\",\n            \"termsAndConditions\": \"Standard top-up terms apply.\",\n            \"usageInstructions\": \"Credited instantly to the mobile number.\"\n          },\n          \"pricing\": {\n            \"currency\": \"INR\",\n            \"minAmount\": 50,\n            \"maxAmount\": 50,\n            \"destinationCurrency\": \"INR\",\n            \"minDestinationAmount\": 50,\n            \"maxDestinationAmount\": 50,\n            \"tax\": {\n              \"taxRate\": 15,\n              \"taxType\": \"VAT\",\n              \"taxAmount\": 7.5\n            }\n          },\n          \"validities\": [\n            {\n              \"type\": \"TIME_BASED\",\n              \"unit\": \"DAYS\",\n              \"quantity\": 30\n            }\n          ],\n          \"classification\": {\n            \"isPromotional\": false,\n            \"categories\": [\n              \"AIRTIME\"\n            ]\n          },\n          \"availableRegions\": [\n            {\n              \"name\": \"Asia\",\n              \"code\": \"AS\"\n            }\n          ],\n          \"operator\": {\n            \"id\": \"341\",\n            \"name\": \"Airtel\",\n            \"country\": {\n              \"name\": \"India\",\n              \"isoCode\": \"IN\",\n              \"regions\": [\n                {\n                  \"name\": \"Asia\",\n                  \"code\": \"AS\"\n                }\n              ]\n            },\n            \"logoUrls\": [\n              \"https://cdn.example.com/operators/airtel.png\"\n            ]\n          }\n        }\n      ],\n      \"count\": 1,\n      \"page\": 1,\n      \"pageSize\": 50,\n      \"totalPages\": 1,\n      \"totalItems\": 1\n    }\n  }\n}"}],"_postman_id":"4d41a86c-b500-4bbc-9963-d1c3ddcada5c"},{"name":"Create Transaction","id":"12ce86cb-8c70-4906-9a7c-c310e2baa72f","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"body":{"mode":"raw","raw":"{\n  \"externalReference\": \"client-ref-3001\",\n  \"productId\": \"6601\",\n  \"destinationNumber\": \"+966512345678\",\n  \"amount\": 50\n}","options":{"raw":{"language":"json"}}},"url":"https://eservices.hoicom.net/api/v0/Topup/async","description":"<p>Submits a top-up <strong>asynchronously</strong>. Returns immediately with a transaction <code>id</code>; poll <strong>Get Transaction by ID</strong> until <code>status</code> is <code>Completed</code>. Orders are <strong>idempotent</strong> on <code>externalReference</code>.</p>\n<hr />\n<h2 id=\"authorization\">Authorization</h2>\n<p>Requires Basic Authentication with your client credentials. Your account must be enabled for the Topup service.</p>\n<hr />\n<h2 id=\"request-body\">Request Body</h2>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Field</th>\n<th>Type</th>\n<th>Required</th>\n<th>Constraints</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>externalReference</code></td>\n<td><code>string</code></td>\n<td>Yes</td>\n<td>Your unique id.</td>\n</tr>\n<tr>\n<td><code>productId</code></td>\n<td><code>string</code></td>\n<td>Yes</td>\n<td>Product id (numeric).</td>\n</tr>\n<tr>\n<td><code>destinationNumber</code></td>\n<td><code>string</code></td>\n<td>Yes</td>\n<td>Recipient phone number. Max 20 chars.</td>\n</tr>\n<tr>\n<td><code>amount</code></td>\n<td><code>decimal</code></td>\n<td>Yes</td>\n<td>Must be greater than <code>0</code> and must exactly equal the product's current price (<code>pricing.minAmount</code>/<code>maxAmount</code> from <strong>Get Products</strong>) at submission time — this applies to <code>INSTANT_VARIABLE</code> products today as well, not just a min/max range. A mismatch returns <code>1415</code>.</td>\n</tr>\n</tbody>\n</table>\n</div><hr />\n<h2 id=\"response\">Response</h2>\n<p>On acceptance <code>code</code> is <code>1000</code> and <code>data</code> contains the transaction <code>id</code>.</p>\n<h3 id=\"common-error-codes\">Common error codes</h3>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Code</th>\n<th>Meaning</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>1102</code></td>\n<td>The request failed validation, <code>productId</code> doesn't match a known product, or <code>destinationNumber</code> couldn't be validated against a supported country.</td>\n</tr>\n<tr>\n<td><code>1407</code></td>\n<td>A transaction already exists for this <code>externalReference</code> (idempotent replay) — call <strong>Get Transaction by ID</strong> with the id from your original submission instead of resubmitting.</td>\n</tr>\n<tr>\n<td><code>1415</code></td>\n<td><code>amount</code> does not match the product's current price.</td>\n</tr>\n<tr>\n<td><code>1113</code></td>\n<td>Your account isn't enabled for the destination country, or no provider is currently available for it.</td>\n</tr>\n<tr>\n<td><code>1101</code></td>\n<td>An unexpected internal error occurred.</td>\n</tr>\n</tbody>\n</table>\n</div><hr />\n<h2 id=\"response-fields\">Response fields</h2>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Field</th>\n<th>Type</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>code</code></td>\n<td>int</td>\n<td>Response status code; <code>1000</code> on acceptance (see Reference values and Common error codes below).</td>\n</tr>\n<tr>\n<td><code>message</code></td>\n<td>string</td>\n<td>Human-readable status message.</td>\n</tr>\n<tr>\n<td><code>data</code></td>\n<td>object</td>\n<td>The created transaction reference.</td>\n</tr>\n<tr>\n<td><code>data.id</code></td>\n<td>string</td>\n<td>Transaction identifier. Pass this to <strong>Get Transaction by ID</strong> to track delivery.</td>\n</tr>\n</tbody>\n</table>\n</div>","urlObject":{"path":["api","v0","Topup","async"],"host":["https://eservices.hoicom.net"],"query":[],"variable":[]}},"response":[{"id":"3468f46e-a36c-4267-aa95-0be20fc5c6ef","name":"OK","originalRequest":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"body":{"mode":"raw","raw":"{\n  \"externalReference\": \"client-ref-3001\",\n  \"productId\": \"6601\",\n  \"destinationNumber\": \"+966512345678\",\n  \"amount\": 50\n}","options":{"raw":{"language":"json"}}},"url":"https://eservices.hoicom.net/api/v0/Topup/async","description":"Submits a top-up **asynchronously**. Returns immediately with a transaction `id`; poll **Get Transaction by ID** until `status` is `Completed`. Orders are **idempotent** on `externalReference`.\n\n---\n\n## Authorization\n\nRequires Basic Authentication with your client credentials. Your account must be enabled for the Topup service.\n\n---\n\n## Request Body\n\n| Field | Type | Required | Constraints |\n| --- | --- | --- | --- |\n| `externalReference` | `string` | Yes | Your unique id. |\n| `productId` | `string` | Yes | Product id (numeric). |\n| `destinationNumber` | `string` | Yes | Recipient phone number. Max 20 chars. |\n| `amount` | `decimal` | Yes | Must be greater than `0`. For `INSTANT_VARIABLE` products, within the product's min/max. |\n\n---\n\n## Response\n\nOn acceptance `code` is `1000` and `data` contains the transaction `id`.\n\n### Common error codes\n\n| Code | Meaning |\n| --- | --- |\n| `1107` | Validation error. |\n| `1401` | Invalid number or account. |\n| `1413` | Invalid product id. |\n| `1418` | Invalid external reference. |\n| `1419` | Transaction already processed (duplicate `externalReference`). |"},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"cookie":[],"responseTime":null,"body":"{\n  \"code\": 1000,\n  \"message\": \"Success\",\n  \"data\": {\n    \"id\": \"topup_txn_9f8e7d6c\"\n  }\n}"}],"_postman_id":"12ce86cb-8c70-4906-9a7c-c310e2baa72f"},{"name":"Get Transaction by ID","id":"23c0a662-ff92-4a5d-bc1d-0a4801307555","request":{"method":"GET","header":[],"url":"https://eservices.hoicom.net/api/v0/Topup/transactions/:id","description":"<p>Returns a single top-up transaction, including its <code>status</code>, the <code>product</code>/<code>operator</code>, amounts, and — for PIN-based products — <code>pinDetails</code>.</p>\n<hr />\n<h2 id=\"authorization\">Authorization</h2>\n<p>Requires Basic Authentication with your client credentials. Your account must be enabled for the Topup service.</p>\n<hr />\n<h2 id=\"path-parameters\">Path Parameters</h2>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Parameter</th>\n<th>Type</th>\n<th>Required</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>id</code></td>\n<td><code>string</code></td>\n<td>Yes</td>\n<td>Transaction identifier.</td>\n</tr>\n</tbody>\n</table>\n</div><hr />\n<h2 id=\"response\">Response</h2>\n<p>On success <code>code</code> is <code>1000</code> and <code>status</code> uses the <strong>Transaction status</strong> values (see folder overview). If the transaction's <code>status</code> is <code>Failed</code>, this endpoint returns HTTP <code>400</code> with <code>code</code> <code>1403</code> — <code>data</code> still contains the full transaction. If <code>id</code> doesn't exist or doesn't belong to your account, <code>code</code> is <code>1303</code> with HTTP <code>404</code>.</p>\n<hr />\n<h2 id=\"response-fields\">Response fields</h2>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Field</th>\n<th>Type</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>code</code></td>\n<td>int</td>\n<td>Response status code; <code>1000</code> on success, <code>1403</code> when the transaction's <code>status</code> is <code>Failed</code> (see Response note below and Reference values).</td>\n</tr>\n<tr>\n<td><code>message</code></td>\n<td>string</td>\n<td>Human-readable status message.</td>\n</tr>\n<tr>\n<td><code>data</code></td>\n<td>object</td>\n<td>The transaction.</td>\n</tr>\n<tr>\n<td><code>data.transactionId</code></td>\n<td>string</td>\n<td>Transaction identifier.</td>\n</tr>\n<tr>\n<td><code>data.externalReference</code></td>\n<td>string</td>\n<td>The <code>externalReference</code> you supplied when creating the transaction.</td>\n</tr>\n<tr>\n<td><code>data.status</code></td>\n<td>string (see Reference values)</td>\n<td>Current transaction status.</td>\n</tr>\n<tr>\n<td><code>data.timestamp.requestedAt</code></td>\n<td>string (ISO-8601 datetime)</td>\n<td>When the transaction was submitted.</td>\n</tr>\n<tr>\n<td><code>data.timestamp.completedAt</code></td>\n<td>string (ISO-8601 datetime)</td>\n<td>When the transaction reached a terminal state; holds a placeholder value while <code>status</code> is not yet terminal.</td>\n</tr>\n<tr>\n<td><code>data.product.id</code></td>\n<td>string</td>\n<td>Product identifier.</td>\n</tr>\n<tr>\n<td><code>data.product.name</code></td>\n<td>string</td>\n<td>Product display name.</td>\n</tr>\n<tr>\n<td><code>data.product.operator.id</code></td>\n<td>string</td>\n<td>Operator identifier.</td>\n</tr>\n<tr>\n<td><code>data.product.operator.name</code></td>\n<td>string</td>\n<td>Operator (telco) name.</td>\n</tr>\n<tr>\n<td><code>data.product.operator.country.name</code></td>\n<td>string</td>\n<td>Country the operator serves.</td>\n</tr>\n<tr>\n<td><code>data.product.operator.country.isoCode</code></td>\n<td>string</td>\n<td>Country ISO code.</td>\n</tr>\n<tr>\n<td><code>data.amounts.requestedAmount.amount</code></td>\n<td>decimal</td>\n<td>Amount that was requested/charged.</td>\n</tr>\n<tr>\n<td><code>data.amounts.requestedAmount.currency</code></td>\n<td>string</td>\n<td>Currency of <code>requestedAmount</code>.</td>\n</tr>\n<tr>\n<td><code>data.amounts.deliveredAmount.amount</code></td>\n<td>decimal</td>\n<td>Amount actually delivered to the destination number.</td>\n</tr>\n<tr>\n<td><code>data.amounts.deliveredAmount.currency</code></td>\n<td>string</td>\n<td>Currency of <code>deliveredAmount</code>.</td>\n</tr>\n<tr>\n<td><code>data.amounts.fees.totalFee</code></td>\n<td>decimal</td>\n<td>Total fees charged, in <code>fees.currency</code>.</td>\n</tr>\n<tr>\n<td><code>data.amounts.fees.currency</code></td>\n<td>string</td>\n<td>Currency of <code>totalFee</code>.</td>\n</tr>\n<tr>\n<td><code>data.pinDetails</code></td>\n<td>object, nullable</td>\n<td>PIN/voucher details for a <code>PIN_BASED</code> product; <code>null</code> for <code>INSTANT_FIXED</code>/<code>INSTANT_VARIABLE</code> products or before delivery. When present it has <code>code</code>, <code>serial</code>, <code>validity</code>, and <code>additionalInfo</code> (array of string).</td>\n</tr>\n<tr>\n<td><code>data.receipt</code></td>\n<td>string, nullable</td>\n<td>Link to a receipt document; may be <code>null</code> until the transaction reaches a terminal state.</td>\n</tr>\n</tbody>\n</table>\n</div>","urlObject":{"path":["api","v0","Topup","transactions",":id"],"host":["https://eservices.hoicom.net"],"query":[],"variable":[{"type":"any","value":"","key":"id"}]}},"response":[{"id":"c46b1888-d25c-455d-94dc-f7b89639200c","name":"OK","originalRequest":{"method":"GET","header":[],"url":{"raw":"https://eservices.hoicom.net/api/v0/Topup/transactions/:id","host":["https://eservices.hoicom.net"],"path":["api","v0","Topup","transactions",":id"],"variable":[{"key":"id","value":""}]},"description":"Returns a single top-up transaction, including its `status`, the `product`/`operator`, amounts, and — for PIN-based products — `pinDetails`.\n\n---\n\n## Authorization\n\nRequires Basic Authentication with your client credentials. Your account must be enabled for the Topup service.\n\n---\n\n## Path Parameters\n\n| Parameter | Type | Required | Description |\n| --- | --- | --- | --- |\n| `id` | `string` | Yes | Transaction identifier. |\n\n---\n\n## Response\n\nOn success `code` is `1000`. `status` uses the **Transaction status** enum (see folder overview)."},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"cookie":[],"responseTime":null,"body":"{\n  \"code\": 1000,\n  \"message\": \"Success\",\n  \"data\": {\n    \"transactionId\": \"topup_txn_9f8e7d6c\",\n    \"externalReference\": \"client-ref-3001\",\n    \"status\": \"Completed\",\n    \"timestamp\": {\n      \"requestedAt\": \"2026-07-01T10:00:00Z\",\n      \"completedAt\": \"2026-07-01T10:00:05Z\"\n    },\n    \"product\": {\n      \"id\": \"6601\",\n      \"name\": \"Airtel 50 INR\",\n      \"operator\": {\n        \"id\": \"341\",\n        \"name\": \"Airtel\",\n        \"country\": {\n          \"name\": \"India\",\n          \"isoCode\": \"IN\"\n        }\n      }\n    },\n    \"amounts\": {\n      \"requestedAmount\": {\n        \"amount\": 50,\n        \"currency\": \"INR\"\n      },\n      \"deliveredAmount\": {\n        \"amount\": 50,\n        \"currency\": \"INR\"\n      },\n      \"fees\": {\n        \"totalFee\": 0,\n        \"currency\": \"INR\"\n      }\n    },\n    \"pinDetails\": null,\n    \"receipt\": \"https://cdn.example.com/receipts/topup_txn_9f8e7d6c.pdf\"\n  }\n}"}],"_postman_id":"23c0a662-ff92-4a5d-bc1d-0a4801307555"},{"name":"Get Transactions","id":"9f134ed8-ef66-48ee-88c3-bdf3c1eee500","request":{"method":"GET","header":[],"url":"https://eservices.hoicom.net/api/v0/Topup/Transactions?transactionId=&externalReference=&status=Completed&fromDate=&toDate=&page=1&pageSize=50","description":"<p>Returns a paginated, filterable list of your top-up transactions.</p>\n<hr />\n<h2 id=\"authorization\">Authorization</h2>\n<p>Requires Basic Authentication with your client credentials. Your account must be enabled for the Topup service.</p>\n<hr />\n<h2 id=\"query-parameters\">Query Parameters</h2>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Parameter</th>\n<th>Type</th>\n<th>Required</th>\n<th>Default</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>transactionId</code></td>\n<td><code>string</code></td>\n<td>No</td>\n<td>—</td>\n<td>Filter by transaction id.</td>\n</tr>\n<tr>\n<td><code>externalReference</code></td>\n<td><code>string</code></td>\n<td>No</td>\n<td>—</td>\n<td>Filter by your external reference.</td>\n</tr>\n<tr>\n<td><code>status</code></td>\n<td><code>string</code></td>\n<td>No</td>\n<td>—</td>\n<td>Filter by status (e.g. <code>Completed</code>); see Reference values.</td>\n</tr>\n<tr>\n<td><code>fromDate</code></td>\n<td><code>datetime</code></td>\n<td>No</td>\n<td>—</td>\n<td>Start of creation-date range.</td>\n</tr>\n<tr>\n<td><code>toDate</code></td>\n<td><code>datetime</code></td>\n<td>No</td>\n<td>—</td>\n<td>End of creation-date range.</td>\n</tr>\n<tr>\n<td><code>page</code></td>\n<td><code>int</code></td>\n<td>No</td>\n<td><code>1</code></td>\n<td>Page number.</td>\n</tr>\n<tr>\n<td><code>pageSize</code></td>\n<td><code>int</code></td>\n<td>No</td>\n<td><code>50</code></td>\n<td>Items per page.</td>\n</tr>\n</tbody>\n</table>\n</div><hr />\n<h2 id=\"response\">Response</h2>\n<p>On success <code>code</code> is <code>1000</code> and <code>data</code> is a paginated list of transactions. Valid <code>status</code> values: <code>Submitted</code>, <code>Pending</code>, <code>Completed</code>, <code>Failed</code>, <code>Cancelled</code>, <code>Refunded</code>.</p>\n<hr />\n<h2 id=\"response-fields\">Response fields</h2>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Field</th>\n<th>Type</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>code</code></td>\n<td>int</td>\n<td>Response status code; <code>1000</code> on success (see Reference values).</td>\n</tr>\n<tr>\n<td><code>message</code></td>\n<td>string</td>\n<td>Human-readable status message.</td>\n</tr>\n<tr>\n<td><code>data</code></td>\n<td>object</td>\n<td>Paginated list of transactions.</td>\n</tr>\n<tr>\n<td><code>data.items</code></td>\n<td>array</td>\n<td>Transactions on this page.</td>\n</tr>\n<tr>\n<td><code>data.items[].transactionId</code></td>\n<td>string</td>\n<td>Transaction identifier.</td>\n</tr>\n<tr>\n<td><code>data.items[].externalReference</code></td>\n<td>string</td>\n<td>The <code>externalReference</code> you supplied when creating the transaction.</td>\n</tr>\n<tr>\n<td><code>data.items[].status</code></td>\n<td>string (see Reference values)</td>\n<td>Current transaction status.</td>\n</tr>\n<tr>\n<td><code>data.items[].timestamp.requestedAt</code></td>\n<td>string (ISO-8601 datetime)</td>\n<td>When the transaction was submitted.</td>\n</tr>\n<tr>\n<td><code>data.items[].timestamp.completedAt</code></td>\n<td>string (ISO-8601 datetime)</td>\n<td>When the transaction reached a terminal state; holds a placeholder value while <code>status</code> is not yet terminal.</td>\n</tr>\n<tr>\n<td><code>data.items[].product.id</code></td>\n<td>string</td>\n<td>Product identifier.</td>\n</tr>\n<tr>\n<td><code>data.items[].product.name</code></td>\n<td>string</td>\n<td>Product display name.</td>\n</tr>\n<tr>\n<td><code>data.items[].product.operator.id</code></td>\n<td>string</td>\n<td>Operator identifier.</td>\n</tr>\n<tr>\n<td><code>data.items[].product.operator.name</code></td>\n<td>string</td>\n<td>Operator (telco) name.</td>\n</tr>\n<tr>\n<td><code>data.items[].product.operator.country.name</code></td>\n<td>string</td>\n<td>Country the operator serves.</td>\n</tr>\n<tr>\n<td><code>data.items[].product.operator.country.isoCode</code></td>\n<td>string</td>\n<td>Country ISO code.</td>\n</tr>\n<tr>\n<td><code>data.items[].amounts.requestedAmount.amount</code></td>\n<td>decimal</td>\n<td>Amount that was requested/charged.</td>\n</tr>\n<tr>\n<td><code>data.items[].amounts.requestedAmount.currency</code></td>\n<td>string</td>\n<td>Currency of <code>requestedAmount</code>.</td>\n</tr>\n<tr>\n<td><code>data.items[].amounts.deliveredAmount.amount</code></td>\n<td>decimal</td>\n<td>Amount actually delivered to the destination number.</td>\n</tr>\n<tr>\n<td><code>data.items[].amounts.deliveredAmount.currency</code></td>\n<td>string</td>\n<td>Currency of <code>deliveredAmount</code>.</td>\n</tr>\n<tr>\n<td><code>data.items[].amounts.fees.totalFee</code></td>\n<td>decimal</td>\n<td>Total fees charged, in <code>fees.currency</code>.</td>\n</tr>\n<tr>\n<td><code>data.items[].amounts.fees.currency</code></td>\n<td>string</td>\n<td>Currency of <code>totalFee</code>.</td>\n</tr>\n<tr>\n<td><code>data.items[].pinDetails</code></td>\n<td>object, nullable</td>\n<td>PIN/voucher details for a <code>PIN_BASED</code> product; <code>null</code> otherwise. When present it has <code>code</code>, <code>serial</code>, <code>validity</code>, and <code>additionalInfo</code> (array of string).</td>\n</tr>\n<tr>\n<td><code>data.items[].receipt</code></td>\n<td>string, nullable</td>\n<td>Link to a receipt document; may be <code>null</code> until the transaction reaches a terminal state.</td>\n</tr>\n<tr>\n<td><code>data.count</code></td>\n<td>int</td>\n<td>Number of items on this page.</td>\n</tr>\n<tr>\n<td><code>data.page</code></td>\n<td>int</td>\n<td>Current page number.</td>\n</tr>\n<tr>\n<td><code>data.pageSize</code></td>\n<td>int</td>\n<td>Items per page.</td>\n</tr>\n<tr>\n<td><code>data.totalPages</code></td>\n<td>int</td>\n<td>Total number of pages available.</td>\n</tr>\n<tr>\n<td><code>data.totalItems</code></td>\n<td>int</td>\n<td>Total number of transactions matching the filter.</td>\n</tr>\n</tbody>\n</table>\n</div>","urlObject":{"path":["api","v0","Topup","Transactions"],"host":["https://eservices.hoicom.net"],"query":[{"key":"transactionId","value":""},{"key":"externalReference","value":""},{"description":{"content":"<p>Enum name, e.g. Completed.</p>\n","type":"text/plain"},"key":"status","value":"Completed"},{"key":"fromDate","value":""},{"key":"toDate","value":""},{"key":"page","value":"1"},{"key":"pageSize","value":"50"}],"variable":[]}},"response":[{"id":"afa00f5b-42ce-4e06-8068-cff17942c2f1","name":"OK","originalRequest":{"method":"GET","header":[],"url":{"raw":"https://eservices.hoicom.net/api/v0/Topup/Transactions?transactionId=&externalReference=&status=Completed&fromDate=&toDate=&page=1&pageSize=50","host":["https://eservices.hoicom.net"],"path":["api","v0","Topup","Transactions"],"query":[{"key":"transactionId","value":""},{"key":"externalReference","value":""},{"key":"status","value":"Completed","description":"Enum name, e.g. Completed."},{"key":"fromDate","value":""},{"key":"toDate","value":""},{"key":"page","value":"1"},{"key":"pageSize","value":"50"}]},"description":"Returns a paginated, filterable list of your top-up transactions.\n\n---\n\n## Authorization\n\nRequires Basic Authentication with your client credentials. Your account must be enabled for the Topup service.\n\n---\n\n## Query Parameters\n\n| Parameter | Type | Required | Default | Description |\n| --- | --- | --- | --- | --- |\n| `transactionId` | `string` | No | — | Filter by transaction id. |\n| `externalReference` | `string` | No | — | Filter by your external reference. |\n| `status` | `string` | No | — | Filter by status (enum name, e.g. `Completed`). |\n| `fromDate` | `datetime` | No | — | Start of creation-date range. |\n| `toDate` | `datetime` | No | — | End of creation-date range. |\n| `page` | `int` | No | `1` | Page number. |\n| `pageSize` | `int` | No | `50` | Items per page. |\n\n---\n\n## Response\n\nOn success `code` is `1000` and `data` is a paginated list of transactions. Valid `status` values: `Submitted`, `Pending`, `Completed`, `Failed`, `Cancelled`."},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"cookie":[],"responseTime":null,"body":"{\n  \"code\": 1000,\n  \"message\": \"Success\",\n  \"data\": {\n    \"items\": [\n      {\n        \"transactionId\": \"topup_txn_9f8e7d6c\",\n        \"externalReference\": \"client-ref-3001\",\n        \"status\": \"Completed\",\n        \"timestamp\": {\n          \"requestedAt\": \"2026-07-01T10:00:00Z\",\n          \"completedAt\": \"2026-07-01T10:00:05Z\"\n        },\n        \"product\": {\n          \"id\": \"6601\",\n          \"name\": \"Airtel 50 INR\",\n          \"operator\": {\n            \"id\": \"341\",\n            \"name\": \"Airtel\",\n            \"country\": {\n              \"name\": \"India\",\n              \"isoCode\": \"IN\"\n            }\n          }\n        },\n        \"amounts\": {\n          \"requestedAmount\": {\n            \"amount\": 50,\n            \"currency\": \"INR\"\n          },\n          \"deliveredAmount\": {\n            \"amount\": 50,\n            \"currency\": \"INR\"\n          },\n          \"fees\": {\n            \"totalFee\": 0,\n            \"currency\": \"INR\"\n          }\n        },\n        \"pinDetails\": null,\n        \"receipt\": \"https://cdn.example.com/receipts/topup_txn_9f8e7d6c.pdf\"\n      }\n    ],\n    \"count\": 1,\n    \"page\": 1,\n    \"pageSize\": 50,\n    \"totalPages\": 1,\n    \"totalItems\": 1\n  }\n}"}],"_postman_id":"9f134ed8-ef66-48ee-88c3-bdf3c1eee500"}],"id":"0139080f-d0bc-4620-a76d-ee2781a0a704","description":"<p>The <strong>Topup</strong> service delivers mobile airtime and data top-ups to a destination phone number — browse supported countries, operators, and products, then submit a top-up and track it.</p>\n<hr />\n<h2 id=\"client-flow\">Client Flow</h2>\n<ol>\n<li><strong>Browse countries</strong> — <code>GET /countries</code>.</li>\n<li><strong>Browse operators</strong> — <code>GET /operators?CountryIsoCode={iso}</code>.</li>\n<li><strong>Browse products</strong> — <code>GET /products?OperatorId={id}</code> — or skip straight to <code>GET /products/lookup/{number}</code> to auto-detect country and operator from a phone number.</li>\n<li><strong>Top up</strong> — <code>POST /async</code>; returns a transaction <code>id</code>, delivery happens in the background.</li>\n<li><strong>Track</strong> — poll <code>GET /transactions/{id}</code> (or <code>GET /Transactions</code> with filters) until <code>status</code> is <code>Completed</code>.</li>\n</ol>\n<p>Orders are <strong>idempotent</strong> on <code>externalReference</code>.</p>\n<hr />\n<h2 id=\"reference-values\">Reference values</h2>\n<h3 id=\"transaction-status-status\">Transaction status (<code>status</code>)</h3>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Value</th>\n<th>Meaning</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>Submitted</code></td>\n<td>Received and queued for processing.</td>\n</tr>\n<tr>\n<td><code>Pending</code></td>\n<td>Being processed / delivered.</td>\n</tr>\n<tr>\n<td><code>Completed</code></td>\n<td>Delivered successfully.</td>\n</tr>\n<tr>\n<td><code>Failed</code></td>\n<td>Delivery failed.</td>\n</tr>\n<tr>\n<td><code>Cancelled</code></td>\n<td>Cancelled before completion.</td>\n</tr>\n<tr>\n<td><code>Refunded</code></td>\n<td>Delivered, then refunded by Hoi support after the fact. Refunds are staff-initiated only and cannot be requested through this API.</td>\n</tr>\n</tbody>\n</table>\n</div><h3 id=\"product-type-type\">Product type (<code>type</code>)</h3>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Value</th>\n<th>Meaning</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>INSTANT_FIXED</code></td>\n<td>Instant delivery, fixed denomination.</td>\n</tr>\n<tr>\n<td><code>INSTANT_VARIABLE</code></td>\n<td>Instant delivery, choose any amount in the allowed range.</td>\n</tr>\n<tr>\n<td><code>PIN_BASED</code></td>\n<td>Delivered as a redeemable PIN/voucher (see <code>pinDetails</code>).</td>\n</tr>\n</tbody>\n</table>\n</div><h3 id=\"product-categories-classificationcategories\">Product categories (<code>classification.categories</code>)</h3>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Value</th>\n<th>Meaning</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>AIRTIME</code></td>\n<td>Voice / airtime credit.</td>\n</tr>\n<tr>\n<td><code>DATA</code></td>\n<td>Mobile data.</td>\n</tr>\n<tr>\n<td><code>BUNDLES</code></td>\n<td>Combined bundle offers.</td>\n</tr>\n</tbody>\n</table>\n</div><h3 id=\"validity-type-validitiestype\">Validity type (<code>validities[].type</code>)</h3>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Value</th>\n<th>Meaning</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>TIME_BASED</code></td>\n<td>Validity measured in time (see time units).</td>\n</tr>\n<tr>\n<td><code>VOLUME_BASED</code></td>\n<td>Validity measured in data volume (see volume units).</td>\n</tr>\n<tr>\n<td><code>UNLIMITED</code></td>\n<td>No validity limit.</td>\n</tr>\n</tbody>\n</table>\n</div><h3 id=\"time-units-validitiesunit-when-type--time_based\">Time units (<code>validities[].unit</code> when type = <code>TIME_BASED</code>)</h3>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Value</th>\n<th>Meaning</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>DAYS</code></td>\n<td>Days.</td>\n</tr>\n<tr>\n<td><code>WEEKS</code></td>\n<td>Weeks.</td>\n</tr>\n<tr>\n<td><code>MONTHS</code></td>\n<td>Months.</td>\n</tr>\n<tr>\n<td><code>YEARS</code></td>\n<td>Years.</td>\n</tr>\n</tbody>\n</table>\n</div><h3 id=\"volume-units-validitiesunit-when-type--volume_based\">Volume units (<code>validities[].unit</code> when type = <code>VOLUME_BASED</code>)</h3>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Value</th>\n<th>Meaning</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>MB</code></td>\n<td>Megabytes.</td>\n</tr>\n<tr>\n<td><code>GB</code></td>\n<td>Gigabytes.</td>\n</tr>\n<tr>\n<td><code>TB</code></td>\n<td>Terabytes.</td>\n</tr>\n</tbody>\n</table>\n</div>","_postman_id":"0139080f-d0bc-4620-a76d-ee2781a0a704"},{"name":"Utilities","item":[{"name":"Get Countries","id":"35916639-2a54-45eb-a0ef-fd034542ce55","request":{"method":"GET","header":[],"url":"https://eservices.hoicom.net/api/v0/Utilities/countries?name=&isoCode=&continentName=&page=1&pageNumber=250","description":"<p>Returns the <strong>countries</strong> bill payments are supported for, with currency, calling codes, and dialing rules.</p>\n<hr />\n<h2 id=\"authorization\">Authorization</h2>\n<p>Requires Basic Authentication with your client credentials. Your account must be enabled for the Utilities service.</p>\n<hr />\n<h2 id=\"query-parameters\">Query Parameters</h2>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Parameter</th>\n<th>Type</th>\n<th>Required</th>\n<th>Default</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>name</code></td>\n<td><code>string</code></td>\n<td>No</td>\n<td>—</td>\n<td>Filter by country name.</td>\n</tr>\n<tr>\n<td><code>isoCode</code></td>\n<td><code>string</code></td>\n<td>No</td>\n<td>—</td>\n<td>Filter by ISO code.</td>\n</tr>\n<tr>\n<td><code>continentName</code></td>\n<td><code>string</code></td>\n<td>No</td>\n<td>—</td>\n<td>Filter by continent.</td>\n</tr>\n<tr>\n<td><code>page</code></td>\n<td><code>int</code></td>\n<td>No</td>\n<td><code>1</code></td>\n<td>Page number.</td>\n</tr>\n<tr>\n<td><code>pageNumber</code></td>\n<td><code>int</code></td>\n<td>No</td>\n<td><code>250</code></td>\n<td><strong>Items per page</strong> — despite the name, this parameter controls page size, not the page number (use <code>page</code> for that). This is a naming quirk specific to this endpoint: every other Topup/Utilities list endpoint calls the equivalent parameter <code>pageSize</code>.</td>\n</tr>\n</tbody>\n</table>\n</div><hr />\n<h2 id=\"response\">Response</h2>\n<p>On success <code>code</code> is <code>1000</code> and <code>data</code> is a paginated list of countries.</p>\n<hr />\n<h2 id=\"response-fields\">Response fields</h2>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Field</th>\n<th>Type</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>code</code></td>\n<td>int</td>\n<td>Response status code; <code>1000</code> on success (see Reference values).</td>\n</tr>\n<tr>\n<td><code>message</code></td>\n<td>string</td>\n<td>Human-readable status message.</td>\n</tr>\n<tr>\n<td><code>data</code></td>\n<td>object</td>\n<td>Paginated list of countries.</td>\n</tr>\n<tr>\n<td><code>data.items</code></td>\n<td>array</td>\n<td>Countries on this page.</td>\n</tr>\n<tr>\n<td><code>data.items[].name</code></td>\n<td>string</td>\n<td>Country name.</td>\n</tr>\n<tr>\n<td><code>data.items[].isoCode</code></td>\n<td>string</td>\n<td>Country ISO code.</td>\n</tr>\n<tr>\n<td><code>data.items[].continentName</code></td>\n<td>string</td>\n<td>Continent the country belongs to.</td>\n</tr>\n<tr>\n<td><code>data.items[].currency.code</code></td>\n<td>string</td>\n<td>Currency code used in this country.</td>\n</tr>\n<tr>\n<td><code>data.items[].currency.name</code></td>\n<td>string</td>\n<td>Currency name.</td>\n</tr>\n<tr>\n<td><code>data.items[].currency.symbol</code></td>\n<td>string</td>\n<td>Currency symbol.</td>\n</tr>\n<tr>\n<td><code>data.items[].flagUrl</code></td>\n<td>string</td>\n<td>URL of the country's flag image; <code>null</code> if none is available.</td>\n</tr>\n<tr>\n<td><code>data.items[].callingCodes</code></td>\n<td>array of string</td>\n<td>International dialing code(s) for the country.</td>\n</tr>\n<tr>\n<td><code>data.items[].regions</code></td>\n<td>array</td>\n<td>Region groupings the country belongs to.</td>\n</tr>\n<tr>\n<td><code>data.items[].regions[].name</code></td>\n<td>string</td>\n<td>Region name.</td>\n</tr>\n<tr>\n<td><code>data.items[].regions[].code</code></td>\n<td>string</td>\n<td>Region code.</td>\n</tr>\n<tr>\n<td><code>data.items[].dialingRules</code></td>\n<td>array</td>\n<td>Destination-number length rules used to validate account/mobile numbers for this country.</td>\n</tr>\n<tr>\n<td><code>data.items[].dialingRules[].prefix</code></td>\n<td>string</td>\n<td>Leading digit(s) the rule applies to.</td>\n</tr>\n<tr>\n<td><code>data.items[].dialingRules[].minimumLength</code></td>\n<td>int</td>\n<td>Minimum national number length for numbers starting with <code>prefix</code>.</td>\n</tr>\n<tr>\n<td><code>data.items[].dialingRules[].maximumLength</code></td>\n<td>int</td>\n<td>Maximum national number length for numbers starting with <code>prefix</code>.</td>\n</tr>\n<tr>\n<td><code>data.count</code></td>\n<td>int</td>\n<td>Number of items on this page.</td>\n</tr>\n<tr>\n<td><code>data.page</code></td>\n<td>int</td>\n<td>Current page number (from <code>page</code>).</td>\n</tr>\n<tr>\n<td><code>data.pageSize</code></td>\n<td>int</td>\n<td>Items per page (from <code>pageNumber</code> — see the parameter note above).</td>\n</tr>\n<tr>\n<td><code>data.totalPages</code></td>\n<td>int</td>\n<td>Total number of pages available.</td>\n</tr>\n<tr>\n<td><code>data.totalItems</code></td>\n<td>int</td>\n<td>Total number of countries matching the filter.</td>\n</tr>\n</tbody>\n</table>\n</div>","urlObject":{"path":["api","v0","Utilities","countries"],"host":["https://eservices.hoicom.net"],"query":[{"key":"name","value":""},{"key":"isoCode","value":""},{"key":"continentName","value":""},{"key":"page","value":"1"},{"key":"pageNumber","value":"250"}],"variable":[]}},"response":[{"id":"fa7e6aaf-afef-4a78-a5e5-edaa30f2741e","name":"OK","originalRequest":{"method":"GET","header":[],"url":{"raw":"https://eservices.hoicom.net/api/v0/Utilities/countries?name=&isoCode=&continentName=&page=1&pageNumber=250","host":["https://eservices.hoicom.net"],"path":["api","v0","Utilities","countries"],"query":[{"key":"name","value":""},{"key":"isoCode","value":""},{"key":"continentName","value":""},{"key":"page","value":"1"},{"key":"pageNumber","value":"250"}]},"description":"Returns the **countries** bill payments are supported for, with currency, calling codes, and dialing rules.\n\n---\n\n## Authorization\n\nRequires Basic Authentication with your client credentials. Your account must be enabled for the Utilities service.\n\n---\n\n## Query Parameters\n\n| Parameter | Type | Required | Default | Description |\n| --- | --- | --- | --- | --- |\n| `name` | `string` | No | — | Filter by country name. |\n| `isoCode` | `string` | No | — | Filter by ISO code. |\n| `continentName` | `string` | No | — | Filter by continent. |\n| `page` | `int` | No | `1` | Page number. |\n| `pageNumber` | `int` | No | `250` | Items per page. |\n\n---\n\n## Response\n\nOn success `code` is `1000` and `data` is a paginated list of countries."},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"cookie":[],"responseTime":null,"body":"{\n  \"code\": 1000,\n  \"message\": \"Success\",\n  \"data\": {\n    \"items\": [\n      {\n        \"name\": \"India\",\n        \"isoCode\": \"IN\",\n        \"continentName\": \"Asia\",\n        \"currency\": {\n          \"code\": \"INR\",\n          \"name\": \"Indian Rupee\",\n          \"symbol\": \"₹\"\n        },\n        \"flagUrl\": \"https://cdn.example.com/flags/in.svg\",\n        \"callingCodes\": [\n          \"+91\"\n        ],\n        \"regions\": [\n          {\n            \"name\": \"Asia\",\n            \"code\": \"AS\"\n          }\n        ],\n        \"dialingRules\": [\n          {\n            \"prefix\": \"5\",\n            \"minimumLength\": 9,\n            \"maximumLength\": 9\n          }\n        ]\n      }\n    ],\n    \"count\": 1,\n    \"page\": 1,\n    \"pageSize\": 50,\n    \"totalPages\": 1,\n    \"totalItems\": 1\n  }\n}"}],"_postman_id":"35916639-2a54-45eb-a0ef-fd034542ce55"},{"name":"Get Operators","id":"6bacc91c-be17-41ba-b18e-fefb5efe7e14","request":{"method":"GET","header":[],"url":"https://eservices.hoicom.net/api/v0/Utilities/operators?countryIsoCodes=SA&ids=&names=&page=1&pageSize=50","description":"<p>Returns billers/<strong>operators</strong>, optionally filtered by country, id, or name. Use an operator <code>id</code> to list its bills/products.</p>\n<hr />\n<h2 id=\"authorization\">Authorization</h2>\n<p>Requires Basic Authentication with your client credentials. Your account must be enabled for the Utilities service.</p>\n<hr />\n<h2 id=\"query-parameters\">Query Parameters</h2>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Parameter</th>\n<th>Type</th>\n<th>Required</th>\n<th>Default</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>countryIsoCodes</code></td>\n<td><code>string[]</code></td>\n<td>No</td>\n<td>—</td>\n<td>Filter by country ISO code(s).</td>\n</tr>\n<tr>\n<td><code>ids</code></td>\n<td><code>string[]</code></td>\n<td>No</td>\n<td>—</td>\n<td>Filter by operator id(s).</td>\n</tr>\n<tr>\n<td><code>names</code></td>\n<td><code>string[]</code></td>\n<td>No</td>\n<td>—</td>\n<td>Filter by operator name(s).</td>\n</tr>\n<tr>\n<td><code>page</code></td>\n<td><code>int</code></td>\n<td>No</td>\n<td><code>1</code></td>\n<td>Page number.</td>\n</tr>\n<tr>\n<td><code>pageSize</code></td>\n<td><code>int</code></td>\n<td>No</td>\n<td><code>50</code></td>\n<td>Items per page.</td>\n</tr>\n</tbody>\n</table>\n</div><hr />\n<h2 id=\"response\">Response</h2>\n<p>On success <code>code</code> is <code>1000</code> and <code>data</code> is a paginated list of operators.</p>\n<hr />\n<h2 id=\"response-fields\">Response fields</h2>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Field</th>\n<th>Type</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>code</code></td>\n<td>int</td>\n<td>Response status code; <code>1000</code> on success (see Reference values).</td>\n</tr>\n<tr>\n<td><code>message</code></td>\n<td>string</td>\n<td>Human-readable status message.</td>\n</tr>\n<tr>\n<td><code>data</code></td>\n<td>object</td>\n<td>Paginated list of operators.</td>\n</tr>\n<tr>\n<td><code>data.items</code></td>\n<td>array</td>\n<td>Operators (billers) on this page.</td>\n</tr>\n<tr>\n<td><code>data.items[].id</code></td>\n<td>string</td>\n<td>Operator identifier; use it to filter Get Products by Operator.</td>\n</tr>\n<tr>\n<td><code>data.items[].name</code></td>\n<td>string</td>\n<td>Operator (biller) name.</td>\n</tr>\n<tr>\n<td><code>data.items[].country.name</code></td>\n<td>string</td>\n<td>Country the operator serves.</td>\n</tr>\n<tr>\n<td><code>data.items[].country.isoCode</code></td>\n<td>string</td>\n<td>Country ISO code.</td>\n</tr>\n<tr>\n<td><code>data.items[].country.regions</code></td>\n<td>array</td>\n<td>Region groupings for the country.</td>\n</tr>\n<tr>\n<td><code>data.items[].country.regions[].name</code></td>\n<td>string</td>\n<td>Region name.</td>\n</tr>\n<tr>\n<td><code>data.items[].country.regions[].code</code></td>\n<td>string</td>\n<td>Region code.</td>\n</tr>\n<tr>\n<td><code>data.items[].logoUrls</code></td>\n<td>array of string</td>\n<td>Operator logo image URL(s).</td>\n</tr>\n<tr>\n<td><code>data.count</code></td>\n<td>int</td>\n<td>Number of items on this page.</td>\n</tr>\n<tr>\n<td><code>data.page</code></td>\n<td>int</td>\n<td>Current page number.</td>\n</tr>\n<tr>\n<td><code>data.pageSize</code></td>\n<td>int</td>\n<td>Items per page.</td>\n</tr>\n<tr>\n<td><code>data.totalPages</code></td>\n<td>int</td>\n<td>Total number of pages available.</td>\n</tr>\n<tr>\n<td><code>data.totalItems</code></td>\n<td>int</td>\n<td>Total number of operators matching the filter.</td>\n</tr>\n</tbody>\n</table>\n</div>","urlObject":{"path":["api","v0","Utilities","operators"],"host":["https://eservices.hoicom.net"],"query":[{"key":"countryIsoCodes","value":"SA"},{"key":"ids","value":""},{"key":"names","value":""},{"key":"page","value":"1"},{"key":"pageSize","value":"50"}],"variable":[]}},"response":[{"id":"ded40b8d-b1a6-4577-9786-4757b9b71431","name":"OK","originalRequest":{"method":"GET","header":[],"url":{"raw":"https://eservices.hoicom.net/api/v0/Utilities/operators?countryIsoCodes=SA&ids=&names=&page=1&pageSize=50","host":["https://eservices.hoicom.net"],"path":["api","v0","Utilities","operators"],"query":[{"key":"countryIsoCodes","value":"SA"},{"key":"ids","value":""},{"key":"names","value":""},{"key":"page","value":"1"},{"key":"pageSize","value":"50"}]},"description":"Returns billers/**operators**, optionally filtered by country, id, or name. Use an operator `id` to list its bills/products.\n\n---\n\n## Authorization\n\nRequires Basic Authentication with your client credentials. Your account must be enabled for the Utilities service.\n\n---\n\n## Query Parameters\n\n| Parameter | Type | Required | Default | Description |\n| --- | --- | --- | --- | --- |\n| `countryIsoCodes` | `string[]` | No | — | Filter by country ISO code(s). |\n| `ids` | `string[]` | No | — | Filter by operator id(s). |\n| `names` | `string[]` | No | — | Filter by operator name(s). |\n| `page` | `int` | No | `1` | Page number. |\n| `pageSize` | `int` | No | `50` | Items per page. |\n\n---\n\n## Response\n\nOn success `code` is `1000` and `data` is a paginated list of operators."},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"cookie":[],"responseTime":null,"body":"{\n  \"code\": 1000,\n  \"message\": \"Success\",\n  \"data\": {\n    \"items\": [\n      {\n        \"id\": \"op_tatapower\",\n        \"name\": \"Tata Power\",\n        \"country\": {\n          \"name\": \"India\",\n          \"isoCode\": \"IN\",\n          \"regions\": [\n            {\n              \"name\": \"Asia\",\n              \"code\": \"AS\"\n            }\n          ]\n        },\n        \"logoUrls\": [\n          \"https://cdn.example.com/operators/tatapower.png\"\n        ]\n      }\n    ],\n    \"count\": 1,\n    \"page\": 1,\n    \"pageSize\": 50,\n    \"totalPages\": 1,\n    \"totalItems\": 1\n  }\n}"}],"_postman_id":"6bacc91c-be17-41ba-b18e-fefb5efe7e14"},{"name":"Get Operators by Country","id":"82653376-af5e-431c-b9fc-88ed9f94acf6","request":{"method":"GET","header":[],"url":"https://eservices.hoicom.net/api/v0/Utilities/countries/:isoCode/operators?page=1&pageSize=50","description":"<p>Returns the billers/operators available in a specific country.</p>\n<hr />\n<h2 id=\"authorization\">Authorization</h2>\n<p>Requires Basic Authentication with your client credentials. Your account must be enabled for the Utilities service.</p>\n<hr />\n<h2 id=\"path-parameters\">Path Parameters</h2>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Parameter</th>\n<th>Type</th>\n<th>Required</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>isoCode</code></td>\n<td><code>string</code></td>\n<td>Yes</td>\n<td>Country ISO code.</td>\n</tr>\n</tbody>\n</table>\n</div><hr />\n<h2 id=\"query-parameters\">Query Parameters</h2>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Parameter</th>\n<th>Type</th>\n<th>Required</th>\n<th>Default</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>page</code></td>\n<td><code>int</code></td>\n<td>No</td>\n<td><code>1</code></td>\n<td>Page number.</td>\n</tr>\n<tr>\n<td><code>pageSize</code></td>\n<td><code>int</code></td>\n<td>No</td>\n<td><code>50</code></td>\n<td>Items per page.</td>\n</tr>\n</tbody>\n</table>\n</div><hr />\n<h2 id=\"response\">Response</h2>\n<p>On success <code>code</code> is <code>1000</code> and <code>data</code> is a paginated list of operators.</p>\n<hr />\n<h2 id=\"response-fields\">Response fields</h2>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Field</th>\n<th>Type</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>code</code></td>\n<td>int</td>\n<td>Response status code; <code>1000</code> on success (see Reference values).</td>\n</tr>\n<tr>\n<td><code>message</code></td>\n<td>string</td>\n<td>Human-readable status message.</td>\n</tr>\n<tr>\n<td><code>data</code></td>\n<td>object</td>\n<td>Paginated list of operators.</td>\n</tr>\n<tr>\n<td><code>data.items</code></td>\n<td>array</td>\n<td>Operators (billers) available in <code>isoCode</code> on this page.</td>\n</tr>\n<tr>\n<td><code>data.items[].id</code></td>\n<td>string</td>\n<td>Operator identifier; use it to filter Get Products by Operator.</td>\n</tr>\n<tr>\n<td><code>data.items[].name</code></td>\n<td>string</td>\n<td>Operator (biller) name.</td>\n</tr>\n<tr>\n<td><code>data.items[].country.name</code></td>\n<td>string</td>\n<td>Country the operator serves.</td>\n</tr>\n<tr>\n<td><code>data.items[].country.isoCode</code></td>\n<td>string</td>\n<td>Country ISO code.</td>\n</tr>\n<tr>\n<td><code>data.items[].country.regions</code></td>\n<td>array</td>\n<td>Region groupings for the country.</td>\n</tr>\n<tr>\n<td><code>data.items[].country.regions[].name</code></td>\n<td>string</td>\n<td>Region name.</td>\n</tr>\n<tr>\n<td><code>data.items[].country.regions[].code</code></td>\n<td>string</td>\n<td>Region code.</td>\n</tr>\n<tr>\n<td><code>data.items[].logoUrls</code></td>\n<td>array of string</td>\n<td>Operator logo image URL(s).</td>\n</tr>\n<tr>\n<td><code>data.count</code></td>\n<td>int</td>\n<td>Number of items on this page.</td>\n</tr>\n<tr>\n<td><code>data.page</code></td>\n<td>int</td>\n<td>Current page number.</td>\n</tr>\n<tr>\n<td><code>data.pageSize</code></td>\n<td>int</td>\n<td>Items per page.</td>\n</tr>\n<tr>\n<td><code>data.totalPages</code></td>\n<td>int</td>\n<td>Total number of pages available.</td>\n</tr>\n<tr>\n<td><code>data.totalItems</code></td>\n<td>int</td>\n<td>Total number of operators in this country.</td>\n</tr>\n</tbody>\n</table>\n</div>","urlObject":{"path":["api","v0","Utilities","countries",":isoCode","operators"],"host":["https://eservices.hoicom.net"],"query":[{"key":"page","value":"1"},{"key":"pageSize","value":"50"}],"variable":[{"type":"any","value":"","key":"isoCode"}]}},"response":[{"id":"acdfdf54-0408-4dcc-8aba-c0fa0923efd4","name":"OK","originalRequest":{"method":"GET","header":[],"url":{"raw":"https://eservices.hoicom.net/api/v0/Utilities/countries/:isoCode/operators?page=1&pageSize=50","host":["https://eservices.hoicom.net"],"path":["api","v0","Utilities","countries",":isoCode","operators"],"query":[{"key":"page","value":"1"},{"key":"pageSize","value":"50"}],"variable":[{"key":"isoCode","value":""}]},"description":"Returns the billers/operators available in a specific country.\n\n---\n\n## Authorization\n\nRequires Basic Authentication with your client credentials. Your account must be enabled for the Utilities service.\n\n---\n\n## Path Parameters\n\n| Parameter | Type | Required | Description |\n| --- | --- | --- | --- |\n| `isoCode` | `string` | Yes | Country ISO code. |\n\n---\n\n## Query Parameters\n\n| Parameter | Type | Required | Default | Description |\n| --- | --- | --- | --- | --- |\n| `page` | `int` | No | `1` | Page number. |\n| `pageSize` | `int` | No | `50` | Items per page. |\n\n---\n\n## Response\n\nOn success `code` is `1000` and `data` is a paginated list of operators."},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"cookie":[],"responseTime":null,"body":"{\n  \"code\": 1000,\n  \"message\": \"Success\",\n  \"data\": {\n    \"items\": [\n      {\n        \"id\": \"op_tatapower\",\n        \"name\": \"Tata Power\",\n        \"country\": {\n          \"name\": \"India\",\n          \"isoCode\": \"IN\",\n          \"regions\": [\n            {\n              \"name\": \"Asia\",\n              \"code\": \"AS\"\n            }\n          ]\n        },\n        \"logoUrls\": [\n          \"https://cdn.example.com/operators/tatapower.png\"\n        ]\n      }\n    ],\n    \"count\": 1,\n    \"page\": 1,\n    \"pageSize\": 50,\n    \"totalPages\": 1,\n    \"totalItems\": 1\n  }\n}"}],"_postman_id":"82653376-af5e-431c-b9fc-88ed9f94acf6"},{"name":"Get Products by Operator","id":"b4610d56-26cf-48e6-855f-b0a9f77dfe65","request":{"method":"GET","header":[],"url":"https://eservices.hoicom.net/api/v0/Utilities/operators/:operatorId/products?page=1&pageSize=50","description":"<p>Returns the bills/<strong>products</strong> offered by a specific operator. Each product carries its <code>pricing</code>, <code>paymentOptions</code>, and the input fields required to pay.</p>\n<hr />\n<h2 id=\"authorization\">Authorization</h2>\n<p>Requires Basic Authentication with your client credentials. Your account must be enabled for the Utilities service.</p>\n<hr />\n<h2 id=\"path-parameters\">Path Parameters</h2>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Parameter</th>\n<th>Type</th>\n<th>Required</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>operatorId</code></td>\n<td><code>string</code></td>\n<td>Yes</td>\n<td>Operator identifier.</td>\n</tr>\n</tbody>\n</table>\n</div><hr />\n<h2 id=\"query-parameters\">Query Parameters</h2>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Parameter</th>\n<th>Type</th>\n<th>Required</th>\n<th>Default</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>page</code></td>\n<td><code>int</code></td>\n<td>No</td>\n<td><code>1</code></td>\n<td>Page number.</td>\n</tr>\n<tr>\n<td><code>pageSize</code></td>\n<td><code>int</code></td>\n<td>No</td>\n<td><code>50</code></td>\n<td>Items per page.</td>\n</tr>\n</tbody>\n</table>\n</div><hr />\n<h2 id=\"response\">Response</h2>\n<p>On success <code>code</code> is <code>1000</code> and <code>data</code> is a paginated list of products. <code>type</code> uses the <strong>Payment type</strong> values and <code>pricing.paymentCurrencyType</code> / <code>paymentOptions.allowedPaymentOptions</code> the <strong>Payment currency</strong> / <strong>Payment option</strong> values (see folder overview).</p>\n<hr />\n<h2 id=\"response-fields\">Response fields</h2>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Field</th>\n<th>Type</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>code</code></td>\n<td>int</td>\n<td>Response status code; <code>1000</code> on success (see Reference values).</td>\n</tr>\n<tr>\n<td><code>message</code></td>\n<td>string</td>\n<td>Human-readable status message.</td>\n</tr>\n<tr>\n<td><code>data</code></td>\n<td>object</td>\n<td>Paginated list of products (bills).</td>\n</tr>\n<tr>\n<td><code>data.items</code></td>\n<td>array</td>\n<td>Products on this page.</td>\n</tr>\n<tr>\n<td><code>data.items[].id</code></td>\n<td>string</td>\n<td>Product identifier; pass as <code>utilityId</code> when creating a transaction or account inquiry.</td>\n</tr>\n<tr>\n<td><code>data.items[].type</code></td>\n<td>string (see Reference values)</td>\n<td>Payment type — <code>RangedPayment</code>, <code>FixedRecharge</code>, or <code>PINPurchase</code>.</td>\n</tr>\n<tr>\n<td><code>data.items[].details.name</code></td>\n<td>string</td>\n<td>Product display name.</td>\n</tr>\n<tr>\n<td><code>data.items[].details.serviceType</code></td>\n<td>string</td>\n<td>Category of bill/service (e.g. <code>Electricity</code>); free text from the biller, no fixed value list.</td>\n</tr>\n<tr>\n<td><code>data.items[].details.description</code></td>\n<td>string</td>\n<td>Product description.</td>\n</tr>\n<tr>\n<td><code>data.items[].details.termsAndConditions</code></td>\n<td>string</td>\n<td>Terms and conditions text.</td>\n</tr>\n<tr>\n<td><code>data.items[].details.usageInstructions</code></td>\n<td>string</td>\n<td>Instructions for how to pay this bill.</td>\n</tr>\n<tr>\n<td><code>data.items[].pricing.paymentCurrencyType</code></td>\n<td>string (see Reference values)</td>\n<td><code>ClientCurrency</code> or <code>DestinationCurrency</code>.</td>\n</tr>\n<tr>\n<td><code>data.items[].pricing.currency</code></td>\n<td>string</td>\n<td>Currency you are charged in.</td>\n</tr>\n<tr>\n<td><code>data.items[].pricing.minAmount</code></td>\n<td>decimal</td>\n<td>Minimum payable amount, in <code>currency</code>.</td>\n</tr>\n<tr>\n<td><code>data.items[].pricing.maxAmount</code></td>\n<td>decimal</td>\n<td>Maximum payable amount, in <code>currency</code>.</td>\n</tr>\n<tr>\n<td><code>data.items[].pricing.destinationCurrency</code></td>\n<td>string</td>\n<td>Currency the payment is applied in at the biller.</td>\n</tr>\n<tr>\n<td><code>data.items[].pricing.minDestinationAmount</code></td>\n<td>decimal</td>\n<td>Minimum applied amount, in <code>destinationCurrency</code>.</td>\n</tr>\n<tr>\n<td><code>data.items[].pricing.maxDestinationAmount</code></td>\n<td>decimal</td>\n<td>Maximum applied amount, in <code>destinationCurrency</code>.</td>\n</tr>\n<tr>\n<td><code>data.items[].pricing.fees</code></td>\n<td>decimal</td>\n<td>Fixed fee added to the payment, in <code>currency</code>.</td>\n</tr>\n<tr>\n<td><code>data.items[].pricing.tax.taxRate</code></td>\n<td>decimal</td>\n<td>Tax rate applied, as a percentage.</td>\n</tr>\n<tr>\n<td><code>data.items[].pricing.tax.taxType</code></td>\n<td>string</td>\n<td>Tax type/name (e.g. <code>VAT</code>).</td>\n</tr>\n<tr>\n<td><code>data.items[].pricing.tax.taxAmount</code></td>\n<td>decimal</td>\n<td>Tax amount included in the price.</td>\n</tr>\n<tr>\n<td><code>data.items[].paymentOptions.supportsAccountInquiry</code></td>\n<td>bool</td>\n<td><code>true</code> if you can call <strong>Account Inquiry</strong> for this product before paying.</td>\n</tr>\n<tr>\n<td><code>data.items[].paymentOptions.allowedPaymentOptions</code></td>\n<td>array of string (see Reference values)</td>\n<td>One or more of <code>ExactAmount</code>, <code>AllowsOverpayment</code>, <code>AcceptsLatePayments</code>, <code>AllowsPartialPayments</code>.</td>\n</tr>\n<tr>\n<td><code>data.items[].validities</code></td>\n<td>array</td>\n<td>Validity/posting-time entries for this product.</td>\n</tr>\n<tr>\n<td><code>data.items[].validities[].type</code></td>\n<td>string</td>\n<td>Free-text value from the biller (e.g. <code>PostingTime</code>); no fixed reference-value list is currently published for Utilities (unlike Topup's validity types).</td>\n</tr>\n<tr>\n<td><code>data.items[].validities[].unit</code></td>\n<td>string</td>\n<td>Free-text unit paired with <code>type</code> (e.g. <code>Day</code>).</td>\n</tr>\n<tr>\n<td><code>data.items[].validities[].quantity</code></td>\n<td>decimal</td>\n<td>Number of <code>unit</code>s.</td>\n</tr>\n<tr>\n<td><code>data.items[].transactionRequiredFields</code></td>\n<td>array of string</td>\n<td>Field names you must supply as keys in <code>transactionRequiredFields</code> on <strong>Account Inquiry</strong> / <strong>Create Transaction</strong> for this product.</td>\n</tr>\n<tr>\n<td><code>data.items[].receiverRequiredFields</code></td>\n<td>array of string</td>\n<td>Field names for additional receiver-related data this product requires, if any (empty array when none needed).</td>\n</tr>\n<tr>\n<td><code>data.items[].operator.id</code></td>\n<td>string</td>\n<td>Operator identifier.</td>\n</tr>\n<tr>\n<td><code>data.items[].operator.name</code></td>\n<td>string</td>\n<td>Operator (biller) name.</td>\n</tr>\n<tr>\n<td><code>data.items[].operator.country.name</code></td>\n<td>string</td>\n<td>Country the operator serves.</td>\n</tr>\n<tr>\n<td><code>data.items[].operator.country.isoCode</code></td>\n<td>string</td>\n<td>Country ISO code.</td>\n</tr>\n<tr>\n<td><code>data.items[].operator.country.regions</code></td>\n<td>array</td>\n<td>Region groupings for the country; may be empty.</td>\n</tr>\n<tr>\n<td><code>data.items[].operator.logoUrls</code></td>\n<td>array of string</td>\n<td>Operator logo image URL(s).</td>\n</tr>\n<tr>\n<td><code>data.count</code></td>\n<td>int</td>\n<td>Number of items on this page.</td>\n</tr>\n<tr>\n<td><code>data.page</code></td>\n<td>int</td>\n<td>Current page number.</td>\n</tr>\n<tr>\n<td><code>data.pageSize</code></td>\n<td>int</td>\n<td>Items per page.</td>\n</tr>\n<tr>\n<td><code>data.totalPages</code></td>\n<td>int</td>\n<td>Total number of pages available.</td>\n</tr>\n<tr>\n<td><code>data.totalItems</code></td>\n<td>int</td>\n<td>Total number of products for this operator.</td>\n</tr>\n</tbody>\n</table>\n</div>","urlObject":{"path":["api","v0","Utilities","operators",":operatorId","products"],"host":["https://eservices.hoicom.net"],"query":[{"key":"page","value":"1"},{"key":"pageSize","value":"50"}],"variable":[{"type":"any","value":"","key":"operatorId"}]}},"response":[{"id":"02b414aa-33c6-4a4f-8298-d388a46ca372","name":"OK","originalRequest":{"method":"GET","header":[],"url":{"raw":"https://eservices.hoicom.net/api/v0/Utilities/operators/:operatorId/products?page=1&pageSize=50","host":["https://eservices.hoicom.net"],"path":["api","v0","Utilities","operators",":operatorId","products"],"query":[{"key":"page","value":"1"},{"key":"pageSize","value":"50"}],"variable":[{"key":"operatorId","value":""}]},"description":"Returns the bills/**products** offered by a specific operator. Each product carries its `pricing`, `paymentOptions`, and the input fields required to pay.\n\n---\n\n## Authorization\n\nRequires Basic Authentication with your client credentials. Your account must be enabled for the Utilities service.\n\n---\n\n## Path Parameters\n\n| Parameter | Type | Required | Description |\n| --- | --- | --- | --- |\n| `operatorId` | `string` | Yes | Operator identifier. |\n\n---\n\n## Query Parameters\n\n| Parameter | Type | Required | Default | Description |\n| --- | --- | --- | --- | --- |\n| `page` | `int` | No | `1` | Page number. |\n| `pageSize` | `int` | No | `50` | Items per page. |\n\n---\n\n## Response\n\nOn success `code` is `1000` and `data` is a paginated list of products. `type` uses the **Payment type** enum and `pricing.paymentCurrencyType` / `paymentOptions.allowedPaymentOptions` the **Payment currency** / **Payment option** enums (see folder overview)."},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"cookie":[],"responseTime":null,"body":"{\n  \"code\": 1000,\n  \"message\": \"Success\",\n  \"data\": {\n    \"items\": [\n      {\n        \"id\": \"V1:12345\",\n        \"type\": \"RangedPayment\",\n        \"details\": {\n          \"name\": \"Tata Power Electricity Bill\",\n          \"serviceType\": \"Electricity\",\n          \"description\": \"Pay your Tata Power electricity bill.\",\n          \"termsAndConditions\": \"Standard terms apply.\",\n          \"usageInstructions\": \"Enter your account number to pay.\"\n        },\n        \"pricing\": {\n          \"paymentCurrencyType\": \"ClientCurrency\",\n          \"currency\": \"INR\",\n          \"minAmount\": 10,\n          \"maxAmount\": 5000,\n          \"destinationCurrency\": \"INR\",\n          \"minDestinationAmount\": 10,\n          \"maxDestinationAmount\": 5000,\n          \"fees\": 0,\n          \"tax\": {\n            \"taxRate\": 15,\n            \"taxType\": \"VAT\",\n            \"taxAmount\": 0\n          }\n        },\n        \"paymentOptions\": {\n          \"supportsAccountInquiry\": true,\n          \"allowedPaymentOptions\": [\n            \"ExactAmount\",\n            \"AllowsPartialPayments\"\n          ]\n        },\n        \"validities\": [\n          {\n            \"type\": \"PostingTime\",\n            \"unit\": \"Day\",\n            \"quantity\": 1\n          }\n        ],\n        \"transactionRequiredFields\": [\n          \"accountNumber\"\n        ],\n        \"receiverRequiredFields\": [],\n        \"operator\": {\n          \"id\": \"op_tatapower\",\n          \"name\": \"Tata Power\",\n          \"country\": {\n            \"name\": \"India\",\n            \"isoCode\": \"IN\",\n            \"regions\": []\n          },\n          \"logoUrls\": [\n            \"https://cdn.example.com/operators/tatapower.png\"\n          ]\n        }\n      }\n    ],\n    \"count\": 1,\n    \"page\": 1,\n    \"pageSize\": 50,\n    \"totalPages\": 1,\n    \"totalItems\": 1\n  }\n}"}],"_postman_id":"b4610d56-26cf-48e6-855f-b0a9f77dfe65"},{"name":"Get Products","id":"59b8a0a8-ec85-4bf2-bd99-aeec2b2f120b","request":{"method":"GET","header":[],"url":"https://eservices.hoicom.net/api/v0/Utilities?countryIsoCodes=SA&operatorsIds=&types=&page=1&pageSize=50","description":"<p>Returns bills/<strong>products</strong> across operators, filterable by country, operator, or type.</p>\n<hr />\n<h2 id=\"authorization\">Authorization</h2>\n<p>Requires Basic Authentication with your client credentials. Your account must be enabled for the Utilities service.</p>\n<hr />\n<h2 id=\"query-parameters\">Query Parameters</h2>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Parameter</th>\n<th>Type</th>\n<th>Required</th>\n<th>Default</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>countryIsoCodes</code></td>\n<td><code>string[]</code></td>\n<td>No</td>\n<td>—</td>\n<td>Filter by country ISO code(s).</td>\n</tr>\n<tr>\n<td><code>operatorsIds</code></td>\n<td><code>string[]</code></td>\n<td>No</td>\n<td>—</td>\n<td>Filter by operator id(s).</td>\n</tr>\n<tr>\n<td><code>types</code></td>\n<td><code>string[]</code></td>\n<td>No</td>\n<td>—</td>\n<td>Filter by payment type: <code>RangedPayment</code>, <code>FixedRecharge</code>, <code>PINPurchase</code>.</td>\n</tr>\n<tr>\n<td><code>page</code></td>\n<td><code>int</code></td>\n<td>No</td>\n<td><code>1</code></td>\n<td>Page number.</td>\n</tr>\n<tr>\n<td><code>pageSize</code></td>\n<td><code>int</code></td>\n<td>No</td>\n<td><code>50</code></td>\n<td>Items per page.</td>\n</tr>\n</tbody>\n</table>\n</div><hr />\n<h2 id=\"response\">Response</h2>\n<p>On success <code>code</code> is <code>1000</code> and <code>data</code> is a paginated list of products.</p>\n<hr />\n<h2 id=\"response-fields\">Response fields</h2>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Field</th>\n<th>Type</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>code</code></td>\n<td>int</td>\n<td>Response status code; <code>1000</code> on success (see Reference values).</td>\n</tr>\n<tr>\n<td><code>message</code></td>\n<td>string</td>\n<td>Human-readable status message.</td>\n</tr>\n<tr>\n<td><code>data</code></td>\n<td>object</td>\n<td>Paginated list of products (bills) across operators.</td>\n</tr>\n<tr>\n<td><code>data.items</code></td>\n<td>array</td>\n<td>Products on this page.</td>\n</tr>\n<tr>\n<td><code>data.items[].id</code></td>\n<td>string</td>\n<td>Product identifier; pass as <code>utilityId</code> when creating a transaction or account inquiry.</td>\n</tr>\n<tr>\n<td><code>data.items[].type</code></td>\n<td>string (see Reference values)</td>\n<td>Payment type — <code>RangedPayment</code>, <code>FixedRecharge</code>, or <code>PINPurchase</code>.</td>\n</tr>\n<tr>\n<td><code>data.items[].details.name</code></td>\n<td>string</td>\n<td>Product display name.</td>\n</tr>\n<tr>\n<td><code>data.items[].details.serviceType</code></td>\n<td>string</td>\n<td>Category of bill/service (e.g. <code>Electricity</code>); free text from the biller, no fixed value list.</td>\n</tr>\n<tr>\n<td><code>data.items[].details.description</code></td>\n<td>string</td>\n<td>Product description.</td>\n</tr>\n<tr>\n<td><code>data.items[].details.termsAndConditions</code></td>\n<td>string</td>\n<td>Terms and conditions text.</td>\n</tr>\n<tr>\n<td><code>data.items[].details.usageInstructions</code></td>\n<td>string</td>\n<td>Instructions for how to pay this bill.</td>\n</tr>\n<tr>\n<td><code>data.items[].pricing.paymentCurrencyType</code></td>\n<td>string (see Reference values)</td>\n<td><code>ClientCurrency</code> or <code>DestinationCurrency</code>.</td>\n</tr>\n<tr>\n<td><code>data.items[].pricing.currency</code></td>\n<td>string</td>\n<td>Currency you are charged in.</td>\n</tr>\n<tr>\n<td><code>data.items[].pricing.minAmount</code></td>\n<td>decimal</td>\n<td>Minimum payable amount, in <code>currency</code>.</td>\n</tr>\n<tr>\n<td><code>data.items[].pricing.maxAmount</code></td>\n<td>decimal</td>\n<td>Maximum payable amount, in <code>currency</code>.</td>\n</tr>\n<tr>\n<td><code>data.items[].pricing.destinationCurrency</code></td>\n<td>string</td>\n<td>Currency the payment is applied in at the biller.</td>\n</tr>\n<tr>\n<td><code>data.items[].pricing.minDestinationAmount</code></td>\n<td>decimal</td>\n<td>Minimum applied amount, in <code>destinationCurrency</code>.</td>\n</tr>\n<tr>\n<td><code>data.items[].pricing.maxDestinationAmount</code></td>\n<td>decimal</td>\n<td>Maximum applied amount, in <code>destinationCurrency</code>.</td>\n</tr>\n<tr>\n<td><code>data.items[].pricing.fees</code></td>\n<td>decimal</td>\n<td>Fixed fee added to the payment, in <code>currency</code>.</td>\n</tr>\n<tr>\n<td><code>data.items[].pricing.tax.taxRate</code></td>\n<td>decimal</td>\n<td>Tax rate applied, as a percentage.</td>\n</tr>\n<tr>\n<td><code>data.items[].pricing.tax.taxType</code></td>\n<td>string</td>\n<td>Tax type/name (e.g. <code>VAT</code>).</td>\n</tr>\n<tr>\n<td><code>data.items[].pricing.tax.taxAmount</code></td>\n<td>decimal</td>\n<td>Tax amount included in the price.</td>\n</tr>\n<tr>\n<td><code>data.items[].paymentOptions.supportsAccountInquiry</code></td>\n<td>bool</td>\n<td><code>true</code> if you can call <strong>Account Inquiry</strong> for this product before paying.</td>\n</tr>\n<tr>\n<td><code>data.items[].paymentOptions.allowedPaymentOptions</code></td>\n<td>array of string (see Reference values)</td>\n<td>One or more of <code>ExactAmount</code>, <code>AllowsOverpayment</code>, <code>AcceptsLatePayments</code>, <code>AllowsPartialPayments</code>.</td>\n</tr>\n<tr>\n<td><code>data.items[].validities</code></td>\n<td>array</td>\n<td>Validity/posting-time entries for this product.</td>\n</tr>\n<tr>\n<td><code>data.items[].validities[].type</code></td>\n<td>string</td>\n<td>Free-text value from the biller (e.g. <code>PostingTime</code>); no fixed reference-value list is currently published for Utilities (unlike Topup's validity types).</td>\n</tr>\n<tr>\n<td><code>data.items[].validities[].unit</code></td>\n<td>string</td>\n<td>Free-text unit paired with <code>type</code> (e.g. <code>Day</code>).</td>\n</tr>\n<tr>\n<td><code>data.items[].validities[].quantity</code></td>\n<td>decimal</td>\n<td>Number of <code>unit</code>s.</td>\n</tr>\n<tr>\n<td><code>data.items[].transactionRequiredFields</code></td>\n<td>array of string</td>\n<td>Field names you must supply as keys in <code>transactionRequiredFields</code> on <strong>Account Inquiry</strong> / <strong>Create Transaction</strong> for this product.</td>\n</tr>\n<tr>\n<td><code>data.items[].receiverRequiredFields</code></td>\n<td>array of string</td>\n<td>Field names for additional receiver-related data this product requires, if any (empty array when none needed).</td>\n</tr>\n<tr>\n<td><code>data.items[].operator.id</code></td>\n<td>string</td>\n<td>Operator identifier.</td>\n</tr>\n<tr>\n<td><code>data.items[].operator.name</code></td>\n<td>string</td>\n<td>Operator (biller) name.</td>\n</tr>\n<tr>\n<td><code>data.items[].operator.country.name</code></td>\n<td>string</td>\n<td>Country the operator serves.</td>\n</tr>\n<tr>\n<td><code>data.items[].operator.country.isoCode</code></td>\n<td>string</td>\n<td>Country ISO code.</td>\n</tr>\n<tr>\n<td><code>data.items[].operator.country.regions</code></td>\n<td>array</td>\n<td>Region groupings for the country; may be empty.</td>\n</tr>\n<tr>\n<td><code>data.items[].operator.logoUrls</code></td>\n<td>array of string</td>\n<td>Operator logo image URL(s).</td>\n</tr>\n<tr>\n<td><code>data.count</code></td>\n<td>int</td>\n<td>Number of items on this page.</td>\n</tr>\n<tr>\n<td><code>data.page</code></td>\n<td>int</td>\n<td>Current page number.</td>\n</tr>\n<tr>\n<td><code>data.pageSize</code></td>\n<td>int</td>\n<td>Items per page.</td>\n</tr>\n<tr>\n<td><code>data.totalPages</code></td>\n<td>int</td>\n<td>Total number of pages available.</td>\n</tr>\n<tr>\n<td><code>data.totalItems</code></td>\n<td>int</td>\n<td>Total number of products matching the filter.</td>\n</tr>\n</tbody>\n</table>\n</div>","urlObject":{"path":["api","v0","Utilities"],"host":["https://eservices.hoicom.net"],"query":[{"key":"countryIsoCodes","value":"SA"},{"key":"operatorsIds","value":""},{"description":{"content":"<p>Filter by payment type (see folder overview).</p>\n","type":"text/plain"},"key":"types","value":""},{"key":"page","value":"1"},{"key":"pageSize","value":"50"}],"variable":[]}},"response":[{"id":"affedbc4-26f5-4b36-a208-808b6e5b42bd","name":"OK","originalRequest":{"method":"GET","header":[],"url":{"raw":"https://eservices.hoicom.net/api/v0/Utilities?countryIsoCodes=SA&operatorsIds=&types=&page=1&pageSize=50","host":["https://eservices.hoicom.net"],"path":["api","v0","Utilities"],"query":[{"key":"countryIsoCodes","value":"SA"},{"key":"operatorsIds","value":""},{"key":"types","value":"","description":"Filter by payment type (see folder overview)."},{"key":"page","value":"1"},{"key":"pageSize","value":"50"}]},"description":"Returns bills/**products** across operators, filterable by country, operator, or type.\n\n---\n\n## Authorization\n\nRequires Basic Authentication with your client credentials. Your account must be enabled for the Utilities service.\n\n---\n\n## Query Parameters\n\n| Parameter | Type | Required | Default | Description |\n| --- | --- | --- | --- | --- |\n| `countryIsoCodes` | `string[]` | No | — | Filter by country ISO code(s). |\n| `operatorsIds` | `string[]` | No | — | Filter by operator id(s). |\n| `types` | `string[]` | No | — | Filter by payment type: `RangedPayment`, `FixedRecharge`, `PINPurchase`. |\n| `page` | `int` | No | `1` | Page number. |\n| `pageSize` | `int` | No | `50` | Items per page. |\n\n---\n\n## Response\n\nOn success `code` is `1000` and `data` is a paginated list of products."},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"cookie":[],"responseTime":null,"body":"{\n  \"code\": 1000,\n  \"message\": \"Success\",\n  \"data\": {\n    \"items\": [\n      {\n        \"id\": \"V1:12345\",\n        \"type\": \"RangedPayment\",\n        \"details\": {\n          \"name\": \"Tata Power Electricity Bill\",\n          \"serviceType\": \"Electricity\",\n          \"description\": \"Pay your Tata Power electricity bill.\",\n          \"termsAndConditions\": \"Standard terms apply.\",\n          \"usageInstructions\": \"Enter your account number to pay.\"\n        },\n        \"pricing\": {\n          \"paymentCurrencyType\": \"ClientCurrency\",\n          \"currency\": \"INR\",\n          \"minAmount\": 10,\n          \"maxAmount\": 5000,\n          \"destinationCurrency\": \"INR\",\n          \"minDestinationAmount\": 10,\n          \"maxDestinationAmount\": 5000,\n          \"fees\": 0,\n          \"tax\": {\n            \"taxRate\": 15,\n            \"taxType\": \"VAT\",\n            \"taxAmount\": 0\n          }\n        },\n        \"paymentOptions\": {\n          \"supportsAccountInquiry\": true,\n          \"allowedPaymentOptions\": [\n            \"ExactAmount\",\n            \"AllowsPartialPayments\"\n          ]\n        },\n        \"validities\": [\n          {\n            \"type\": \"PostingTime\",\n            \"unit\": \"Day\",\n            \"quantity\": 1\n          }\n        ],\n        \"transactionRequiredFields\": [\n          \"accountNumber\"\n        ],\n        \"receiverRequiredFields\": [],\n        \"operator\": {\n          \"id\": \"op_tatapower\",\n          \"name\": \"Tata Power\",\n          \"country\": {\n            \"name\": \"India\",\n            \"isoCode\": \"IN\",\n            \"regions\": []\n          },\n          \"logoUrls\": [\n            \"https://cdn.example.com/operators/tatapower.png\"\n          ]\n        }\n      }\n    ],\n    \"count\": 1,\n    \"page\": 1,\n    \"pageSize\": 50,\n    \"totalPages\": 1,\n    \"totalItems\": 1\n  }\n}"}],"_postman_id":"59b8a0a8-ec85-4bf2-bd99-aeec2b2f120b"},{"name":"Account Inquiry","id":"69f93392-32af-46d3-8155-ca955d1f0383","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"body":{"mode":"raw","raw":"{\n  \"productId\": \"V1:12345\",\n  \"transactionRequiredFields\": {\n    \"accountNumber\": \"123456789\"\n  }\n}","options":{"raw":{"language":"json"}}},"url":"https://eservices.hoicom.net/api/v0/Utilities/accounts/inquiry","description":"<p>For products where <code>paymentOptions.supportsAccountInquiry</code> is <code>true</code>, looks up the outstanding <strong>bill(s)</strong> for an account before payment — returns the amount due, issue/due dates, and a customer reference.</p>\n<hr />\n<h2 id=\"authorization\">Authorization</h2>\n<p>Requires Basic Authentication with your client credentials. Your account must be enabled for the Utilities service.</p>\n<hr />\n<h2 id=\"request-body\">Request Body</h2>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Field</th>\n<th>Type</th>\n<th>Required</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>productId</code></td>\n<td><code>string</code></td>\n<td>Yes</td>\n<td>The product/utility id to inquire against.</td>\n</tr>\n<tr>\n<td><code>transactionRequiredFields</code></td>\n<td><code>object</code></td>\n<td>Yes</td>\n<td>Key/value map of the product's required fields (e.g. <code>accountNumber</code>).</td>\n</tr>\n</tbody>\n</table>\n</div><hr />\n<h2 id=\"response\">Response</h2>\n<p>On success <code>code</code> is <code>1000</code> and <code>data</code> is a list of bills, each with <code>amountDue</code>, <code>issueDate</code>, <code>dueDate</code>, and <code>customerReference</code>.</p>\n<h3 id=\"common-error-codes\">Common error codes</h3>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Code</th>\n<th>Meaning</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>1102</code></td>\n<td><code>productId</code> doesn't support account inquiry, or is otherwise invalid.</td>\n</tr>\n<tr>\n<td><code>1303</code></td>\n<td><code>productId</code> is blank or <code>transactionRequiredFields</code> is empty — currently returned as \"no results found\" rather than a validation error; see Gaps.</td>\n</tr>\n<tr>\n<td><code>1101</code></td>\n<td>An unexpected internal error occurred.</td>\n</tr>\n</tbody>\n</table>\n</div><hr />\n<h2 id=\"response-fields\">Response fields</h2>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Field</th>\n<th>Type</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>code</code></td>\n<td>int</td>\n<td>Response status code; <code>1000</code> on success (see Reference values and Common error codes below).</td>\n</tr>\n<tr>\n<td><code>message</code></td>\n<td>string</td>\n<td>Human-readable status message.</td>\n</tr>\n<tr>\n<td><code>data</code></td>\n<td>array</td>\n<td>One entry per outstanding bill found for the account.</td>\n</tr>\n<tr>\n<td><code>data[].amountDue.amount</code></td>\n<td>decimal</td>\n<td>Outstanding amount for this bill.</td>\n</tr>\n<tr>\n<td><code>data[].amountDue.currency</code></td>\n<td>string</td>\n<td>Currency of <code>amount</code>.</td>\n</tr>\n<tr>\n<td><code>data[].issueDate</code></td>\n<td>string (ISO-8601 datetime)</td>\n<td>Date the bill was issued.</td>\n</tr>\n<tr>\n<td><code>data[].dueDate</code></td>\n<td>string (ISO-8601 datetime)</td>\n<td>Date the bill is due.</td>\n</tr>\n<tr>\n<td><code>data[].customerReference</code></td>\n<td>string</td>\n<td>Reference identifier for this bill/account at the biller (e.g. account or customer reference).</td>\n</tr>\n</tbody>\n</table>\n</div>","urlObject":{"path":["api","v0","Utilities","accounts","inquiry"],"host":["https://eservices.hoicom.net"],"query":[],"variable":[]}},"response":[{"id":"d6d9e274-b345-47ad-b66f-f28d5935736f","name":"OK","originalRequest":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"body":{"mode":"raw","raw":"{\n  \"productId\": \"V1:12345\",\n  \"transactionRequiredFields\": {\n    \"accountNumber\": \"123456789\"\n  }\n}","options":{"raw":{"language":"json"}}},"url":"https://eservices.hoicom.net/api/v0/Utilities/accounts/inquiry","description":"For products where `paymentOptions.supportsAccountInquiry` is `true`, looks up the outstanding **bill(s)** for an account before payment — returns the amount due, issue/due dates, and a customer reference.\n\n---\n\n## Authorization\n\nRequires Basic Authentication with your client credentials. Your account must be enabled for the Utilities service.\n\n---\n\n## Request Body\n\n| Field | Type | Required | Description |\n| --- | --- | --- | --- |\n| `productId` | `string` | Yes | The product/utility id to inquire against. |\n| `transactionRequiredFields` | `object` | Yes | Key/value map of the product's required fields (e.g. `accountNumber`). |\n\n---\n\n## Response\n\nOn success `code` is `1000` and `data` is a list of bills, each with `amountDue`, `issueDate`, `dueDate`, and `customerReference`."},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"cookie":[],"responseTime":null,"body":"{\n  \"code\": 1000,\n  \"message\": \"Success\",\n  \"data\": [\n    {\n      \"amountDue\": {\n        \"amount\": 245.5,\n        \"currency\": \"INR\"\n      },\n      \"issueDate\": \"2026-06-01T00:00:00Z\",\n      \"dueDate\": \"2026-07-15T00:00:00Z\",\n      \"customerReference\": \"ACC-778812\"\n    }\n  ]\n}"}],"_postman_id":"69f93392-32af-46d3-8155-ca955d1f0383"},{"name":"Create Transaction","id":"58181ec6-f609-4dd2-8790-2d73761946f3","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"body":{"mode":"raw","raw":"{\n  \"externalReference\": \"client-ref-4001\",\n  \"utilityId\": \"V1:12345\",\n  \"transactionRequiredFields\": {\n    \"accountNumber\": \"123456789\"\n  },\n  \"receiverRequiredFields\": null,\n  \"amount\": 245.5\n}","options":{"raw":{"language":"json"}}},"url":"https://eservices.hoicom.net/api/v0/Utilities/transactions/async","description":"<p>Pays a bill <strong>asynchronously</strong>. Returns immediately with a <code>transactionId</code>; poll <strong>Get Transaction by ID</strong> until <code>status</code> is <code>Completed</code> — most payments complete within roughly 60-90 seconds of submission (see the folder overview for the full polling schedule). Idempotent on <code>externalReference</code>.</p>\n<hr />\n<h2 id=\"authorization\">Authorization</h2>\n<p>Requires Basic Authentication with your client credentials. Your account must be enabled for the Utilities service.</p>\n<hr />\n<h2 id=\"request-body\">Request Body</h2>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Field</th>\n<th>Type</th>\n<th>Required</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>externalReference</code></td>\n<td><code>string</code></td>\n<td>Yes</td>\n<td>Your unique id (idempotency key).</td>\n</tr>\n<tr>\n<td><code>utilityId</code></td>\n<td><code>string</code></td>\n<td>Yes</td>\n<td>The product/utility id to pay.</td>\n</tr>\n<tr>\n<td><code>transactionRequiredFields</code></td>\n<td><code>object</code></td>\n<td>Yes</td>\n<td>Key/value map of the product's required fields (e.g. <code>accountNumber</code>).</td>\n</tr>\n<tr>\n<td><code>receiverRequiredFields</code></td>\n<td><code>object</code></td>\n<td>No</td>\n<td>Additional receiver fields, when the product requires them.</td>\n</tr>\n<tr>\n<td><code>amount</code></td>\n<td><code>decimal</code></td>\n<td>Yes</td>\n<td>Amount to pay (within the product's min/max).</td>\n</tr>\n</tbody>\n</table>\n</div><hr />\n<h2 id=\"response\">Response</h2>\n<p>On acceptance <code>code</code> is <code>1000</code> and <code>data</code> contains the <code>transactionId</code>.</p>\n<h3 id=\"common-error-codes\">Common error codes</h3>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Code</th>\n<th>Meaning</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>1102</code></td>\n<td>The request failed validation (e.g. missing <code>externalReference</code>, or <code>amount</code> not greater than <code>0</code>).</td>\n</tr>\n<tr>\n<td><code>1114</code></td>\n<td><code>utilityId</code> doesn't match a known product, <strong>or</strong> <code>externalReference</code> was already used for a prior transaction — both currently return this same code with HTTP <code>409</code>; see Gaps.</td>\n</tr>\n<tr>\n<td><code>1101</code></td>\n<td>An unexpected internal error occurred.</td>\n</tr>\n</tbody>\n</table>\n</div><hr />\n<h2 id=\"response-fields\">Response fields</h2>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Field</th>\n<th>Type</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>code</code></td>\n<td>int</td>\n<td>Response status code; <code>1000</code> on acceptance (see Reference values and Common error codes below).</td>\n</tr>\n<tr>\n<td><code>message</code></td>\n<td>string</td>\n<td>Human-readable status message.</td>\n</tr>\n<tr>\n<td><code>data</code></td>\n<td>object</td>\n<td>The created transaction reference.</td>\n</tr>\n<tr>\n<td><code>data.transactionId</code></td>\n<td>string</td>\n<td>Transaction identifier. Pass this to <strong>Get Transaction by ID</strong> to track payment.</td>\n</tr>\n</tbody>\n</table>\n</div>","urlObject":{"path":["api","v0","Utilities","transactions","async"],"host":["https://eservices.hoicom.net"],"query":[],"variable":[]}},"response":[{"id":"3ca6295b-3b33-49a9-a5a6-7656f7296ef9","name":"OK","originalRequest":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"body":{"mode":"raw","raw":"{\n  \"externalReference\": \"client-ref-4001\",\n  \"utilityId\": \"V1:12345\",\n  \"transactionRequiredFields\": {\n    \"accountNumber\": \"123456789\"\n  },\n  \"receiverRequiredFields\": null,\n  \"amount\": 245.5\n}","options":{"raw":{"language":"json"}}},"url":"https://eservices.hoicom.net/api/v0/Utilities/transactions/async","description":"Pays a bill **asynchronously**. Returns immediately with a `transactionId`; poll **Get Transaction by ID** until `status` is `Completed`. Idempotent on `externalReference`.\n\n---\n\n## Authorization\n\nRequires Basic Authentication with your client credentials. Your account must be enabled for the Utilities service.\n\n---\n\n## Request Body\n\n| Field | Type | Required | Description |\n| --- | --- | --- | --- |\n| `externalReference` | `string` | Yes | Your unique id (idempotency key). |\n| `utilityId` | `string` | Yes | The product/utility id to pay. |\n| `transactionRequiredFields` | `object` | Yes | Key/value map of the product's required fields (e.g. `accountNumber`). |\n| `receiverRequiredFields` | `object` | No | Additional receiver fields, when the product requires them. |\n| `amount` | `decimal` | Yes | Amount to pay (within the product's min/max). |\n\n---\n\n## Response\n\nOn acceptance `code` is `1000` and `data` contains the `transactionId`.\n\n### Common error codes\n\n| Code | Meaning |\n| --- | --- |\n| `1107` | Validation error. |\n| `1401` | Invalid number or account. |\n| `1413` | Invalid product id. |\n| `1418` | Invalid external reference. |\n| `1419` | Transaction already processed (duplicate `externalReference`). |"},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"cookie":[],"responseTime":null,"body":"{\n  \"code\": 1000,\n  \"message\": \"Success\",\n  \"data\": {\n    \"transactionId\": \"util_txn_7c2d\"\n  }\n}"}],"_postman_id":"58181ec6-f609-4dd2-8790-2d73761946f3"},{"name":"Get Transaction by ID","id":"3f436779-094c-4e82-b62a-385aba380b22","request":{"method":"GET","header":[],"url":"https://eservices.hoicom.net/api/v0/Utilities/transactions/:id","description":"<p>Returns a single bill-payment transaction, including its <code>status</code>, product/operator, and amounts.</p>\n<hr />\n<h2 id=\"authorization\">Authorization</h2>\n<p>Requires Basic Authentication with your client credentials. Your account must be enabled for the Utilities service.</p>\n<hr />\n<h2 id=\"path-parameters\">Path Parameters</h2>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Parameter</th>\n<th>Type</th>\n<th>Required</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>id</code></td>\n<td><code>string</code></td>\n<td>Yes</td>\n<td>Transaction identifier.</td>\n</tr>\n</tbody>\n</table>\n</div><hr />\n<h2 id=\"response\">Response</h2>\n<p>On success <code>code</code> is <code>1000</code> and <code>status</code> uses the <strong>Transaction status</strong> values (see folder overview). If the transaction's <code>status</code> is <code>Failed</code>, <code>code</code> is <code>1404</code> in the body, but the HTTP status stays <code>200</code> — this endpoint has no status-code override (unlike Topup's equivalent endpoint, which returns HTTP <code>400</code>), so always check <code>code</code>/<code>status</code> in the body rather than the HTTP status alone. If <code>id</code> doesn't exist or doesn't belong to your account, <code>code</code> is <code>1303</code> with HTTP <code>404</code>.</p>\n<hr />\n<h2 id=\"response-fields\">Response fields</h2>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Field</th>\n<th>Type</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>code</code></td>\n<td>int</td>\n<td>Response status code; <code>1000</code> on success, <code>1404</code> when the transaction's <code>status</code> is <code>Failed</code> (see Response note below and Reference values).</td>\n</tr>\n<tr>\n<td><code>message</code></td>\n<td>string</td>\n<td>Human-readable status message.</td>\n</tr>\n<tr>\n<td><code>data</code></td>\n<td>object</td>\n<td>The transaction.</td>\n</tr>\n<tr>\n<td><code>data.transactionId</code></td>\n<td>string</td>\n<td>Transaction identifier.</td>\n</tr>\n<tr>\n<td><code>data.externalReference</code></td>\n<td>string</td>\n<td>The <code>externalReference</code> you supplied when creating the transaction.</td>\n</tr>\n<tr>\n<td><code>data.status</code></td>\n<td>string (see Reference values)</td>\n<td>Current transaction status.</td>\n</tr>\n<tr>\n<td><code>data.timestamp.requestedAt</code></td>\n<td>string (ISO-8601 datetime)</td>\n<td>When the transaction was submitted.</td>\n</tr>\n<tr>\n<td><code>data.timestamp.completedAt</code></td>\n<td>string (ISO-8601 datetime)</td>\n<td>When the transaction reached a terminal state; holds a placeholder value while <code>status</code> is not yet terminal.</td>\n</tr>\n<tr>\n<td><code>data.product.id</code></td>\n<td>string</td>\n<td>Product identifier.</td>\n</tr>\n<tr>\n<td><code>data.product.name</code></td>\n<td>string</td>\n<td>Product display name.</td>\n</tr>\n<tr>\n<td><code>data.product.operator.id</code></td>\n<td>string</td>\n<td>Operator identifier.</td>\n</tr>\n<tr>\n<td><code>data.product.operator.name</code></td>\n<td>string</td>\n<td>Operator (biller) name.</td>\n</tr>\n<tr>\n<td><code>data.product.operator.country.name</code></td>\n<td>string</td>\n<td>Country the operator serves.</td>\n</tr>\n<tr>\n<td><code>data.product.operator.country.isoCode</code></td>\n<td>string</td>\n<td>Country ISO code.</td>\n</tr>\n<tr>\n<td><code>data.amounts.requestedAmount.amount</code></td>\n<td>decimal</td>\n<td>Amount that was requested/charged.</td>\n</tr>\n<tr>\n<td><code>data.amounts.requestedAmount.currency</code></td>\n<td>string</td>\n<td>Currency of <code>requestedAmount</code>.</td>\n</tr>\n<tr>\n<td><code>data.amounts.deliveredAmount.amount</code></td>\n<td>decimal</td>\n<td>Amount actually applied to the bill.</td>\n</tr>\n<tr>\n<td><code>data.amounts.deliveredAmount.currency</code></td>\n<td>string</td>\n<td>Currency of <code>deliveredAmount</code>.</td>\n</tr>\n<tr>\n<td><code>data.amounts.fees.totalFee</code></td>\n<td>decimal</td>\n<td>Total fees charged, in <code>fees.currency</code>.</td>\n</tr>\n<tr>\n<td><code>data.amounts.fees.currency</code></td>\n<td>string</td>\n<td>Currency of <code>totalFee</code>.</td>\n</tr>\n<tr>\n<td><code>data.pinDetails</code></td>\n<td>object, nullable</td>\n<td>PIN/voucher details for a <code>PINPurchase</code> product; <code>null</code> for other product types or before delivery. When present it has <code>code</code>, <code>serial</code>, <code>validity</code>, and <code>additionalInfo</code> (array of string).</td>\n</tr>\n<tr>\n<td><code>data.receipt</code></td>\n<td>string, nullable</td>\n<td>Human-readable payment summary (see the example); may be <code>null</code> until the transaction reaches a terminal state.</td>\n</tr>\n</tbody>\n</table>\n</div>","urlObject":{"path":["api","v0","Utilities","transactions",":id"],"host":["https://eservices.hoicom.net"],"query":[],"variable":[{"type":"any","value":"","key":"id"}]}},"response":[{"id":"b6e50b17-c09d-4d8b-abd6-00e00d0400c7","name":"OK","originalRequest":{"method":"GET","header":[],"url":{"raw":"https://eservices.hoicom.net/api/v0/Utilities/transactions/:id","host":["https://eservices.hoicom.net"],"path":["api","v0","Utilities","transactions",":id"],"variable":[{"key":"id","value":""}]},"description":"Returns a single bill-payment transaction, including its `status`, product/operator, and amounts.\n\n---\n\n## Authorization\n\nRequires Basic Authentication with your client credentials. Your account must be enabled for the Utilities service.\n\n---\n\n## Path Parameters\n\n| Parameter | Type | Required | Description |\n| --- | --- | --- | --- |\n| `id` | `string` | Yes | Transaction identifier. |\n\n---\n\n## Response\n\nOn success `code` is `1000`. `status` uses the **Transaction status** enum (see folder overview)."},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"cookie":[],"responseTime":null,"body":"{\n  \"code\": 1000,\n  \"message\": \"Success\",\n  \"data\": {\n    \"transactionId\": \"util_txn_7c2d\",\n    \"externalReference\": \"client-ref-4001\",\n    \"status\": \"Completed\",\n    \"timestamp\": {\n      \"requestedAt\": \"2026-07-01T11:00:00Z\",\n      \"completedAt\": \"2026-07-01T11:01:30Z\"\n    },\n    \"product\": {\n      \"id\": \"V1:12345\",\n      \"name\": \"Tata Power Electricity Bill\",\n      \"operator\": {\n        \"id\": \"op_tatapower\",\n        \"name\": \"Tata Power\",\n        \"country\": {\n          \"name\": \"India\",\n          \"isoCode\": \"IN\"\n        }\n      }\n    },\n    \"amounts\": {\n      \"requestedAmount\": {\n        \"amount\": 245.5,\n        \"currency\": \"INR\"\n      },\n      \"deliveredAmount\": {\n        \"amount\": 245.5,\n        \"currency\": \"INR\"\n      },\n      \"fees\": {\n        \"totalFee\": 0,\n        \"currency\": \"INR\"\n      }\n    },\n    \"pinDetails\": null,\n    \"receipt\": \"Bill payment of INR 245.50 to Tata Power (account ACC-778812) — completed.\"\n  }\n}"}],"_postman_id":"3f436779-094c-4e82-b62a-385aba380b22"},{"name":"Get Transactions","id":"cfaf038f-7568-4387-926c-9879b793d1de","request":{"method":"GET","header":[],"url":"https://eservices.hoicom.net/api/v0/Utilities/Transactions?transactionId=&externalReference=&status=Completed&fromDate=&toDate=&page=1&pageSize=50","description":"<p>Returns a paginated, filterable list of your bill-payment transactions.</p>\n<hr />\n<h2 id=\"authorization\">Authorization</h2>\n<p>Requires Basic Authentication with your client credentials. Your account must be enabled for the Utilities service.</p>\n<hr />\n<h2 id=\"query-parameters\">Query Parameters</h2>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Parameter</th>\n<th>Type</th>\n<th>Required</th>\n<th>Default</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>transactionId</code></td>\n<td><code>string</code></td>\n<td>No</td>\n<td>—</td>\n<td>Filter by transaction id.</td>\n</tr>\n<tr>\n<td><code>externalReference</code></td>\n<td><code>string</code></td>\n<td>No</td>\n<td>—</td>\n<td>Filter by your external reference.</td>\n</tr>\n<tr>\n<td><code>status</code></td>\n<td><code>string</code></td>\n<td>No</td>\n<td>—</td>\n<td>Filter by status (e.g. <code>Completed</code>); see Reference values.</td>\n</tr>\n<tr>\n<td><code>fromDate</code></td>\n<td><code>datetime</code></td>\n<td>No</td>\n<td>—</td>\n<td>Start of creation-date range.</td>\n</tr>\n<tr>\n<td><code>toDate</code></td>\n<td><code>datetime</code></td>\n<td>No</td>\n<td>—</td>\n<td>End of creation-date range.</td>\n</tr>\n<tr>\n<td><code>page</code></td>\n<td><code>int</code></td>\n<td>No</td>\n<td><code>1</code></td>\n<td>Page number.</td>\n</tr>\n<tr>\n<td><code>pageSize</code></td>\n<td><code>int</code></td>\n<td>No</td>\n<td><code>50</code></td>\n<td>Items per page.</td>\n</tr>\n</tbody>\n</table>\n</div><hr />\n<h2 id=\"response\">Response</h2>\n<p>On success <code>code</code> is <code>1000</code> and <code>data</code> is a paginated list of transactions. Valid <code>status</code> values: <code>Submitted</code>, <code>Pending</code>, <code>Completed</code>, <code>Failed</code>, <code>Cancelled</code>, <code>Refunded</code>.</p>\n<hr />\n<h2 id=\"response-fields\">Response fields</h2>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Field</th>\n<th>Type</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>code</code></td>\n<td>int</td>\n<td>Response status code; <code>1000</code> on success (see Reference values).</td>\n</tr>\n<tr>\n<td><code>message</code></td>\n<td>string</td>\n<td>Human-readable status message.</td>\n</tr>\n<tr>\n<td><code>data</code></td>\n<td>object</td>\n<td>Paginated list of transactions.</td>\n</tr>\n<tr>\n<td><code>data.items</code></td>\n<td>array</td>\n<td>Transactions on this page.</td>\n</tr>\n<tr>\n<td><code>data.items[].transactionId</code></td>\n<td>string</td>\n<td>Transaction identifier.</td>\n</tr>\n<tr>\n<td><code>data.items[].externalReference</code></td>\n<td>string</td>\n<td>The <code>externalReference</code> you supplied when creating the transaction.</td>\n</tr>\n<tr>\n<td><code>data.items[].status</code></td>\n<td>string (see Reference values)</td>\n<td>Current transaction status.</td>\n</tr>\n<tr>\n<td><code>data.items[].timestamp.requestedAt</code></td>\n<td>string (ISO-8601 datetime)</td>\n<td>When the transaction was submitted.</td>\n</tr>\n<tr>\n<td><code>data.items[].timestamp.completedAt</code></td>\n<td>string (ISO-8601 datetime)</td>\n<td>When the transaction reached a terminal state; holds a placeholder value while <code>status</code> is not yet terminal.</td>\n</tr>\n<tr>\n<td><code>data.items[].product.id</code></td>\n<td>string</td>\n<td>Product identifier.</td>\n</tr>\n<tr>\n<td><code>data.items[].product.name</code></td>\n<td>string</td>\n<td>Product display name.</td>\n</tr>\n<tr>\n<td><code>data.items[].product.operator.id</code></td>\n<td>string</td>\n<td>Operator identifier.</td>\n</tr>\n<tr>\n<td><code>data.items[].product.operator.name</code></td>\n<td>string</td>\n<td>Operator (biller) name.</td>\n</tr>\n<tr>\n<td><code>data.items[].product.operator.country.name</code></td>\n<td>string</td>\n<td>Country the operator serves.</td>\n</tr>\n<tr>\n<td><code>data.items[].product.operator.country.isoCode</code></td>\n<td>string</td>\n<td>Country ISO code.</td>\n</tr>\n<tr>\n<td><code>data.items[].amounts.requestedAmount.amount</code></td>\n<td>decimal</td>\n<td>Amount that was requested/charged.</td>\n</tr>\n<tr>\n<td><code>data.items[].amounts.requestedAmount.currency</code></td>\n<td>string</td>\n<td>Currency of <code>requestedAmount</code>.</td>\n</tr>\n<tr>\n<td><code>data.items[].amounts.deliveredAmount.amount</code></td>\n<td>decimal</td>\n<td>Amount actually applied to the bill.</td>\n</tr>\n<tr>\n<td><code>data.items[].amounts.deliveredAmount.currency</code></td>\n<td>string</td>\n<td>Currency of <code>deliveredAmount</code>.</td>\n</tr>\n<tr>\n<td><code>data.items[].amounts.fees.totalFee</code></td>\n<td>decimal</td>\n<td>Total fees charged, in <code>fees.currency</code>.</td>\n</tr>\n<tr>\n<td><code>data.items[].amounts.fees.currency</code></td>\n<td>string</td>\n<td>Currency of <code>totalFee</code>.</td>\n</tr>\n<tr>\n<td><code>data.items[].pinDetails</code></td>\n<td>object, nullable</td>\n<td>PIN/voucher details for a <code>PINPurchase</code> product; <code>null</code> otherwise. When present it has <code>code</code>, <code>serial</code>, <code>validity</code>, and <code>additionalInfo</code> (array of string).</td>\n</tr>\n<tr>\n<td><code>data.items[].receipt</code></td>\n<td>string, nullable</td>\n<td>Human-readable payment summary; may be <code>null</code> until the transaction reaches a terminal state.</td>\n</tr>\n<tr>\n<td><code>data.count</code></td>\n<td>int</td>\n<td>Number of items on this page.</td>\n</tr>\n<tr>\n<td><code>data.page</code></td>\n<td>int</td>\n<td>Current page number.</td>\n</tr>\n<tr>\n<td><code>data.pageSize</code></td>\n<td>int</td>\n<td>Items per page.</td>\n</tr>\n<tr>\n<td><code>data.totalPages</code></td>\n<td>int</td>\n<td>Total number of pages available.</td>\n</tr>\n<tr>\n<td><code>data.totalItems</code></td>\n<td>int</td>\n<td>Total number of transactions matching the filter.</td>\n</tr>\n</tbody>\n</table>\n</div>","urlObject":{"path":["api","v0","Utilities","Transactions"],"host":["https://eservices.hoicom.net"],"query":[{"key":"transactionId","value":""},{"key":"externalReference","value":""},{"description":{"content":"<p>Enum name, e.g. Completed.</p>\n","type":"text/plain"},"key":"status","value":"Completed"},{"key":"fromDate","value":""},{"key":"toDate","value":""},{"key":"page","value":"1"},{"key":"pageSize","value":"50"}],"variable":[]}},"response":[{"id":"fe67b853-b7a1-412d-a430-dea2317ce0de","name":"OK","originalRequest":{"method":"GET","header":[],"url":{"raw":"https://eservices.hoicom.net/api/v0/Utilities/Transactions?transactionId=&externalReference=&status=Completed&fromDate=&toDate=&page=1&pageSize=50","host":["https://eservices.hoicom.net"],"path":["api","v0","Utilities","Transactions"],"query":[{"key":"transactionId","value":""},{"key":"externalReference","value":""},{"key":"status","value":"Completed","description":"Enum name, e.g. Completed."},{"key":"fromDate","value":""},{"key":"toDate","value":""},{"key":"page","value":"1"},{"key":"pageSize","value":"50"}]},"description":"Returns a paginated, filterable list of your bill-payment transactions.\n\n---\n\n## Authorization\n\nRequires Basic Authentication with your client credentials. Your account must be enabled for the Utilities service.\n\n---\n\n## Query Parameters\n\n| Parameter | Type | Required | Default | Description |\n| --- | --- | --- | --- | --- |\n| `transactionId` | `string` | No | — | Filter by transaction id. |\n| `externalReference` | `string` | No | — | Filter by your external reference. |\n| `status` | `string` | No | — | Filter by status (enum name, e.g. `Completed`). |\n| `fromDate` | `datetime` | No | — | Start of creation-date range. |\n| `toDate` | `datetime` | No | — | End of creation-date range. |\n| `page` | `int` | No | `1` | Page number. |\n| `pageSize` | `int` | No | `50` | Items per page. |\n\n---\n\n## Response\n\nOn success `code` is `1000` and `data` is a paginated list of transactions. Valid `status` values: `Submitted`, `Pending`, `Completed`, `Failed`, `Cancelled`."},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"cookie":[],"responseTime":null,"body":"{\n  \"code\": 1000,\n  \"message\": \"Success\",\n  \"data\": {\n    \"items\": [\n      {\n        \"transactionId\": \"util_txn_7c2d\",\n        \"externalReference\": \"client-ref-4001\",\n        \"status\": \"Completed\",\n        \"timestamp\": {\n          \"requestedAt\": \"2026-07-01T11:00:00Z\",\n          \"completedAt\": \"2026-07-01T11:01:30Z\"\n        },\n        \"product\": {\n          \"id\": \"V1:12345\",\n          \"name\": \"Tata Power Electricity Bill\",\n          \"operator\": {\n            \"id\": \"op_tatapower\",\n            \"name\": \"Tata Power\",\n            \"country\": {\n              \"name\": \"India\",\n              \"isoCode\": \"IN\"\n            }\n          }\n        },\n        \"amounts\": {\n          \"requestedAmount\": {\n            \"amount\": 245.5,\n            \"currency\": \"INR\"\n          },\n          \"deliveredAmount\": {\n            \"amount\": 245.5,\n            \"currency\": \"INR\"\n          },\n          \"fees\": {\n            \"totalFee\": 0,\n            \"currency\": \"INR\"\n          }\n        },\n        \"pinDetails\": null,\n        \"receipt\": \"Bill payment of INR 245.50 to Tata Power (account ACC-778812) — completed.\"\n      }\n    ],\n    \"count\": 1,\n    \"page\": 1,\n    \"pageSize\": 50,\n    \"totalPages\": 1,\n    \"totalItems\": 1\n  }\n}"}],"_postman_id":"cfaf038f-7568-4387-926c-9879b793d1de"}],"id":"b7122c82-6166-4320-adb9-a2a4b58b51c0","description":"<p>The <strong>Utilities</strong> service pays bills and utility accounts (telecom, electricity, water, and more) via supported billers — browse countries, operators, and products, look up an outstanding bill, then pay it and track the payment.</p>\n<hr />\n<h2 id=\"client-flow\">Client Flow</h2>\n<ol>\n<li><strong>Browse countries</strong> — <code>GET /countries</code>.</li>\n<li><strong>Browse operators</strong> — <code>GET /operators?countryIsoCodes={iso}</code> or <code>GET /countries/{iso}/operators</code>.</li>\n<li><strong>Browse products</strong> — <code>GET /operators/{operatorId}/products</code> (or <code>GET /</code> with filters).</li>\n<li><strong>Look up a bill (if supported)</strong> — when a product has <code>paymentOptions.supportsAccountInquiry = true</code>, call <code>POST /accounts/inquiry</code> to fetch the amount due.</li>\n<li><strong>Pay</strong> — <code>POST /transactions/async</code>; returns a <code>transactionId</code>, payment happens in the background.</li>\n<li><strong>Track</strong> — poll <code>GET /transactions/{id}</code> (or <code>GET /Transactions</code> with filters) until <code>status</code> is <code>Completed</code>. Most payments finish within roughly 60-90 seconds of submission, since the platform's first status check runs about a minute after you submit; billers that take longer are checked again at increasing intervals for up to 72 hours before the platform gives up, so polling more often than every 10-15 seconds is not useful.</li>\n</ol>\n<p>Payments are <strong>idempotent</strong> on <code>externalReference</code>. Use the product's <code>transactionRequiredFields</code> list to know which key/value fields to send.</p>\n<hr />\n<h2 id=\"reference-values\">Reference values</h2>\n<h3 id=\"transaction-status-status\">Transaction status (<code>status</code>)</h3>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Value</th>\n<th>Meaning</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>Submitted</code></td>\n<td>Received and queued for processing.</td>\n</tr>\n<tr>\n<td><code>Pending</code></td>\n<td>Being processed / paid.</td>\n</tr>\n<tr>\n<td><code>Completed</code></td>\n<td>Paid successfully.</td>\n</tr>\n<tr>\n<td><code>Failed</code></td>\n<td>Payment failed.</td>\n</tr>\n<tr>\n<td><code>Cancelled</code></td>\n<td>Cancelled before completion.</td>\n</tr>\n<tr>\n<td><code>Refunded</code></td>\n<td>Paid, then refunded by Hoi support after the fact. Refunds are staff-initiated only and cannot be requested through this API.</td>\n</tr>\n</tbody>\n</table>\n</div><h3 id=\"payment-type-type\">Payment type (<code>type</code>)</h3>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Value</th>\n<th>Meaning</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>RangedPayment</code></td>\n<td>Pay any amount within the product's min/max.</td>\n</tr>\n<tr>\n<td><code>FixedRecharge</code></td>\n<td>Fixed amount.</td>\n</tr>\n<tr>\n<td><code>PINPurchase</code></td>\n<td>PIN / voucher purchase.</td>\n</tr>\n</tbody>\n</table>\n</div><h3 id=\"payment-currency-pricingpaymentcurrencytype\">Payment currency (<code>pricing.paymentCurrencyType</code>)</h3>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Value</th>\n<th>Meaning</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>ClientCurrency</code></td>\n<td>Amount is charged in your currency (SAR).</td>\n</tr>\n<tr>\n<td><code>DestinationCurrency</code></td>\n<td>Amount is expressed in the bill's destination currency.</td>\n</tr>\n</tbody>\n</table>\n</div><h3 id=\"payment-options-paymentoptionsallowedpaymentoptions\">Payment options (<code>paymentOptions.allowedPaymentOptions</code>)</h3>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Value</th>\n<th>Meaning</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>ExactAmount</code></td>\n<td>The exact amount due must be paid.</td>\n</tr>\n<tr>\n<td><code>AllowsOverpayment</code></td>\n<td>Payments above the due amount are accepted.</td>\n</tr>\n<tr>\n<td><code>AcceptsLatePayments</code></td>\n<td>Payments after the due date are accepted.</td>\n</tr>\n<tr>\n<td><code>AllowsPartialPayments</code></td>\n<td>Partial payments are accepted.</td>\n</tr>\n</tbody>\n</table>\n</div>","_postman_id":"b7122c82-6166-4320-adb9-a2a4b58b51c0"},{"name":"Gift Cards","item":[{"name":"Get Brands","id":"9f2e2cf7-fe42-4603-9026-10008a90b008","request":{"method":"GET","header":[],"url":"https://eservices.hoicom.net/api/v0/giftcards/brands?ids=&categories=ENTERTAINMENT&countryIso3Codes=USA&searchTerms=&lang=English&page=1&pageSize=50","description":"<p>Lists the gift-card <strong>brands</strong> available to your account (e.g. iTunes, Amazon), filterable by category, country, or search term.</p>\n<hr />\n<h2 id=\"authorization\">Authorization</h2>\n<p>Requires Basic Authentication with your client credentials. Your account must be enabled for the Gift Cards service.</p>\n<hr />\n<h2 id=\"query-parameters\">Query Parameters</h2>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Parameter</th>\n<th>Type</th>\n<th>Required</th>\n<th>Default</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>ids</code></td>\n<td><code>int[]</code></td>\n<td>No</td>\n<td>—</td>\n<td>Filter by brand id(s).</td>\n</tr>\n<tr>\n<td><code>categories</code></td>\n<td><code>string[]</code></td>\n<td>No</td>\n<td>—</td>\n<td>Filter by category (see folder overview).</td>\n</tr>\n<tr>\n<td><code>countryIso3Codes</code></td>\n<td><code>string[]</code></td>\n<td>No</td>\n<td>—</td>\n<td>Filter by ISO 3166-1 alpha-3 country code(s).</td>\n</tr>\n<tr>\n<td><code>searchTerms</code></td>\n<td><code>string[]</code></td>\n<td>No</td>\n<td>—</td>\n<td>Match brand name.</td>\n</tr>\n<tr>\n<td><code>lang</code></td>\n<td><code>string</code></td>\n<td>No</td>\n<td><code>English</code></td>\n<td>Display language: <code>English</code> or <code>Arabic</code>. With <code>Arabic</code> every brand is still listed; a brand without an Arabic translation shows its English name and description.</td>\n</tr>\n<tr>\n<td><code>page</code></td>\n<td><code>int</code></td>\n<td>No</td>\n<td><code>1</code></td>\n<td>Page number.</td>\n</tr>\n<tr>\n<td><code>pageSize</code></td>\n<td><code>int</code></td>\n<td>No</td>\n<td><code>50</code></td>\n<td>Items per page (max 100).</td>\n</tr>\n</tbody>\n</table>\n</div><hr />\n<h2 id=\"response\">Response</h2>\n<p>On success <code>code</code> is <code>1000</code> and <code>data</code> is a paginated list of brands. <code>category</code> uses the <strong>Category</strong> values (see folder overview).</p>\n<hr />\n<h2 id=\"response-fields\">Response fields</h2>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Field</th>\n<th>Type</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>code</code></td>\n<td>int</td>\n<td>Response status code; <code>1000</code> means success.</td>\n</tr>\n<tr>\n<td><code>message</code></td>\n<td>string</td>\n<td>Human-readable status message.</td>\n</tr>\n<tr>\n<td><code>data</code></td>\n<td>object</td>\n<td>The paginated result envelope.</td>\n</tr>\n<tr>\n<td><code>data.items</code></td>\n<td>array</td>\n<td>The page of matching brands.</td>\n</tr>\n<tr>\n<td><code>data.items[].id</code></td>\n<td>int</td>\n<td>The brand's id — use this in <code>products?brandIds=</code>.</td>\n</tr>\n<tr>\n<td><code>data.items[].category</code></td>\n<td>string (values: <code>RETAIL</code> | <code>GAMING</code> | <code>CASH_CARDS</code> | <code>FOOD</code> | <code>ENTERTAINMENT</code> | <code>TRAVEL_TRANSPORT</code> | <code>OTHER</code>)</td>\n<td>The brand's category (see Reference values).</td>\n</tr>\n<tr>\n<td><code>data.items[].countryIso3</code></td>\n<td>string</td>\n<td>ISO 3166-1 alpha-3 country the brand's cards are valid in.</td>\n</tr>\n<tr>\n<td><code>data.items[].name</code></td>\n<td>string</td>\n<td>Brand display name, localized to the requested <code>lang</code>.</td>\n</tr>\n<tr>\n<td><code>data.items[].description</code></td>\n<td>string</td>\n<td><code>null</code> when the brand has no description text; localized to the requested <code>lang</code>.</td>\n</tr>\n<tr>\n<td><code>data.count</code></td>\n<td>int</td>\n<td>Number of items on this page.</td>\n</tr>\n<tr>\n<td><code>data.page</code></td>\n<td>int</td>\n<td>The page number returned.</td>\n</tr>\n<tr>\n<td><code>data.pageSize</code></td>\n<td>int</td>\n<td>Items per page requested.</td>\n</tr>\n<tr>\n<td><code>data.totalPages</code></td>\n<td>int</td>\n<td>Total pages across all matching brands.</td>\n</tr>\n<tr>\n<td><code>data.totalItems</code></td>\n<td>int</td>\n<td>Total matching brands across all pages.</td>\n</tr>\n</tbody>\n</table>\n</div>","urlObject":{"path":["api","v0","giftcards","brands"],"host":["https://eservices.hoicom.net"],"query":[{"key":"ids","value":""},{"description":{"content":"<p>Filter by category (see folder overview).</p>\n","type":"text/plain"},"key":"categories","value":"ENTERTAINMENT"},{"key":"countryIso3Codes","value":"USA"},{"key":"searchTerms","value":""},{"description":{"content":"<p>English or Arabic.</p>\n","type":"text/plain"},"key":"lang","value":"English"},{"key":"page","value":"1"},{"key":"pageSize","value":"50"}],"variable":[]}},"response":[{"id":"ac22a29c-a285-4988-affa-decbe9fd03bb","name":"OK","originalRequest":{"method":"GET","header":[],"url":{"raw":"https://eservices.hoicom.net/api/v0/giftcards/brands?ids=&categories=ENTERTAINMENT&countryIso3Codes=USA&searchTerms=&lang=English&page=1&pageSize=50","host":["https://eservices.hoicom.net"],"path":["api","v0","giftcards","brands"],"query":[{"key":"ids","value":""},{"key":"categories","value":"ENTERTAINMENT","description":"Filter by category (see folder overview)."},{"key":"countryIso3Codes","value":"USA"},{"key":"searchTerms","value":""},{"key":"lang","value":"English","description":"English or Arabic."},{"key":"page","value":"1"},{"key":"pageSize","value":"50"}]},"description":"Lists the gift-card **brands** available to your account (e.g. iTunes, Amazon), filterable by category, country, or search term.\n\n---\n\n## Authorization\n\nRequires Basic Authentication with your client credentials. Your account must be enabled for the Gift Cards service.\n\n---\n\n## Query Parameters\n\n| Parameter | Type | Required | Default | Description |\n| --- | --- | --- | --- | --- |\n| `ids` | `int[]` | No | — | Filter by brand id(s). |\n| `categories` | `string[]` | No | — | Filter by category (see folder overview). |\n| `countryIso3Codes` | `string[]` | No | — | Filter by ISO 3166-1 alpha-3 country code(s). |\n| `searchTerms` | `string[]` | No | — | Match brand name. |\n| `lang` | `string` | No | `English` | Display language: `English` or `Arabic`. With `Arabic` every brand is still listed; a brand without an Arabic translation shows its English name and description. |\n| `page` | `int` | No | `1` | Page number. |\n| `pageSize` | `int` | No | `50` | Items per page (max 100). |\n\n---\n\n## Response\n\nOn success `code` is `1000` and `data` is a paginated list of brands. `category` uses the **Category** values (see folder overview).\n\n---\n\n## Response fields\n\n| Field | Type | Description |\n| --- | --- | --- |\n| `code` | int | Response status code; `1000` means success. |\n| `message` | string | Human-readable status message. |\n| `data` | object | The paginated result envelope. |\n| `data.items` | array | The page of matching brands. |\n| `data.items[].id` | int | The brand's id — use this in `products?brandIds=`. |\n| `data.items[].category` | string (values: `RETAIL` \\| `GAMING` \\| `CASH_CARDS` \\| `FOOD` \\| `ENTERTAINMENT` \\| `TRAVEL_TRANSPORT` \\| `OTHER`) | The brand's category (see Reference values). |\n| `data.items[].countryIso3` | string | ISO 3166-1 alpha-3 country the brand's cards are valid in. |\n| `data.items[].name` | string | Brand display name, localized to the requested `lang`. |\n| `data.items[].description` | string | `null` when the brand has no description text; localized to the requested `lang`. |\n| `data.count` | int | Number of items on this page. |\n| `data.page` | int | The page number returned. |\n| `data.pageSize` | int | Items per page requested. |\n| `data.totalPages` | int | Total pages across all matching brands. |\n| `data.totalItems` | int | Total matching brands across all pages. |\n"},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"cookie":[],"responseTime":null,"body":"{\n  \"code\": 1000,\n  \"message\": \"Success\",\n  \"data\": {\n    \"items\": [\n      {\n        \"id\": 123,\n        \"category\": \"ENTERTAINMENT\",\n        \"countryIso3\": \"USA\",\n        \"name\": \"iTunes (US)\",\n        \"description\": \"Apple iTunes US gift cards.\"\n      }\n    ],\n    \"count\": 1,\n    \"page\": 1,\n    \"pageSize\": 50,\n    \"totalPages\": 1,\n    \"totalItems\": 1\n  }\n}"}],"_postman_id":"9f2e2cf7-fe42-4603-9026-10008a90b008"},{"name":"Get Products","id":"7baf8bdc-6e7f-42a7-8a57-4f299532a91f","request":{"method":"GET","header":[],"url":"https://eservices.hoicom.net/api/v0/giftcards/products?ids=&brandIds=123&categories=&countryIso3Codes=&denominationTypes=FIXED&searchTerms=&includeContent=true&includeInputFields=true&lang=English&page=1&pageSize=50","description":"<p>Lists the priced gift-card <strong>products</strong> (specific denominations of a brand). Each product carries its <code>denomination</code>, <code>pricing</code> (in SAR), <code>deliveryFormat</code>, and — when requested — descriptive <code>content</code> and required <code>transactionInputFields</code>.</p>\n<hr />\n<h2 id=\"authorization\">Authorization</h2>\n<p>Requires Basic Authentication with your client credentials. Your account must be enabled for the Gift Cards service.</p>\n<hr />\n<h2 id=\"query-parameters\">Query Parameters</h2>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Parameter</th>\n<th>Type</th>\n<th>Required</th>\n<th>Default</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>ids</code></td>\n<td><code>int[]</code></td>\n<td>No</td>\n<td>—</td>\n<td>Filter by product id(s). Fetch a single product this way.</td>\n</tr>\n<tr>\n<td><code>brandIds</code></td>\n<td><code>int[]</code></td>\n<td>No</td>\n<td>—</td>\n<td>Filter by brand id(s).</td>\n</tr>\n<tr>\n<td><code>categories</code></td>\n<td><code>string[]</code></td>\n<td>No</td>\n<td>—</td>\n<td>Filter by category.</td>\n</tr>\n<tr>\n<td><code>countryIso3Codes</code></td>\n<td><code>string[]</code></td>\n<td>No</td>\n<td>—</td>\n<td>Filter by ISO alpha-3 country code(s).</td>\n</tr>\n<tr>\n<td><code>denominationTypes</code></td>\n<td><code>string[]</code></td>\n<td>No</td>\n<td>—</td>\n<td>Filter by denomination type: <code>FIXED</code>, <code>RANGE</code>, <code>OPEN</code>.</td>\n</tr>\n<tr>\n<td><code>searchTerms</code></td>\n<td><code>string[]</code></td>\n<td>No</td>\n<td>—</td>\n<td>Match product name.</td>\n</tr>\n<tr>\n<td><code>includeContent</code></td>\n<td><code>bool</code></td>\n<td>No</td>\n<td><code>false</code></td>\n<td>Include localized descriptions / T&amp;C / images.</td>\n</tr>\n<tr>\n<td><code>includeInputFields</code></td>\n<td><code>bool</code></td>\n<td>No</td>\n<td><code>false</code></td>\n<td>Include the required transaction input fields.</td>\n</tr>\n<tr>\n<td><code>lang</code></td>\n<td><code>string</code></td>\n<td>No</td>\n<td><code>English</code></td>\n<td>Display language: <code>English</code> or <code>Arabic</code>. With <code>Arabic</code> every product is still listed; text without an Arabic translation falls back to English.</td>\n</tr>\n<tr>\n<td><code>page</code></td>\n<td><code>int</code></td>\n<td>No</td>\n<td><code>1</code></td>\n<td>Page number.</td>\n</tr>\n<tr>\n<td><code>pageSize</code></td>\n<td><code>int</code></td>\n<td>No</td>\n<td><code>50</code></td>\n<td>Items per page (max 100).</td>\n</tr>\n</tbody>\n</table>\n</div><hr />\n<h2 id=\"response\">Response</h2>\n<p>On success <code>code</code> is <code>1000</code> and <code>data</code> is a paginated list of products. <code>denomination.type</code>, <code>deliveryFormat</code>, <code>pricing.mode</code>, and <code>transactionInputFields[].type</code> use the values in the folder overview. <code>pricing.wholesale</code> is your price — what you are billed (SAR) — in both pricing modes. <code>pricing.retail</code> is the recommended end-customer price (a suggestion in <code>WHOLESALE</code> mode, and it may be <code>null</code>). In <code>DISCOUNT</code> mode, <code>pricing.discount</code> shows your price against retail (see Pricing mode in the folder overview).</p>\n<p>Products whose pricing is not valid are not listed, so a page can contain fewer than <code>pageSize</code> items (<code>totalItems</code> excludes them).</p>\n<hr />\n<h2 id=\"response-fields\">Response fields</h2>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Field</th>\n<th>Type</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>code</code></td>\n<td>int</td>\n<td>Response status code; <code>1000</code> means success.</td>\n</tr>\n<tr>\n<td><code>message</code></td>\n<td>string</td>\n<td>Human-readable status message.</td>\n</tr>\n<tr>\n<td><code>data</code></td>\n<td>object</td>\n<td>The paginated result envelope.</td>\n</tr>\n<tr>\n<td><code>data.items</code></td>\n<td>array</td>\n<td>The page of matching products.</td>\n</tr>\n<tr>\n<td><code>data.items[].id</code></td>\n<td>int</td>\n<td>The product's id — pass this as <code>productId</code> when ordering.</td>\n</tr>\n<tr>\n<td><code>data.items[].info.brandId</code></td>\n<td>int</td>\n<td>The id of the brand this product belongs to.</td>\n</tr>\n<tr>\n<td><code>data.items[].info.category</code></td>\n<td>string (values: <code>RETAIL</code> | <code>GAMING</code> | <code>CASH_CARDS</code> | <code>FOOD</code> | <code>ENTERTAINMENT</code> | <code>TRAVEL_TRANSPORT</code> | <code>OTHER</code>)</td>\n<td>The product's category (see Reference values).</td>\n</tr>\n<tr>\n<td><code>data.items[].info.countryIso3</code></td>\n<td>string</td>\n<td>ISO alpha-3 country the card is valid in.</td>\n</tr>\n<tr>\n<td><code>data.items[].info.name</code></td>\n<td>string</td>\n<td>Product display name, localized to the requested <code>lang</code>.</td>\n</tr>\n<tr>\n<td><code>data.items[].amountCurrency</code></td>\n<td>string (values: <code>LOCAL</code> | <code>DESTINATION</code>)</td>\n<td><code>null</code> for a <code>FIXED</code> product; for <code>RANGE</code>/<code>OPEN</code>, which currency you must express <code>amount</code> in when ordering — see the worked example in the folder overview.</td>\n</tr>\n<tr>\n<td><code>data.items[].deliveryFormat</code></td>\n<td>string (values: <code>PIN</code> | <code>REDEMPTION_URL</code> | <code>QR_CODE</code> | <code>DIRECT_CREDIT</code>)</td>\n<td>How the purchased card is delivered (see Reference values).</td>\n</tr>\n<tr>\n<td><code>data.items[].transactionInputFields</code></td>\n<td>array</td>\n<td><code>null</code> unless the request had <code>includeInputFields=true</code>; the inputs you must supply in <code>transactionInputs</code> when ordering.</td>\n</tr>\n<tr>\n<td><code>data.items[].transactionInputFields[].key</code></td>\n<td>string</td>\n<td>The machine key to use in <code>transactionInputs</code>.</td>\n</tr>\n<tr>\n<td><code>data.items[].transactionInputFields[].label</code></td>\n<td>string</td>\n<td>Human-readable label for the input.</td>\n</tr>\n<tr>\n<td><code>data.items[].transactionInputFields[].type</code></td>\n<td>string (values: <code>TEXT</code> | <code>EMAIL</code> | <code>PHONE_NUMBER</code> | <code>NUMBER</code> | <code>DATE</code> | <code>SELECT</code>)</td>\n<td>The expected data type/format of the input (see Reference values).</td>\n</tr>\n<tr>\n<td><code>data.items[].transactionInputFields[].required</code></td>\n<td>bool</td>\n<td>Whether the input must be provided.</td>\n</tr>\n<tr>\n<td><code>data.items[].transactionInputFields[].validation</code></td>\n<td>object</td>\n<td><code>null</code> when the field declares no extra constraints.</td>\n</tr>\n<tr>\n<td><code>data.items[].transactionInputFields[].validation.regex</code></td>\n<td>string</td>\n<td><code>null</code> unless the value must match a pattern.</td>\n</tr>\n<tr>\n<td><code>data.items[].transactionInputFields[].validation.minLength</code></td>\n<td>int</td>\n<td><code>null</code> unless a minimum text length applies.</td>\n</tr>\n<tr>\n<td><code>data.items[].transactionInputFields[].validation.maxLength</code></td>\n<td>int</td>\n<td><code>null</code> unless a maximum text length applies.</td>\n</tr>\n<tr>\n<td><code>data.items[].transactionInputFields[].validation.min</code></td>\n<td>decimal</td>\n<td><code>null</code> unless a minimum numeric value applies.</td>\n</tr>\n<tr>\n<td><code>data.items[].transactionInputFields[].validation.max</code></td>\n<td>decimal</td>\n<td><code>null</code> unless a maximum numeric value applies.</td>\n</tr>\n<tr>\n<td><code>data.items[].transactionInputFields[].validation.allowedValues</code></td>\n<td>array of string</td>\n<td>Empty unless <code>type</code> is <code>SELECT</code>, in which case it lists the only acceptable values.</td>\n</tr>\n<tr>\n<td><code>data.items[].denomination.type</code></td>\n<td>string (values: <code>FIXED</code> | <code>RANGE</code> | <code>OPEN</code>)</td>\n<td>How the card's face value is chosen (see Reference values).</td>\n</tr>\n<tr>\n<td><code>data.items[].denomination.currency</code></td>\n<td>string</td>\n<td>ISO 4217 currency of the card's face value — the destination/card currency, never SAR.</td>\n</tr>\n<tr>\n<td><code>data.items[].denomination.value</code></td>\n<td>decimal</td>\n<td>The single face value for a <code>FIXED</code> product; <code>null</code> for <code>RANGE</code>/<code>OPEN</code>.</td>\n</tr>\n<tr>\n<td><code>data.items[].denomination.min</code></td>\n<td>decimal</td>\n<td>Minimum face value for a <code>RANGE</code> product; <code>null</code> otherwise.</td>\n</tr>\n<tr>\n<td><code>data.items[].denomination.max</code></td>\n<td>decimal</td>\n<td>Maximum face value for a <code>RANGE</code> product; <code>null</code> otherwise.</td>\n</tr>\n<tr>\n<td><code>data.items[].denomination.increment</code></td>\n<td>decimal</td>\n<td>Step between allowed face values for a <code>RANGE</code> product; <code>null</code> otherwise.</td>\n</tr>\n<tr>\n<td><code>data.items[].pricing.currency</code></td>\n<td>string</td>\n<td>Billing currency — always <code>\"SAR\"</code>.</td>\n</tr>\n<tr>\n<td><code>data.items[].pricing.mode</code></td>\n<td>string (values: <code>WHOLESALE</code> | <code>DISCOUNT</code>)</td>\n<td>How your price is derived (see Pricing mode in the folder overview).</td>\n</tr>\n<tr>\n<td><code>data.items[].pricing.wholesale.value</code></td>\n<td>decimal</td>\n<td>Your price — what you are billed (SAR) — for a <code>FIXED</code> product; <code>null</code> for <code>RANGE</code>/<code>OPEN</code>.</td>\n</tr>\n<tr>\n<td><code>data.items[].pricing.wholesale.rate</code></td>\n<td>decimal</td>\n<td>SAR billed per 1 unit of the card's destination currency, for a <code>RANGE</code>/<code>OPEN</code> product; <code>null</code> for <code>FIXED</code>.</td>\n</tr>\n<tr>\n<td><code>data.items[].pricing.wholesale.min</code></td>\n<td>decimal</td>\n<td>Minimum SAR you would be billed across the range (<code>rate × denomination.min</code>); <code>null</code> for <code>FIXED</code>.</td>\n</tr>\n<tr>\n<td><code>data.items[].pricing.wholesale.max</code></td>\n<td>decimal</td>\n<td>Maximum SAR you would be billed across the range (<code>rate × denomination.max</code>); <code>null</code> for <code>FIXED</code>.</td>\n</tr>\n<tr>\n<td><code>data.items[].pricing.wholesale.increment</code></td>\n<td>decimal</td>\n<td>Reserved; always <code>null</code> today.</td>\n</tr>\n<tr>\n<td><code>data.items[].pricing.retail.value</code></td>\n<td>decimal</td>\n<td>For a <code>FIXED</code> product: the recommended end-customer price (a suggestion in <code>WHOLESALE</code> mode, may be <code>null</code>); <code>null</code> for <code>RANGE</code>/<code>OPEN</code>. You are not billed this amount.</td>\n</tr>\n<tr>\n<td><code>data.items[].pricing.retail.rate</code></td>\n<td>decimal</td>\n<td>Same as <code>pricing.wholesale.rate</code> but for the recommended end-customer price, for <code>RANGE</code>/<code>OPEN</code> products.</td>\n</tr>\n<tr>\n<td><code>data.items[].pricing.retail.min</code></td>\n<td>decimal</td>\n<td><code>rate × denomination.min</code>; <code>null</code> for <code>FIXED</code>.</td>\n</tr>\n<tr>\n<td><code>data.items[].pricing.retail.max</code></td>\n<td>decimal</td>\n<td><code>rate × denomination.max</code>; <code>null</code> for <code>FIXED</code>.</td>\n</tr>\n<tr>\n<td><code>data.items[].pricing.retail.increment</code></td>\n<td>decimal</td>\n<td>Reserved; always <code>null</code> today.</td>\n</tr>\n<tr>\n<td><code>data.items[].pricing.discount</code></td>\n<td>object</td>\n<td><code>null</code> unless <code>pricing.mode</code> is <code>DISCOUNT</code>.</td>\n</tr>\n<tr>\n<td><code>data.items[].pricing.discount.percent</code></td>\n<td>decimal</td>\n<td><code>(retail − your price) ÷ retail × 100</code>, as a percentage.</td>\n</tr>\n<tr>\n<td><code>data.items[].pricing.discount.value</code></td>\n<td>decimal</td>\n<td><code>pricing.retail − pricing.wholesale</code> in SAR for a <code>FIXED</code> product — how far your price is below retail; <code>null</code> for <code>RANGE</code>/<code>OPEN</code>.</td>\n</tr>\n<tr>\n<td><code>data.items[].content</code></td>\n<td>object</td>\n<td><code>null</code> unless the request had <code>includeContent=true</code>.</td>\n</tr>\n<tr>\n<td><code>data.items[].content.description</code></td>\n<td>string</td>\n<td>Long-form description, localized to <code>lang</code>; <code>null</code> if none.</td>\n</tr>\n<tr>\n<td><code>data.items[].content.shortDescription</code></td>\n<td>string</td>\n<td>Short description, localized to <code>lang</code>; <code>null</code> if none.</td>\n</tr>\n<tr>\n<td><code>data.items[].content.termsAndConditions</code></td>\n<td>string</td>\n<td>Terms and conditions text; <code>null</code> if none.</td>\n</tr>\n<tr>\n<td><code>data.items[].content.redemptionInstructions</code></td>\n<td>string</td>\n<td>How to redeem the card; <code>null</code> if none.</td>\n</tr>\n<tr>\n<td><code>data.items[].content.disclaimer</code></td>\n<td>string</td>\n<td>Disclaimer text; <code>null</code> if none.</td>\n</tr>\n<tr>\n<td><code>data.items[].content.validityText</code></td>\n<td>string</td>\n<td>Human-readable validity/expiry text (e.g. <code>\"12 Months\"</code>); <code>null</code> if none.</td>\n</tr>\n<tr>\n<td><code>data.items[].content.images</code></td>\n<td>array</td>\n<td>The product's image assets; empty if none.</td>\n</tr>\n<tr>\n<td><code>data.items[].content.images[].type</code></td>\n<td>string (values: <code>LOGO</code> | <code>PROVIDER_LOGO</code> | <code>CARD</code> | <code>ARTICLE</code> | <code>THUMBNAIL</code>)</td>\n<td>The role of the image (see Reference values).</td>\n</tr>\n<tr>\n<td><code>data.items[].content.images[].url</code></td>\n<td>string</td>\n<td>The image's URL.</td>\n</tr>\n<tr>\n<td><code>data.count</code></td>\n<td>int</td>\n<td>Number of items on this page.</td>\n</tr>\n<tr>\n<td><code>data.page</code></td>\n<td>int</td>\n<td>The page number returned.</td>\n</tr>\n<tr>\n<td><code>data.pageSize</code></td>\n<td>int</td>\n<td>Items per page requested.</td>\n</tr>\n<tr>\n<td><code>data.totalPages</code></td>\n<td>int</td>\n<td>Total pages across all matching products.</td>\n</tr>\n<tr>\n<td><code>data.totalItems</code></td>\n<td>int</td>\n<td>Total matching products across all pages.</td>\n</tr>\n</tbody>\n</table>\n</div>","urlObject":{"path":["api","v0","giftcards","products"],"host":["https://eservices.hoicom.net"],"query":[{"key":"ids","value":""},{"key":"brandIds","value":"123"},{"key":"categories","value":""},{"key":"countryIso3Codes","value":""},{"description":{"content":"<p>FIXED, RANGE, or OPEN.</p>\n","type":"text/plain"},"key":"denominationTypes","value":"FIXED"},{"key":"searchTerms","value":""},{"description":{"content":"<p>Include the localized content block.</p>\n","type":"text/plain"},"key":"includeContent","value":"true"},{"description":{"content":"<p>Include required transaction input fields.</p>\n","type":"text/plain"},"key":"includeInputFields","value":"true"},{"key":"lang","value":"English"},{"key":"page","value":"1"},{"key":"pageSize","value":"50"}],"variable":[]}},"response":[{"id":"af23e1f3-d1ae-4e7d-9231-a0f14dfafc60","name":"OK","originalRequest":{"method":"GET","header":[],"url":{"raw":"https://eservices.hoicom.net/api/v0/giftcards/products?ids=&brandIds=123&categories=&countryIso3Codes=&denominationTypes=FIXED&searchTerms=&includeContent=true&includeInputFields=true&lang=English&page=1&pageSize=50","host":["https://eservices.hoicom.net"],"path":["api","v0","giftcards","products"],"query":[{"key":"ids","value":""},{"key":"brandIds","value":"123"},{"key":"categories","value":""},{"key":"countryIso3Codes","value":""},{"key":"denominationTypes","value":"FIXED","description":"FIXED, RANGE, or OPEN."},{"key":"searchTerms","value":""},{"key":"includeContent","value":"true","description":"Include the localized content block."},{"key":"includeInputFields","value":"true","description":"Include required transaction input fields."},{"key":"lang","value":"English"},{"key":"page","value":"1"},{"key":"pageSize","value":"50"}]},"description":"Lists the priced gift-card **products** (specific denominations of a brand). Each product carries its `denomination`, `pricing` (in SAR), `deliveryFormat`, and — when requested — descriptive `content` and required `transactionInputFields`.\n\n---\n\n## Authorization\n\nRequires Basic Authentication with your client credentials. Your account must be enabled for the Gift Cards service.\n\n---\n\n## Query Parameters\n\n| Parameter | Type | Required | Default | Description |\n| --- | --- | --- | --- | --- |\n| `ids` | `int[]` | No | — | Filter by product id(s). Fetch a single product this way. |\n| `brandIds` | `int[]` | No | — | Filter by brand id(s). |\n| `categories` | `string[]` | No | — | Filter by category. |\n| `countryIso3Codes` | `string[]` | No | — | Filter by ISO alpha-3 country code(s). |\n| `denominationTypes` | `string[]` | No | — | Filter by denomination type: `FIXED`, `RANGE`, `OPEN`. |\n| `searchTerms` | `string[]` | No | — | Match product name. |\n| `includeContent` | `bool` | No | `false` | Include localized descriptions / T&C / images. |\n| `includeInputFields` | `bool` | No | `false` | Include the required transaction input fields. |\n| `lang` | `string` | No | `English` | Display language: `English` or `Arabic`. With `Arabic` every product is still listed; text without an Arabic translation falls back to English. |\n| `page` | `int` | No | `1` | Page number. |\n| `pageSize` | `int` | No | `50` | Items per page (max 100). |\n\n---\n\n## Response\n\nOn success `code` is `1000` and `data` is a paginated list of products. `denomination.type`, `deliveryFormat`, `pricing.mode`, and `transactionInputFields[].type` use the values in the folder overview. `pricing.wholesale` is your price — what you are billed (SAR) — in both pricing modes. `pricing.retail` is the recommended end-customer price (a suggestion in `WHOLESALE` mode, and it may be `null`). In `DISCOUNT` mode, `pricing.discount` shows your price against retail (see Pricing mode in the folder overview).\n\nProducts whose pricing is not valid are not listed, so a page can contain fewer than `pageSize` items (`totalItems` excludes them).\n\n---\n\n## Response fields\n\n| Field | Type | Description |\n| --- | --- | --- |\n| `code` | int | Response status code; `1000` means success. |\n| `message` | string | Human-readable status message. |\n| `data` | object | The paginated result envelope. |\n| `data.items` | array | The page of matching products. |\n| `data.items[].id` | int | The product's id — pass this as `productId` when ordering. |\n| `data.items[].info.brandId` | int | The id of the brand this product belongs to. |\n| `data.items[].info.category` | string (values: `RETAIL` \\| `GAMING` \\| `CASH_CARDS` \\| `FOOD` \\| `ENTERTAINMENT` \\| `TRAVEL_TRANSPORT` \\| `OTHER`) | The product's category (see Reference values). |\n| `data.items[].info.countryIso3` | string | ISO alpha-3 country the card is valid in. |\n| `data.items[].info.name` | string | Product display name, localized to the requested `lang`. |\n| `data.items[].amountCurrency` | string (values: `LOCAL` \\| `DESTINATION`) | `null` for a `FIXED` product; for `RANGE`/`OPEN`, which currency you must express `amount` in when ordering — see the worked example in the folder overview. |\n| `data.items[].deliveryFormat` | string (values: `PIN` \\| `REDEMPTION_URL` \\| `QR_CODE` \\| `DIRECT_CREDIT`) | How the purchased card is delivered (see Reference values). |\n| `data.items[].transactionInputFields` | array | `null` unless the request had `includeInputFields=true`; the inputs you must supply in `transactionInputs` when ordering. |\n| `data.items[].transactionInputFields[].key` | string | The machine key to use in `transactionInputs`. |\n| `data.items[].transactionInputFields[].label` | string | Human-readable label for the input. |\n| `data.items[].transactionInputFields[].type` | string (values: `TEXT` \\| `EMAIL` \\| `PHONE_NUMBER` \\| `NUMBER` \\| `DATE` \\| `SELECT`) | The expected data type/format of the input (see Reference values). |\n| `data.items[].transactionInputFields[].required` | bool | Whether the input must be provided. |\n| `data.items[].transactionInputFields[].validation` | object | `null` when the field declares no extra constraints. |\n| `data.items[].transactionInputFields[].validation.regex` | string | `null` unless the value must match a pattern. |\n| `data.items[].transactionInputFields[].validation.minLength` | int | `null` unless a minimum text length applies. |\n| `data.items[].transactionInputFields[].validation.maxLength` | int | `null` unless a maximum text length applies. |\n| `data.items[].transactionInputFields[].validation.min` | decimal | `null` unless a minimum numeric value applies. |\n| `data.items[].transactionInputFields[].validation.max` | decimal | `null` unless a maximum numeric value applies. |\n| `data.items[].transactionInputFields[].validation.allowedValues` | array of string | Empty unless `type` is `SELECT`, in which case it lists the only acceptable values. |\n| `data.items[].denomination.type` | string (values: `FIXED` \\| `RANGE` \\| `OPEN`) | How the card's face value is chosen (see Reference values). |\n| `data.items[].denomination.currency` | string | ISO 4217 currency of the card's face value — the destination/card currency, never SAR. |\n| `data.items[].denomination.value` | decimal | The single face value for a `FIXED` product; `null` for `RANGE`/`OPEN`. |\n| `data.items[].denomination.min` | decimal | Minimum face value for a `RANGE` product; `null` otherwise. |\n| `data.items[].denomination.max` | decimal | Maximum face value for a `RANGE` product; `null` otherwise. |\n| `data.items[].denomination.increment` | decimal | Step between allowed face values for a `RANGE` product; `null` otherwise. |\n| `data.items[].pricing.currency` | string | Billing currency — always `\"SAR\"`. |\n| `data.items[].pricing.mode` | string (values: `WHOLESALE` \\| `DISCOUNT`) | How your price is derived (see Pricing mode in the folder overview). |\n| `data.items[].pricing.wholesale.value` | decimal | Your price — what you are billed (SAR) — for a `FIXED` product; `null` for `RANGE`/`OPEN`. |\n| `data.items[].pricing.wholesale.rate` | decimal | SAR billed per 1 unit of the card's destination currency, for a `RANGE`/`OPEN` product; `null` for `FIXED`. |\n| `data.items[].pricing.wholesale.min` | decimal | Minimum SAR you would be billed across the range (`rate × denomination.min`); `null` for `FIXED`. |\n| `data.items[].pricing.wholesale.max` | decimal | Maximum SAR you would be billed across the range (`rate × denomination.max`); `null` for `FIXED`. |\n| `data.items[].pricing.wholesale.increment` | decimal | Reserved; always `null` today. |\n| `data.items[].pricing.retail.value` | decimal | For a `FIXED` product: the recommended end-customer price (a suggestion in `WHOLESALE` mode, may be `null`); `null` for `RANGE`/`OPEN`. You are not billed this amount. |\n| `data.items[].pricing.retail.rate` | decimal | Same as `pricing.wholesale.rate` but for the recommended end-customer price, for `RANGE`/`OPEN` products. |\n| `data.items[].pricing.retail.min` | decimal | `rate × denomination.min`; `null` for `FIXED`. |\n| `data.items[].pricing.retail.max` | decimal | `rate × denomination.max`; `null` for `FIXED`. |\n| `data.items[].pricing.retail.increment` | decimal | Reserved; always `null` today. |\n| `data.items[].pricing.discount` | object | `null` unless `pricing.mode` is `DISCOUNT`. |\n| `data.items[].pricing.discount.percent` | decimal | `(retail − your price) ÷ retail × 100`, as a percentage. |\n| `data.items[].pricing.discount.value` | decimal | `pricing.retail − pricing.wholesale` in SAR for a `FIXED` product — how far your price is below retail; `null` for `RANGE`/`OPEN`. |\n| `data.items[].content` | object | `null` unless the request had `includeContent=true`. |\n| `data.items[].content.description` | string | Long-form description, localized to `lang`; `null` if none. |\n| `data.items[].content.shortDescription` | string | Short description, localized to `lang`; `null` if none. |\n| `data.items[].content.termsAndConditions` | string | Terms and conditions text; `null` if none. |\n| `data.items[].content.redemptionInstructions` | string | How to redeem the card; `null` if none. |\n| `data.items[].content.disclaimer` | string | Disclaimer text; `null` if none. |\n| `data.items[].content.validityText` | string | Human-readable validity/expiry text (e.g. `\"12 Months\"`); `null` if none. |\n| `data.items[].content.images` | array | The product's image assets; empty if none. |\n| `data.items[].content.images[].type` | string (values: `LOGO` \\| `PROVIDER_LOGO` \\| `CARD` \\| `ARTICLE` \\| `THUMBNAIL`) | The role of the image (see Reference values). |\n| `data.items[].content.images[].url` | string | The image's URL. |\n| `data.count` | int | Number of items on this page. |\n| `data.page` | int | The page number returned. |\n| `data.pageSize` | int | Items per page requested. |\n| `data.totalPages` | int | Total pages across all matching products. |\n| `data.totalItems` | int | Total matching products across all pages. |\n"},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"cookie":[],"responseTime":null,"body":"{\n  \"code\": 1000,\n  \"message\": \"Success\",\n  \"data\": {\n    \"items\": [\n      {\n        \"id\": 456,\n        \"info\": {\n          \"brandId\": 123,\n          \"category\": \"ENTERTAINMENT\",\n          \"countryIso3\": \"USA\",\n          \"name\": \"iTunes US $10\"\n        },\n        \"amountCurrency\": null,\n        \"deliveryFormat\": \"PIN\",\n        \"transactionInputFields\": [\n          {\n            \"key\": \"email\",\n            \"label\": \"Recipient Email\",\n            \"type\": \"EMAIL\",\n            \"required\": true,\n            \"validation\": {\n              \"regex\": \"^[^@]+@[^@]+$\",\n              \"minLength\": null,\n              \"maxLength\": 255,\n              \"min\": null,\n              \"max\": null,\n              \"allowedValues\": []\n            }\n          }\n        ],\n        \"denomination\": {\n          \"type\": \"FIXED\",\n          \"currency\": \"USD\",\n          \"value\": 10,\n          \"min\": null,\n          \"max\": null,\n          \"increment\": null\n        },\n        \"pricing\": {\n          \"currency\": \"SAR\",\n          \"mode\": \"WHOLESALE\",\n          \"wholesale\": {\n            \"value\": 37.5,\n            \"rate\": null,\n            \"min\": null,\n            \"max\": null,\n            \"increment\": null\n          },\n          \"retail\": {\n            \"value\": 45,\n            \"rate\": null,\n            \"min\": null,\n            \"max\": null,\n            \"increment\": null\n          },\n          \"discount\": null\n        },\n        \"content\": {\n          \"description\": \"Redeem for apps, games, music and more on the US App Store / iTunes.\",\n          \"shortDescription\": \"iTunes US gift card\",\n          \"termsAndConditions\": \"Valid for 12 months from purchase. US accounts only.\",\n          \"redemptionInstructions\": \"Redeem at itunes.com/redeem.\",\n          \"disclaimer\": \"Non-refundable.\",\n          \"validityText\": \"12 Months\",\n          \"images\": [\n            {\n              \"type\": \"LOGO\",\n              \"url\": \"https://cdn.example.com/giftcards/itunes-logo.png\"\n            },\n            {\n              \"type\": \"CARD\",\n              \"url\": \"https://cdn.example.com/giftcards/itunes-card.png\"\n            }\n          ]\n        }\n      },\n      {\n        \"id\": 271,\n        \"info\": {\n          \"brandId\": 355,\n          \"category\": \"RETAIL\",\n          \"countryIso3\": \"SAU\",\n          \"name\": \"Example Store 100 SAR\"\n        },\n        \"amountCurrency\": null,\n        \"deliveryFormat\": \"PIN\",\n        \"transactionInputFields\": null,\n        \"denomination\": {\n          \"type\": \"FIXED\",\n          \"currency\": \"SAR\",\n          \"value\": 100,\n          \"min\": null,\n          \"max\": null,\n          \"increment\": null\n        },\n        \"pricing\": {\n          \"currency\": \"SAR\",\n          \"mode\": \"DISCOUNT\",\n          \"wholesale\": {\n            \"value\": 96,\n            \"rate\": null,\n            \"min\": null,\n            \"max\": null,\n            \"increment\": null\n          },\n          \"retail\": {\n            \"value\": 100,\n            \"rate\": null,\n            \"min\": null,\n            \"max\": null,\n            \"increment\": null\n          },\n          \"discount\": {\n            \"percent\": 4,\n            \"value\": 4\n          }\n        },\n        \"content\": null\n      }\n    ],\n    \"count\": 2,\n    \"page\": 1,\n    \"pageSize\": 50,\n    \"totalPages\": 1,\n    \"totalItems\": 2\n  }\n}"}],"_postman_id":"7baf8bdc-6e7f-42a7-8a57-4f299532a91f"},{"name":"Create Transaction","id":"66a6858e-a616-4636-9cfb-fdf81ec91322","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"body":{"mode":"raw","raw":"{\n  \"externalReference\": \"client-ref-5001\",\n  \"productId\": 456,\n  \"amount\": null,\n  \"amountCurrency\": null,\n  \"transactionInputs\": [\n    {\n      \"key\": \"email\",\n      \"value\": \"recipient@example.com\"\n    }\n  ]\n}","options":{"raw":{"language":"json"}}},"url":"https://eservices.hoicom.net/api/v0/giftcards/transactions/async","description":"<p>Orders a gift card <strong>asynchronously</strong>. Returns immediately with a <code>transactionId</code>; poll <strong>Get Transaction by ID</strong> until <code>status</code> is <code>Completed</code> to retrieve the delivered card (PIN / redemption URL / QR). Idempotent on <code>externalReference</code>, which must be unique within your account across all your services.</p>\n<hr />\n<h2 id=\"authorization\">Authorization</h2>\n<p>Requires Basic Authentication with your client credentials. Your account must be enabled for the Gift Cards service.</p>\n<hr />\n<h2 id=\"request-body\">Request Body</h2>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Field</th>\n<th>Type</th>\n<th>Required</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>externalReference</code></td>\n<td><code>string</code></td>\n<td>Yes</td>\n<td>Your unique id (idempotency key). Unique per client across all your services — reusing it on another of your services is rejected (see Common error codes).</td>\n</tr>\n<tr>\n<td><code>productId</code></td>\n<td><code>int</code></td>\n<td>Yes</td>\n<td>The catalogue product to order.</td>\n</tr>\n<tr>\n<td><code>amount</code></td>\n<td><code>decimal</code></td>\n<td>No</td>\n<td>Order amount — required for <code>RANGE</code>/<code>OPEN</code> products; omit for <code>FIXED</code>.</td>\n</tr>\n<tr>\n<td><code>amountCurrency</code></td>\n<td><code>string</code></td>\n<td>No</td>\n<td>Currency of <code>amount</code>: <code>LOCAL</code> (SAR) or <code>DESTINATION</code> (card currency) — see the worked example in the folder overview.</td>\n</tr>\n<tr>\n<td><code>transactionInputs</code></td>\n<td><code>array</code></td>\n<td>Yes</td>\n<td>Values for the product's required input fields, as <code>{ key, value }</code> pairs.</td>\n</tr>\n</tbody>\n</table>\n</div><hr />\n<h2 id=\"response\">Response</h2>\n<p>On acceptance <code>code</code> is <code>1000</code> and <code>data</code> contains the <code>transactionId</code>.</p>\n<h3 id=\"common-error-codes\">Common error codes</h3>\n<p>Most codes come back as HTTP 200, with the code in the response envelope. <code>1403</code> changes the HTTP status to 400, <code>1404</code> to 502, and <code>1114</code> (a reference already used on another of your services) is returned with HTTP 409.</p>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Code</th>\n<th>Meaning</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>1107</code></td>\n<td>Validation error.</td>\n</tr>\n<tr>\n<td><code>1403</code></td>\n<td>Transaction rejected (→ HTTP 400). Returned as \"This product is not available for purchase right now.\" when the product is listed but cannot currently be sold, or its price cannot be applied.</td>\n</tr>\n<tr>\n<td><code>1404</code></td>\n<td>Declined by provider (→ HTTP 502).</td>\n</tr>\n<tr>\n<td><code>1407</code></td>\n<td>Duplicate transaction — this <code>externalReference</code> was already used for a Gift Cards order in your account (HTTP 200).</td>\n</tr>\n<tr>\n<td><code>1409</code></td>\n<td>Invalid transaction amount.</td>\n</tr>\n<tr>\n<td><code>1413</code></td>\n<td>Unknown, inactive, or not offered to your account product id.</td>\n</tr>\n<tr>\n<td><code>1114</code></td>\n<td>The <code>externalReference</code> is already used by your account on a different service (HTTP 409).</td>\n</tr>\n</tbody>\n</table>\n</div><p>--- | --- |\n| <code>1107</code> | Validation error. |\n| <code>1403</code> | Transaction rejected (→ HTTP 400). |\n| <code>1404</code> | Declined by provider (→ HTTP 502). |\n| <code>1407</code> | Duplicate transaction — this <code>externalReference</code> was already used. |\n| <code>1409</code> | Invalid transaction amount. |\n| <code>1413</code> | Unknown, inactive, or misconfigured product id. |</p>\n<hr />\n<h2 id=\"response-fields\">Response fields</h2>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Field</th>\n<th>Type</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>code</code></td>\n<td>int</td>\n<td>Response status code; <code>1000</code> means the order was accepted.</td>\n</tr>\n<tr>\n<td><code>message</code></td>\n<td>string</td>\n<td>Human-readable status message.</td>\n</tr>\n<tr>\n<td><code>data</code></td>\n<td>object</td>\n<td><code>null</code> when the request was rejected before a transaction was created (see Common error codes).</td>\n</tr>\n<tr>\n<td><code>data.transactionId</code></td>\n<td>string</td>\n<td>The created transaction's id — poll <strong>Get Transaction by ID</strong> with this value.</td>\n</tr>\n</tbody>\n</table>\n</div>","urlObject":{"path":["api","v0","giftcards","transactions","async"],"host":["https://eservices.hoicom.net"],"query":[],"variable":[]}},"response":[{"id":"6bd0b669-e919-48aa-860e-7daaae25f6c5","name":"OK","originalRequest":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"body":{"mode":"raw","raw":"{\n  \"externalReference\": \"client-ref-5001\",\n  \"productId\": 456,\n  \"amount\": null,\n  \"amountCurrency\": null,\n  \"transactionInputs\": [\n    {\n      \"key\": \"email\",\n      \"value\": \"recipient@example.com\"\n    }\n  ]\n}","options":{"raw":{"language":"json"}}},"url":"https://eservices.hoicom.net/api/v0/giftcards/transactions/async","description":"Orders a gift card **asynchronously**. Returns immediately with a `transactionId`; poll **Get Transaction by ID** until `status` is `Completed` to retrieve the delivered card (PIN / redemption URL / QR). Idempotent on `externalReference`, which must be unique within your account across all your services.\n\n---\n\n## Authorization\n\nRequires Basic Authentication with your client credentials. Your account must be enabled for the Gift Cards service.\n\n---\n\n## Request Body\n\n| Field | Type | Required | Description |\n| --- | --- | --- | --- |\n| `externalReference` | `string` | Yes | Your unique id (idempotency key). Unique per client across all your services — reusing it on another of your services is rejected (see Common error codes). |\n| `productId` | `int` | Yes | The catalogue product to order. |\n| `amount` | `decimal` | No | Order amount — required for `RANGE`/`OPEN` products; omit for `FIXED`. |\n| `amountCurrency` | `string` | No | Currency of `amount`: `LOCAL` (SAR) or `DESTINATION` (card currency) — see the worked example in the folder overview. |\n| `transactionInputs` | `array` | Yes | Values for the product's required input fields, as `{ key, value }` pairs. |\n\n---\n\n## Response\n\nOn acceptance `code` is `1000` and `data` contains the `transactionId`.\n\n### Common error codes\n\nMost codes come back as HTTP 200, with the code in the response envelope. `1403` changes the HTTP status to 400, `1404` to 502, and `1114` (a reference already used on another of your services) is returned with HTTP 409.\n\n| Code | Meaning |\n| --- | --- |\n| `1107` | Validation error. |\n| `1403` | Transaction rejected (→ HTTP 400). Returned as \"This product is not available for purchase right now.\" when the product is listed but cannot currently be sold, or its price cannot be applied. |\n| `1404` | Declined by provider (→ HTTP 502). |\n| `1407` | Duplicate transaction — this `externalReference` was already used for a Gift Cards order in your account (HTTP 200). |\n| `1409` | Invalid transaction amount. |\n| `1413` | Unknown, inactive, or not offered to your account product id. |\n| `1114` | The `externalReference` is already used by your account on a different service (HTTP 409). |\n\n--- | --- |\n| `1107` | Validation error. |\n| `1403` | Transaction rejected (→ HTTP 400). |\n| `1404` | Declined by provider (→ HTTP 502). |\n| `1407` | Duplicate transaction — this `externalReference` was already used. |\n| `1409` | Invalid transaction amount. |\n| `1413` | Unknown, inactive, or misconfigured product id. |\n\n---\n\n## Response fields\n\n| Field | Type | Description |\n| --- | --- | --- |\n| `code` | int | Response status code; `1000` means the order was accepted. |\n| `message` | string | Human-readable status message. |\n| `data` | object | `null` when the request was rejected before a transaction was created (see Common error codes). |\n| `data.transactionId` | string | The created transaction's id — poll **Get Transaction by ID** with this value. |\n"},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"cookie":[],"responseTime":null,"body":"{\n  \"code\": 1000,\n  \"message\": \"Success\",\n  \"data\": {\n    \"transactionId\": \"gc_txn_20260701_00123\"\n  }\n}"},{"id":"83eb0c6b-1ee4-40ad-b970-b789df696fb7","name":"Product not available","originalRequest":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"body":{"mode":"raw","raw":"{\n  \"externalReference\": \"client-ref-5001\",\n  \"productId\": 456,\n  \"amount\": null,\n  \"amountCurrency\": null,\n  \"transactionInputs\": [\n    {\n      \"key\": \"email\",\n      \"value\": \"recipient@example.com\"\n    }\n  ]\n}","options":{"raw":{"language":"json"}}},"url":"https://eservices.hoicom.net/api/v0/giftcards/transactions/async","description":"Orders a gift card **asynchronously**. Returns immediately with a `transactionId`; poll **Get Transaction by ID** until `status` is `Completed` to retrieve the delivered card (PIN / redemption URL / QR). Idempotent on `externalReference`, which must be unique within your account across all your services.\n\n---\n\n## Authorization\n\nRequires Basic Authentication with your client credentials. Your account must be enabled for the Gift Cards service.\n\n---\n\n## Request Body\n\n| Field | Type | Required | Description |\n| --- | --- | --- | --- |\n| `externalReference` | `string` | Yes | Your unique id (idempotency key). Unique per client across all your services — reusing it on another of your services is rejected (see Common error codes). |\n| `productId` | `int` | Yes | The catalogue product to order. |\n| `amount` | `decimal` | No | Order amount — required for `RANGE`/`OPEN` products; omit for `FIXED`. |\n| `amountCurrency` | `string` | No | Currency of `amount`: `LOCAL` (SAR) or `DESTINATION` (card currency) — see the worked example in the folder overview. |\n| `transactionInputs` | `array` | Yes | Values for the product's required input fields, as `{ key, value }` pairs. |\n\n---\n\n## Response\n\nOn acceptance `code` is `1000` and `data` contains the `transactionId`.\n\n### Common error codes\n\nMost codes come back as HTTP 200, with the code in the response envelope. `1403` changes the HTTP status to 400, `1404` to 502, and `1114` (a reference already used on another of your services) is returned with HTTP 409.\n\n| Code | Meaning |\n| --- | --- |\n| `1107` | Validation error. |\n| `1403` | Transaction rejected (→ HTTP 400). Returned as \"This product is not available for purchase right now.\" when the product is listed but cannot currently be sold, or its price cannot be applied. |\n| `1404` | Declined by provider (→ HTTP 502). |\n| `1407` | Duplicate transaction — this `externalReference` was already used for a Gift Cards order in your account (HTTP 200). |\n| `1409` | Invalid transaction amount. |\n| `1413` | Unknown, inactive, or not offered to your account product id. |\n| `1114` | The `externalReference` is already used by your account on a different service (HTTP 409). |\n\n--- | --- |\n| `1107` | Validation error. |\n| `1403` | Transaction rejected (→ HTTP 400). |\n| `1404` | Declined by provider (→ HTTP 502). |\n| `1407` | Duplicate transaction — this `externalReference` was already used. |\n| `1409` | Invalid transaction amount. |\n| `1413` | Unknown, inactive, or misconfigured product id. |\n\n---\n\n## Response fields\n\n| Field | Type | Description |\n| --- | --- | --- |\n| `code` | int | Response status code; `1000` means the order was accepted. |\n| `message` | string | Human-readable status message. |\n| `data` | object | `null` when the request was rejected before a transaction was created (see Common error codes). |\n| `data.transactionId` | string | The created transaction's id — poll **Get Transaction by ID** with this value. |\n"},"status":"Bad Request","code":400,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"cookie":[],"responseTime":null,"body":"{\n  \"code\": 1403,\n  \"message\": \"This product is not available for purchase right now.\",\n  \"data\": null\n}"}],"_postman_id":"66a6858e-a616-4636-9cfb-fdf81ec91322"},{"name":"Get Transaction by ID","id":"e5c36ce0-7372-4a37-b33c-eef4e5bc8b29","request":{"method":"GET","header":[],"url":"https://eservices.hoicom.net/api/v0/giftcards/transactions/:id","description":"<p>Returns a single gift-card transaction — its <code>status</code>, ordered <code>denomination</code>, billed <code>price</code>, and (once <code>Completed</code>) the delivered card artifact in <code>delivery</code>.</p>\n<hr />\n<h2 id=\"authorization\">Authorization</h2>\n<p>Requires Basic Authentication with your client credentials. Your account must be enabled for the Gift Cards service.</p>\n<hr />\n<h2 id=\"path-parameters\">Path Parameters</h2>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Parameter</th>\n<th>Type</th>\n<th>Required</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>id</code></td>\n<td><code>string</code></td>\n<td>Yes</td>\n<td>Transaction identifier.</td>\n</tr>\n</tbody>\n</table>\n</div><hr />\n<h2 id=\"response\">Response</h2>\n<p>On success <code>code</code> is <code>1000</code>. <code>status</code> uses the <strong>Transaction status</strong> values; <code>delivery.format</code> the <strong>Delivery format</strong> values (see folder overview). <code>delivery</code> is populated only when <code>status</code> is <code>Completed</code>; <code>errorDetails</code> is set only when <code>status</code> is <code>Failed</code>. A rejected/not-found lookup still returns HTTP 200 with the code in the envelope, except <code>1403</code> (→ 400) and <code>1404</code> (→ 502), which change the HTTP status.</p>\n<hr />\n<h2 id=\"response-fields\">Response fields</h2>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Field</th>\n<th>Type</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>code</code></td>\n<td>int</td>\n<td>Response status code; <code>1000</code> means success.</td>\n</tr>\n<tr>\n<td><code>message</code></td>\n<td>string</td>\n<td>Human-readable status message.</td>\n</tr>\n<tr>\n<td><code>data</code></td>\n<td>object</td>\n<td>The transaction.</td>\n</tr>\n<tr>\n<td><code>data.transactionId</code></td>\n<td>string</td>\n<td>The transaction's id.</td>\n</tr>\n<tr>\n<td><code>data.externalReference</code></td>\n<td>string</td>\n<td>Your idempotency key, echoed back.</td>\n</tr>\n<tr>\n<td><code>data.productId</code></td>\n<td>int</td>\n<td>The ordered product's id.</td>\n</tr>\n<tr>\n<td><code>data.status</code></td>\n<td>string (values: <code>Submitted</code> | <code>Pending</code> | <code>Completed</code> | <code>Failed</code> | <code>Cancelled</code> | <code>Refunded</code>)</td>\n<td>The transaction's current state (see Reference values).</td>\n</tr>\n<tr>\n<td><code>data.denomination.type</code></td>\n<td>string (value: <code>FIXED</code>)</td>\n<td>Always <code>FIXED</code> on a placed transaction — it reflects the one concrete value ordered, not the original product's <code>FIXED</code>/<code>RANGE</code>/<code>OPEN</code> kind.</td>\n</tr>\n<tr>\n<td><code>data.denomination.currency</code></td>\n<td>string</td>\n<td>The card's destination currency.</td>\n</tr>\n<tr>\n<td><code>data.denomination.value</code></td>\n<td>decimal</td>\n<td>The concrete ordered face value.</td>\n</tr>\n<tr>\n<td><code>data.denomination.min</code></td>\n<td>decimal</td>\n<td>Always <code>null</code> on a placed transaction.</td>\n</tr>\n<tr>\n<td><code>data.denomination.max</code></td>\n<td>decimal</td>\n<td>Always <code>null</code> on a placed transaction.</td>\n</tr>\n<tr>\n<td><code>data.denomination.increment</code></td>\n<td>decimal</td>\n<td>Always <code>null</code> on a placed transaction.</td>\n</tr>\n<tr>\n<td><code>data.amountCurrency</code></td>\n<td>string (values: <code>LOCAL</code> | <code>DESTINATION</code>)</td>\n<td><code>null</code> for a <code>FIXED</code> product; otherwise the currency the order amount was expressed in.</td>\n</tr>\n<tr>\n<td><code>data.price</code></td>\n<td>object</td>\n<td>The price of this order as recorded when you placed it; it does not change if the product's price changes later.</td>\n</tr>\n<tr>\n<td><code>data.price.currency</code></td>\n<td>string</td>\n<td>Billing currency — always <code>\"SAR\"</code>.</td>\n</tr>\n<tr>\n<td><code>data.price.wholesale</code></td>\n<td>decimal</td>\n<td>What you were billed (SAR) for this order.</td>\n</tr>\n<tr>\n<td><code>data.price.retail</code></td>\n<td>decimal</td>\n<td>The recommended end-customer price recorded for this order. You were billed <code>price.wholesale</code>, not this amount.</td>\n</tr>\n<tr>\n<td><code>data.price.discount</code></td>\n<td>object</td>\n<td><code>null</code> unless this order was priced in <code>DISCOUNT</code> mode.</td>\n</tr>\n<tr>\n<td><code>data.price.discount.percent</code></td>\n<td>decimal</td>\n<td><code>(retail − wholesale) ÷ retail × 100</code>, as a percentage.</td>\n</tr>\n<tr>\n<td><code>data.price.discount.value</code></td>\n<td>decimal</td>\n<td><code>retail − wholesale</code> in SAR; <code>null</code> for a <code>RANGE</code>/<code>OPEN</code> order.</td>\n</tr>\n<tr>\n<td><code>data.delivery</code></td>\n<td>object</td>\n<td><code>null</code> unless <code>status</code> is <code>Completed</code>.</td>\n</tr>\n<tr>\n<td><code>data.delivery.format</code></td>\n<td>string (values: <code>PIN</code> | <code>REDEMPTION_URL</code> | <code>QR_CODE</code> | <code>DIRECT_CREDIT</code>)</td>\n<td>How the card was delivered (see Reference values).</td>\n</tr>\n<tr>\n<td><code>data.delivery.code</code></td>\n<td>string</td>\n<td><code>null</code> unless the delivery format is <code>PIN</code> and a claim code applies.</td>\n</tr>\n<tr>\n<td><code>data.delivery.pin</code></td>\n<td>string</td>\n<td><code>null</code> unless the delivery format is <code>PIN</code>.</td>\n</tr>\n<tr>\n<td><code>data.delivery.cardNumber</code></td>\n<td>string</td>\n<td><code>null</code> unless the delivery format is <code>PIN</code> and a card number applies.</td>\n</tr>\n<tr>\n<td><code>data.delivery.serial</code></td>\n<td>string</td>\n<td><code>null</code> unless the delivery format is <code>PIN</code> and a serial applies.</td>\n</tr>\n<tr>\n<td><code>data.delivery.redemptionUrl</code></td>\n<td>string</td>\n<td><code>null</code> unless the delivery format is <code>REDEMPTION_URL</code>.</td>\n</tr>\n<tr>\n<td><code>data.delivery.qrCode</code></td>\n<td>string</td>\n<td><code>null</code> unless the delivery format is <code>QR_CODE</code>.</td>\n</tr>\n<tr>\n<td><code>data.delivery.instructions</code></td>\n<td>string</td>\n<td>Redemption instructions; <code>null</code> if none provided.</td>\n</tr>\n<tr>\n<td><code>data.createdAt</code></td>\n<td>string (ISO 8601 datetime)</td>\n<td>When the transaction was created.</td>\n</tr>\n<tr>\n<td><code>data.completedAt</code></td>\n<td>string (ISO 8601 datetime)</td>\n<td><code>null</code> until <code>status</code> is <code>Completed</code>.</td>\n</tr>\n<tr>\n<td><code>data.errorDetails</code></td>\n<td>string</td>\n<td>Exactly <code>\"The order could not be completed.\"</code> whenever <code>status</code> is <code>Failed</code>; <code>null</code> otherwise.</td>\n</tr>\n</tbody>\n</table>\n</div>","urlObject":{"path":["api","v0","giftcards","transactions",":id"],"host":["https://eservices.hoicom.net"],"query":[],"variable":[{"type":"any","value":"","key":"id"}]}},"response":[{"id":"2807a818-c0b9-4962-acda-75d0586e1496","name":"OK","originalRequest":{"method":"GET","header":[],"url":{"raw":"https://eservices.hoicom.net/api/v0/giftcards/transactions/:id","host":["https://eservices.hoicom.net"],"path":["api","v0","giftcards","transactions",":id"],"variable":[{"key":"id","value":""}]},"description":"Returns a single gift-card transaction — its `status`, ordered `denomination`, billed `price`, and (once `Completed`) the delivered card artifact in `delivery`.\n\n---\n\n## Authorization\n\nRequires Basic Authentication with your client credentials. Your account must be enabled for the Gift Cards service.\n\n---\n\n## Path Parameters\n\n| Parameter | Type | Required | Description |\n| --- | --- | --- | --- |\n| `id` | `string` | Yes | Transaction identifier. |\n\n---\n\n## Response\n\nOn success `code` is `1000`. `status` uses the **Transaction status** values; `delivery.format` the **Delivery format** values (see folder overview). `delivery` is populated only when `status` is `Completed`; `errorDetails` is set only when `status` is `Failed`. A rejected/not-found lookup still returns HTTP 200 with the code in the envelope, except `1403` (→ 400) and `1404` (→ 502), which change the HTTP status.\n\n---\n\n## Response fields\n\n| Field | Type | Description |\n| --- | --- | --- |\n| `code` | int | Response status code; `1000` means success. |\n| `message` | string | Human-readable status message. |\n| `data` | object | The transaction. |\n| `data.transactionId` | string | The transaction's id. |\n| `data.externalReference` | string | Your idempotency key, echoed back. |\n| `data.productId` | int | The ordered product's id. |\n| `data.status` | string (values: `Submitted` \\| `Pending` \\| `Completed` \\| `Failed` \\| `Cancelled` \\| `Refunded`) | The transaction's current state (see Reference values). |\n| `data.denomination.type` | string (value: `FIXED`) | Always `FIXED` on a placed transaction — it reflects the one concrete value ordered, not the original product's `FIXED`/`RANGE`/`OPEN` kind. |\n| `data.denomination.currency` | string | The card's destination currency. |\n| `data.denomination.value` | decimal | The concrete ordered face value. |\n| `data.denomination.min` | decimal | Always `null` on a placed transaction. |\n| `data.denomination.max` | decimal | Always `null` on a placed transaction. |\n| `data.denomination.increment` | decimal | Always `null` on a placed transaction. |\n| `data.amountCurrency` | string (values: `LOCAL` \\| `DESTINATION`) | `null` for a `FIXED` product; otherwise the currency the order amount was expressed in. |\n| `data.price` | object | The price of this order as recorded when you placed it; it does not change if the product's price changes later. |\n| `data.price.currency` | string | Billing currency — always `\"SAR\"`. |\n| `data.price.wholesale` | decimal | What you were billed (SAR) for this order. |\n| `data.price.retail` | decimal | The recommended end-customer price recorded for this order. You were billed `price.wholesale`, not this amount. |\n| `data.price.discount` | object | `null` unless this order was priced in `DISCOUNT` mode. |\n| `data.price.discount.percent` | decimal | `(retail − wholesale) ÷ retail × 100`, as a percentage. |\n| `data.price.discount.value` | decimal | `retail − wholesale` in SAR; `null` for a `RANGE`/`OPEN` order. |\n| `data.delivery` | object | `null` unless `status` is `Completed`. |\n| `data.delivery.format` | string (values: `PIN` \\| `REDEMPTION_URL` \\| `QR_CODE` \\| `DIRECT_CREDIT`) | How the card was delivered (see Reference values). |\n| `data.delivery.code` | string | `null` unless the delivery format is `PIN` and a claim code applies. |\n| `data.delivery.pin` | string | `null` unless the delivery format is `PIN`. |\n| `data.delivery.cardNumber` | string | `null` unless the delivery format is `PIN` and a card number applies. |\n| `data.delivery.serial` | string | `null` unless the delivery format is `PIN` and a serial applies. |\n| `data.delivery.redemptionUrl` | string | `null` unless the delivery format is `REDEMPTION_URL`. |\n| `data.delivery.qrCode` | string | `null` unless the delivery format is `QR_CODE`. |\n| `data.delivery.instructions` | string | Redemption instructions; `null` if none provided. |\n| `data.createdAt` | string (ISO 8601 datetime) | When the transaction was created. |\n| `data.completedAt` | string (ISO 8601 datetime) | `null` until `status` is `Completed`. |\n| `data.errorDetails` | string | Exactly `\"The order could not be completed.\"` whenever `status` is `Failed`; `null` otherwise. |\n"},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"cookie":[],"responseTime":null,"body":"{\n  \"code\": 1000,\n  \"message\": \"Success\",\n  \"data\": {\n    \"transactionId\": \"gc_txn_20260701_00123\",\n    \"externalReference\": \"client-ref-5001\",\n    \"productId\": 456,\n    \"status\": \"Completed\",\n    \"denomination\": {\n      \"type\": \"FIXED\",\n      \"currency\": \"USD\",\n      \"value\": 10,\n      \"min\": null,\n      \"max\": null,\n      \"increment\": null\n    },\n    \"amountCurrency\": null,\n    \"price\": {\n      \"currency\": \"SAR\",\n      \"wholesale\": 37.5,\n      \"retail\": 45,\n      \"discount\": null\n    },\n    \"delivery\": {\n      \"format\": \"PIN\",\n      \"pin\": \"5678\",\n      \"cardNumber\": null,\n      \"serial\": \"ITUNES-USA-001122\",\n      \"redemptionUrl\": null,\n      \"qrCode\": null,\n      \"instructions\": \"Redeem at itunes.com/redeem.\"\n    },\n    \"createdAt\": \"2026-07-01T14:30:00Z\",\n    \"completedAt\": \"2026-07-01T14:31:20Z\",\n    \"errorDetails\": null\n  }\n}"},{"id":"8a7da19c-ab65-424f-9654-1fbc817ef01b","name":"Failed","originalRequest":{"method":"GET","header":[],"url":{"raw":"https://eservices.hoicom.net/api/v0/giftcards/transactions/:id","host":["https://eservices.hoicom.net"],"path":["api","v0","giftcards","transactions",":id"],"variable":[{"key":"id","value":""}]},"description":"Returns a single gift-card transaction — its `status`, ordered `denomination`, billed `price`, and (once `Completed`) the delivered card artifact in `delivery`.\n\n---\n\n## Authorization\n\nRequires Basic Authentication with your client credentials. Your account must be enabled for the Gift Cards service.\n\n---\n\n## Path Parameters\n\n| Parameter | Type | Required | Description |\n| --- | --- | --- | --- |\n| `id` | `string` | Yes | Transaction identifier. |\n\n---\n\n## Response\n\nOn success `code` is `1000`. `status` uses the **Transaction status** values; `delivery.format` the **Delivery format** values (see folder overview). `delivery` is populated only when `status` is `Completed`; `errorDetails` is set only when `status` is `Failed`. A rejected/not-found lookup still returns HTTP 200 with the code in the envelope, except `1403` (→ 400) and `1404` (→ 502), which change the HTTP status.\n\n---\n\n## Response fields\n\n| Field | Type | Description |\n| --- | --- | --- |\n| `code` | int | Response status code; `1000` means success. |\n| `message` | string | Human-readable status message. |\n| `data` | object | The transaction. |\n| `data.transactionId` | string | The transaction's id. |\n| `data.externalReference` | string | Your idempotency key, echoed back. |\n| `data.productId` | int | The ordered product's id. |\n| `data.status` | string (values: `Submitted` \\| `Pending` \\| `Completed` \\| `Failed` \\| `Cancelled` \\| `Refunded`) | The transaction's current state (see Reference values). |\n| `data.denomination.type` | string (value: `FIXED`) | Always `FIXED` on a placed transaction — it reflects the one concrete value ordered, not the original product's `FIXED`/`RANGE`/`OPEN` kind. |\n| `data.denomination.currency` | string | The card's destination currency. |\n| `data.denomination.value` | decimal | The concrete ordered face value. |\n| `data.denomination.min` | decimal | Always `null` on a placed transaction. |\n| `data.denomination.max` | decimal | Always `null` on a placed transaction. |\n| `data.denomination.increment` | decimal | Always `null` on a placed transaction. |\n| `data.amountCurrency` | string (values: `LOCAL` \\| `DESTINATION`) | `null` for a `FIXED` product; otherwise the currency the order amount was expressed in. |\n| `data.price` | object | The price of this order as recorded when you placed it; it does not change if the product's price changes later. |\n| `data.price.currency` | string | Billing currency — always `\"SAR\"`. |\n| `data.price.wholesale` | decimal | What you were billed (SAR) for this order. |\n| `data.price.retail` | decimal | The recommended end-customer price recorded for this order. You were billed `price.wholesale`, not this amount. |\n| `data.price.discount` | object | `null` unless this order was priced in `DISCOUNT` mode. |\n| `data.price.discount.percent` | decimal | `(retail − wholesale) ÷ retail × 100`, as a percentage. |\n| `data.price.discount.value` | decimal | `retail − wholesale` in SAR; `null` for a `RANGE`/`OPEN` order. |\n| `data.delivery` | object | `null` unless `status` is `Completed`. |\n| `data.delivery.format` | string (values: `PIN` \\| `REDEMPTION_URL` \\| `QR_CODE` \\| `DIRECT_CREDIT`) | How the card was delivered (see Reference values). |\n| `data.delivery.code` | string | `null` unless the delivery format is `PIN` and a claim code applies. |\n| `data.delivery.pin` | string | `null` unless the delivery format is `PIN`. |\n| `data.delivery.cardNumber` | string | `null` unless the delivery format is `PIN` and a card number applies. |\n| `data.delivery.serial` | string | `null` unless the delivery format is `PIN` and a serial applies. |\n| `data.delivery.redemptionUrl` | string | `null` unless the delivery format is `REDEMPTION_URL`. |\n| `data.delivery.qrCode` | string | `null` unless the delivery format is `QR_CODE`. |\n| `data.delivery.instructions` | string | Redemption instructions; `null` if none provided. |\n| `data.createdAt` | string (ISO 8601 datetime) | When the transaction was created. |\n| `data.completedAt` | string (ISO 8601 datetime) | `null` until `status` is `Completed`. |\n| `data.errorDetails` | string | Exactly `\"The order could not be completed.\"` whenever `status` is `Failed`; `null` otherwise. |\n"},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"cookie":[],"responseTime":null,"body":"{\n  \"code\": 1000,\n  \"message\": \"Success\",\n  \"data\": {\n    \"transactionId\": \"gc_txn_20260701_00123\",\n    \"externalReference\": \"client-ref-5001\",\n    \"productId\": 456,\n    \"status\": \"Failed\",\n    \"denomination\": {\n      \"type\": \"FIXED\",\n      \"currency\": \"USD\",\n      \"value\": 10,\n      \"min\": null,\n      \"max\": null,\n      \"increment\": null\n    },\n    \"amountCurrency\": null,\n    \"price\": {\n      \"currency\": \"SAR\",\n      \"wholesale\": 37.5,\n      \"retail\": 45,\n      \"discount\": null\n    },\n    \"delivery\": null,\n    \"createdAt\": \"2026-07-01T14:30:00Z\",\n    \"completedAt\": null,\n    \"errorDetails\": \"The order could not be completed.\"\n  }\n}"}],"_postman_id":"e5c36ce0-7372-4a37-b33c-eef4e5bc8b29"},{"name":"Get Transactions","id":"41279ef4-9e17-4d14-b1ff-a128b121af62","request":{"method":"GET","header":[],"url":"https://eservices.hoicom.net/api/v0/giftcards/transactions?transactionIds=&externalReferences=&productIds=&statuses=Completed&fromDate=&toDate=&page=1&pageSize=50","description":"<p>Returns a paginated, filterable list of your gift-card transactions.</p>\n<hr />\n<h2 id=\"authorization\">Authorization</h2>\n<p>Requires Basic Authentication with your client credentials. Your account must be enabled for the Gift Cards service.</p>\n<hr />\n<h2 id=\"query-parameters\">Query Parameters</h2>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Parameter</th>\n<th>Type</th>\n<th>Required</th>\n<th>Default</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>transactionIds</code></td>\n<td><code>string[]</code></td>\n<td>No</td>\n<td>—</td>\n<td>Filter by transaction id(s).</td>\n</tr>\n<tr>\n<td><code>externalReferences</code></td>\n<td><code>string[]</code></td>\n<td>No</td>\n<td>—</td>\n<td>Filter by your external reference(s).</td>\n</tr>\n<tr>\n<td><code>productIds</code></td>\n<td><code>int[]</code></td>\n<td>No</td>\n<td>—</td>\n<td>Filter by product id(s).</td>\n</tr>\n<tr>\n<td><code>statuses</code></td>\n<td><code>string[]</code></td>\n<td>No</td>\n<td>—</td>\n<td>Filter by status (e.g. <code>Completed</code>).</td>\n</tr>\n<tr>\n<td><code>fromDate</code></td>\n<td><code>datetime</code></td>\n<td>No</td>\n<td>—</td>\n<td>Created on/after.</td>\n</tr>\n<tr>\n<td><code>toDate</code></td>\n<td><code>datetime</code></td>\n<td>No</td>\n<td>—</td>\n<td>Created on/before.</td>\n</tr>\n<tr>\n<td><code>page</code></td>\n<td><code>int</code></td>\n<td>No</td>\n<td><code>1</code></td>\n<td>Page number.</td>\n</tr>\n<tr>\n<td><code>pageSize</code></td>\n<td><code>int</code></td>\n<td>No</td>\n<td><code>50</code></td>\n<td>Items per page (max 100).</td>\n</tr>\n</tbody>\n</table>\n</div><hr />\n<h2 id=\"response\">Response</h2>\n<p>On success <code>code</code> is <code>1000</code> and <code>data</code> is a paginated list of transactions. Valid <code>status</code> values: <code>Submitted</code>, <code>Pending</code>, <code>Completed</code>, <code>Failed</code>, <code>Cancelled</code>, <code>Refunded</code>. <code>errorDetails</code> is set only on <code>Failed</code> transactions.</p>\n<hr />\n<h2 id=\"response-fields\">Response fields</h2>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Field</th>\n<th>Type</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>code</code></td>\n<td>int</td>\n<td>Response status code; <code>1000</code> means success.</td>\n</tr>\n<tr>\n<td><code>message</code></td>\n<td>string</td>\n<td>Human-readable status message.</td>\n</tr>\n<tr>\n<td><code>data</code></td>\n<td>object</td>\n<td>The paginated result envelope.</td>\n</tr>\n<tr>\n<td><code>data.items</code></td>\n<td>array</td>\n<td>The page of matching transactions.</td>\n</tr>\n<tr>\n<td><code>data.items[].transactionId</code></td>\n<td>string</td>\n<td>The transaction's id.</td>\n</tr>\n<tr>\n<td><code>data.items[].externalReference</code></td>\n<td>string</td>\n<td>Your idempotency key, echoed back.</td>\n</tr>\n<tr>\n<td><code>data.items[].productId</code></td>\n<td>int</td>\n<td>The ordered product's id.</td>\n</tr>\n<tr>\n<td><code>data.items[].status</code></td>\n<td>string (values: <code>Submitted</code> | <code>Pending</code> | <code>Completed</code> | <code>Failed</code> | <code>Cancelled</code> | <code>Refunded</code>)</td>\n<td>The transaction's current state (see Reference values).</td>\n</tr>\n<tr>\n<td><code>data.items[].denomination.type</code></td>\n<td>string (value: <code>FIXED</code>)</td>\n<td>Always <code>FIXED</code> on a placed transaction — it reflects the one concrete value ordered, not the original product's <code>FIXED</code>/<code>RANGE</code>/<code>OPEN</code> kind.</td>\n</tr>\n<tr>\n<td><code>data.items[].denomination.currency</code></td>\n<td>string</td>\n<td>The card's destination currency.</td>\n</tr>\n<tr>\n<td><code>data.items[].denomination.value</code></td>\n<td>decimal</td>\n<td>The concrete ordered face value.</td>\n</tr>\n<tr>\n<td><code>data.items[].denomination.min</code></td>\n<td>decimal</td>\n<td>Always <code>null</code> on a placed transaction.</td>\n</tr>\n<tr>\n<td><code>data.items[].denomination.max</code></td>\n<td>decimal</td>\n<td>Always <code>null</code> on a placed transaction.</td>\n</tr>\n<tr>\n<td><code>data.items[].denomination.increment</code></td>\n<td>decimal</td>\n<td>Always <code>null</code> on a placed transaction.</td>\n</tr>\n<tr>\n<td><code>data.items[].amountCurrency</code></td>\n<td>string (values: <code>LOCAL</code> | <code>DESTINATION</code>)</td>\n<td><code>null</code> for a <code>FIXED</code> product; otherwise the currency the order amount was expressed in.</td>\n</tr>\n<tr>\n<td><code>data.items[].price</code></td>\n<td>object</td>\n<td>The price of this order as recorded when you placed it; it does not change if the product's price changes later.</td>\n</tr>\n<tr>\n<td><code>data.items[].price.currency</code></td>\n<td>string</td>\n<td>Billing currency — always <code>\"SAR\"</code>.</td>\n</tr>\n<tr>\n<td><code>data.items[].price.wholesale</code></td>\n<td>decimal</td>\n<td>What you were billed (SAR) for this order.</td>\n</tr>\n<tr>\n<td><code>data.items[].price.retail</code></td>\n<td>decimal</td>\n<td>The recommended end-customer price recorded for this order. You were billed <code>price.wholesale</code>, not this amount.</td>\n</tr>\n<tr>\n<td><code>data.items[].price.discount</code></td>\n<td>object</td>\n<td><code>null</code> unless this order was priced in <code>DISCOUNT</code> mode.</td>\n</tr>\n<tr>\n<td><code>data.items[].price.discount.percent</code></td>\n<td>decimal</td>\n<td><code>(retail − wholesale) ÷ retail × 100</code>, as a percentage.</td>\n</tr>\n<tr>\n<td><code>data.items[].price.discount.value</code></td>\n<td>decimal</td>\n<td><code>retail − wholesale</code> in SAR; <code>null</code> for a <code>RANGE</code>/<code>OPEN</code> order.</td>\n</tr>\n<tr>\n<td><code>data.items[].delivery</code></td>\n<td>object</td>\n<td><code>null</code> unless <code>status</code> is <code>Completed</code>.</td>\n</tr>\n<tr>\n<td><code>data.items[].delivery.format</code></td>\n<td>string (values: <code>PIN</code> | <code>REDEMPTION_URL</code> | <code>QR_CODE</code> | <code>DIRECT_CREDIT</code>)</td>\n<td>How the card was delivered (see Reference values).</td>\n</tr>\n<tr>\n<td><code>data.items[].delivery.code</code></td>\n<td>string</td>\n<td><code>null</code> unless the delivery format is <code>PIN</code> and a claim code applies.</td>\n</tr>\n<tr>\n<td><code>data.items[].delivery.pin</code></td>\n<td>string</td>\n<td><code>null</code> unless the delivery format is <code>PIN</code>.</td>\n</tr>\n<tr>\n<td><code>data.items[].delivery.cardNumber</code></td>\n<td>string</td>\n<td><code>null</code> unless the delivery format is <code>PIN</code> and a card number applies.</td>\n</tr>\n<tr>\n<td><code>data.items[].delivery.serial</code></td>\n<td>string</td>\n<td><code>null</code> unless the delivery format is <code>PIN</code> and a serial applies.</td>\n</tr>\n<tr>\n<td><code>data.items[].delivery.redemptionUrl</code></td>\n<td>string</td>\n<td><code>null</code> unless the delivery format is <code>REDEMPTION_URL</code>.</td>\n</tr>\n<tr>\n<td><code>data.items[].delivery.qrCode</code></td>\n<td>string</td>\n<td><code>null</code> unless the delivery format is <code>QR_CODE</code>.</td>\n</tr>\n<tr>\n<td><code>data.items[].delivery.instructions</code></td>\n<td>string</td>\n<td>Redemption instructions; <code>null</code> if none provided.</td>\n</tr>\n<tr>\n<td><code>data.items[].createdAt</code></td>\n<td>string (ISO 8601 datetime)</td>\n<td>When the transaction was created.</td>\n</tr>\n<tr>\n<td><code>data.items[].completedAt</code></td>\n<td>string (ISO 8601 datetime)</td>\n<td><code>null</code> until <code>status</code> is <code>Completed</code>.</td>\n</tr>\n<tr>\n<td><code>data.items[].errorDetails</code></td>\n<td>string</td>\n<td>Exactly <code>\"The order could not be completed.\"</code> whenever <code>status</code> is <code>Failed</code>; <code>null</code> otherwise.</td>\n</tr>\n<tr>\n<td><code>data.count</code></td>\n<td>int</td>\n<td>Number of items on this page.</td>\n</tr>\n<tr>\n<td><code>data.page</code></td>\n<td>int</td>\n<td>The page number returned.</td>\n</tr>\n<tr>\n<td><code>data.pageSize</code></td>\n<td>int</td>\n<td>Items per page requested.</td>\n</tr>\n<tr>\n<td><code>data.totalPages</code></td>\n<td>int</td>\n<td>Total pages across all matching transactions.</td>\n</tr>\n<tr>\n<td><code>data.totalItems</code></td>\n<td>int</td>\n<td>Total matching transactions across all pages.</td>\n</tr>\n</tbody>\n</table>\n</div>","urlObject":{"path":["api","v0","giftcards","transactions"],"host":["https://eservices.hoicom.net"],"query":[{"key":"transactionIds","value":""},{"key":"externalReferences","value":""},{"key":"productIds","value":""},{"description":{"content":"<p>Enum name, e.g. Completed.</p>\n","type":"text/plain"},"key":"statuses","value":"Completed"},{"key":"fromDate","value":""},{"key":"toDate","value":""},{"key":"page","value":"1"},{"key":"pageSize","value":"50"}],"variable":[]}},"response":[{"id":"3c0c300b-a573-4550-beaf-bf7359956d6b","name":"OK","originalRequest":{"method":"GET","header":[],"url":{"raw":"https://eservices.hoicom.net/api/v0/giftcards/transactions?transactionIds=&externalReferences=&productIds=&statuses=Completed&fromDate=&toDate=&page=1&pageSize=50","host":["https://eservices.hoicom.net"],"path":["api","v0","giftcards","transactions"],"query":[{"key":"transactionIds","value":""},{"key":"externalReferences","value":""},{"key":"productIds","value":""},{"key":"statuses","value":"Completed","description":"Enum name, e.g. Completed."},{"key":"fromDate","value":""},{"key":"toDate","value":""},{"key":"page","value":"1"},{"key":"pageSize","value":"50"}]},"description":"Returns a paginated, filterable list of your gift-card transactions.\n\n---\n\n## Authorization\n\nRequires Basic Authentication with your client credentials. Your account must be enabled for the Gift Cards service.\n\n---\n\n## Query Parameters\n\n| Parameter | Type | Required | Default | Description |\n| --- | --- | --- | --- | --- |\n| `transactionIds` | `string[]` | No | — | Filter by transaction id(s). |\n| `externalReferences` | `string[]` | No | — | Filter by your external reference(s). |\n| `productIds` | `int[]` | No | — | Filter by product id(s). |\n| `statuses` | `string[]` | No | — | Filter by status (e.g. `Completed`). |\n| `fromDate` | `datetime` | No | — | Created on/after. |\n| `toDate` | `datetime` | No | — | Created on/before. |\n| `page` | `int` | No | `1` | Page number. |\n| `pageSize` | `int` | No | `50` | Items per page (max 100). |\n\n---\n\n## Response\n\nOn success `code` is `1000` and `data` is a paginated list of transactions. Valid `status` values: `Submitted`, `Pending`, `Completed`, `Failed`, `Cancelled`, `Refunded`. `errorDetails` is set only on `Failed` transactions.\n\n---\n\n## Response fields\n\n| Field | Type | Description |\n| --- | --- | --- |\n| `code` | int | Response status code; `1000` means success. |\n| `message` | string | Human-readable status message. |\n| `data` | object | The paginated result envelope. |\n| `data.items` | array | The page of matching transactions. |\n| `data.items[].transactionId` | string | The transaction's id. |\n| `data.items[].externalReference` | string | Your idempotency key, echoed back. |\n| `data.items[].productId` | int | The ordered product's id. |\n| `data.items[].status` | string (values: `Submitted` \\| `Pending` \\| `Completed` \\| `Failed` \\| `Cancelled` \\| `Refunded`) | The transaction's current state (see Reference values). |\n| `data.items[].denomination.type` | string (value: `FIXED`) | Always `FIXED` on a placed transaction — it reflects the one concrete value ordered, not the original product's `FIXED`/`RANGE`/`OPEN` kind. |\n| `data.items[].denomination.currency` | string | The card's destination currency. |\n| `data.items[].denomination.value` | decimal | The concrete ordered face value. |\n| `data.items[].denomination.min` | decimal | Always `null` on a placed transaction. |\n| `data.items[].denomination.max` | decimal | Always `null` on a placed transaction. |\n| `data.items[].denomination.increment` | decimal | Always `null` on a placed transaction. |\n| `data.items[].amountCurrency` | string (values: `LOCAL` \\| `DESTINATION`) | `null` for a `FIXED` product; otherwise the currency the order amount was expressed in. |\n| `data.items[].price` | object | The price of this order as recorded when you placed it; it does not change if the product's price changes later. |\n| `data.items[].price.currency` | string | Billing currency — always `\"SAR\"`. |\n| `data.items[].price.wholesale` | decimal | What you were billed (SAR) for this order. |\n| `data.items[].price.retail` | decimal | The recommended end-customer price recorded for this order. You were billed `price.wholesale`, not this amount. |\n| `data.items[].price.discount` | object | `null` unless this order was priced in `DISCOUNT` mode. |\n| `data.items[].price.discount.percent` | decimal | `(retail − wholesale) ÷ retail × 100`, as a percentage. |\n| `data.items[].price.discount.value` | decimal | `retail − wholesale` in SAR; `null` for a `RANGE`/`OPEN` order. |\n| `data.items[].delivery` | object | `null` unless `status` is `Completed`. |\n| `data.items[].delivery.format` | string (values: `PIN` \\| `REDEMPTION_URL` \\| `QR_CODE` \\| `DIRECT_CREDIT`) | How the card was delivered (see Reference values). |\n| `data.items[].delivery.code` | string | `null` unless the delivery format is `PIN` and a claim code applies. |\n| `data.items[].delivery.pin` | string | `null` unless the delivery format is `PIN`. |\n| `data.items[].delivery.cardNumber` | string | `null` unless the delivery format is `PIN` and a card number applies. |\n| `data.items[].delivery.serial` | string | `null` unless the delivery format is `PIN` and a serial applies. |\n| `data.items[].delivery.redemptionUrl` | string | `null` unless the delivery format is `REDEMPTION_URL`. |\n| `data.items[].delivery.qrCode` | string | `null` unless the delivery format is `QR_CODE`. |\n| `data.items[].delivery.instructions` | string | Redemption instructions; `null` if none provided. |\n| `data.items[].createdAt` | string (ISO 8601 datetime) | When the transaction was created. |\n| `data.items[].completedAt` | string (ISO 8601 datetime) | `null` until `status` is `Completed`. |\n| `data.items[].errorDetails` | string | Exactly `\"The order could not be completed.\"` whenever `status` is `Failed`; `null` otherwise. |\n| `data.count` | int | Number of items on this page. |\n| `data.page` | int | The page number returned. |\n| `data.pageSize` | int | Items per page requested. |\n| `data.totalPages` | int | Total pages across all matching transactions. |\n| `data.totalItems` | int | Total matching transactions across all pages. |\n"},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"cookie":[],"responseTime":null,"body":"{\n  \"code\": 1000,\n  \"message\": \"Success\",\n  \"data\": {\n    \"items\": [\n      {\n        \"transactionId\": \"gc_txn_20260701_00123\",\n        \"externalReference\": \"client-ref-5001\",\n        \"productId\": 456,\n        \"status\": \"Completed\",\n        \"denomination\": {\n          \"type\": \"FIXED\",\n          \"currency\": \"USD\",\n          \"value\": 10,\n          \"min\": null,\n          \"max\": null,\n          \"increment\": null\n        },\n        \"amountCurrency\": null,\n        \"price\": {\n          \"currency\": \"SAR\",\n          \"wholesale\": 37.5,\n          \"retail\": 45,\n          \"discount\": null\n        },\n        \"delivery\": {\n          \"format\": \"PIN\",\n          \"pin\": \"5678\",\n          \"cardNumber\": null,\n          \"serial\": \"ITUNES-USA-001122\",\n          \"redemptionUrl\": null,\n          \"qrCode\": null,\n          \"instructions\": \"Redeem at itunes.com/redeem.\"\n        },\n        \"createdAt\": \"2026-07-01T14:30:00Z\",\n        \"completedAt\": \"2026-07-01T14:31:20Z\",\n        \"errorDetails\": null\n      }\n    ],\n    \"count\": 1,\n    \"page\": 1,\n    \"pageSize\": 50,\n    \"totalPages\": 1,\n    \"totalItems\": 1\n  }\n}"},{"id":"8a66bce7-f019-4f99-a980-0139962e02ae","name":"Failed","originalRequest":{"method":"GET","header":[],"url":{"raw":"https://eservices.hoicom.net/api/v0/giftcards/transactions?transactionIds=&externalReferences=&productIds=&statuses=Completed&fromDate=&toDate=&page=1&pageSize=50","host":["https://eservices.hoicom.net"],"path":["api","v0","giftcards","transactions"],"query":[{"key":"transactionIds","value":""},{"key":"externalReferences","value":""},{"key":"productIds","value":""},{"key":"statuses","value":"Completed","description":"Enum name, e.g. Completed."},{"key":"fromDate","value":""},{"key":"toDate","value":""},{"key":"page","value":"1"},{"key":"pageSize","value":"50"}]},"description":"Returns a paginated, filterable list of your gift-card transactions.\n\n---\n\n## Authorization\n\nRequires Basic Authentication with your client credentials. Your account must be enabled for the Gift Cards service.\n\n---\n\n## Query Parameters\n\n| Parameter | Type | Required | Default | Description |\n| --- | --- | --- | --- | --- |\n| `transactionIds` | `string[]` | No | — | Filter by transaction id(s). |\n| `externalReferences` | `string[]` | No | — | Filter by your external reference(s). |\n| `productIds` | `int[]` | No | — | Filter by product id(s). |\n| `statuses` | `string[]` | No | — | Filter by status (e.g. `Completed`). |\n| `fromDate` | `datetime` | No | — | Created on/after. |\n| `toDate` | `datetime` | No | — | Created on/before. |\n| `page` | `int` | No | `1` | Page number. |\n| `pageSize` | `int` | No | `50` | Items per page (max 100). |\n\n---\n\n## Response\n\nOn success `code` is `1000` and `data` is a paginated list of transactions. Valid `status` values: `Submitted`, `Pending`, `Completed`, `Failed`, `Cancelled`, `Refunded`. `errorDetails` is set only on `Failed` transactions.\n\n---\n\n## Response fields\n\n| Field | Type | Description |\n| --- | --- | --- |\n| `code` | int | Response status code; `1000` means success. |\n| `message` | string | Human-readable status message. |\n| `data` | object | The paginated result envelope. |\n| `data.items` | array | The page of matching transactions. |\n| `data.items[].transactionId` | string | The transaction's id. |\n| `data.items[].externalReference` | string | Your idempotency key, echoed back. |\n| `data.items[].productId` | int | The ordered product's id. |\n| `data.items[].status` | string (values: `Submitted` \\| `Pending` \\| `Completed` \\| `Failed` \\| `Cancelled` \\| `Refunded`) | The transaction's current state (see Reference values). |\n| `data.items[].denomination.type` | string (value: `FIXED`) | Always `FIXED` on a placed transaction — it reflects the one concrete value ordered, not the original product's `FIXED`/`RANGE`/`OPEN` kind. |\n| `data.items[].denomination.currency` | string | The card's destination currency. |\n| `data.items[].denomination.value` | decimal | The concrete ordered face value. |\n| `data.items[].denomination.min` | decimal | Always `null` on a placed transaction. |\n| `data.items[].denomination.max` | decimal | Always `null` on a placed transaction. |\n| `data.items[].denomination.increment` | decimal | Always `null` on a placed transaction. |\n| `data.items[].amountCurrency` | string (values: `LOCAL` \\| `DESTINATION`) | `null` for a `FIXED` product; otherwise the currency the order amount was expressed in. |\n| `data.items[].price` | object | The price of this order as recorded when you placed it; it does not change if the product's price changes later. |\n| `data.items[].price.currency` | string | Billing currency — always `\"SAR\"`. |\n| `data.items[].price.wholesale` | decimal | What you were billed (SAR) for this order. |\n| `data.items[].price.retail` | decimal | The recommended end-customer price recorded for this order. You were billed `price.wholesale`, not this amount. |\n| `data.items[].price.discount` | object | `null` unless this order was priced in `DISCOUNT` mode. |\n| `data.items[].price.discount.percent` | decimal | `(retail − wholesale) ÷ retail × 100`, as a percentage. |\n| `data.items[].price.discount.value` | decimal | `retail − wholesale` in SAR; `null` for a `RANGE`/`OPEN` order. |\n| `data.items[].delivery` | object | `null` unless `status` is `Completed`. |\n| `data.items[].delivery.format` | string (values: `PIN` \\| `REDEMPTION_URL` \\| `QR_CODE` \\| `DIRECT_CREDIT`) | How the card was delivered (see Reference values). |\n| `data.items[].delivery.code` | string | `null` unless the delivery format is `PIN` and a claim code applies. |\n| `data.items[].delivery.pin` | string | `null` unless the delivery format is `PIN`. |\n| `data.items[].delivery.cardNumber` | string | `null` unless the delivery format is `PIN` and a card number applies. |\n| `data.items[].delivery.serial` | string | `null` unless the delivery format is `PIN` and a serial applies. |\n| `data.items[].delivery.redemptionUrl` | string | `null` unless the delivery format is `REDEMPTION_URL`. |\n| `data.items[].delivery.qrCode` | string | `null` unless the delivery format is `QR_CODE`. |\n| `data.items[].delivery.instructions` | string | Redemption instructions; `null` if none provided. |\n| `data.items[].createdAt` | string (ISO 8601 datetime) | When the transaction was created. |\n| `data.items[].completedAt` | string (ISO 8601 datetime) | `null` until `status` is `Completed`. |\n| `data.items[].errorDetails` | string | Exactly `\"The order could not be completed.\"` whenever `status` is `Failed`; `null` otherwise. |\n| `data.count` | int | Number of items on this page. |\n| `data.page` | int | The page number returned. |\n| `data.pageSize` | int | Items per page requested. |\n| `data.totalPages` | int | Total pages across all matching transactions. |\n| `data.totalItems` | int | Total matching transactions across all pages. |\n"},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"cookie":[],"responseTime":null,"body":"{\n  \"code\": 1000,\n  \"message\": \"Success\",\n  \"data\": {\n    \"items\": [\n      {\n        \"transactionId\": \"gc_txn_20260701_00123\",\n        \"externalReference\": \"client-ref-5001\",\n        \"productId\": 456,\n        \"status\": \"Failed\",\n        \"denomination\": {\n          \"type\": \"FIXED\",\n          \"currency\": \"USD\",\n          \"value\": 10,\n          \"min\": null,\n          \"max\": null,\n          \"increment\": null\n        },\n        \"amountCurrency\": null,\n        \"price\": {\n          \"currency\": \"SAR\",\n          \"wholesale\": 37.5,\n          \"retail\": 45,\n          \"discount\": null\n        },\n        \"delivery\": null,\n        \"createdAt\": \"2026-07-01T14:30:00Z\",\n        \"completedAt\": null,\n        \"errorDetails\": \"The order could not be completed.\"\n      }\n    ],\n    \"count\": 1,\n    \"page\": 1,\n    \"pageSize\": 50,\n    \"totalPages\": 1,\n    \"totalItems\": 1\n  }\n}"}],"_postman_id":"41279ef4-9e17-4d14-b1ff-a128b121af62"}],"id":"b9f2673c-e2df-4de6-a35d-7c3c87d62f8a","description":"<p>The <strong>Gift Cards</strong> service sells digital gift cards (retail, gaming, entertainment, and more) — browse brands and their priced products, order a card, and retrieve the delivered redemption artifact (PIN, redemption URL, or QR code).</p>\n<hr />\n<h2 id=\"client-flow\">Client Flow</h2>\n<ol>\n<li><strong>Browse brands</strong> — <code>GET /brands</code> (filter by category / country / search).</li>\n<li><strong>Browse products</strong> — <code>GET /products?brandIds={id}&amp;includeContent=true&amp;includeInputFields=true</code>. Check <code>denomination</code> (FIXED vs RANGE/OPEN), <code>pricing.wholesale</code> (your price — what you are billed) / <code>pricing.retail</code> (the recommended end-customer price), and the required <code>transactionInputFields</code>.</li>\n<li><strong>Order</strong> — <code>POST /transactions/async</code> with the product id and required inputs; returns a <code>transactionId</code>.</li>\n<li><strong>Retrieve card</strong> — poll <code>GET /transactions/{id}</code> until <code>status</code> is <code>Completed</code>; the <code>delivery</code> block then carries the PIN / redemption URL / QR.</li>\n<li><strong>History</strong> — <code>GET /transactions</code> (filter by reference, product, status, date).</li>\n</ol>\n<p>Orders are <strong>idempotent</strong> on <code>externalReference</code>, which must be unique within your account across all your services (a repeat on Gift Cards returns code <code>1407</code>). Prices are always in <strong>SAR</strong>.</p>\n<hr />\n<h2 id=\"reference-values\">Reference values</h2>\n<h3 id=\"transaction-status-status\">Transaction status (<code>status</code>)</h3>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Value</th>\n<th>Meaning</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>Submitted</code></td>\n<td>Received and queued.</td>\n</tr>\n<tr>\n<td><code>Pending</code></td>\n<td>Being processed / fulfilled.</td>\n</tr>\n<tr>\n<td><code>Completed</code></td>\n<td>Delivered; <code>delivery</code> is populated.</td>\n</tr>\n<tr>\n<td><code>Failed</code></td>\n<td>Failed; see <code>errorDetails</code>.</td>\n</tr>\n<tr>\n<td><code>Cancelled</code></td>\n<td>Cancelled before completion.</td>\n</tr>\n<tr>\n<td><code>Refunded</code></td>\n<td>Refunded after completion (the original <code>delivery</code> artifact is left in place for your records).</td>\n</tr>\n</tbody>\n</table>\n</div><h3 id=\"category-category\">Category (<code>category</code>)</h3>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Value</th>\n<th>Meaning</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>RETAIL</code></td>\n<td>General retail / shopping.</td>\n</tr>\n<tr>\n<td><code>GAMING</code></td>\n<td>Games and gaming platforms.</td>\n</tr>\n<tr>\n<td><code>CASH_CARDS</code></td>\n<td>Open-loop / prepaid cash.</td>\n</tr>\n<tr>\n<td><code>FOOD</code></td>\n<td>Food, restaurants, delivery.</td>\n</tr>\n<tr>\n<td><code>ENTERTAINMENT</code></td>\n<td>Streaming, music, video.</td>\n</tr>\n<tr>\n<td><code>TRAVEL_TRANSPORT</code></td>\n<td>Travel, transport, fuel.</td>\n</tr>\n<tr>\n<td><code>OTHER</code></td>\n<td>Uncategorized.</td>\n</tr>\n</tbody>\n</table>\n</div><h3 id=\"denomination-type-denominationtype\">Denomination type (<code>denomination.type</code>)</h3>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Value</th>\n<th>Meaning</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>FIXED</code></td>\n<td>A single preset value.</td>\n</tr>\n<tr>\n<td><code>RANGE</code></td>\n<td>Any value between <code>min</code> and <code>max</code>, stepped by <code>increment</code>.</td>\n</tr>\n<tr>\n<td><code>OPEN</code></td>\n<td>Any value, no bounds.</td>\n</tr>\n</tbody>\n</table>\n</div><h3 id=\"delivery-format-deliveryformat--deliveryformat\">Delivery format (<code>deliveryFormat</code> / <code>delivery.format</code>)</h3>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Value</th>\n<th>Meaning</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>PIN</code></td>\n<td>PIN / code (plus optional card number / serial).</td>\n</tr>\n<tr>\n<td><code>REDEMPTION_URL</code></td>\n<td>A hosted redemption URL.</td>\n</tr>\n<tr>\n<td><code>QR_CODE</code></td>\n<td>A scannable QR code.</td>\n</tr>\n<tr>\n<td><code>DIRECT_CREDIT</code></td>\n<td>Credited directly to an account (no artifact).</td>\n</tr>\n</tbody>\n</table>\n</div><h3 id=\"order-amount-currency-amountcurrency\">Order amount currency (<code>amountCurrency</code>)</h3>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Value</th>\n<th>Meaning</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>LOCAL</code></td>\n<td>The amount is in SAR.</td>\n</tr>\n<tr>\n<td><code>DESTINATION</code></td>\n<td>The amount is in the card's currency.</td>\n</tr>\n</tbody>\n</table>\n</div><p><strong>Worked example</strong> — a RANGE product with <code>denomination.min = 5</code>, <code>denomination.max = 100</code> (USD) and a price rate of 3.75 SAR per 1 USD: ordering with <code>amountCurrency: \"DESTINATION\"</code> and <code>amount: 20</code> gets you a 20 USD card and bills 75 SAR; ordering with <code>amountCurrency: \"LOCAL\"</code> and <code>amount: 75</code> bills 75 SAR and gets you the same 20 USD card (75 ÷ 3.75). <code>amountCurrency</code> is always <code>null</code> for <code>FIXED</code> products — their amount and price are preset, so no currency choice applies.</p>\n<h3 id=\"pricing-mode-pricingmode\">Pricing mode (<code>pricing.mode</code>)</h3>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Value</th>\n<th>Meaning</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>WHOLESALE</code></td>\n<td>You are billed <code>pricing.wholesale</code>. <code>pricing.retail</code> is only a <strong>suggested</strong> end-customer price (it may be <code>null</code>) — you're free to sell at whatever price you choose. <code>pricing.discount</code> is <code>null</code>.</td>\n</tr>\n<tr>\n<td><code>DISCOUNT</code></td>\n<td>You are billed <code>pricing.wholesale</code>. <code>pricing.retail</code> is the recommended end-customer price, and <code>pricing.discount</code> shows how far your price sits below it: <code>discount.value</code> = retail − your price (<code>FIXED</code> products only; <code>null</code> for <code>RANGE</code>/<code>OPEN</code>) and <code>discount.percent</code> = that amount ÷ retail × 100.</td>\n</tr>\n</tbody>\n</table>\n</div><p>In both modes <strong>you are always billed <code>pricing.wholesale</code></strong> — never <code>pricing.retail</code>.</p>\n<h3 id=\"input-field-type-transactioninputfieldstype\">Input field type (<code>transactionInputFields[].type</code>)</h3>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Value</th>\n<th>Meaning</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>TEXT</code></td>\n<td>Free text.</td>\n</tr>\n<tr>\n<td><code>EMAIL</code></td>\n<td>Email address.</td>\n</tr>\n<tr>\n<td><code>PHONE_NUMBER</code></td>\n<td>Phone number.</td>\n</tr>\n<tr>\n<td><code>NUMBER</code></td>\n<td>Numeric value.</td>\n</tr>\n<tr>\n<td><code>DATE</code></td>\n<td>Date.</td>\n</tr>\n<tr>\n<td><code>SELECT</code></td>\n<td>One of <code>validation.allowedValues</code>.</td>\n</tr>\n</tbody>\n</table>\n</div><h3 id=\"image-type-contentimagestype\">Image type (<code>content.images[].type</code>)</h3>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Value</th>\n<th>Meaning</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>LOGO</code></td>\n<td>Brand logo.</td>\n</tr>\n<tr>\n<td><code>PROVIDER_LOGO</code></td>\n<td>Provider logo.</td>\n</tr>\n<tr>\n<td><code>CARD</code></td>\n<td>Card artwork.</td>\n</tr>\n<tr>\n<td><code>ARTICLE</code></td>\n<td>Article / promo image.</td>\n</tr>\n<tr>\n<td><code>THUMBNAIL</code></td>\n<td>Thumbnail.</td>\n</tr>\n</tbody>\n</table>\n</div><h3 id=\"language-lang-request-parameter\">Language (<code>lang</code> request parameter)</h3>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Value</th>\n<th>Meaning</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>English</code></td>\n<td>English display text.</td>\n</tr>\n<tr>\n<td><code>Arabic</code></td>\n<td>Arabic display text.</td>\n</tr>\n</tbody>\n</table>\n</div><hr />\n<h2 id=\"identifiers\">Identifiers</h2>\n<p>Each brand and product is identified by its <code>id</code> — that's the value the API accepts: pass a product's <code>id</code> as <code>productId</code> when ordering, and a brand's <code>id</code> in <code>products?brandIds=</code>.</p>\n","_postman_id":"b9f2673c-e2df-4de6-a35d-7c3c87d62f8a"},{"name":"Gifts","item":[{"name":"Get Locations","id":"c86834cb-b8ba-4ab0-8f2f-8f81fe5552f7","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"GET","header":[],"url":"https://eservices.hoicom.net/api/v0/gifts/locations?page=1&pageSize=50","description":"<p>Returns the locations available for gift delivery, each with its associated <strong>fulfillment centers</strong>. A fulfillment center is the hub that prepares and dispatches orders for a delivery area — you use its <code>fulfillmentCenterId</code> to filter products and to check delivery time slots.</p>\n<p>This is typically the <strong>first call</strong> in the gift ordering journey.</p>\n<hr />\n<h2 id=\"authorization\">Authorization</h2>\n<p>Requires Basic Authentication with your client credentials. Your account must be enabled for the Gifts service.</p>\n<hr />\n<h2 id=\"query-parameters\">Query Parameters</h2>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Parameter</th>\n<th>Type</th>\n<th>Required</th>\n<th>Default</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>page</code></td>\n<td><code>int</code></td>\n<td>No</td>\n<td><code>1</code></td>\n<td>Page number for pagination.</td>\n</tr>\n<tr>\n<td><code>pageSize</code></td>\n<td><code>int</code></td>\n<td>No</td>\n<td><code>50</code></td>\n<td>Number of items per page.</td>\n</tr>\n</tbody>\n</table>\n</div><hr />\n<h2 id=\"response\">Response</h2>\n<p>On success <code>code</code> is <code>1000</code> and <code>data</code> holds a paginated list of countries, their cities, and each city's fulfillment centers. See the example below.</p>\n<hr />\n<h2 id=\"identifiers-returned-here\">Identifiers returned here</h2>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Value</th>\n<th>Used as</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>cities[].id</code></td>\n<td><code>cityId</code> on <strong>Get Products</strong> and <strong>Check Availability</strong>.</td>\n</tr>\n<tr>\n<td><code>cities[].fulfillmentCenters[].id</code></td>\n<td><code>fulfillmentCenterId</code> on <strong>Get Products</strong>, <strong>Check Availability</strong>, <strong>Get Delivery Time Slots</strong>, and as <code>recipient.fulfillmentCenterId</code> on <strong>Create Order</strong>.</td>\n</tr>\n</tbody>\n</table>\n</div><p>Only countries your account is entitled to, and only cities with at least one active fulfillment center, are returned.</p>\n<hr />\n<h2 id=\"response-fields\">Response fields</h2>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Field</th>\n<th>Type</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>code</td>\n<td>int</td>\n<td>Response status code. <code>1000</code> on success.</td>\n</tr>\n<tr>\n<td>message</td>\n<td>string</td>\n<td>Human-readable status message.</td>\n</tr>\n<tr>\n<td>data</td>\n<td>object</td>\n<td>Paginated list of countries and their fulfillment locations.</td>\n</tr>\n<tr>\n<td>data.items</td>\n<td>array</td>\n<td>One entry per country your account is entitled to that has at least one active fulfillment center.</td>\n</tr>\n<tr>\n<td>data.items[].name</td>\n<td>string</td>\n<td>Country display name.</td>\n</tr>\n<tr>\n<td>data.items[].isoCode</td>\n<td>string</td>\n<td>2-letter ISO country code.</td>\n</tr>\n<tr>\n<td>data.items[].cities</td>\n<td>array</td>\n<td>Cities in this country with at least one active fulfillment center.</td>\n</tr>\n<tr>\n<td>data.items[].cities[].id</td>\n<td>int</td>\n<td>City id. Use as <code>cityId</code> on Get Products and Check Availability.</td>\n</tr>\n<tr>\n<td>data.items[].cities[].name</td>\n<td>string</td>\n<td>City display name.</td>\n</tr>\n<tr>\n<td>data.items[].cities[].fulfillmentCenters</td>\n<td>array</td>\n<td>Fulfillment centers serving this city.</td>\n</tr>\n<tr>\n<td>data.items[].cities[].fulfillmentCenters[].id</td>\n<td>string</td>\n<td>Fulfillment center id. Use as <code>fulfillmentCenterId</code> on Get Products, Check Availability, Get Delivery Time Slots, and as <code>recipient.fulfillmentCenterId</code> on Create Order.</td>\n</tr>\n<tr>\n<td>data.items[].cities[].fulfillmentCenters[].name</td>\n<td>string</td>\n<td>Fulfillment center display name.</td>\n</tr>\n<tr>\n<td>data.count</td>\n<td>int</td>\n<td>Number of country items on this page.</td>\n</tr>\n<tr>\n<td>data.page</td>\n<td>int</td>\n<td>Current page number.</td>\n</tr>\n<tr>\n<td>data.pageSize</td>\n<td>int</td>\n<td>Requested page size.</td>\n</tr>\n<tr>\n<td>data.totalPages</td>\n<td>int</td>\n<td>Total number of pages available.</td>\n</tr>\n<tr>\n<td>data.totalItems</td>\n<td>int</td>\n<td>Total number of country items across all pages.</td>\n</tr>\n</tbody>\n</table>\n</div>","urlObject":{"path":["api","v0","gifts","locations"],"host":["https://eservices.hoicom.net"],"query":[{"description":{"content":"<p>Page number for pagination (default: 1).</p>\n","type":"text/plain"},"key":"page","value":"1"},{"description":{"content":"<p>Number of items per page (default: 50).</p>\n","type":"text/plain"},"key":"pageSize","value":"50"}],"variable":[]}},"response":[{"id":"ea570931-8d92-4c16-8155-5fa4e44e6d9e","name":"OK","originalRequest":{"method":"GET","header":[],"url":{"raw":"https://eservices.hoicom.net/api/v0/gifts/locations?page=1&pageSize=50","host":["https://eservices.hoicom.net"],"path":["api","v0","gifts","locations"],"query":[{"key":"page","value":"1","description":"Page number for pagination (default: 1)."},{"key":"pageSize","value":"50","description":"Number of items per page (default: 50)."}]},"description":"Returns the locations available for gift delivery, each with its associated **fulfillment centers**. A fulfillment center is the hub that prepares and dispatches orders for a delivery area — you use its `fulfillmentCenterId` to filter products and to check delivery time slots.\n\nThis is typically the **first call** in the gift ordering journey.\n\n---\n\n## Authorization\n\nRequires Basic Authentication with your client credentials. Your account must be enabled for the Gifts service.\n\n---\n\n## Query Parameters\n\n| Parameter | Type | Required | Default | Description |\n| --- | --- | --- | --- | --- |\n| `page` | `int` | No | `1` | Page number for pagination. |\n| `pageSize` | `int` | No | `50` | Number of items per page. |\n\n---\n\n## Response\n\nOn success `code` is `1000` and `data` holds a paginated list of countries, their cities, and each city's fulfillment centers. See the example below.\n\n---\n\n## Identifiers returned here\n\n| Value | Used as |\n| --- | --- |\n| `cities[].id` | `cityId` on **Get Products** and **Check Availability**. |\n| `cities[].fulfillmentCenters[].id` | `fulfillmentCenterId` on **Get Products**, **Check Availability**, **Get Delivery Time Slots**, and as `recipient.fulfillmentCenterId` on **Create Order**. |\n\nOnly countries your account is entitled to, and only cities with at least one active fulfillment center, are returned."},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"cookie":[],"responseTime":null,"body":"{\n  \"code\": 1000,\n  \"message\": \"Success\",\n  \"data\": {\n    \"items\": [\n      {\n        \"name\": \"Saudi Arabia\",\n        \"isoCode\": \"SA\",\n        \"cities\": [\n          {\n            \"id\": 2,\n            \"name\": \"Riyadh\",\n            \"fulfillmentCenters\": [\n              {\n                \"id\": \"fc_riyadh_01\",\n                \"name\": \"Riyadh Central\"\n              },\n              {\n                \"id\": \"fc_riyadh_02\",\n                \"name\": \"Riyadh North\"\n              }\n            ]\n          }\n        ]\n      }\n    ],\n    \"count\": 1,\n    \"page\": 1,\n    \"pageSize\": 50,\n    \"totalPages\": 1,\n    \"totalItems\": 1\n  }\n}"},{"id":"36671adf-cac2-4856-b2a0-f1a680631fc8","name":"Internal Server Error","originalRequest":{"method":"GET","header":[],"url":{"raw":"https://eservices.hoicom.net/api/v0/gifts/locations?page=1&pageSize=50","host":["https://eservices.hoicom.net"],"path":["api","v0","gifts","locations"],"query":[{"key":"page","value":"1","description":"Page number for pagination (default: 1)."},{"key":"pageSize","value":"50","description":"Number of items per page (default: 50)."}]},"description":"Returns the locations available for gift delivery, each with its associated **fulfillment centers**. A fulfillment center is the hub that prepares and dispatches orders for a delivery area — you use its `fulfillmentCenterId` to filter products and to check delivery time slots.\n\nThis is typically the **first call** in the gift ordering journey.\n\n---\n\n## Authorization\n\nRequires Basic Authentication with your client credentials. Your account must be enabled for the Gifts service.\n\n---\n\n## Query Parameters\n\n| Parameter | Type | Required | Default | Description |\n| --- | --- | --- | --- | --- |\n| `page` | `int` | No | `1` | Page number for pagination. |\n| `pageSize` | `int` | No | `50` | Number of items per page. |\n\n---\n\n## Response\n\nOn success `code` is `1000` and `data` holds a paginated list of countries, their cities, and each city's fulfillment centers. See the example below.\n\n---\n\n## Identifiers returned here\n\n| Value | Used as |\n| --- | --- |\n| `cities[].id` | `cityId` on **Get Products** and **Check Availability**. |\n| `cities[].fulfillmentCenters[].id` | `fulfillmentCenterId` on **Get Products**, **Check Availability**, **Get Delivery Time Slots**, and as `recipient.fulfillmentCenterId` on **Create Order**. |\n\nOnly countries your account is entitled to, and only cities with at least one active fulfillment center, are returned."},"status":"Internal Server Error","code":500,"_postman_previewlanguage":"text","header":[],"cookie":[],"responseTime":null,"body":""},{"id":"e00ba23b-6147-4667-8efb-9265a8555317","name":"Service Unavailable","originalRequest":{"method":"GET","header":[],"url":{"raw":"https://eservices.hoicom.net/api/v0/gifts/locations?page=1&pageSize=50","host":["https://eservices.hoicom.net"],"path":["api","v0","gifts","locations"],"query":[{"key":"page","value":"1","description":"Page number for pagination (default: 1)."},{"key":"pageSize","value":"50","description":"Number of items per page (default: 50)."}]},"description":"Returns the locations available for gift delivery, each with its associated **fulfillment centers**. A fulfillment center is the hub that prepares and dispatches orders for a delivery area — you use its `fulfillmentCenterId` to filter products and to check delivery time slots.\n\nThis is typically the **first call** in the gift ordering journey.\n\n---\n\n## Authorization\n\nRequires Basic Authentication with your client credentials. Your account must be enabled for the Gifts service.\n\n---\n\n## Query Parameters\n\n| Parameter | Type | Required | Default | Description |\n| --- | --- | --- | --- | --- |\n| `page` | `int` | No | `1` | Page number for pagination. |\n| `pageSize` | `int` | No | `50` | Number of items per page. |\n\n---\n\n## Response\n\nOn success `code` is `1000` and `data` holds a paginated list of countries, their cities, and each city's fulfillment centers. See the example below.\n\n---\n\n## Identifiers returned here\n\n| Value | Used as |\n| --- | --- |\n| `cities[].id` | `cityId` on **Get Products** and **Check Availability**. |\n| `cities[].fulfillmentCenters[].id` | `fulfillmentCenterId` on **Get Products**, **Check Availability**, **Get Delivery Time Slots**, and as `recipient.fulfillmentCenterId` on **Create Order**. |\n\nOnly countries your account is entitled to, and only cities with at least one active fulfillment center, are returned."},"status":"Service Unavailable","code":503,"_postman_previewlanguage":"text","header":[],"cookie":[],"responseTime":null,"body":""}],"_postman_id":"c86834cb-b8ba-4ab0-8f2f-8f81fe5552f7"},{"name":"Get Categories","id":"865547d1-d185-46f3-97d3-15b406de46d8","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"GET","header":[],"url":"https://eservices.hoicom.net/api/v0/gifts/categories?page=1&pageSize=50","description":"<p>Returns the gift <strong>category tree</strong> — the taxonomy you can browse and filter products by.</p>\n<p>Use it to build a category navigation, then pass a category's <code>id</code> to <strong>Get Products</strong> as <code>categoryId</code>.</p>\n<hr />\n<h2 id=\"authorization\">Authorization</h2>\n<p>Requires Basic Authentication with your client credentials. Your account must be enabled for the Gifts service.</p>\n<hr />\n<h2 id=\"query-parameters\">Query Parameters</h2>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Parameter</th>\n<th>Type</th>\n<th>Required</th>\n<th>Default</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>cityId</code></td>\n<td><code>int</code></td>\n<td>No</td>\n<td>—</td>\n<td>Limit to categories with products purchasable in this city.</td>\n</tr>\n<tr>\n<td><code>fulfillmentCenterId</code></td>\n<td><code>string</code></td>\n<td>No</td>\n<td>—</td>\n<td>Limit to categories with products purchasable at this center.</td>\n</tr>\n<tr>\n<td><code>lang</code></td>\n<td><code>string</code></td>\n<td>No</td>\n<td><code>ar</code></td>\n<td><code>ar</code> or <code>en</code>. Falls back to English where an Arabic name is missing.</td>\n</tr>\n<tr>\n<td><code>page</code></td>\n<td><code>int</code></td>\n<td>No</td>\n<td><code>1</code></td>\n<td>Page number — applies to <strong>root</strong> categories only.</td>\n</tr>\n<tr>\n<td><code>pageSize</code></td>\n<td><code>int</code></td>\n<td>No</td>\n<td><code>50</code></td>\n<td>Root categories per page.</td>\n</tr>\n</tbody>\n</table>\n</div><p><code>cityId</code> and <code>fulfillmentCenterId</code> are alternatives. If you send both, <strong><code>fulfillmentCenterId</code> wins and <code>cityId</code> is ignored</strong> — this is not an error.</p>\n<hr />\n<h2 id=\"response\">Response</h2>\n<p><code>code</code> is <code>1000</code> and <code>data</code> holds a paginated tree.</p>\n<ul>\n<li><strong>Pagination applies to root categories only.</strong> A root category always arrives with its complete <code>children</code>, however deep — paging can never cut a subtree in half.</li>\n<li><code>children</code> is always present. Leaves carry <code>[]</code>, never <code>null</code> and never an omitted key.</li>\n<li>If the scope resolves to nothing, you get <code>200</code> with an empty <code>items</code> array — not a <code>404</code>.</li>\n</ul>\n<hr />\n<h2 id=\"things-worth-knowing-before-you-integrate\">Things worth knowing before you integrate</h2>\n<p><strong>This is not the partner's full taxonomy.</strong> Categories reach us attached to products, so a category appears only once we have received a product carrying it.</p>\n<p><strong>A category whose parent has no products of its own appears at the root</strong> rather than nested under that parent, because we never invent a parent we have no name for.</p>\n<p><strong>Key on <code>id</code>, never on <code>name</code>.</strong> The same category id can briefly show a different name here than on a product, while the partner's rename works its way through the catalogue. Ids always agree.</p>\n<p><strong>Sort order is ordinal</strong>, not human-alphabetical: <code>\"Zebra\"</code> sorts before <code>\"apple\"</code>, and Arabic and English orderings differ. It is stable and deterministic, just not what a phone book would do.</p>\n<hr />\n<h2 id=\"response-fields\">Response fields</h2>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Field</th>\n<th>Type</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>code</td>\n<td>int</td>\n<td>Response status code. <code>1000</code> on success.</td>\n</tr>\n<tr>\n<td>message</td>\n<td>string</td>\n<td>Human-readable status message.</td>\n</tr>\n<tr>\n<td>data</td>\n<td>object</td>\n<td>Paginated category tree.</td>\n</tr>\n<tr>\n<td>data.items</td>\n<td>array</td>\n<td>Root-level categories for this page.</td>\n</tr>\n<tr>\n<td>data.items[].id</td>\n<td>string</td>\n<td>Stable opaque category id. Use as <code>categoryId</code> on Get Products / Get Products by Fulfillment Center.</td>\n</tr>\n<tr>\n<td>data.items[].name</td>\n<td>string</td>\n<td>Category display name, resolved for the request's <code>lang</code>.</td>\n</tr>\n<tr>\n<td>data.items[].children</td>\n<td>array</td>\n<td>Child categories nested under this one, in the same <code>{id, name, children}</code> shape (recursing to any depth). Always present - <code>[]</code> for a leaf category, never omitted or <code>null</code>.</td>\n</tr>\n<tr>\n<td>data.count</td>\n<td>int</td>\n<td>Number of root-category items on this page.</td>\n</tr>\n<tr>\n<td>data.page</td>\n<td>int</td>\n<td>Current page number (root categories only).</td>\n</tr>\n<tr>\n<td>data.pageSize</td>\n<td>int</td>\n<td>Requested page size (root categories only).</td>\n</tr>\n<tr>\n<td>data.totalPages</td>\n<td>int</td>\n<td>Total number of pages of root categories.</td>\n</tr>\n<tr>\n<td>data.totalItems</td>\n<td>int</td>\n<td>Total number of root-category items across all pages.</td>\n</tr>\n</tbody>\n</table>\n</div>","urlObject":{"path":["api","v0","gifts","categories"],"host":["https://eservices.hoicom.net"],"query":[{"disabled":true,"description":{"content":"<p>Optional. Limit to categories purchasable in this city.</p>\n","type":"text/plain"},"key":"cityId","value":""},{"disabled":true,"description":{"content":"<p>Optional. Limit to categories purchasable at this center. Wins over cityId if both are sent.</p>\n","type":"text/plain"},"key":"fulfillmentCenterId","value":""},{"disabled":true,"description":{"content":"<p>Optional. ar (default) or en.</p>\n","type":"text/plain"},"key":"lang","value":""},{"description":{"content":"<p>Page number for root categories (default: 1).</p>\n","type":"text/plain"},"key":"page","value":"1"},{"description":{"content":"<p>Root categories per page (default: 50).</p>\n","type":"text/plain"},"key":"pageSize","value":"50"}],"variable":[]}},"response":[{"id":"e9fca63d-921e-4325-939a-c716ecc3ffe4","name":"200 — Category tree","originalRequest":{"method":"GET","header":[],"url":{"raw":"https://eservices.hoicom.net/api/v0/gifts/categories?page=1&pageSize=50","host":["https://eservices.hoicom.net"],"path":["api","v0","gifts","categories"],"query":[{"key":"page","value":"1"},{"key":"pageSize","value":"50"}]},"description":"Returns the gift **category tree** — the taxonomy you can browse and filter products by.\n\nUse it to build a category navigation, then pass a category's `id` to **Get Products** as `categoryId`.\n\n---\n\n## Authorization\n\nRequires Basic Authentication with your client credentials. Your account must be enabled for the Gifts service.\n\n---\n\n## Query Parameters\n\n| Parameter | Type | Required | Default | Description |\n| --- | --- | --- | --- | --- |\n| `cityId` | `int` | No | — | Limit to categories with products purchasable in this city. |\n| `fulfillmentCenterId` | `string` | No | — | Limit to categories with products purchasable at this center. |\n| `lang` | `string` | No | `ar` | `ar` or `en`. Falls back to English where an Arabic name is missing. |\n| `page` | `int` | No | `1` | Page number — applies to **root** categories only. |\n| `pageSize` | `int` | No | `50` | Root categories per page. |\n\n`cityId` and `fulfillmentCenterId` are alternatives. If you send both, **`fulfillmentCenterId` wins and `cityId` is ignored** — this is not an error.\n\n---\n\n## Response\n\n`code` is `1000` and `data` holds a paginated tree.\n\n- **Pagination applies to root categories only.** A root category always arrives with its complete `children`, however deep — paging can never cut a subtree in half.\n- `children` is always present. Leaves carry `[]`, never `null` and never an omitted key.\n- If the scope resolves to nothing, you get `200` with an empty `items` array — not a `404`.\n\n---\n\n## Things worth knowing before you integrate\n\n**This is not the partner's full taxonomy.** Categories reach us attached to products, so a category appears only once we have received a product carrying it.\n\n**A category whose parent has no products of its own appears at the root** rather than nested under that parent, because we never invent a parent we have no name for.\n\n**Key on `id`, never on `name`.** The same category id can briefly show a different name here than on a product, while the partner's rename works its way through the catalogue. Ids always agree.\n\n**Sort order is ordinal**, not human-alphabetical: `\"Zebra\"` sorts before `\"apple\"`, and Arabic and English orderings differ. It is stable and deterministic, just not what a phone book would do."},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"cookie":[],"responseTime":null,"body":"{\n    \"code\": 1000,\n    \"message\": \"Request processed successfully.\",\n    \"data\": {\n        \"items\": [\n            {\n                \"id\": \"6988\",\n                \"name\": \"Flowers & Plants\",\n                \"children\": [\n                    {\n                        \"id\": \"7104\",\n                        \"name\": \"Roses\",\n                        \"children\": []\n                    },\n                    {\n                        \"id\": \"7105\",\n                        \"name\": \"Tulips\",\n                        \"children\": []\n                    }\n                ]\n            },\n            {\n                \"id\": \"7012\",\n                \"name\": \"Birthday\",\n                \"children\": []\n            }\n        ],\n        \"count\": 2,\n        \"page\": 1,\n        \"pageSize\": 50,\n        \"totalPages\": 1,\n        \"totalItems\": 2\n    }\n}"}],"_postman_id":"865547d1-d185-46f3-97d3-15b406de46d8"},{"name":"Get Products by Fulfillment Center","id":"d5bc9587-115b-4385-8e77-75c4c166f1fa","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"GET","header":[{"key":"Accept","value":"text/plain"}],"url":"https://eservices.hoicom.net/api/v0/gifts/products/fc/:fulfillmentCenterId?searchTerm=string&sku=string&productId=string&minPrice=6039.208844241599&maxPrice=6039.208844241599&minQty=6997&maxQty=6997&sortBy=Details.ProductName&sortDescending=false&page=1&pageSize=50&lang=ar","description":"<p>Returns the gift products (flowers, chocolates, gift baskets, etc.) available for delivery by a specific <strong>fulfillment center</strong>, with full search, filtering, and sorting support. Prices and quantities reflect what that fulfillment center can offer.</p>\n<p>Use this after selecting a location/fulfillment center from <strong>Get Locations</strong>.</p>\n<hr />\n<h2 id=\"authorization\">Authorization</h2>\n<p>Requires Basic Authentication with your client credentials. Your account must be enabled for the Gifts service.</p>\n<hr />\n<h2 id=\"path-parameters\">Path Parameters</h2>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Parameter</th>\n<th>Type</th>\n<th>Required</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>fulfillmentCenterId</code></td>\n<td><code>string</code></td>\n<td>Yes</td>\n<td>The fulfillment center to list products for.</td>\n</tr>\n</tbody>\n</table>\n</div><hr />\n<h2 id=\"query-parameters\">Query Parameters</h2>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Parameter</th>\n<th>Type</th>\n<th>Required</th>\n<th>Default</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>searchTerm</code></td>\n<td><code>string</code></td>\n<td>No</td>\n<td>—</td>\n<td>Keyword to search in product names or descriptions.</td>\n</tr>\n<tr>\n<td><code>sku</code></td>\n<td><code>string</code></td>\n<td>No</td>\n<td>—</td>\n<td>Exact product SKU to filter by.</td>\n</tr>\n<tr>\n<td><code>productId</code></td>\n<td><code>string</code></td>\n<td>No</td>\n<td>—</td>\n<td>Product ID to filter by.</td>\n</tr>\n<tr>\n<td><code>minPrice</code></td>\n<td><code>decimal</code></td>\n<td>No</td>\n<td>—</td>\n<td>Minimum price filter.</td>\n</tr>\n<tr>\n<td><code>maxPrice</code></td>\n<td><code>decimal</code></td>\n<td>No</td>\n<td>—</td>\n<td>Maximum price filter.</td>\n</tr>\n<tr>\n<td><code>minQty</code></td>\n<td><code>int</code></td>\n<td>No</td>\n<td>—</td>\n<td>Minimum available-quantity filter.</td>\n</tr>\n<tr>\n<td><code>maxQty</code></td>\n<td><code>int</code></td>\n<td>No</td>\n<td>—</td>\n<td>Maximum available-quantity filter.</td>\n</tr>\n<tr>\n<td><code>sortBy</code></td>\n<td><code>string</code></td>\n<td>No</td>\n<td><code>Details.ProductName</code></td>\n<td>Sort field. One of: <code>Details.ProductName</code>, <code>Details.Sku</code>, <code>Pricing.Price</code>, <code>Availability.Qty</code>.</td>\n</tr>\n<tr>\n<td><code>sortDescending</code></td>\n<td><code>bool</code></td>\n<td>No</td>\n<td><code>false</code></td>\n<td>Sort in descending order.</td>\n</tr>\n<tr>\n<td><code>page</code></td>\n<td><code>int</code></td>\n<td>No</td>\n<td><code>1</code></td>\n<td>Page number for pagination.</td>\n</tr>\n<tr>\n<td><code>pageSize</code></td>\n<td><code>int</code></td>\n<td>No</td>\n<td><code>50</code></td>\n<td>Number of items per page.</td>\n</tr>\n<tr>\n<td><code>lang</code></td>\n<td><code>string</code></td>\n<td>No</td>\n<td><code>ar</code></td>\n<td>Language for text fields: <code>ar</code> (Arabic) or <code>en</code> (English).</td>\n</tr>\n<tr>\n<td><code>categoryId</code></td>\n<td><code>string</code></td>\n<td>No</td>\n<td>—</td>\n<td>Filter to products tagged with this category id. Take the id from <strong>Get Categories</strong>. Narrows the product set only — it does not change the price range.</td>\n</tr>\n</tbody>\n</table>\n</div><hr />\n<h2 id=\"response\">Response</h2>\n<p>On success <code>code</code> is <code>1000</code> and <code>data</code> holds a paginated list of products, each with its <code>details</code> (name, SKU, images, description) and <code>pricing</code> (price, VAT, currency, total, deliveryFee). See the example below.</p>\n<p><strong>Pricing on this endpoint is a single exact price.</strong> The response carries <code>price</code>, <code>vat</code>, <code>currency</code>, <code>total</code> and <code>deliveryFee</code>. It does <strong>not</strong> include <code>priceFrom</code> or <code>priceTo</code> — those belong to <strong>Get Products</strong>, where a product can span several fulfillment centers at different prices.</p>\n<blockquote>\n<p><strong>No matches on this route is a <code>404</code>.</strong> <code>?categoryId=</code> with nothing matching returns HTTP <code>404</code>, because this route treats <em>any</em> empty result page as \"not found\" — pre-existing behaviour, unrelated to categories (an unmatched <code>searchTerm</code> does the same). Don't read it as a broken endpoint or a bad <code>categoryId</code>; check for zero matches, not a missing resource. <strong>Get Products</strong> returns <code>200</code> with an empty list for the same case.</p>\n</blockquote>\n<blockquote>\n<p><strong>Delivery prices unavailable is also a <code>404</code>.</strong> If this fulfillment center's delivery prices cannot be read, the route returns <strong>HTTP 404 / code <code>1303</code></strong>. Retry later.</p>\n</blockquote>\n<hr />\n<h2 id=\"response-fields\">Response fields</h2>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Field</th>\n<th>Type</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>code</td>\n<td>int</td>\n<td>Response status code. <code>1000</code> on success.</td>\n</tr>\n<tr>\n<td>message</td>\n<td>string</td>\n<td>Human-readable status message.</td>\n</tr>\n<tr>\n<td>data</td>\n<td>object</td>\n<td>Paginated list of products available at this fulfillment center.</td>\n</tr>\n<tr>\n<td>data.items</td>\n<td>array</td>\n<td>Product items on this page.</td>\n</tr>\n<tr>\n<td>data.items[].id</td>\n<td>string</td>\n<td>Product id. Use as <code>items[].productId</code> on Check Availability and Create Order.</td>\n</tr>\n<tr>\n<td>data.items[].details</td>\n<td>object</td>\n<td>Descriptive product fields.</td>\n</tr>\n<tr>\n<td>data.items[].details.name</td>\n<td>string</td>\n<td>Product display name, resolved for the request's <code>lang</code>.</td>\n</tr>\n<tr>\n<td>data.items[].details.sku</td>\n<td>string</td>\n<td>Product SKU.</td>\n</tr>\n<tr>\n<td>data.items[].details.mainImage</td>\n<td>string</td>\n<td>URL of the primary product image.</td>\n</tr>\n<tr>\n<td>data.items[].details.imageUrls</td>\n<td>array of string</td>\n<td>URLs of additional product images.</td>\n</tr>\n<tr>\n<td>data.items[].details.description</td>\n<td>string</td>\n<td>Full product description.</td>\n</tr>\n<tr>\n<td>data.items[].details.shortDescription</td>\n<td>string</td>\n<td>Short product summary.</td>\n</tr>\n<tr>\n<td>data.items[].pricing</td>\n<td>object</td>\n<td>Pricing at this fulfillment center. Exact - no range.</td>\n</tr>\n<tr>\n<td>data.items[].pricing.price</td>\n<td>decimal</td>\n<td>This center's exact unit price, VAT-exclusive.</td>\n</tr>\n<tr>\n<td>data.items[].pricing.vat</td>\n<td>decimal</td>\n<td>VAT amount applied to <code>price</code>.</td>\n</tr>\n<tr>\n<td>data.items[].pricing.currency</td>\n<td>string</td>\n<td>3-letter currency code for all amounts on this item.</td>\n</tr>\n<tr>\n<td>data.items[].pricing.total</td>\n<td>decimal</td>\n<td>VAT-inclusive unit price (<code>price</code> + <code>vat</code>). Indicative only - excludes delivery and is not a cart total; charge off Check Availability's <code>total</code> instead.</td>\n</tr>\n<tr>\n<td>data.items[].pricing.deliveryFee</td>\n<td>object</td>\n<td>Delivery fee of this fulfillment center, charged once per order (not per item). All <code>0</code> when the center lists no delivery charge.</td>\n</tr>\n<tr>\n<td>data.items[].pricing.deliveryFee.amount</td>\n<td>decimal</td>\n<td>VAT-exclusive delivery fee.</td>\n</tr>\n<tr>\n<td>data.items[].pricing.deliveryFee.vatAmount</td>\n<td>decimal</td>\n<td>VAT on the delivery fee.</td>\n</tr>\n<tr>\n<td>data.items[].pricing.deliveryFee.total</td>\n<td>decimal</td>\n<td>VAT-inclusive delivery fee (<code>amount</code> + <code>vatAmount</code>).</td>\n</tr>\n<tr>\n<td>data.items[].pricing.deliveryFee.currency</td>\n<td>string</td>\n<td>Currency code.</td>\n</tr>\n<tr>\n<td>data.count</td>\n<td>int</td>\n<td>Number of product items on this page.</td>\n</tr>\n<tr>\n<td>data.page</td>\n<td>int</td>\n<td>Current page number.</td>\n</tr>\n<tr>\n<td>data.pageSize</td>\n<td>int</td>\n<td>Requested page size.</td>\n</tr>\n<tr>\n<td>data.totalPages</td>\n<td>int</td>\n<td>Total number of pages available.</td>\n</tr>\n<tr>\n<td>data.totalItems</td>\n<td>int</td>\n<td>Total number of matching products across all pages.</td>\n</tr>\n</tbody>\n</table>\n</div>","urlObject":{"path":["api","v0","gifts","products","fc",":fulfillmentCenterId"],"host":["https://eservices.hoicom.net"],"query":[{"description":{"content":"<p>Optional keyword to search in product names or descriptions.</p>\n","type":"text/plain"},"key":"searchTerm","value":"string"},{"description":{"content":"<p>Optional exact product SKU to filter by.</p>\n","type":"text/plain"},"key":"sku","value":"string"},{"description":{"content":"<p>Optional product ID to filter by.</p>\n","type":"text/plain"},"key":"productId","value":"string"},{"description":{"content":"<p>Optional minimum price filter.</p>\n","type":"text/plain"},"key":"minPrice","value":"6039.208844241599"},{"description":{"content":"<p>Optional maximum price filter.</p>\n","type":"text/plain"},"key":"maxPrice","value":"6039.208844241599"},{"description":{"content":"<p>Optional minimum quantity filter.</p>\n","type":"text/plain"},"key":"minQty","value":"6997"},{"description":{"content":"<p>Optional maximum quantity filter.</p>\n","type":"text/plain"},"key":"maxQty","value":"6997"},{"description":{"content":"<p>Optional field to sort by: Details.ProductName, Details.Sku, Pricing.Price, Availability.Qty.</p>\n","type":"text/plain"},"key":"sortBy","value":"Details.ProductName"},{"description":{"content":"<p>Optional whether to sort descending (default: false).</p>\n","type":"text/plain"},"key":"sortDescending","value":"false"},{"description":{"content":"<p>Page number for pagination (default: 1).</p>\n","type":"text/plain"},"key":"page","value":"1"},{"description":{"content":"<p>Number of items per page (default: 50).</p>\n","type":"text/plain"},"key":"pageSize","value":"50"},{"description":{"content":"<p>Language for text fields: \"ar\" (Arabic, default) or \"en\" (English).</p>\n","type":"text/plain"},"key":"lang","value":"ar"},{"disabled":true,"description":{"content":"<p>Optional. Narrows results to products in this category. Take the id from <strong>Get Categories</strong>. Filtering by category narrows the product set only — it does not narrow the price range.</p>\n","type":"text/plain"},"key":"categoryId","value":""}],"variable":[{"description":{"content":"<p>The fulfillment center identifier to filter products by.</p>\n","type":"text/plain"},"type":"any","value":"string","key":"fulfillmentCenterId"}]}},"response":[{"id":"e8fc37ae-2209-46fb-9302-d5a94b532779","name":"OK","originalRequest":{"method":"GET","header":[{"key":"Accept","value":"text/plain"}],"url":{"raw":"https://eservices.hoicom.net/api/v0/gifts/products/fc/:fulfillmentCenterId?searchTerm=string&sku=string&productId=string&minPrice=6039.208844241599&maxPrice=6039.208844241599&minQty=6997&maxQty=6997&sortBy=Details.ProductName&sortDescending=false&page=1&pageSize=50&lang=ar","host":["https://eservices.hoicom.net"],"path":["api","v0","gifts","products","fc",":fulfillmentCenterId"],"query":[{"key":"searchTerm","value":"string","description":"Optional keyword to search in product names or descriptions."},{"key":"sku","value":"string","description":"Optional exact product SKU to filter by."},{"key":"productId","value":"string","description":"Optional product ID to filter by."},{"key":"minPrice","value":"6039.208844241599","description":"Optional minimum price filter."},{"key":"maxPrice","value":"6039.208844241599","description":"Optional maximum price filter."},{"key":"minQty","value":"6997","description":"Optional minimum quantity filter."},{"key":"maxQty","value":"6997","description":"Optional maximum quantity filter."},{"key":"sortBy","value":"Details.ProductName","description":"Optional field to sort by: Details.ProductName, Details.Sku, Pricing.Price, Availability.Qty."},{"key":"sortDescending","value":"false","description":"Optional whether to sort descending (default: false)."},{"key":"page","value":"1","description":"Page number for pagination (default: 1)."},{"key":"pageSize","value":"50","description":"Number of items per page (default: 50)."},{"key":"lang","value":"ar","description":"Language for text fields: \"ar\" (Arabic, default) or \"en\" (English)."}],"variable":[{"key":"fulfillmentCenterId","value":"string","description":"The fulfillment center identifier to filter products by."}]},"description":"Returns the gift products (flowers, chocolates, gift baskets, etc.) available for delivery by a specific **fulfillment center**, with full search, filtering, and sorting support. Prices and quantities reflect what that fulfillment center can offer.\n\nUse this after selecting a location/fulfillment center from **Get Locations**.\n\n---\n\n## Authorization\n\nRequires Basic Authentication with your client credentials. Your account must be enabled for the Gifts service.\n\n---\n\n## Path Parameters\n\n| Parameter | Type | Required | Description |\n| --- | --- | --- | --- |\n| `fulfillmentCenterId` | `string` | Yes | The fulfillment center to list products for. |\n\n---\n\n## Query Parameters\n\n| Parameter | Type | Required | Default | Description |\n| --- | --- | --- | --- | --- |\n| `searchTerm` | `string` | No | — | Keyword to search in product names or descriptions. |\n| `sku` | `string` | No | — | Exact product SKU to filter by. |\n| `productId` | `string` | No | — | Product ID to filter by. |\n| `minPrice` | `decimal` | No | — | Minimum price filter. |\n| `maxPrice` | `decimal` | No | — | Maximum price filter. |\n| `minQty` | `int` | No | — | Minimum available-quantity filter. |\n| `maxQty` | `int` | No | — | Maximum available-quantity filter. |\n| `sortBy` | `string` | No | `Details.ProductName` | Sort field. One of: `Details.ProductName`, `Details.Sku`, `Pricing.Price`, `Availability.Qty`. |\n| `sortDescending` | `bool` | No | `false` | Sort in descending order. |\n| `page` | `int` | No | `1` | Page number for pagination. |\n| `pageSize` | `int` | No | `50` | Number of items per page. |\n| `lang` | `string` | No | `ar` | Language for text fields: `ar` (Arabic) or `en` (English). |\n| `categoryId` | `string` | No | — | Filter to products tagged with this category id. Take the id from **Get Categories**. Narrows the product set only — it does not change the price range. |\n\n---\n\n## Response\n\nOn success `code` is `1000` and `data` holds a paginated list of products, each with its `details` (name, SKU, images, description) and `pricing` (price, VAT, currency, total). See the example below.\n\n**Pricing on this endpoint is a single exact price.** The response carries `price`, `vat`, `currency` and `total`. It does **not** include `priceFrom` or `priceTo` — those belong to **Get Products**, where a product can span several fulfillment centers at different prices.\n\n> **No matches on this route is a `404`.** `?categoryId=` with nothing matching returns HTTP `404`, because this route treats *any* empty result page as \"not found\" — pre-existing behaviour, unrelated to categories (an unmatched `searchTerm` does the same). Don't read it as a broken endpoint or a bad `categoryId`; check for zero matches, not a missing resource. **Get Products** returns `200` with an empty list for the same case."},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"cookie":[],"responseTime":null,"body":"{\n  \"code\": 1000,\n  \"message\": \"Success\",\n  \"data\": {\n    \"items\": [\n      {\n        \"id\": \"prod_10021\",\n        \"details\": {\n          \"name\": \"Red Roses Bouquet\",\n          \"sku\": \"FLW-ROSE-RED-12\",\n          \"mainImage\": \"https://cdn.example.com/products/roses-red.jpg\",\n          \"imageUrls\": [\n            \"https://cdn.example.com/products/roses-red-1.jpg\",\n            \"https://cdn.example.com/products/roses-red-2.jpg\"\n          ],\n          \"description\": \"A dozen premium long-stem red roses, hand-arranged.\",\n          \"shortDescription\": \"12 premium red roses\"\n        },\n        \"pricing\": {\n          \"price\": 217.39,\n          \"vat\": 15,\n          \"currency\": \"SAR\",\n          \"total\": 249.9985,\n          \"deliveryFee\": {\n            \"amount\": 21.74,\n            \"vatAmount\": 3.26,\n            \"total\": 25,\n            \"currency\": \"SAR\"\n          }\n        },\n        \"provider\": {\n          \"name\": \"Floward\",\n          \"logoUrls\": [\n            \"https://cdn.example.com/logos/provider.png\"\n          ],\n          \"fulfillmentCenter\": {\n            \"id\": \"fc_riyadh_01\",\n            \"name\": \"Riyadh\"\n          }\n        }\n      }\n    ],\n    \"count\": 1,\n    \"page\": 1,\n    \"pageSize\": 50,\n    \"totalPages\": 1,\n    \"totalItems\": 1\n  }\n}"},{"id":"0c90832d-8359-4b10-b4ad-e2a5056bfc8d","name":"Internal Server Error","originalRequest":{"method":"GET","header":[],"url":{"raw":"https://eservices.hoicom.net/api/v0/gifts/products/fc/:fulfillmentCenterId?searchTerm=string&sku=string&productId=string&minPrice=6039.208844241599&maxPrice=6039.208844241599&minQty=6997&maxQty=6997&sortBy=Details.ProductName&sortDescending=false&page=1&pageSize=50&lang=ar","host":["https://eservices.hoicom.net"],"path":["api","v0","gifts","products","fc",":fulfillmentCenterId"],"query":[{"key":"searchTerm","value":"string","description":"Optional keyword to search in product names or descriptions."},{"key":"sku","value":"string","description":"Optional exact product SKU to filter by."},{"key":"productId","value":"string","description":"Optional product ID to filter by."},{"key":"minPrice","value":"6039.208844241599","description":"Optional minimum price filter."},{"key":"maxPrice","value":"6039.208844241599","description":"Optional maximum price filter."},{"key":"minQty","value":"6997","description":"Optional minimum quantity filter."},{"key":"maxQty","value":"6997","description":"Optional maximum quantity filter."},{"key":"sortBy","value":"Details.ProductName","description":"Optional field to sort by: Details.ProductName, Details.Sku, Pricing.Price, Availability.Qty."},{"key":"sortDescending","value":"false","description":"Optional whether to sort descending (default: false)."},{"key":"page","value":"1","description":"Page number for pagination (default: 1)."},{"key":"pageSize","value":"50","description":"Number of items per page (default: 50)."},{"key":"lang","value":"ar","description":"Language for text fields: \"ar\" (Arabic, default) or \"en\" (English)."}],"variable":[{"key":"fulfillmentCenterId","value":"string","description":"The fulfillment center identifier to filter products by."}]},"description":"Returns the gift products (flowers, chocolates, gift baskets, etc.) available for delivery by a specific **fulfillment center**, with full search, filtering, and sorting support. Prices and quantities reflect what that fulfillment center can offer.\n\nUse this after selecting a location/fulfillment center from **Get Locations**.\n\n---\n\n## Authorization\n\nRequires Basic Authentication with your client credentials. Your account must be enabled for the Gifts service.\n\n---\n\n## Path Parameters\n\n| Parameter | Type | Required | Description |\n| --- | --- | --- | --- |\n| `fulfillmentCenterId` | `string` | Yes | The fulfillment center to list products for. |\n\n---\n\n## Query Parameters\n\n| Parameter | Type | Required | Default | Description |\n| --- | --- | --- | --- | --- |\n| `searchTerm` | `string` | No | — | Keyword to search in product names or descriptions. |\n| `sku` | `string` | No | — | Exact product SKU to filter by. |\n| `productId` | `string` | No | — | Product ID to filter by. |\n| `minPrice` | `decimal` | No | — | Minimum price filter. |\n| `maxPrice` | `decimal` | No | — | Maximum price filter. |\n| `minQty` | `int` | No | — | Minimum available-quantity filter. |\n| `maxQty` | `int` | No | — | Maximum available-quantity filter. |\n| `sortBy` | `string` | No | `Details.ProductName` | Sort field. One of: `Details.ProductName`, `Details.Sku`, `Pricing.Price`, `Availability.Qty`. |\n| `sortDescending` | `bool` | No | `false` | Sort in descending order. |\n| `page` | `int` | No | `1` | Page number for pagination. |\n| `pageSize` | `int` | No | `50` | Number of items per page. |\n| `lang` | `string` | No | `ar` | Language for text fields: `ar` (Arabic) or `en` (English). |\n| `categoryId` | `string` | No | — | Filter to products tagged with this category id. Take the id from **Get Categories**. Narrows the product set only — it does not change the price range. |\n\n---\n\n## Response\n\nOn success `code` is `1000` and `data` holds a paginated list of products, each with its `details` (name, SKU, images, description) and `pricing` (price, VAT, currency, total). See the example below.\n\n**Pricing on this endpoint is a single exact price.** The response carries `price`, `vat`, `currency` and `total`. It does **not** include `priceFrom` or `priceTo` — those belong to **Get Products**, where a product can span several fulfillment centers at different prices.\n\n> **No matches on this route is a `404`.** `?categoryId=` with nothing matching returns HTTP `404`, because this route treats *any* empty result page as \"not found\" — pre-existing behaviour, unrelated to categories (an unmatched `searchTerm` does the same). Don't read it as a broken endpoint or a bad `categoryId`; check for zero matches, not a missing resource. **Get Products** returns `200` with an empty list for the same case."},"status":"Internal Server Error","code":500,"_postman_previewlanguage":"text","header":[],"cookie":[],"responseTime":null,"body":""},{"id":"acb3fbc4-1777-41d0-89c3-f42a23a469b1","name":"Service Unavailable","originalRequest":{"method":"GET","header":[],"url":{"raw":"https://eservices.hoicom.net/api/v0/gifts/products/fc/:fulfillmentCenterId?searchTerm=string&sku=string&productId=string&minPrice=6039.208844241599&maxPrice=6039.208844241599&minQty=6997&maxQty=6997&sortBy=Details.ProductName&sortDescending=false&page=1&pageSize=50&lang=ar","host":["https://eservices.hoicom.net"],"path":["api","v0","gifts","products","fc",":fulfillmentCenterId"],"query":[{"key":"searchTerm","value":"string","description":"Optional keyword to search in product names or descriptions."},{"key":"sku","value":"string","description":"Optional exact product SKU to filter by."},{"key":"productId","value":"string","description":"Optional product ID to filter by."},{"key":"minPrice","value":"6039.208844241599","description":"Optional minimum price filter."},{"key":"maxPrice","value":"6039.208844241599","description":"Optional maximum price filter."},{"key":"minQty","value":"6997","description":"Optional minimum quantity filter."},{"key":"maxQty","value":"6997","description":"Optional maximum quantity filter."},{"key":"sortBy","value":"Details.ProductName","description":"Optional field to sort by: Details.ProductName, Details.Sku, Pricing.Price, Availability.Qty."},{"key":"sortDescending","value":"false","description":"Optional whether to sort descending (default: false)."},{"key":"page","value":"1","description":"Page number for pagination (default: 1)."},{"key":"pageSize","value":"50","description":"Number of items per page (default: 50)."},{"key":"lang","value":"ar","description":"Language for text fields: \"ar\" (Arabic, default) or \"en\" (English)."}],"variable":[{"key":"fulfillmentCenterId","value":"string","description":"The fulfillment center identifier to filter products by."}]},"description":"Returns the gift products (flowers, chocolates, gift baskets, etc.) available for delivery by a specific **fulfillment center**, with full search, filtering, and sorting support. Prices and quantities reflect what that fulfillment center can offer.\n\nUse this after selecting a location/fulfillment center from **Get Locations**.\n\n---\n\n## Authorization\n\nRequires Basic Authentication with your client credentials. Your account must be enabled for the Gifts service.\n\n---\n\n## Path Parameters\n\n| Parameter | Type | Required | Description |\n| --- | --- | --- | --- |\n| `fulfillmentCenterId` | `string` | Yes | The fulfillment center to list products for. |\n\n---\n\n## Query Parameters\n\n| Parameter | Type | Required | Default | Description |\n| --- | --- | --- | --- | --- |\n| `searchTerm` | `string` | No | — | Keyword to search in product names or descriptions. |\n| `sku` | `string` | No | — | Exact product SKU to filter by. |\n| `productId` | `string` | No | — | Product ID to filter by. |\n| `minPrice` | `decimal` | No | — | Minimum price filter. |\n| `maxPrice` | `decimal` | No | — | Maximum price filter. |\n| `minQty` | `int` | No | — | Minimum available-quantity filter. |\n| `maxQty` | `int` | No | — | Maximum available-quantity filter. |\n| `sortBy` | `string` | No | `Details.ProductName` | Sort field. One of: `Details.ProductName`, `Details.Sku`, `Pricing.Price`, `Availability.Qty`. |\n| `sortDescending` | `bool` | No | `false` | Sort in descending order. |\n| `page` | `int` | No | `1` | Page number for pagination. |\n| `pageSize` | `int` | No | `50` | Number of items per page. |\n| `lang` | `string` | No | `ar` | Language for text fields: `ar` (Arabic) or `en` (English). |\n| `categoryId` | `string` | No | — | Filter to products tagged with this category id. Take the id from **Get Categories**. Narrows the product set only — it does not change the price range. |\n\n---\n\n## Response\n\nOn success `code` is `1000` and `data` holds a paginated list of products, each with its `details` (name, SKU, images, description) and `pricing` (price, VAT, currency, total). See the example below.\n\n**Pricing on this endpoint is a single exact price.** The response carries `price`, `vat`, `currency` and `total`. It does **not** include `priceFrom` or `priceTo` — those belong to **Get Products**, where a product can span several fulfillment centers at different prices.\n\n> **No matches on this route is a `404`.** `?categoryId=` with nothing matching returns HTTP `404`, because this route treats *any* empty result page as \"not found\" — pre-existing behaviour, unrelated to categories (an unmatched `searchTerm` does the same). Don't read it as a broken endpoint or a bad `categoryId`; check for zero matches, not a missing resource. **Get Products** returns `200` with an empty list for the same case."},"status":"Service Unavailable","code":503,"_postman_previewlanguage":"text","header":[],"cookie":[],"responseTime":null,"body":""}],"_postman_id":"d5bc9587-115b-4385-8e77-75c4c166f1fa"},{"name":"Get Products","id":"7d37b92a-9b42-4e36-bea8-c431a767922e","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"GET","header":[{"key":"Accept","value":"text/plain"}],"url":"https://eservices.hoicom.net/api/v0/gifts/products?searchTerm=string&sku=string&productId=string&minPrice=6039.208844241599&maxPrice=6039.208844241599&minQty=6997&maxQty=6997&sortBy=Details.ProductName&sortDescending=false&page=1&pageSize=50&lang=ar","description":"<p>Returns gift products <strong>across all fulfillment centers</strong>. Use this to browse the full catalogue when you are not yet tied to a specific delivery area.</p>\n<p>Because the same product costs different amounts at different fulfillment centers, an unscoped call returns a price <strong>range</strong> (<code>priceFrom</code> / <code>priceTo</code>) alongside the headline <code>price</code>.</p>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Field</th>\n<th>Unscoped</th>\n<th>With <code>cityId</code></th>\n<th>With <code>fulfillmentCenterId</code></th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>price</code></td>\n<td>Lowest purchasable price anywhere</td>\n<td>Lowest price in that city</td>\n<td>That center's exact price</td>\n</tr>\n<tr>\n<td><code>priceFrom</code></td>\n<td>Same as <code>price</code></td>\n<td>Lowest price in that city</td>\n<td>Same as <code>price</code></td>\n</tr>\n<tr>\n<td><code>priceTo</code></td>\n<td>Highest price anywhere</td>\n<td>Highest price in that city</td>\n<td>Same as <code>price</code></td>\n</tr>\n</tbody>\n</table>\n</div><p><code>priceFrom</code> equals <code>priceTo</code> only when exactly one fulfillment center is in scope. A city with two centers still returns a genuine range.</p>\n<blockquote>\n<p><strong>These prices are indicative.</strong> To get the amount to charge and to send on an order, post the cart to <strong>Check Availability</strong>. Browse prices exclude delivery, so ordering off one is rejected with <strong>HTTP 400 / code 1415</strong>.</p>\n</blockquote>\n<p><code>pricing.deliveryFee</code> is the delivery fee of the fulfillment center the price comes from (the requested center, or the cheapest one when unscoped). It is charged once per order, not per item, and is shown for information.</p>\n<hr />\n<h2 id=\"authorization\">Authorization</h2>\n<p>Requires Basic Authentication with your client credentials. Your account must be enabled for the Gifts service.</p>\n<hr />\n<h2 id=\"query-parameters\">Query Parameters</h2>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Parameter</th>\n<th>Type</th>\n<th>Required</th>\n<th>Default</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>cityId</code></td>\n<td><code>int</code></td>\n<td>No</td>\n<td>—</td>\n<td>Restrict to the fulfillment centers in one city. From <strong>Get Locations</strong>.</td>\n</tr>\n<tr>\n<td><code>fulfillmentCenterId</code></td>\n<td><code>string</code></td>\n<td>No</td>\n<td>—</td>\n<td>Restrict to one fulfillment center, making every price exact. Takes precedence if <code>cityId</code> is also sent.</td>\n</tr>\n<tr>\n<td><code>searchTerm</code></td>\n<td><code>string</code></td>\n<td>No</td>\n<td>—</td>\n<td>Keyword to search in product names or descriptions.</td>\n</tr>\n<tr>\n<td><code>sku</code></td>\n<td><code>string</code></td>\n<td>No</td>\n<td>—</td>\n<td>Exact product SKU to filter by.</td>\n</tr>\n<tr>\n<td><code>productId</code></td>\n<td><code>string</code></td>\n<td>No</td>\n<td>—</td>\n<td>Product ID to filter by.</td>\n</tr>\n<tr>\n<td><code>minPrice</code></td>\n<td><code>decimal</code></td>\n<td>No</td>\n<td>—</td>\n<td>Minimum price filter, applied to the lowest price in scope.</td>\n</tr>\n<tr>\n<td><code>maxPrice</code></td>\n<td><code>decimal</code></td>\n<td>No</td>\n<td>—</td>\n<td>Maximum price filter, applied to the lowest price in scope.</td>\n</tr>\n<tr>\n<td><code>minQty</code></td>\n<td><code>int</code></td>\n<td>No</td>\n<td>—</td>\n<td>Minimum available-quantity filter, across the centers in scope.</td>\n</tr>\n<tr>\n<td><code>maxQty</code></td>\n<td><code>int</code></td>\n<td>No</td>\n<td>—</td>\n<td>Maximum available-quantity filter, across the centers in scope.</td>\n</tr>\n<tr>\n<td><code>sortBy</code></td>\n<td><code>string</code></td>\n<td>No</td>\n<td><code>Details.ProductName</code></td>\n<td>Sort field. One of: <code>Details.ProductName</code>, <code>Details.Sku</code>, <code>Pricing.Price</code>, <code>Availability.Qty</code>.</td>\n</tr>\n<tr>\n<td><code>sortDescending</code></td>\n<td><code>bool</code></td>\n<td>No</td>\n<td><code>false</code></td>\n<td>Sort in descending order.</td>\n</tr>\n<tr>\n<td><code>page</code></td>\n<td><code>int</code></td>\n<td>No</td>\n<td><code>1</code></td>\n<td>Page number for pagination.</td>\n</tr>\n<tr>\n<td><code>pageSize</code></td>\n<td><code>int</code></td>\n<td>No</td>\n<td><code>50</code></td>\n<td>Number of items per page.</td>\n</tr>\n<tr>\n<td><code>lang</code></td>\n<td><code>string</code></td>\n<td>No</td>\n<td><code>ar</code></td>\n<td>Language for text fields: <code>ar</code> (Arabic) or <code>en</code> (English).</td>\n</tr>\n<tr>\n<td><code>categoryId</code></td>\n<td><code>string</code></td>\n<td>No</td>\n<td>—</td>\n<td>Filter to products tagged with this category id. Take the id from <strong>Get Categories</strong>. Narrows the product set only — it does not change the price range.</td>\n</tr>\n</tbody>\n</table>\n</div><p>Only products with active stock at one or more fulfillment centers are returned. A <code>cityId</code> or <code>fulfillmentCenterId</code> that does not resolve to an active fulfillment center you are entitled to returns an <strong>empty page</strong> — HTTP 200, code <code>1000</code>, <code>items: []</code> — not a 404. The same empty page is returned if delivery prices cannot be read.</p>\n<hr />\n<h2 id=\"response\">Response</h2>\n<p>On success <code>code</code> is <code>1000</code> and <code>data</code> holds a paginated list of products (details + pricing). See the example below.</p>\n<blockquote>\n<p><strong>No matches is a <code>200</code>, not a <code>404</code>.</strong> <code>?categoryId=</code> with nothing matching returns <code>code</code> <code>1000</code> and an empty <code>items: []</code>. Compare <strong>Get Products by Fulfillment Center</strong>, which returns <code>404</code> for the same case.</p>\n</blockquote>\n<hr />\n<h2 id=\"response-fields\">Response fields</h2>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Field</th>\n<th>Type</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>code</td>\n<td>int</td>\n<td>Response status code. <code>1000</code> on success.</td>\n</tr>\n<tr>\n<td>message</td>\n<td>string</td>\n<td>Human-readable status message.</td>\n</tr>\n<tr>\n<td>data</td>\n<td>object</td>\n<td>Paginated list of products across the fulfillment centers in scope.</td>\n</tr>\n<tr>\n<td>data.items</td>\n<td>array</td>\n<td>Product items on this page.</td>\n</tr>\n<tr>\n<td>data.items[].id</td>\n<td>string</td>\n<td>Product id. Use as <code>items[].productId</code> on Check Availability and Create Order.</td>\n</tr>\n<tr>\n<td>data.items[].details</td>\n<td>object</td>\n<td>Descriptive product fields.</td>\n</tr>\n<tr>\n<td>data.items[].details.name</td>\n<td>string</td>\n<td>Product display name, resolved for the request's <code>lang</code>.</td>\n</tr>\n<tr>\n<td>data.items[].details.sku</td>\n<td>string</td>\n<td>Product SKU.</td>\n</tr>\n<tr>\n<td>data.items[].details.mainImage</td>\n<td>string</td>\n<td>URL of the primary product image.</td>\n</tr>\n<tr>\n<td>data.items[].details.imageUrls</td>\n<td>array of string</td>\n<td>URLs of additional product images.</td>\n</tr>\n<tr>\n<td>data.items[].details.description</td>\n<td>string</td>\n<td>Full product description.</td>\n</tr>\n<tr>\n<td>data.items[].details.shortDescription</td>\n<td>string</td>\n<td>Short product summary.</td>\n</tr>\n<tr>\n<td>data.items[].pricing</td>\n<td>object</td>\n<td>Indicative pricing across the fulfillment centers in scope - see Pricing: browse ranges vs binding totals in the folder overview.</td>\n</tr>\n<tr>\n<td>data.items[].pricing.price</td>\n<td>decimal</td>\n<td>Headline price: the lowest purchasable price in scope, or the exact price when scoped to one fulfillment center.</td>\n</tr>\n<tr>\n<td>data.items[].pricing.priceFrom</td>\n<td>decimal</td>\n<td>Lowest price across the fulfillment centers in scope. Equal to <code>price</code>.</td>\n</tr>\n<tr>\n<td>data.items[].pricing.priceTo</td>\n<td>decimal</td>\n<td>Highest price across the fulfillment centers in scope.</td>\n</tr>\n<tr>\n<td>data.items[].pricing.vat</td>\n<td>decimal</td>\n<td>VAT amount applied to <code>price</code>.</td>\n</tr>\n<tr>\n<td>data.items[].pricing.currency</td>\n<td>string</td>\n<td>3-letter currency code for all amounts on this item.</td>\n</tr>\n<tr>\n<td>data.items[].pricing.total</td>\n<td>decimal</td>\n<td>VAT-inclusive unit price (<code>price</code> + <code>vat</code>). Indicative only - excludes delivery; never charge or order off this figure; use Check Availability's <code>total</code> instead.</td>\n</tr>\n<tr>\n<td>data.items[].pricing.deliveryFee</td>\n<td>object</td>\n<td>Delivery fee of the fulfillment center the price comes from, charged once per order (not per item). All <code>0</code> when the center lists no delivery charge.</td>\n</tr>\n<tr>\n<td>data.items[].pricing.deliveryFee.amount</td>\n<td>decimal</td>\n<td>VAT-exclusive delivery fee.</td>\n</tr>\n<tr>\n<td>data.items[].pricing.deliveryFee.vatAmount</td>\n<td>decimal</td>\n<td>VAT on the delivery fee.</td>\n</tr>\n<tr>\n<td>data.items[].pricing.deliveryFee.total</td>\n<td>decimal</td>\n<td>VAT-inclusive delivery fee (<code>amount</code> + <code>vatAmount</code>).</td>\n</tr>\n<tr>\n<td>data.items[].pricing.deliveryFee.currency</td>\n<td>string</td>\n<td>Currency code.</td>\n</tr>\n<tr>\n<td>data.count</td>\n<td>int</td>\n<td>Number of product items on this page.</td>\n</tr>\n<tr>\n<td>data.page</td>\n<td>int</td>\n<td>Current page number.</td>\n</tr>\n<tr>\n<td>data.pageSize</td>\n<td>int</td>\n<td>Requested page size.</td>\n</tr>\n<tr>\n<td>data.totalPages</td>\n<td>int</td>\n<td>Total number of pages available.</td>\n</tr>\n<tr>\n<td>data.totalItems</td>\n<td>int</td>\n<td>Total number of matching products across all pages.</td>\n</tr>\n</tbody>\n</table>\n</div>","urlObject":{"path":["api","v0","gifts","products"],"host":["https://eservices.hoicom.net"],"query":[{"disabled":true,"description":{"content":"<p>Optional. Restrict to one fulfillment center; makes every price exact.</p>\n","type":"text/plain"},"key":"fulfillmentCenterId","value":"fc_riyadh_01"},{"disabled":true,"description":{"content":"<p>Optional. Restrict to the fulfillment centers in one city.</p>\n","type":"text/plain"},"key":"cityId","value":"2"},{"description":{"content":"<p>Optional keyword to search in product names or descriptions.</p>\n","type":"text/plain"},"key":"searchTerm","value":"string"},{"description":{"content":"<p>Optional exact product SKU to filter by.</p>\n","type":"text/plain"},"key":"sku","value":"string"},{"description":{"content":"<p>Optional product ID to filter by.</p>\n","type":"text/plain"},"key":"productId","value":"string"},{"description":{"content":"<p>Optional minimum price filter.</p>\n","type":"text/plain"},"key":"minPrice","value":"6039.208844241599"},{"description":{"content":"<p>Optional maximum price filter.</p>\n","type":"text/plain"},"key":"maxPrice","value":"6039.208844241599"},{"description":{"content":"<p>Optional minimum quantity filter.</p>\n","type":"text/plain"},"key":"minQty","value":"6997"},{"description":{"content":"<p>Optional maximum quantity filter.</p>\n","type":"text/plain"},"key":"maxQty","value":"6997"},{"description":{"content":"<p>Optional field to sort by: Details.ProductName, Details.Sku, Pricing.Price, Availability.Qty.</p>\n","type":"text/plain"},"key":"sortBy","value":"Details.ProductName"},{"description":{"content":"<p>Optional whether to sort descending (default: false).</p>\n","type":"text/plain"},"key":"sortDescending","value":"false"},{"description":{"content":"<p>Page number for pagination (default: 1).</p>\n","type":"text/plain"},"key":"page","value":"1"},{"description":{"content":"<p>Number of items per page (default: 50).</p>\n","type":"text/plain"},"key":"pageSize","value":"50"},{"description":{"content":"<p>Language for text fields: \"ar\" (Arabic, default) or \"en\" (English).</p>\n","type":"text/plain"},"key":"lang","value":"ar"},{"disabled":true,"description":{"content":"<p>Optional. Narrows results to products in this category. Take the id from <strong>Get Categories</strong>. Filtering by category narrows the product set only — it does not narrow the price range.</p>\n","type":"text/plain"},"key":"categoryId","value":""}],"variable":[]}},"response":[{"id":"5b6da409-153e-4a5a-9f40-aed589d9a536","name":"OK","originalRequest":{"method":"GET","header":[{"key":"Accept","value":"text/plain"}],"url":{"raw":"https://eservices.hoicom.net/api/v0/gifts/products?searchTerm=string&sku=string&productId=string&minPrice=6039.208844241599&maxPrice=6039.208844241599&minQty=6997&maxQty=6997&sortBy=Details.ProductName&sortDescending=false&page=1&pageSize=50&lang=ar","host":["https://eservices.hoicom.net"],"path":["api","v0","gifts","products"],"query":[{"key":"fulfillmentCenterId","value":"fc_riyadh_01","description":"Optional. Restrict to one fulfillment center; makes every price exact.","disabled":true},{"key":"cityId","value":"2","description":"Optional. Restrict to the fulfillment centers in one city.","disabled":true},{"key":"searchTerm","value":"string","description":"Optional keyword to search in product names or descriptions."},{"key":"sku","value":"string","description":"Optional exact product SKU to filter by."},{"key":"productId","value":"string","description":"Optional product ID to filter by."},{"key":"minPrice","value":"6039.208844241599","description":"Optional minimum price filter."},{"key":"maxPrice","value":"6039.208844241599","description":"Optional maximum price filter."},{"key":"minQty","value":"6997","description":"Optional minimum quantity filter."},{"key":"maxQty","value":"6997","description":"Optional maximum quantity filter."},{"key":"sortBy","value":"Details.ProductName","description":"Optional field to sort by: Details.ProductName, Details.Sku, Pricing.Price, Availability.Qty."},{"key":"sortDescending","value":"false","description":"Optional whether to sort descending (default: false)."},{"key":"page","value":"1","description":"Page number for pagination (default: 1)."},{"key":"pageSize","value":"50","description":"Number of items per page (default: 50)."},{"key":"lang","value":"ar","description":"Language for text fields: \"ar\" (Arabic, default) or \"en\" (English)."}]},"description":"Returns gift products **across all fulfillment centers**. Use this to browse the full catalogue when you are not yet tied to a specific delivery area.\n\nBecause the same product costs different amounts at different fulfillment centers, an unscoped call returns a price **range** (`priceFrom` / `priceTo`) alongside the headline `price`.\n\n| Field | Unscoped | With `cityId` | With `fulfillmentCenterId` |\n| --- | --- | --- | --- |\n| `price` | Lowest purchasable price anywhere | Lowest price in that city | That center's exact price |\n| `priceFrom` | Same as `price` | Lowest price in that city | Same as `price` |\n| `priceTo` | Highest price anywhere | Highest price in that city | Same as `price` |\n\n`priceFrom` equals `priceTo` only when exactly one fulfillment center is in scope. A city with two centers still returns a genuine range.\n\n> **These prices are indicative.** To get the amount to charge and to send on an order, post the cart to **Check Availability**. Ordering off a browse price is rejected with **HTTP 400 / code 1415** whenever the recipient's center charges more.\n\n---\n\n## Authorization\n\nRequires Basic Authentication with your client credentials. Your account must be enabled for the Gifts service.\n\n---\n\n## Query Parameters\n\n| Parameter | Type | Required | Default | Description |\n| --- | --- | --- | --- | --- |\n| `cityId` | `int` | No | — | Restrict to the fulfillment centers in one city. From **Get Locations**. |\n| `fulfillmentCenterId` | `string` | No | — | Restrict to one fulfillment center, making every price exact. Takes precedence if `cityId` is also sent. |\n| `searchTerm` | `string` | No | — | Keyword to search in product names or descriptions. |\n| `sku` | `string` | No | — | Exact product SKU to filter by. |\n| `productId` | `string` | No | — | Product ID to filter by. |\n| `minPrice` | `decimal` | No | — | Minimum price filter, applied to the lowest price in scope. |\n| `maxPrice` | `decimal` | No | — | Maximum price filter, applied to the lowest price in scope. |\n| `minQty` | `int` | No | — | Minimum available-quantity filter, across the centers in scope. |\n| `maxQty` | `int` | No | — | Maximum available-quantity filter, across the centers in scope. |\n| `sortBy` | `string` | No | `Details.ProductName` | Sort field. One of: `Details.ProductName`, `Details.Sku`, `Pricing.Price`, `Availability.Qty`. |\n| `sortDescending` | `bool` | No | `false` | Sort in descending order. |\n| `page` | `int` | No | `1` | Page number for pagination. |\n| `pageSize` | `int` | No | `50` | Number of items per page. |\n| `lang` | `string` | No | `ar` | Language for text fields: `ar` (Arabic) or `en` (English). |\n| `categoryId` | `string` | No | — | Filter to products tagged with this category id. Take the id from **Get Categories**. Narrows the product set only — it does not change the price range. |\n\nOnly products with active stock at one or more fulfillment centers are returned. A `cityId` or `fulfillmentCenterId` that does not resolve to an active fulfillment center you are entitled to returns an **empty page** — HTTP 200, code `1000`, `items: []` — not a 404.\n\n---\n\n## Response\n\nOn success `code` is `1000` and `data` holds a paginated list of products (details + pricing). See the example below.\n\n> **No matches is a `200`, not a `404`.** `?categoryId=` with nothing matching returns `code` `1000` and an empty `items: []`. Compare **Get Products by Fulfillment Center**, which returns `404` for the same case."},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"cookie":[],"responseTime":null,"body":"{\n  \"code\": 1000,\n  \"message\": \"Success\",\n  \"data\": {\n    \"items\": [\n      {\n        \"id\": \"prod_10021\",\n        \"details\": {\n          \"name\": \"Red Roses Bouquet\",\n          \"sku\": \"FLW-ROSE-RED-12\",\n          \"mainImage\": \"https://cdn.example.com/products/roses-red.jpg\",\n          \"imageUrls\": [\n            \"https://cdn.example.com/products/roses-red-1.jpg\",\n            \"https://cdn.example.com/products/roses-red-2.jpg\"\n          ],\n          \"description\": \"A dozen premium long-stem red roses, hand-arranged.\",\n          \"shortDescription\": \"12 premium red roses\"\n        },\n        \"pricing\": {\n          \"price\": 217.39,\n          \"priceFrom\": 217.39,\n          \"priceTo\": 230,\n          \"vat\": 15,\n          \"currency\": \"SAR\",\n          \"total\": 249.9985,\n          \"deliveryFee\": {\n            \"amount\": 21.74,\n            \"vatAmount\": 3.26,\n            \"total\": 25,\n            \"currency\": \"SAR\"\n          }\n        },\n        \"provider\": {\n          \"name\": \"Floward\",\n          \"logoUrls\": [\n            \"https://cdn.example.com/logos/provider.png\"\n          ],\n          \"fulfillmentCenter\": {\n            \"id\": \"fc_riyadh_01\",\n            \"name\": \"Riyadh\"\n          }\n        }\n      }\n    ],\n    \"count\": 1,\n    \"page\": 1,\n    \"pageSize\": 50,\n    \"totalPages\": 1,\n    \"totalItems\": 1\n  }\n}"},{"id":"53a31442-f9f5-47e1-b1cb-bded0a3951e1","name":"Internal Server Error","originalRequest":{"method":"GET","header":[],"url":{"raw":"https://eservices.hoicom.net/api/v0/gifts/products?searchTerm=string&sku=string&productId=string&minPrice=6039.208844241599&maxPrice=6039.208844241599&minQty=6997&maxQty=6997&sortBy=Details.ProductName&sortDescending=false&page=1&pageSize=50&lang=ar","host":["https://eservices.hoicom.net"],"path":["api","v0","gifts","products"],"query":[{"key":"fulfillmentCenterId","value":"fc_riyadh_01","description":"Optional. Restrict to one fulfillment center; makes every price exact.","disabled":true},{"key":"cityId","value":"2","description":"Optional. Restrict to the fulfillment centers in one city.","disabled":true},{"key":"searchTerm","value":"string","description":"Optional keyword to search in product names or descriptions."},{"key":"sku","value":"string","description":"Optional exact product SKU to filter by."},{"key":"productId","value":"string","description":"Optional product ID to filter by."},{"key":"minPrice","value":"6039.208844241599","description":"Optional minimum price filter."},{"key":"maxPrice","value":"6039.208844241599","description":"Optional maximum price filter."},{"key":"minQty","value":"6997","description":"Optional minimum quantity filter."},{"key":"maxQty","value":"6997","description":"Optional maximum quantity filter."},{"key":"sortBy","value":"Details.ProductName","description":"Optional field to sort by: Details.ProductName, Details.Sku, Pricing.Price, Availability.Qty."},{"key":"sortDescending","value":"false","description":"Optional whether to sort descending (default: false)."},{"key":"page","value":"1","description":"Page number for pagination (default: 1)."},{"key":"pageSize","value":"50","description":"Number of items per page (default: 50)."},{"key":"lang","value":"ar","description":"Language for text fields: \"ar\" (Arabic, default) or \"en\" (English)."}]},"description":"Returns gift products **across all fulfillment centers**. Use this to browse the full catalogue when you are not yet tied to a specific delivery area.\n\nBecause the same product costs different amounts at different fulfillment centers, an unscoped call returns a price **range** (`priceFrom` / `priceTo`) alongside the headline `price`.\n\n| Field | Unscoped | With `cityId` | With `fulfillmentCenterId` |\n| --- | --- | --- | --- |\n| `price` | Lowest purchasable price anywhere | Lowest price in that city | That center's exact price |\n| `priceFrom` | Same as `price` | Lowest price in that city | Same as `price` |\n| `priceTo` | Highest price anywhere | Highest price in that city | Same as `price` |\n\n`priceFrom` equals `priceTo` only when exactly one fulfillment center is in scope. A city with two centers still returns a genuine range.\n\n> **These prices are indicative.** To get the amount to charge and to send on an order, post the cart to **Check Availability**. Ordering off a browse price is rejected with **HTTP 400 / code 1415** whenever the recipient's center charges more.\n\n---\n\n## Authorization\n\nRequires Basic Authentication with your client credentials. Your account must be enabled for the Gifts service.\n\n---\n\n## Query Parameters\n\n| Parameter | Type | Required | Default | Description |\n| --- | --- | --- | --- | --- |\n| `cityId` | `int` | No | — | Restrict to the fulfillment centers in one city. From **Get Locations**. |\n| `fulfillmentCenterId` | `string` | No | — | Restrict to one fulfillment center, making every price exact. Takes precedence if `cityId` is also sent. |\n| `searchTerm` | `string` | No | — | Keyword to search in product names or descriptions. |\n| `sku` | `string` | No | — | Exact product SKU to filter by. |\n| `productId` | `string` | No | — | Product ID to filter by. |\n| `minPrice` | `decimal` | No | — | Minimum price filter, applied to the lowest price in scope. |\n| `maxPrice` | `decimal` | No | — | Maximum price filter, applied to the lowest price in scope. |\n| `minQty` | `int` | No | — | Minimum available-quantity filter, across the centers in scope. |\n| `maxQty` | `int` | No | — | Maximum available-quantity filter, across the centers in scope. |\n| `sortBy` | `string` | No | `Details.ProductName` | Sort field. One of: `Details.ProductName`, `Details.Sku`, `Pricing.Price`, `Availability.Qty`. |\n| `sortDescending` | `bool` | No | `false` | Sort in descending order. |\n| `page` | `int` | No | `1` | Page number for pagination. |\n| `pageSize` | `int` | No | `50` | Number of items per page. |\n| `lang` | `string` | No | `ar` | Language for text fields: `ar` (Arabic) or `en` (English). |\n| `categoryId` | `string` | No | — | Filter to products tagged with this category id. Take the id from **Get Categories**. Narrows the product set only — it does not change the price range. |\n\nOnly products with active stock at one or more fulfillment centers are returned. A `cityId` or `fulfillmentCenterId` that does not resolve to an active fulfillment center you are entitled to returns an **empty page** — HTTP 200, code `1000`, `items: []` — not a 404.\n\n---\n\n## Response\n\nOn success `code` is `1000` and `data` holds a paginated list of products (details + pricing). See the example below.\n\n> **No matches is a `200`, not a `404`.** `?categoryId=` with nothing matching returns `code` `1000` and an empty `items: []`. Compare **Get Products by Fulfillment Center**, which returns `404` for the same case."},"status":"Internal Server Error","code":500,"_postman_previewlanguage":"text","header":[],"cookie":[],"responseTime":null,"body":""},{"id":"3e5ed2b4-2484-4668-8294-1e5256b3a5c7","name":"Service Unavailable","originalRequest":{"method":"GET","header":[],"url":{"raw":"https://eservices.hoicom.net/api/v0/gifts/products?searchTerm=string&sku=string&productId=string&minPrice=6039.208844241599&maxPrice=6039.208844241599&minQty=6997&maxQty=6997&sortBy=Details.ProductName&sortDescending=false&page=1&pageSize=50&lang=ar","host":["https://eservices.hoicom.net"],"path":["api","v0","gifts","products"],"query":[{"key":"fulfillmentCenterId","value":"fc_riyadh_01","description":"Optional. Restrict to one fulfillment center; makes every price exact.","disabled":true},{"key":"cityId","value":"2","description":"Optional. Restrict to the fulfillment centers in one city.","disabled":true},{"key":"searchTerm","value":"string","description":"Optional keyword to search in product names or descriptions."},{"key":"sku","value":"string","description":"Optional exact product SKU to filter by."},{"key":"productId","value":"string","description":"Optional product ID to filter by."},{"key":"minPrice","value":"6039.208844241599","description":"Optional minimum price filter."},{"key":"maxPrice","value":"6039.208844241599","description":"Optional maximum price filter."},{"key":"minQty","value":"6997","description":"Optional minimum quantity filter."},{"key":"maxQty","value":"6997","description":"Optional maximum quantity filter."},{"key":"sortBy","value":"Details.ProductName","description":"Optional field to sort by: Details.ProductName, Details.Sku, Pricing.Price, Availability.Qty."},{"key":"sortDescending","value":"false","description":"Optional whether to sort descending (default: false)."},{"key":"page","value":"1","description":"Page number for pagination (default: 1)."},{"key":"pageSize","value":"50","description":"Number of items per page (default: 50)."},{"key":"lang","value":"ar","description":"Language for text fields: \"ar\" (Arabic, default) or \"en\" (English)."}]},"description":"Returns gift products **across all fulfillment centers**. Use this to browse the full catalogue when you are not yet tied to a specific delivery area.\n\nBecause the same product costs different amounts at different fulfillment centers, an unscoped call returns a price **range** (`priceFrom` / `priceTo`) alongside the headline `price`.\n\n| Field | Unscoped | With `cityId` | With `fulfillmentCenterId` |\n| --- | --- | --- | --- |\n| `price` | Lowest purchasable price anywhere | Lowest price in that city | That center's exact price |\n| `priceFrom` | Same as `price` | Lowest price in that city | Same as `price` |\n| `priceTo` | Highest price anywhere | Highest price in that city | Same as `price` |\n\n`priceFrom` equals `priceTo` only when exactly one fulfillment center is in scope. A city with two centers still returns a genuine range.\n\n> **These prices are indicative.** To get the amount to charge and to send on an order, post the cart to **Check Availability**. Ordering off a browse price is rejected with **HTTP 400 / code 1415** whenever the recipient's center charges more.\n\n---\n\n## Authorization\n\nRequires Basic Authentication with your client credentials. Your account must be enabled for the Gifts service.\n\n---\n\n## Query Parameters\n\n| Parameter | Type | Required | Default | Description |\n| --- | --- | --- | --- | --- |\n| `cityId` | `int` | No | — | Restrict to the fulfillment centers in one city. From **Get Locations**. |\n| `fulfillmentCenterId` | `string` | No | — | Restrict to one fulfillment center, making every price exact. Takes precedence if `cityId` is also sent. |\n| `searchTerm` | `string` | No | — | Keyword to search in product names or descriptions. |\n| `sku` | `string` | No | — | Exact product SKU to filter by. |\n| `productId` | `string` | No | — | Product ID to filter by. |\n| `minPrice` | `decimal` | No | — | Minimum price filter, applied to the lowest price in scope. |\n| `maxPrice` | `decimal` | No | — | Maximum price filter, applied to the lowest price in scope. |\n| `minQty` | `int` | No | — | Minimum available-quantity filter, across the centers in scope. |\n| `maxQty` | `int` | No | — | Maximum available-quantity filter, across the centers in scope. |\n| `sortBy` | `string` | No | `Details.ProductName` | Sort field. One of: `Details.ProductName`, `Details.Sku`, `Pricing.Price`, `Availability.Qty`. |\n| `sortDescending` | `bool` | No | `false` | Sort in descending order. |\n| `page` | `int` | No | `1` | Page number for pagination. |\n| `pageSize` | `int` | No | `50` | Number of items per page. |\n| `lang` | `string` | No | `ar` | Language for text fields: `ar` (Arabic) or `en` (English). |\n| `categoryId` | `string` | No | — | Filter to products tagged with this category id. Take the id from **Get Categories**. Narrows the product set only — it does not change the price range. |\n\nOnly products with active stock at one or more fulfillment centers are returned. A `cityId` or `fulfillmentCenterId` that does not resolve to an active fulfillment center you are entitled to returns an **empty page** — HTTP 200, code `1000`, `items: []` — not a 404.\n\n---\n\n## Response\n\nOn success `code` is `1000` and `data` holds a paginated list of products (details + pricing). See the example below.\n\n> **No matches is a `200`, not a `404`.** `?categoryId=` with nothing matching returns `code` `1000` and an empty `items: []`. Compare **Get Products by Fulfillment Center**, which returns `404` for the same case."},"status":"Service Unavailable","code":503,"_postman_previewlanguage":"text","header":[],"cookie":[],"responseTime":null,"body":""}],"_postman_id":"7d37b92a-9b42-4e36-bea8-c431a767922e"},{"name":"Check Availability","id":"8fadc6c9-32d1-4bc6-b3dc-860dc60c5674","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"body":{"mode":"raw","raw":"{\n  \"items\": [\n    {\n      \"productId\": \"prod_10021\",\n      \"quantity\": 2\n    },\n    {\n      \"productId\": \"prod_10877\",\n      \"quantity\": 1\n    }\n  ],\n  \"cityId\": 2\n}","options":{"raw":{"language":"json"}}},"url":"https://eservices.hoicom.net/api/v0/gifts/availability","description":"<p>Confirms whether a cart can actually be delivered, and returns the binding price to charge (products plus delivery).</p>\n<p>A gift order is fulfilled from a <strong>single</strong> fulfillment center, so a multi-item cart is only orderable if one center stocks every item in the requested quantities. This endpoint evaluates the whole cart against each candidate center and reports the outcome per center and per item.</p>\n<p>The <code>total</code> on an available center includes the delivery fee. It is the amount to charge the customer and to send as <code>amount</code> on <strong>Create Order</strong>, which must equal it (±0.01). Prices from <strong>Get Products</strong> are indicative and must not be used for either.</p>\n<hr />\n<h2 id=\"authorization\">Authorization</h2>\n<p>Requires Basic Authentication with your client credentials. Your account must be enabled for the Gifts service.</p>\n<hr />\n<h2 id=\"scope\">Scope</h2>\n<p>Supply <strong>at most one</strong> of <code>cityId</code> or <code>fulfillmentCenterId</code>. Supplying both is a validation error.</p>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Scope</th>\n<th>Which centers are returned</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>None</td>\n<td>Only centers that can serve the <strong>entire</strong> cart. An empty <code>fulfillmentCenters</code> array means no single center can fulfil this cart anywhere.</td>\n</tr>\n<tr>\n<td><code>cityId</code></td>\n<td>Every active center in that city, available or not, each with per-item reasons.</td>\n</tr>\n<tr>\n<td><code>fulfillmentCenterId</code></td>\n<td>That one center, available or not, with per-item reasons.</td>\n</tr>\n</tbody>\n</table>\n</div><hr />\n<h2 id=\"request-body\">Request Body</h2>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Field</th>\n<th>Type</th>\n<th>Required</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>items</code></td>\n<td><code>array</code></td>\n<td>Yes</td>\n<td>1–20 entries. Duplicate <code>productId</code> values are summed into a single line.</td>\n</tr>\n<tr>\n<td><code>items[].productId</code></td>\n<td><code>string</code></td>\n<td>Yes</td>\n<td>Numeric product id from <strong>Get Products</strong>.</td>\n</tr>\n<tr>\n<td><code>items[].quantity</code></td>\n<td><code>int</code></td>\n<td>Yes</td>\n<td>Between <code>1</code> and <code>99</code>.</td>\n</tr>\n<tr>\n<td><code>cityId</code></td>\n<td><code>int</code></td>\n<td>No</td>\n<td>City id from <strong>Get Locations</strong>. Mutually exclusive with <code>fulfillmentCenterId</code>.</td>\n</tr>\n<tr>\n<td><code>fulfillmentCenterId</code></td>\n<td><code>string</code></td>\n<td>No</td>\n<td>Fulfillment center id from <strong>Get Locations</strong>. Mutually exclusive with <code>cityId</code>.</td>\n</tr>\n</tbody>\n</table>\n</div><hr />\n<h2 id=\"response\">Response</h2>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Field</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>isAvailable</code></td>\n<td><code>true</code> if at least one returned center can serve the whole cart.</td>\n</tr>\n<tr>\n<td><code>fulfillmentCenters[]</code></td>\n<td>Candidate centers, ordered by country, then city, then <code>total</code> ascending.</td>\n</tr>\n<tr>\n<td><code>fulfillmentCenters[].id</code></td>\n<td>Use as <code>recipient.fulfillmentCenterId</code> on <strong>Create Order</strong>, and in the <strong>Get Delivery Time Slots</strong> path.</td>\n</tr>\n<tr>\n<td><code>fulfillmentCenters[].isAvailable</code></td>\n<td><code>true</code> only if <strong>every</strong> item is available here.</td>\n</tr>\n<tr>\n<td><code>fulfillmentCenters[].deliveryFee</code></td>\n<td>Delivery fee at this center: <code>{ amount, vatAmount, total, currency }</code>. Charged once per order. Present for unavailable centers too.</td>\n</tr>\n<tr>\n<td><code>fulfillmentCenters[].total</code></td>\n<td>VAT-inclusive cart total at this center <strong>including the delivery fee</strong> (items plus <code>deliveryFee.total</code>), and the exact order <code>amount</code> to send. <strong><code>0</code> when the center is unavailable.</strong></td>\n</tr>\n<tr>\n<td><code>items[].quantity</code></td>\n<td>The <strong>summed</strong> quantity for that product — one entry per distinct <code>productId</code>.</td>\n</tr>\n<tr>\n<td><code>items[].availableQty</code></td>\n<td>Stock held at this center. <code>0</code> when the product is unknown or not stocked here.</td>\n</tr>\n<tr>\n<td><code>items[].unitPrice</code></td>\n<td>VAT-exclusive unit price at this center.</td>\n</tr>\n<tr>\n<td><code>items[].lineTotal</code></td>\n<td>Item total including VAT. <code>0</code> for an unavailable item.</td>\n</tr>\n<tr>\n<td><code>items[].reason</code></td>\n<td><code>null</code> when the item is available; otherwise one of the values below.</td>\n</tr>\n</tbody>\n</table>\n</div><p>Because unavailable centers report <code>total: 0</code>, they can sort ahead of available ones. <strong>Always select a center by <code>isAvailable</code>, never by position</strong>, and read the center's <code>total</code> rather than summing <code>lineTotal</code> yourself (it also contains the delivery fee).</p>\n<h3 id=\"reasons\">Reasons</h3>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Reason</th>\n<th>Meaning</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>ProductNotFound</code></td>\n<td>No such product id in the catalogue.</td>\n</tr>\n<tr>\n<td><code>NotStockedAtFulfillmentCenter</code></td>\n<td>The product is real, but this center does not carry it.</td>\n</tr>\n<tr>\n<td><code>InsufficientQuantity</code></td>\n<td>Stocked here, but <code>availableQty</code> is less than the requested quantity.</td>\n</tr>\n<tr>\n<td><code>Inactive</code></td>\n<td>Stocked here, but not currently sellable.</td>\n</tr>\n</tbody>\n</table>\n</div><hr />\n<h2 id=\"notes\">Notes</h2>\n<ul>\n<li>\"Not available\" is a <strong>success</strong> response: HTTP 200, code <code>1000</code>, <code>isAvailable: false</code>. This endpoint never returns 404 for an unfulfillable cart.</li>\n<li>An unknown or inactive <code>cityId</code> / <code>fulfillmentCenterId</code>, or one your account is not entitled to, returns <code>isAvailable: false</code> with an empty <code>fulfillmentCenters</code> array.</li>\n<li>If the delivery prices cannot be read, this endpoint returns <strong>HTTP 404 / code <code>1303</code></strong>. Retry later.</li>\n<li>Availability reflects stock at the moment of the call. Re-check immediately before charging.</li>\n</ul>\n<hr />\n<h2 id=\"response-fields\">Response fields</h2>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Field</th>\n<th>Type</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>code</td>\n<td>int</td>\n<td>Response status code. <code>1000</code> on success - an unfulfillable cart is still a <code>1000</code> success with <code>isAvailable: false</code>.</td>\n</tr>\n<tr>\n<td>message</td>\n<td>string</td>\n<td>Human-readable status message.</td>\n</tr>\n<tr>\n<td>data</td>\n<td>object</td>\n<td>Availability result for the submitted cart.</td>\n</tr>\n<tr>\n<td>data.isAvailable</td>\n<td>bool</td>\n<td><code>true</code> if at least one returned fulfillment center can serve the whole cart.</td>\n</tr>\n<tr>\n<td>data.fulfillmentCenters</td>\n<td>array</td>\n<td>Candidate fulfillment centers, ordered by country, then city, then <code>total</code> ascending. Empty when no center (in scope) can serve the cart.</td>\n</tr>\n<tr>\n<td>data.fulfillmentCenters[].id</td>\n<td>string</td>\n<td>Fulfillment center id. Use as <code>recipient.fulfillmentCenterId</code> on Create Order and in the Get Delivery Time Slots path.</td>\n</tr>\n<tr>\n<td>data.fulfillmentCenters[].name</td>\n<td>string</td>\n<td>Fulfillment center display name.</td>\n</tr>\n<tr>\n<td>data.fulfillmentCenters[].city</td>\n<td>object</td>\n<td>City this fulfillment center serves.</td>\n</tr>\n<tr>\n<td>data.fulfillmentCenters[].city.id</td>\n<td>int</td>\n<td>City id.</td>\n</tr>\n<tr>\n<td>data.fulfillmentCenters[].city.name</td>\n<td>string</td>\n<td>City display name.</td>\n</tr>\n<tr>\n<td>data.fulfillmentCenters[].country</td>\n<td>object</td>\n<td>Country this fulfillment center is in.</td>\n</tr>\n<tr>\n<td>data.fulfillmentCenters[].country.isoCode</td>\n<td>string</td>\n<td>ISO country code.</td>\n</tr>\n<tr>\n<td>data.fulfillmentCenters[].country.name</td>\n<td>string</td>\n<td>Country display name.</td>\n</tr>\n<tr>\n<td>data.fulfillmentCenters[].isAvailable</td>\n<td>bool</td>\n<td><code>true</code> only if every requested item is available at this center.</td>\n</tr>\n<tr>\n<td>data.fulfillmentCenters[].currency</td>\n<td>string</td>\n<td>3-letter currency code for <code>total</code> and the item amounts below.</td>\n</tr>\n<tr>\n<td>data.fulfillmentCenters[].deliveryFee</td>\n<td>object</td>\n<td>Delivery fee at this center, charged once per order. Present even when the center is unavailable.</td>\n</tr>\n<tr>\n<td>data.fulfillmentCenters[].deliveryFee.amount</td>\n<td>decimal</td>\n<td>VAT-exclusive delivery fee.</td>\n</tr>\n<tr>\n<td>data.fulfillmentCenters[].deliveryFee.vatAmount</td>\n<td>decimal</td>\n<td>VAT on the delivery fee.</td>\n</tr>\n<tr>\n<td>data.fulfillmentCenters[].deliveryFee.total</td>\n<td>decimal</td>\n<td>VAT-inclusive delivery fee (<code>amount</code> + <code>vatAmount</code>).</td>\n</tr>\n<tr>\n<td>data.fulfillmentCenters[].deliveryFee.currency</td>\n<td>string</td>\n<td>Currency code.</td>\n</tr>\n<tr>\n<td>data.fulfillmentCenters[].total</td>\n<td>decimal</td>\n<td>VAT-inclusive cart total at this center including the delivery fee (items plus <code>deliveryFee.total</code>) - the binding amount to charge and to send as <code>amount</code> on Create Order. <code>0</code> when the center is unavailable.</td>\n</tr>\n<tr>\n<td>data.fulfillmentCenters[].items</td>\n<td>array</td>\n<td>Per-item availability at this center, one entry per distinct <code>productId</code> (quantities for duplicate <code>productId</code> values are summed).</td>\n</tr>\n<tr>\n<td>data.fulfillmentCenters[].items[].productId</td>\n<td>string</td>\n<td>Product id, as submitted in the request.</td>\n</tr>\n<tr>\n<td>data.fulfillmentCenters[].items[].quantity</td>\n<td>int</td>\n<td>Summed requested quantity for this product.</td>\n</tr>\n<tr>\n<td>data.fulfillmentCenters[].items[].isAvailable</td>\n<td>bool</td>\n<td><code>true</code> if this item can be fulfilled here in the requested quantity.</td>\n</tr>\n<tr>\n<td>data.fulfillmentCenters[].items[].availableQty</td>\n<td>int</td>\n<td>Stock held for this product at this center. <code>0</code> when the product is unknown or not stocked here.</td>\n</tr>\n<tr>\n<td>data.fulfillmentCenters[].items[].unitPrice</td>\n<td>decimal</td>\n<td>VAT-exclusive unit price at this center.</td>\n</tr>\n<tr>\n<td>data.fulfillmentCenters[].items[].vat</td>\n<td>decimal</td>\n<td>VAT amount applied to this item's line.</td>\n</tr>\n<tr>\n<td>data.fulfillmentCenters[].items[].lineTotal</td>\n<td>decimal</td>\n<td>VAT-inclusive line total for this item's quantity. <code>0</code> when the item is unavailable.</td>\n</tr>\n<tr>\n<td>data.fulfillmentCenters[].items[].reason</td>\n<td>string (values: ProductNotFound</td>\n<td>NotStockedAtFulfillmentCenter</td>\n</tr>\n</tbody>\n</table>\n</div>","urlObject":{"path":["api","v0","gifts","availability"],"host":["https://eservices.hoicom.net"],"query":[],"variable":[]}},"response":[{"id":"71985d06-2096-482f-b003-54e3312f85ae","name":"OK - Available","originalRequest":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"body":{"mode":"raw","raw":"{\n  \"items\": [\n    {\n      \"productId\": \"prod_10021\",\n      \"quantity\": 2\n    },\n    {\n      \"productId\": \"prod_10877\",\n      \"quantity\": 1\n    }\n  ],\n  \"cityId\": 2\n}","options":{"raw":{"language":"json"}}},"url":"https://eservices.hoicom.net/api/v0/gifts/availability","description":"Confirms whether a cart can actually be delivered, and returns the binding price to charge.\n\nA gift order is fulfilled from a **single** fulfillment center, so a multi-item cart is only orderable if one center stocks every item in the requested quantities. This endpoint evaluates the whole cart against each candidate center and reports the outcome per center and per item.\n\nThe `total` on an available center is the amount to charge the customer and to send as `amount` on **Create Order**. Prices from **Get Products** are indicative and must not be used for either.\n\n---\n\n## Authorization\n\nRequires Basic Authentication with your client credentials. Your account must be enabled for the Gifts service.\n\n---\n\n## Scope\n\nSupply **at most one** of `cityId` or `fulfillmentCenterId`. Supplying both is a validation error.\n\n| Scope | Which centers are returned |\n| --- | --- |\n| None | Only centers that can serve the **entire** cart. An empty `fulfillmentCenters` array means no single center can fulfil this cart anywhere. |\n| `cityId` | Every active center in that city, available or not, each with per-item reasons. |\n| `fulfillmentCenterId` | That one center, available or not, with per-item reasons. |\n\n---\n\n## Request Body\n\n| Field | Type | Required | Description |\n| --- | --- | --- | --- |\n| `items` | `array` | Yes | 1–20 entries. Duplicate `productId` values are summed into a single line. |\n| `items[].productId` | `string` | Yes | Numeric product id from **Get Products**. |\n| `items[].quantity` | `int` | Yes | Between `1` and `99`. |\n| `cityId` | `int` | No | City id from **Get Locations**. Mutually exclusive with `fulfillmentCenterId`. |\n| `fulfillmentCenterId` | `string` | No | Fulfillment center id from **Get Locations**. Mutually exclusive with `cityId`. |\n\n---\n\n## Response\n\n| Field | Description |\n| --- | --- |\n| `isAvailable` | `true` if at least one returned center can serve the whole cart. |\n| `fulfillmentCenters[]` | Candidate centers, ordered by country, then city, then `total` ascending. |\n| `fulfillmentCenters[].id` | Use as `recipient.fulfillmentCenterId` on **Create Order**, and in the **Get Delivery Time Slots** path. |\n| `fulfillmentCenters[].isAvailable` | `true` only if **every** item is available here. |\n| `fulfillmentCenters[].total` | VAT-inclusive cart total at this center, and the minimum acceptable order `amount`. **`0` when the center is unavailable.** |\n| `items[].quantity` | The **summed** quantity for that product — one entry per distinct `productId`. |\n| `items[].availableQty` | Stock held at this center. `0` when the product is unknown or not stocked here. |\n| `items[].unitPrice` | VAT-exclusive unit price at this center. |\n| `items[].lineTotal` | Item total including VAT. `0` for an unavailable item. |\n| `items[].reason` | `null` when the item is available; otherwise one of the values below. |\n\nBecause unavailable centers report `total: 0`, they can sort ahead of available ones. **Always select a center by `isAvailable`, never by position**, and read the center's `total` rather than summing `lineTotal` yourself.\n\n### Reasons\n\n| Reason | Meaning |\n| --- | --- |\n| `ProductNotFound` | No such product id in the catalogue. |\n| `NotStockedAtFulfillmentCenter` | The product is real, but this center does not carry it. |\n| `InsufficientQuantity` | Stocked here, but `availableQty` is less than the requested quantity. |\n| `Inactive` | Stocked here, but not currently sellable. |\n\n---\n\n## Notes\n\n- \"Not available\" is a **success** response: HTTP 200, code `1000`, `isAvailable: false`. This endpoint never returns 404 for an unfulfillable cart.\n- An unknown or inactive `cityId` / `fulfillmentCenterId`, or one your account is not entitled to, returns `isAvailable: false` with an empty `fulfillmentCenters` array.\n- Availability reflects stock at the moment of the call. Re-check immediately before charging."},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"cookie":[],"responseTime":null,"body":"{\n  \"code\": 1000,\n  \"message\": \"Success\",\n  \"data\": {\n    \"isAvailable\": true,\n    \"fulfillmentCenters\": [\n      {\n        \"id\": \"fc_riyadh_01\",\n        \"name\": \"Riyadh Central\",\n        \"city\": {\n          \"id\": 2,\n          \"name\": \"Riyadh\"\n        },\n        \"country\": {\n          \"isoCode\": \"SAU\",\n          \"name\": \"Saudi Arabia\"\n        },\n        \"isAvailable\": true,\n        \"currency\": \"SAR\",\n        \"deliveryFee\": {\n          \"amount\": 21.74,\n          \"vatAmount\": 3.26,\n          \"total\": 25,\n          \"currency\": \"SAR\"\n        },\n        \"total\": 275,\n        \"items\": [\n          {\n            \"productId\": \"prod_10021\",\n            \"quantity\": 1,\n            \"isAvailable\": true,\n            \"availableQty\": 20,\n            \"unitPrice\": 217.39,\n            \"vat\": 15,\n            \"lineTotal\": 250,\n            \"reason\": null\n          }\n        ]\n      }\n    ]\n  }\n}"},{"id":"60db5075-6027-481b-ae15-05d64bc08c6a","name":"OK - Unavailable with reasons","originalRequest":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"body":{"mode":"raw","raw":"{\n  \"items\": [\n    {\n      \"productId\": \"prod_10021\",\n      \"quantity\": 2\n    },\n    {\n      \"productId\": \"prod_10877\",\n      \"quantity\": 1\n    }\n  ],\n  \"cityId\": 2\n}","options":{"raw":{"language":"json"}}},"url":"https://eservices.hoicom.net/api/v0/gifts/availability","description":"Confirms whether a cart can actually be delivered, and returns the binding price to charge.\n\nA gift order is fulfilled from a **single** fulfillment center, so a multi-item cart is only orderable if one center stocks every item in the requested quantities. This endpoint evaluates the whole cart against each candidate center and reports the outcome per center and per item.\n\nThe `total` on an available center is the amount to charge the customer and to send as `amount` on **Create Order**. Prices from **Get Products** are indicative and must not be used for either.\n\n---\n\n## Authorization\n\nRequires Basic Authentication with your client credentials. Your account must be enabled for the Gifts service.\n\n---\n\n## Scope\n\nSupply **at most one** of `cityId` or `fulfillmentCenterId`. Supplying both is a validation error.\n\n| Scope | Which centers are returned |\n| --- | --- |\n| None | Only centers that can serve the **entire** cart. An empty `fulfillmentCenters` array means no single center can fulfil this cart anywhere. |\n| `cityId` | Every active center in that city, available or not, each with per-item reasons. |\n| `fulfillmentCenterId` | That one center, available or not, with per-item reasons. |\n\n---\n\n## Request Body\n\n| Field | Type | Required | Description |\n| --- | --- | --- | --- |\n| `items` | `array` | Yes | 1–20 entries. Duplicate `productId` values are summed into a single line. |\n| `items[].productId` | `string` | Yes | Numeric product id from **Get Products**. |\n| `items[].quantity` | `int` | Yes | Between `1` and `99`. |\n| `cityId` | `int` | No | City id from **Get Locations**. Mutually exclusive with `fulfillmentCenterId`. |\n| `fulfillmentCenterId` | `string` | No | Fulfillment center id from **Get Locations**. Mutually exclusive with `cityId`. |\n\n---\n\n## Response\n\n| Field | Description |\n| --- | --- |\n| `isAvailable` | `true` if at least one returned center can serve the whole cart. |\n| `fulfillmentCenters[]` | Candidate centers, ordered by country, then city, then `total` ascending. |\n| `fulfillmentCenters[].id` | Use as `recipient.fulfillmentCenterId` on **Create Order**, and in the **Get Delivery Time Slots** path. |\n| `fulfillmentCenters[].isAvailable` | `true` only if **every** item is available here. |\n| `fulfillmentCenters[].total` | VAT-inclusive cart total at this center, and the minimum acceptable order `amount`. **`0` when the center is unavailable.** |\n| `items[].quantity` | The **summed** quantity for that product — one entry per distinct `productId`. |\n| `items[].availableQty` | Stock held at this center. `0` when the product is unknown or not stocked here. |\n| `items[].unitPrice` | VAT-exclusive unit price at this center. |\n| `items[].lineTotal` | Item total including VAT. `0` for an unavailable item. |\n| `items[].reason` | `null` when the item is available; otherwise one of the values below. |\n\nBecause unavailable centers report `total: 0`, they can sort ahead of available ones. **Always select a center by `isAvailable`, never by position**, and read the center's `total` rather than summing `lineTotal` yourself.\n\n### Reasons\n\n| Reason | Meaning |\n| --- | --- |\n| `ProductNotFound` | No such product id in the catalogue. |\n| `NotStockedAtFulfillmentCenter` | The product is real, but this center does not carry it. |\n| `InsufficientQuantity` | Stocked here, but `availableQty` is less than the requested quantity. |\n| `Inactive` | Stocked here, but not currently sellable. |\n\n---\n\n## Notes\n\n- \"Not available\" is a **success** response: HTTP 200, code `1000`, `isAvailable: false`. This endpoint never returns 404 for an unfulfillable cart.\n- An unknown or inactive `cityId` / `fulfillmentCenterId`, or one your account is not entitled to, returns `isAvailable: false` with an empty `fulfillmentCenters` array.\n- Availability reflects stock at the moment of the call. Re-check immediately before charging."},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"cookie":[],"responseTime":null,"body":"{\n  \"code\": 1000,\n  \"message\": \"Success\",\n  \"data\": {\n    \"isAvailable\": false,\n    \"fulfillmentCenters\": [\n      {\n        \"id\": \"fc_jeddah_01\",\n        \"name\": \"Jeddah Central\",\n        \"city\": {\n          \"id\": 3,\n          \"name\": \"Jeddah\"\n        },\n        \"country\": {\n          \"isoCode\": \"SAU\",\n          \"name\": \"Saudi Arabia\"\n        },\n        \"isAvailable\": false,\n        \"currency\": \"SAR\",\n        \"deliveryFee\": {\n          \"amount\": 21.74,\n          \"vatAmount\": 3.26,\n          \"total\": 25,\n          \"currency\": \"SAR\"\n        },\n        \"total\": 0,\n        \"items\": [\n          {\n            \"productId\": \"prod_10021\",\n            \"quantity\": 50,\n            \"isAvailable\": false,\n            \"availableQty\": 4,\n            \"unitPrice\": 140,\n            \"vat\": 15,\n            \"lineTotal\": 0,\n            \"reason\": \"InsufficientQuantity\"\n          },\n          {\n            \"productId\": \"prod_10510\",\n            \"quantity\": 1,\n            \"isAvailable\": true,\n            \"availableQty\": 22,\n            \"unitPrice\": 95,\n            \"vat\": 15,\n            \"lineTotal\": 109.25,\n            \"reason\": null\n          },\n          {\n            \"productId\": \"prod_77001\",\n            \"quantity\": 1,\n            \"isAvailable\": false,\n            \"availableQty\": 0,\n            \"unitPrice\": 0,\n            \"vat\": 0,\n            \"lineTotal\": 0,\n            \"reason\": \"ProductNotFound\"\n          }\n        ]\n      }\n    ]\n  }\n}"},{"id":"5ff64b5a-0893-4004-9c25-b9d64b2b195a","name":"OK - No center can serve this cart","originalRequest":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"body":{"mode":"raw","raw":"{\n  \"items\": [\n    {\n      \"productId\": \"prod_10021\",\n      \"quantity\": 2\n    },\n    {\n      \"productId\": \"prod_10877\",\n      \"quantity\": 1\n    }\n  ],\n  \"cityId\": 2\n}","options":{"raw":{"language":"json"}}},"url":"https://eservices.hoicom.net/api/v0/gifts/availability","description":"Confirms whether a cart can actually be delivered, and returns the binding price to charge.\n\nA gift order is fulfilled from a **single** fulfillment center, so a multi-item cart is only orderable if one center stocks every item in the requested quantities. This endpoint evaluates the whole cart against each candidate center and reports the outcome per center and per item.\n\nThe `total` on an available center is the amount to charge the customer and to send as `amount` on **Create Order**. Prices from **Get Products** are indicative and must not be used for either.\n\n---\n\n## Authorization\n\nRequires Basic Authentication with your client credentials. Your account must be enabled for the Gifts service.\n\n---\n\n## Scope\n\nSupply **at most one** of `cityId` or `fulfillmentCenterId`. Supplying both is a validation error.\n\n| Scope | Which centers are returned |\n| --- | --- |\n| None | Only centers that can serve the **entire** cart. An empty `fulfillmentCenters` array means no single center can fulfil this cart anywhere. |\n| `cityId` | Every active center in that city, available or not, each with per-item reasons. |\n| `fulfillmentCenterId` | That one center, available or not, with per-item reasons. |\n\n---\n\n## Request Body\n\n| Field | Type | Required | Description |\n| --- | --- | --- | --- |\n| `items` | `array` | Yes | 1–20 entries. Duplicate `productId` values are summed into a single line. |\n| `items[].productId` | `string` | Yes | Numeric product id from **Get Products**. |\n| `items[].quantity` | `int` | Yes | Between `1` and `99`. |\n| `cityId` | `int` | No | City id from **Get Locations**. Mutually exclusive with `fulfillmentCenterId`. |\n| `fulfillmentCenterId` | `string` | No | Fulfillment center id from **Get Locations**. Mutually exclusive with `cityId`. |\n\n---\n\n## Response\n\n| Field | Description |\n| --- | --- |\n| `isAvailable` | `true` if at least one returned center can serve the whole cart. |\n| `fulfillmentCenters[]` | Candidate centers, ordered by country, then city, then `total` ascending. |\n| `fulfillmentCenters[].id` | Use as `recipient.fulfillmentCenterId` on **Create Order**, and in the **Get Delivery Time Slots** path. |\n| `fulfillmentCenters[].isAvailable` | `true` only if **every** item is available here. |\n| `fulfillmentCenters[].total` | VAT-inclusive cart total at this center, and the minimum acceptable order `amount`. **`0` when the center is unavailable.** |\n| `items[].quantity` | The **summed** quantity for that product — one entry per distinct `productId`. |\n| `items[].availableQty` | Stock held at this center. `0` when the product is unknown or not stocked here. |\n| `items[].unitPrice` | VAT-exclusive unit price at this center. |\n| `items[].lineTotal` | Item total including VAT. `0` for an unavailable item. |\n| `items[].reason` | `null` when the item is available; otherwise one of the values below. |\n\nBecause unavailable centers report `total: 0`, they can sort ahead of available ones. **Always select a center by `isAvailable`, never by position**, and read the center's `total` rather than summing `lineTotal` yourself.\n\n### Reasons\n\n| Reason | Meaning |\n| --- | --- |\n| `ProductNotFound` | No such product id in the catalogue. |\n| `NotStockedAtFulfillmentCenter` | The product is real, but this center does not carry it. |\n| `InsufficientQuantity` | Stocked here, but `availableQty` is less than the requested quantity. |\n| `Inactive` | Stocked here, but not currently sellable. |\n\n---\n\n## Notes\n\n- \"Not available\" is a **success** response: HTTP 200, code `1000`, `isAvailable: false`. This endpoint never returns 404 for an unfulfillable cart.\n- An unknown or inactive `cityId` / `fulfillmentCenterId`, or one your account is not entitled to, returns `isAvailable: false` with an empty `fulfillmentCenters` array.\n- Availability reflects stock at the moment of the call. Re-check immediately before charging."},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"cookie":[],"responseTime":null,"body":"{\n  \"code\": 1000,\n  \"message\": \"Success\",\n  \"data\": {\n    \"isAvailable\": false,\n    \"fulfillmentCenters\": []\n  }\n}"}],"_postman_id":"8fadc6c9-32d1-4bc6-b3dc-860dc60c5674"},{"name":"Get Delivery Time Slots","id":"08484a03-cca2-4749-b70b-f6d5a8bc26e4","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"GET","header":[],"url":"https://eservices.hoicom.net/api/v0/gifts/delivery/fc/:fulfillmentCenterId/timeslots/:date","description":"<p>Returns the delivery <strong>time slots</strong> a fulfillment center can serve on a given date. The slot <code>id</code> returned here is what you pass in <code>delivery.slotId</code> when creating an order.</p>\n<p>Call this after choosing products, to confirm the recipient can receive the gift on the intended date.</p>\n<hr />\n<h2 id=\"authorization\">Authorization</h2>\n<p>Requires Basic Authentication with your client credentials. Your account must be enabled for the Gifts service.</p>\n<hr />\n<h2 id=\"path-parameters\">Path Parameters</h2>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Parameter</th>\n<th>Type</th>\n<th>Required</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>fulfillmentCenterId</code></td>\n<td><code>string</code></td>\n<td>Yes</td>\n<td>The fulfillment center to check availability for.</td>\n</tr>\n<tr>\n<td><code>date</code></td>\n<td><code>string</code> (date)</td>\n<td>Yes</td>\n<td>The delivery date to check, in <code>YYYY-MM-DD</code> format.</td>\n</tr>\n</tbody>\n</table>\n</div><hr />\n<h2 id=\"response\">Response</h2>\n<p>On success <code>code</code> is <code>1000</code> and <code>data</code> holds the date and its available slots, each with an <code>id</code> and a human-readable <code>name</code> (time window). See the example below.</p>\n<hr />\n<h2 id=\"response-fields\">Response fields</h2>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Field</th>\n<th>Type</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>code</td>\n<td>int</td>\n<td>Response status code. <code>1000</code> on success.</td>\n</tr>\n<tr>\n<td>message</td>\n<td>string</td>\n<td>Human-readable status message.</td>\n</tr>\n<tr>\n<td>data</td>\n<td>object</td>\n<td>Delivery date and its available time slots.</td>\n</tr>\n<tr>\n<td>data.deliveryDate</td>\n<td>string (date)</td>\n<td>The date these slots apply to, <code>YYYY-MM-DD</code>, echoing the requested <code>date</code> path parameter.</td>\n</tr>\n<tr>\n<td>data.slots</td>\n<td>array</td>\n<td>Time slots this fulfillment center can serve on this date.</td>\n</tr>\n<tr>\n<td>data.slots[].id</td>\n<td>string</td>\n<td>Slot id. Pass this as <code>delivery.slotId</code> on Create Order.</td>\n</tr>\n<tr>\n<td>data.slots[].name</td>\n<td>string</td>\n<td>Human-readable time window, e.g. <code>09:00 - 12:00</code>.</td>\n</tr>\n</tbody>\n</table>\n</div>","urlObject":{"path":["api","v0","gifts","delivery","fc",":fulfillmentCenterId","timeslots",":date"],"host":["https://eservices.hoicom.net"],"query":[],"variable":[{"description":{"content":"<p>The fulfillment center identifier.</p>\n","type":"text/plain"},"type":"any","value":"string","key":"fulfillmentCenterId"},{"description":{"content":"<p>The delivery date to check availability for.</p>\n","type":"text/plain"},"type":"any","value":"1960-01-01","key":"date"}]}},"response":[{"id":"0fdfbf51-7db6-44c5-a2f6-ec879c4662c7","name":"OK","originalRequest":{"method":"GET","header":[],"url":{"raw":"https://eservices.hoicom.net/api/v0/gifts/delivery/fc/:fulfillmentCenterId/timeslots/:date","host":["https://eservices.hoicom.net"],"path":["api","v0","gifts","delivery","fc",":fulfillmentCenterId","timeslots",":date"],"variable":[{"key":"fulfillmentCenterId","value":"string","description":"The fulfillment center identifier."},{"key":"date","value":"1960-01-01","description":"The delivery date to check availability for."}]},"description":"Returns the delivery **time slots** a fulfillment center can serve on a given date. The slot `id` returned here is what you pass in `delivery.slotId` when creating an order.\n\nCall this after choosing products, to confirm the recipient can receive the gift on the intended date.\n\n---\n\n## Authorization\n\nRequires Basic Authentication with your client credentials. Your account must be enabled for the Gifts service.\n\n---\n\n## Path Parameters\n\n| Parameter | Type | Required | Description |\n| --- | --- | --- | --- |\n| `fulfillmentCenterId` | `string` | Yes | The fulfillment center to check availability for. |\n| `date` | `string` (date) | Yes | The delivery date to check, in `YYYY-MM-DD` format. |\n\n---\n\n## Response\n\nOn success `code` is `1000` and `data` holds the date and its available slots, each with an `id` and a human-readable `name` (time window). See the example below."},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"cookie":[],"responseTime":null,"body":"{\n  \"code\": 1000,\n  \"message\": \"Success\",\n  \"data\": {\n    \"deliveryDate\": \"2026-07-10\",\n    \"slots\": [\n      {\n        \"id\": \"slot_morning\",\n        \"name\": \"09:00 - 12:00\"\n      },\n      {\n        \"id\": \"slot_evening\",\n        \"name\": \"16:00 - 19:00\"\n      }\n    ]\n  }\n}"},{"id":"f60d0b5b-fca6-4c13-adef-9d58fa3af3b7","name":"Internal Server Error","originalRequest":{"method":"GET","header":[],"url":{"raw":"https://eservices.hoicom.net/api/v0/gifts/delivery/fc/:fulfillmentCenterId/timeslots/:date","host":["https://eservices.hoicom.net"],"path":["api","v0","gifts","delivery","fc",":fulfillmentCenterId","timeslots",":date"],"variable":[{"key":"fulfillmentCenterId","value":"string","description":"The fulfillment center identifier."},{"key":"date","value":"1960-01-01","description":"The delivery date to check availability for."}]},"description":"Returns the delivery **time slots** a fulfillment center can serve on a given date. The slot `id` returned here is what you pass in `delivery.slotId` when creating an order.\n\nCall this after choosing products, to confirm the recipient can receive the gift on the intended date.\n\n---\n\n## Authorization\n\nRequires Basic Authentication with your client credentials. Your account must be enabled for the Gifts service.\n\n---\n\n## Path Parameters\n\n| Parameter | Type | Required | Description |\n| --- | --- | --- | --- |\n| `fulfillmentCenterId` | `string` | Yes | The fulfillment center to check availability for. |\n| `date` | `string` (date) | Yes | The delivery date to check, in `YYYY-MM-DD` format. |\n\n---\n\n## Response\n\nOn success `code` is `1000` and `data` holds the date and its available slots, each with an `id` and a human-readable `name` (time window). See the example below."},"status":"Internal Server Error","code":500,"_postman_previewlanguage":"text","header":[],"cookie":[],"responseTime":null,"body":""},{"id":"26a603d9-9040-4126-80c4-091372d7efa5","name":"Service Unavailable","originalRequest":{"method":"GET","header":[],"url":{"raw":"https://eservices.hoicom.net/api/v0/gifts/delivery/fc/:fulfillmentCenterId/timeslots/:date","host":["https://eservices.hoicom.net"],"path":["api","v0","gifts","delivery","fc",":fulfillmentCenterId","timeslots",":date"],"variable":[{"key":"fulfillmentCenterId","value":"string","description":"The fulfillment center identifier."},{"key":"date","value":"1960-01-01","description":"The delivery date to check availability for."}]},"description":"Returns the delivery **time slots** a fulfillment center can serve on a given date. The slot `id` returned here is what you pass in `delivery.slotId` when creating an order.\n\nCall this after choosing products, to confirm the recipient can receive the gift on the intended date.\n\n---\n\n## Authorization\n\nRequires Basic Authentication with your client credentials. Your account must be enabled for the Gifts service.\n\n---\n\n## Path Parameters\n\n| Parameter | Type | Required | Description |\n| --- | --- | --- | --- |\n| `fulfillmentCenterId` | `string` | Yes | The fulfillment center to check availability for. |\n| `date` | `string` (date) | Yes | The delivery date to check, in `YYYY-MM-DD` format. |\n\n---\n\n## Response\n\nOn success `code` is `1000` and `data` holds the date and its available slots, each with an `id` and a human-readable `name` (time window). See the example below."},"status":"Service Unavailable","code":503,"_postman_previewlanguage":"text","header":[],"cookie":[],"responseTime":null,"body":""}],"_postman_id":"08484a03-cca2-4749-b70b-f6d5a8bc26e4"},{"name":"Create Order","id":"3ad4724d-9abd-4b88-aae6-d22dc0847d6a","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"body":{"mode":"raw","raw":"{\n  \"externalReference\": \"string\",\n  \"recipient\": {\n    \"name\": \"string\",\n    \"phone\": \"string\",\n    \"fulfillmentCenterId\": \"string\"\n  },\n  \"sender\": {\n    \"name\": \"string\",\n    \"email\": \"string\",\n    \"phone\": \"string\",\n    \"countryCode\": \"string\"\n  },\n  \"items\": [\n    {\n      \"productId\": \"string\",\n      \"quantity\": 2035\n    },\n    {\n      \"productId\": \"string\",\n      \"quantity\": 141\n    }\n  ],\n  \"delivery\": {\n    \"slotId\": \"string\",\n    \"deliveryDate\": \"1967-09-20T22:20:15.581Z\"\n  },\n  \"cardMessage\": {\n    \"from\": \"string\",\n    \"to\": \"string\",\n    \"message\": \"string\",\n    \"cardType\": \"string\",\n    \"feelingLink\": \"https://links.example.com/feelings/birthday-01\"\n  },\n  \"amount\": 712.2471014755782,\n  \"currency\": \"string\"\n}","options":{"raw":{"headerFamily":"json","language":"json"}}},"url":"https://eservices.hoicom.net/api/v0/gifts/orders/async","description":"<p>Submits a gift order for <strong>asynchronous</strong> processing. The request returns immediately once accepted; the order is then processed in the background and moves through the fulfillment stages described in the folder overview. Poll <strong>Get Order by ID</strong> to track progress.</p>\n<p>Orders are <strong>idempotent</strong> on <code>externalReference</code> — reusing a reference will not create a duplicate order. A reused reference returns <strong>HTTP 409 / code <code>1114</code></strong>.</p>\n<hr />\n<h2 id=\"authorization\">Authorization</h2>\n<p>Requires Basic Authentication with your client credentials. Your account must be enabled for the Gifts service.</p>\n<hr />\n<h2 id=\"request-body\">Request Body</h2>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Field</th>\n<th>Type</th>\n<th>Required</th>\n<th>Constraints</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>externalReference</code></td>\n<td><code>string</code></td>\n<td>Yes</td>\n<td>Client-provided id, unique within your account (across all your services). Max 100 chars.</td>\n</tr>\n<tr>\n<td><code>recipient</code></td>\n<td><code>object</code></td>\n<td>Yes</td>\n<td>See <strong>Recipient</strong> below.</td>\n</tr>\n<tr>\n<td><code>sender</code></td>\n<td><code>object</code></td>\n<td>Yes</td>\n<td>See <strong>Sender</strong> below.</td>\n</tr>\n<tr>\n<td><code>items</code></td>\n<td><code>array</code></td>\n<td>Yes</td>\n<td>At least one item. See <strong>Item</strong> below.</td>\n</tr>\n<tr>\n<td><code>delivery</code></td>\n<td><code>object</code></td>\n<td>Yes</td>\n<td>See <strong>Delivery</strong> below.</td>\n</tr>\n<tr>\n<td><code>cardMessage</code></td>\n<td><code>object</code></td>\n<td>No</td>\n<td>See <strong>Card Message</strong> below.</td>\n</tr>\n<tr>\n<td><code>amount</code></td>\n<td><code>decimal</code></td>\n<td>Yes</td>\n<td>Total order amount: the availability <code>total</code> for this cart at <code>recipient.fulfillmentCenterId</code>, delivery included. Must be greater than <code>0</code> and equal the availability <code>total</code> (±0.01).</td>\n</tr>\n<tr>\n<td><code>currency</code></td>\n<td><code>string</code></td>\n<td>No</td>\n<td>3-letter ISO code (e.g. <code>SAR</code>, <code>USD</code>). Defaults to <code>SAR</code>.</td>\n</tr>\n</tbody>\n</table>\n</div><h3 id=\"recipient\">Recipient</h3>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Field</th>\n<th>Type</th>\n<th>Required</th>\n<th>Constraints</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>name</code></td>\n<td><code>string</code></td>\n<td>Yes</td>\n<td>Max 100 chars.</td>\n</tr>\n<tr>\n<td><code>phone</code></td>\n<td><code>string</code></td>\n<td>Yes</td>\n<td>Digits and <code>+ - ( ) space</code> only. Max 20 chars.</td>\n</tr>\n<tr>\n<td><code>fulfillmentCenterId</code></td>\n<td><code>string</code></td>\n<td>Yes</td>\n<td>Max 50 chars.</td>\n</tr>\n</tbody>\n</table>\n</div><h3 id=\"sender\">Sender</h3>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Field</th>\n<th>Type</th>\n<th>Required</th>\n<th>Constraints</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>name</code></td>\n<td><code>string</code></td>\n<td>Yes</td>\n<td>Max 100 chars.</td>\n</tr>\n<tr>\n<td><code>email</code></td>\n<td><code>string</code></td>\n<td>Yes</td>\n<td>Valid email. Max 150 chars.</td>\n</tr>\n<tr>\n<td><code>phone</code></td>\n<td><code>string</code></td>\n<td>Yes</td>\n<td>Digits and <code>+ - ( ) space</code> only. Max 20 chars.</td>\n</tr>\n<tr>\n<td><code>countryCode</code></td>\n<td><code>string</code></td>\n<td>Yes</td>\n<td>2–3 chars (e.g. <code>SA</code>, <code>+966</code>).</td>\n</tr>\n</tbody>\n</table>\n</div><h3 id=\"item\">Item</h3>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Field</th>\n<th>Type</th>\n<th>Required</th>\n<th>Constraints</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>productId</code></td>\n<td><code>string</code></td>\n<td>Yes</td>\n<td>Max 50 chars.</td>\n</tr>\n<tr>\n<td><code>quantity</code></td>\n<td><code>int</code></td>\n<td>Yes</td>\n<td>Between <code>1</code> and <code>99</code>.</td>\n</tr>\n</tbody>\n</table>\n</div><h3 id=\"delivery\">Delivery</h3>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Field</th>\n<th>Type</th>\n<th>Required</th>\n<th>Constraints</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>slotId</code></td>\n<td><code>string</code></td>\n<td>Yes</td>\n<td>From <strong>Get Delivery Time Slots</strong>. Max 50 chars.</td>\n</tr>\n<tr>\n<td><code>deliveryDate</code></td>\n<td><code>datetime</code></td>\n<td>Yes</td>\n<td>Must be in the future and within 1 year.</td>\n</tr>\n</tbody>\n</table>\n</div><h3 id=\"card-message-optional\">Card Message (optional)</h3>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Field</th>\n<th>Type</th>\n<th>Required</th>\n<th>Constraints</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>from</code></td>\n<td><code>string</code></td>\n<td>Yes*</td>\n<td>*Required when <code>cardMessage</code> is present. Max 100 chars.</td>\n</tr>\n<tr>\n<td><code>to</code></td>\n<td><code>string</code></td>\n<td>No</td>\n<td>Max 100 chars. Defaults to the recipient's name.</td>\n</tr>\n<tr>\n<td><code>message</code></td>\n<td><code>string</code></td>\n<td>No</td>\n<td>Max 500 chars.</td>\n</tr>\n<tr>\n<td><code>cardType</code></td>\n<td><code>string</code></td>\n<td>No</td>\n<td>The card design or theme, e.g. <code>Birthday</code>. Max 50 chars. Returned as-is on order responses.</td>\n</tr>\n<tr>\n<td><code>feelingLink</code></td>\n<td><code>string</code></td>\n<td>No</td>\n<td>Link to a feeling or music video to attach to the card. Must be a valid absolute URL. Max 500 chars.</td>\n</tr>\n</tbody>\n</table>\n</div><p><code>cardType</code> and <code>feelingLink</code> are independent. Sending only a <code>feelingLink</code> leaves <code>cardType</code> empty on the response — the link is never returned as the card design.</p>\n<hr />\n<h2 id=\"response\">Response</h2>\n<p>On acceptance <code>code</code> is <code>1000</code> and <code>data</code> contains the <code>transactionId</code> used to track the order. See the example below.</p>\n<h3 id=\"error-codes\">Error codes</h3>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Code</th>\n<th>HTTP</th>\n<th>Meaning</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>1102</code></td>\n<td>400</td>\n<td>Validation error (a field failed the constraints above), or the sender phone / country code is invalid.</td>\n</tr>\n<tr>\n<td><code>1114</code></td>\n<td>400</td>\n<td>The fulfillment center is unknown, inactive or not enabled for you, or a product is not available there.</td>\n</tr>\n<tr>\n<td><code>1114</code></td>\n<td>409</td>\n<td>Duplicate <code>externalReference</code> for your account. Look the order up by reference instead of resending.</td>\n</tr>\n<tr>\n<td><code>1415</code></td>\n<td>400</td>\n<td><code>amount</code> does not match the availability total.</td>\n</tr>\n<tr>\n<td><code>1303</code></td>\n<td>404</td>\n<td>Delivery prices could not be read. Retry later.</td>\n</tr>\n<tr>\n<td><code>1113</code></td>\n<td>503</td>\n<td>Gifts is not active for your account.</td>\n</tr>\n</tbody>\n</table>\n</div><p><code>externalReference</code> is unique per client, across all of your services. Another client may use the same value; prefixing per service (for example <code>gifts-…</code>) is recommended.</p>\n<hr />\n<h2 id=\"amount-validation\">Amount validation</h2>\n<p><code>amount</code> must <strong>equal</strong> the availability total for this exact cart at <code>recipient.fulfillmentCenterId</code>, delivery included. Get it from <strong>Check Availability</strong> scoped with <code>fulfillmentCenterId</code>, and send that center's <code>total</code> unchanged. A difference of up to 0.01 is accepted. An <code>amount</code> that is higher <strong>or</strong> lower is rejected.</p>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Code</th>\n<th>Meaning</th>\n<th>Fix</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>1415</code></td>\n<td><code>amount</code> differs from the availability total for this cart at this fulfillment center by more than 0.01. Usually caused by sending a catalogue-wide <code>price</code> or <code>priceFrom</code>, or a products-only figure that leaves out the delivery fee.</td>\n<td>Re-run <strong>Check Availability</strong> with the same <code>fulfillmentCenterId</code> and resubmit with that <code>total</code> as <code>amount</code>.</td>\n</tr>\n<tr>\n<td><code>1114</code></td>\n<td>The fulfillment center id is unknown, inactive, or not one your account is entitled to; <strong>or</strong> at least one ordered product is not stocked there, not active, or not held in sufficient quantity.</td>\n<td>Re-run <strong>Check Availability</strong> with the same cart and <code>fulfillmentCenterId</code> — the per-item <code>reason</code> identifies the offending line.</td>\n</tr>\n</tbody>\n</table>\n</div><p>Both are synchronous <code>400</code> responses returned before any transaction is created. The error envelope carries only the code and its standard message — it does not name the failing product or field, so <strong>Check Availability</strong> is the diagnostic. Checking availability immediately before ordering turns both into conditions you resolve before the customer is charged rather than after.</p>\n<p>You are charged the quoted total, not your own rounding of it. After acceptance, an order whose placement cannot be confirmed immediately stays <code>Pending</code> rather than failing; keep polling <strong>Get Order by ID</strong> and do not create it again.</p>\n<hr />\n<h2 id=\"response-fields\">Response fields</h2>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Field</th>\n<th>Type</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>code</td>\n<td>int</td>\n<td>Response status code. <code>1000</code> on acceptance.</td>\n</tr>\n<tr>\n<td>message</td>\n<td>string</td>\n<td>Human-readable status message.</td>\n</tr>\n<tr>\n<td>data</td>\n<td>object</td>\n<td>Accepted-order reference. <code>null</code> on the error examples below.</td>\n</tr>\n<tr>\n<td>data.transactionId</td>\n<td>string</td>\n<td>Id of the newly created order. Poll Get Order by ID with this value to track fulfillment.</td>\n</tr>\n</tbody>\n</table>\n</div>","urlObject":{"path":["api","v0","gifts","orders","async"],"host":["https://eservices.hoicom.net"],"query":[],"variable":[]}},"response":[{"id":"c95a2d78-9ae7-4678-ac20-2f57cd9841d9","name":"OK","originalRequest":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"body":{"mode":"raw","raw":"{\n  \"externalReference\": \"string\",\n  \"recipient\": {\n    \"name\": \"string\",\n    \"phone\": \"string\",\n    \"fulfillmentCenterId\": \"string\"\n  },\n  \"sender\": {\n    \"name\": \"string\",\n    \"email\": \"string\",\n    \"phone\": \"string\",\n    \"countryCode\": \"string\"\n  },\n  \"items\": [\n    {\n      \"productId\": \"string\",\n      \"quantity\": 2035\n    },\n    {\n      \"productId\": \"string\",\n      \"quantity\": 141\n    }\n  ],\n  \"delivery\": {\n    \"slotId\": \"string\",\n    \"deliveryDate\": \"1967-09-20T22:20:15.581Z\"\n  },\n  \"cardMessage\": {\n    \"from\": \"string\",\n    \"to\": \"string\",\n    \"message\": \"string\",\n    \"cardType\": \"string\"\n  },\n  \"amount\": 712.2471014755782,\n  \"currency\": \"string\"\n}","options":{"raw":{"headerFamily":"json","language":"json"}}},"url":"https://eservices.hoicom.net/api/v0/gifts/orders/async","description":"Submits a gift order for **asynchronous** processing. The request returns immediately once accepted; the order is then processed in the background and moves through the fulfillment stages described in the folder overview. Poll **Get Order by ID** to track progress.\n\nOrders are **idempotent** on `externalReference` — reusing a reference that has already been processed will not create a duplicate order.\n\n---\n\n## Authorization\n\nRequires Basic Authentication with your client credentials. Your account must be enabled for the Gifts service.\n\n---\n\n## Request Body\n\n| Field | Type | Required | Constraints |\n| --- | --- | --- | --- |\n| `externalReference` | `string` | Yes | Client-provided unique id. Max 100 chars. |\n| `recipient` | `object` | Yes | See **Recipient** below. |\n| `sender` | `object` | Yes | See **Sender** below. |\n| `items` | `array` | Yes | At least one item. See **Item** below. |\n| `delivery` | `object` | Yes | See **Delivery** below. |\n| `cardMessage` | `object` | No | See **Card Message** below. |\n| `amount` | `decimal` | Yes | Total order amount. Must be greater than `0`. |\n| `currency` | `string` | No | 3-letter ISO code (e.g. `SAR`, `USD`). Defaults to `SAR`. |\n\n### Recipient\n\n| Field | Type | Required | Constraints |\n| --- | --- | --- | --- |\n| `name` | `string` | Yes | Max 100 chars. |\n| `phone` | `string` | Yes | Digits and `+ - ( ) space` only. Max 20 chars. |\n| `fulfillmentCenterId` | `string` | Yes | Max 50 chars. |\n\n### Sender\n\n| Field | Type | Required | Constraints |\n| --- | --- | --- | --- |\n| `name` | `string` | Yes | Max 100 chars. |\n| `email` | `string` | Yes | Valid email. Max 150 chars. |\n| `phone` | `string` | Yes | Digits and `+ - ( ) space` only. Max 20 chars. |\n| `countryCode` | `string` | Yes | 2–3 chars (e.g. `SA`, `+966`). |\n\n### Item\n\n| Field | Type | Required | Constraints |\n| --- | --- | --- | --- |\n| `productId` | `string` | Yes | Max 50 chars. |\n| `quantity` | `int` | Yes | Between `1` and `99`. |\n\n### Delivery\n\n| Field | Type | Required | Constraints |\n| --- | --- | --- | --- |\n| `slotId` | `string` | Yes | From **Get Delivery Time Slots**. Max 50 chars. |\n| `deliveryDate` | `datetime` | Yes | Must be in the future and within 1 year. |\n\n### Card Message (optional)\n\n| Field | Type | Required | Constraints |\n| --- | --- | --- | --- |\n| `from` | `string` | Yes* | *Required when `cardMessage` is present. Max 100 chars. |\n| `to` | `string` | No | Max 100 chars. Defaults to the recipient's name. |\n| `message` | `string` | No | Max 500 chars. |\n| `cardType` | `string` | No | The card design or theme, e.g. `Birthday`. Max 50 chars. Returned as-is on order responses. |\n| `feelingLink` | `string` | No | Link to a feeling or music video to attach to the card. Must be a valid absolute URL. Max 500 chars. |\n\n`cardType` and `feelingLink` are independent. Sending only a `feelingLink` leaves `cardType` empty on the response — the link is never returned as the card design.\n\n---\n\n## Response\n\nOn acceptance `code` is `1000` and `data` contains the `transactionId` used to track the order. See the example below.\n\n### Common error codes\n\n| Code | Meaning |\n| --- | --- |\n| `1107` | Validation error (a field failed the constraints above). |\n| `1418` | Invalid external reference. |\n| `1419` | Transaction already processed (duplicate `externalReference`). |\n\n---\n\n## Amount validation\n\n`amount` must be **greater than or equal to** the availability total for this exact cart at `recipient.fulfillmentCenterId`. Get it from **Check Availability** scoped with `fulfillmentCenterId`, and send that center's `total` unchanged. A higher `amount` is accepted; a lower one is rejected.\n\n| Code | Meaning | Fix |\n| --- | --- | --- |\n| `1415` | `amount` is below the cost of this cart at this fulfillment center. Usually caused by quoting a catalogue-wide `price` or `priceFrom` instead of the availability total. | Re-run **Check Availability** with the same `fulfillmentCenterId` and resubmit with that `total` as `amount`. |\n| `1114` | The fulfillment center id is unknown, inactive, or not one your account is entitled to; **or** at least one ordered product is not stocked there, not active, or not held in sufficient quantity. | Re-run **Check Availability** with the same cart and `fulfillmentCenterId` — the per-item `reason` identifies the offending line. |\n\nBoth are synchronous `400` responses returned before any transaction is created. The error envelope carries only the code and its standard message — it does not name the failing product or field, so **Check Availability** is the diagnostic. Checking availability immediately before ordering turns both into conditions you resolve before the customer is charged rather than after."},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"cookie":[],"responseTime":null,"body":"{\n  \"code\": 1000,\n  \"message\": \"Success\",\n  \"data\": {\n    \"transactionId\": \"gift_txn_8f3a2b7c\"\n  }\n}"},{"id":"5c1b4395-e5a6-4faa-8058-ba90b843c5b9","name":"Internal Server Error","originalRequest":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"body":{"mode":"raw","raw":"{\n  \"externalReference\": \"string\",\n  \"recipient\": {\n    \"name\": \"string\",\n    \"phone\": \"string\",\n    \"fulfillmentCenterId\": \"string\"\n  },\n  \"sender\": {\n    \"name\": \"string\",\n    \"email\": \"string\",\n    \"phone\": \"string\",\n    \"countryCode\": \"string\"\n  },\n  \"items\": [\n    {\n      \"productId\": \"string\",\n      \"quantity\": 2035\n    },\n    {\n      \"productId\": \"string\",\n      \"quantity\": 141\n    }\n  ],\n  \"delivery\": {\n    \"slotId\": \"string\",\n    \"deliveryDate\": \"1967-09-20T22:20:15.581Z\"\n  },\n  \"cardMessage\": {\n    \"from\": \"string\",\n    \"to\": \"string\",\n    \"message\": \"string\",\n    \"cardType\": \"string\"\n  },\n  \"amount\": 712.2471014755782,\n  \"currency\": \"string\"\n}","options":{"raw":{"headerFamily":"json","language":"json"}}},"url":"https://eservices.hoicom.net/api/v0/gifts/orders/async","description":"Submits a gift order for **asynchronous** processing. The request returns immediately once accepted; the order is then processed in the background and moves through the fulfillment stages described in the folder overview. Poll **Get Order by ID** to track progress.\n\nOrders are **idempotent** on `externalReference` — reusing a reference that has already been processed will not create a duplicate order.\n\n---\n\n## Authorization\n\nRequires Basic Authentication with your client credentials. Your account must be enabled for the Gifts service.\n\n---\n\n## Request Body\n\n| Field | Type | Required | Constraints |\n| --- | --- | --- | --- |\n| `externalReference` | `string` | Yes | Client-provided unique id. Max 100 chars. |\n| `recipient` | `object` | Yes | See **Recipient** below. |\n| `sender` | `object` | Yes | See **Sender** below. |\n| `items` | `array` | Yes | At least one item. See **Item** below. |\n| `delivery` | `object` | Yes | See **Delivery** below. |\n| `cardMessage` | `object` | No | See **Card Message** below. |\n| `amount` | `decimal` | Yes | Total order amount. Must be greater than `0`. |\n| `currency` | `string` | No | 3-letter ISO code (e.g. `SAR`, `USD`). Defaults to `SAR`. |\n\n### Recipient\n\n| Field | Type | Required | Constraints |\n| --- | --- | --- | --- |\n| `name` | `string` | Yes | Max 100 chars. |\n| `phone` | `string` | Yes | Digits and `+ - ( ) space` only. Max 20 chars. |\n| `fulfillmentCenterId` | `string` | Yes | Max 50 chars. |\n\n### Sender\n\n| Field | Type | Required | Constraints |\n| --- | --- | --- | --- |\n| `name` | `string` | Yes | Max 100 chars. |\n| `email` | `string` | Yes | Valid email. Max 150 chars. |\n| `phone` | `string` | Yes | Digits and `+ - ( ) space` only. Max 20 chars. |\n| `countryCode` | `string` | Yes | 2–3 chars (e.g. `SA`, `+966`). |\n\n### Item\n\n| Field | Type | Required | Constraints |\n| --- | --- | --- | --- |\n| `productId` | `string` | Yes | Max 50 chars. |\n| `quantity` | `int` | Yes | Between `1` and `99`. |\n\n### Delivery\n\n| Field | Type | Required | Constraints |\n| --- | --- | --- | --- |\n| `slotId` | `string` | Yes | From **Get Delivery Time Slots**. Max 50 chars. |\n| `deliveryDate` | `datetime` | Yes | Must be in the future and within 1 year. |\n\n### Card Message (optional)\n\n| Field | Type | Required | Constraints |\n| --- | --- | --- | --- |\n| `from` | `string` | Yes* | *Required when `cardMessage` is present. Max 100 chars. |\n| `to` | `string` | No | Max 100 chars. Defaults to the recipient's name. |\n| `message` | `string` | No | Max 500 chars. |\n| `cardType` | `string` | No | The card design or theme, e.g. `Birthday`. Max 50 chars. Returned as-is on order responses. |\n| `feelingLink` | `string` | No | Link to a feeling or music video to attach to the card. Must be a valid absolute URL. Max 500 chars. |\n\n`cardType` and `feelingLink` are independent. Sending only a `feelingLink` leaves `cardType` empty on the response — the link is never returned as the card design.\n\n---\n\n## Response\n\nOn acceptance `code` is `1000` and `data` contains the `transactionId` used to track the order. See the example below.\n\n### Common error codes\n\n| Code | Meaning |\n| --- | --- |\n| `1107` | Validation error (a field failed the constraints above). |\n| `1418` | Invalid external reference. |\n| `1419` | Transaction already processed (duplicate `externalReference`). |\n\n---\n\n## Amount validation\n\n`amount` must be **greater than or equal to** the availability total for this exact cart at `recipient.fulfillmentCenterId`. Get it from **Check Availability** scoped with `fulfillmentCenterId`, and send that center's `total` unchanged. A higher `amount` is accepted; a lower one is rejected.\n\n| Code | Meaning | Fix |\n| --- | --- | --- |\n| `1415` | `amount` is below the cost of this cart at this fulfillment center. Usually caused by quoting a catalogue-wide `price` or `priceFrom` instead of the availability total. | Re-run **Check Availability** with the same `fulfillmentCenterId` and resubmit with that `total` as `amount`. |\n| `1114` | The fulfillment center id is unknown, inactive, or not one your account is entitled to; **or** at least one ordered product is not stocked there, not active, or not held in sufficient quantity. | Re-run **Check Availability** with the same cart and `fulfillmentCenterId` — the per-item `reason` identifies the offending line. |\n\nBoth are synchronous `400` responses returned before any transaction is created. The error envelope carries only the code and its standard message — it does not name the failing product or field, so **Check Availability** is the diagnostic. Checking availability immediately before ordering turns both into conditions you resolve before the customer is charged rather than after."},"status":"Internal Server Error","code":500,"_postman_previewlanguage":"text","header":[],"cookie":[],"responseTime":null,"body":""},{"id":"45ba52d0-6c03-4c94-9823-39834c1130e5","name":"Service Unavailable","originalRequest":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"body":{"mode":"raw","raw":"{\n  \"externalReference\": \"string\",\n  \"recipient\": {\n    \"name\": \"string\",\n    \"phone\": \"string\",\n    \"fulfillmentCenterId\": \"string\"\n  },\n  \"sender\": {\n    \"name\": \"string\",\n    \"email\": \"string\",\n    \"phone\": \"string\",\n    \"countryCode\": \"string\"\n  },\n  \"items\": [\n    {\n      \"productId\": \"string\",\n      \"quantity\": 2035\n    },\n    {\n      \"productId\": \"string\",\n      \"quantity\": 141\n    }\n  ],\n  \"delivery\": {\n    \"slotId\": \"string\",\n    \"deliveryDate\": \"1967-09-20T22:20:15.581Z\"\n  },\n  \"cardMessage\": {\n    \"from\": \"string\",\n    \"to\": \"string\",\n    \"message\": \"string\",\n    \"cardType\": \"string\"\n  },\n  \"amount\": 712.2471014755782,\n  \"currency\": \"string\"\n}","options":{"raw":{"headerFamily":"json","language":"json"}}},"url":"https://eservices.hoicom.net/api/v0/gifts/orders/async","description":"Submits a gift order for **asynchronous** processing. The request returns immediately once accepted; the order is then processed in the background and moves through the fulfillment stages described in the folder overview. Poll **Get Order by ID** to track progress.\n\nOrders are **idempotent** on `externalReference` — reusing a reference that has already been processed will not create a duplicate order.\n\n---\n\n## Authorization\n\nRequires Basic Authentication with your client credentials. Your account must be enabled for the Gifts service.\n\n---\n\n## Request Body\n\n| Field | Type | Required | Constraints |\n| --- | --- | --- | --- |\n| `externalReference` | `string` | Yes | Client-provided unique id. Max 100 chars. |\n| `recipient` | `object` | Yes | See **Recipient** below. |\n| `sender` | `object` | Yes | See **Sender** below. |\n| `items` | `array` | Yes | At least one item. See **Item** below. |\n| `delivery` | `object` | Yes | See **Delivery** below. |\n| `cardMessage` | `object` | No | See **Card Message** below. |\n| `amount` | `decimal` | Yes | Total order amount. Must be greater than `0`. |\n| `currency` | `string` | No | 3-letter ISO code (e.g. `SAR`, `USD`). Defaults to `SAR`. |\n\n### Recipient\n\n| Field | Type | Required | Constraints |\n| --- | --- | --- | --- |\n| `name` | `string` | Yes | Max 100 chars. |\n| `phone` | `string` | Yes | Digits and `+ - ( ) space` only. Max 20 chars. |\n| `fulfillmentCenterId` | `string` | Yes | Max 50 chars. |\n\n### Sender\n\n| Field | Type | Required | Constraints |\n| --- | --- | --- | --- |\n| `name` | `string` | Yes | Max 100 chars. |\n| `email` | `string` | Yes | Valid email. Max 150 chars. |\n| `phone` | `string` | Yes | Digits and `+ - ( ) space` only. Max 20 chars. |\n| `countryCode` | `string` | Yes | 2–3 chars (e.g. `SA`, `+966`). |\n\n### Item\n\n| Field | Type | Required | Constraints |\n| --- | --- | --- | --- |\n| `productId` | `string` | Yes | Max 50 chars. |\n| `quantity` | `int` | Yes | Between `1` and `99`. |\n\n### Delivery\n\n| Field | Type | Required | Constraints |\n| --- | --- | --- | --- |\n| `slotId` | `string` | Yes | From **Get Delivery Time Slots**. Max 50 chars. |\n| `deliveryDate` | `datetime` | Yes | Must be in the future and within 1 year. |\n\n### Card Message (optional)\n\n| Field | Type | Required | Constraints |\n| --- | --- | --- | --- |\n| `from` | `string` | Yes* | *Required when `cardMessage` is present. Max 100 chars. |\n| `to` | `string` | No | Max 100 chars. Defaults to the recipient's name. |\n| `message` | `string` | No | Max 500 chars. |\n| `cardType` | `string` | No | The card design or theme, e.g. `Birthday`. Max 50 chars. Returned as-is on order responses. |\n| `feelingLink` | `string` | No | Link to a feeling or music video to attach to the card. Must be a valid absolute URL. Max 500 chars. |\n\n`cardType` and `feelingLink` are independent. Sending only a `feelingLink` leaves `cardType` empty on the response — the link is never returned as the card design.\n\n---\n\n## Response\n\nOn acceptance `code` is `1000` and `data` contains the `transactionId` used to track the order. See the example below.\n\n### Common error codes\n\n| Code | Meaning |\n| --- | --- |\n| `1107` | Validation error (a field failed the constraints above). |\n| `1418` | Invalid external reference. |\n| `1419` | Transaction already processed (duplicate `externalReference`). |\n\n---\n\n## Amount validation\n\n`amount` must be **greater than or equal to** the availability total for this exact cart at `recipient.fulfillmentCenterId`. Get it from **Check Availability** scoped with `fulfillmentCenterId`, and send that center's `total` unchanged. A higher `amount` is accepted; a lower one is rejected.\n\n| Code | Meaning | Fix |\n| --- | --- | --- |\n| `1415` | `amount` is below the cost of this cart at this fulfillment center. Usually caused by quoting a catalogue-wide `price` or `priceFrom` instead of the availability total. | Re-run **Check Availability** with the same `fulfillmentCenterId` and resubmit with that `total` as `amount`. |\n| `1114` | The fulfillment center id is unknown, inactive, or not one your account is entitled to; **or** at least one ordered product is not stocked there, not active, or not held in sufficient quantity. | Re-run **Check Availability** with the same cart and `fulfillmentCenterId` — the per-item `reason` identifies the offending line. |\n\nBoth are synchronous `400` responses returned before any transaction is created. The error envelope carries only the code and its standard message — it does not name the failing product or field, so **Check Availability** is the diagnostic. Checking availability immediately before ordering turns both into conditions you resolve before the customer is charged rather than after."},"status":"Service Unavailable","code":503,"_postman_previewlanguage":"text","header":[],"cookie":[],"responseTime":null,"body":""},{"id":"3f4f90c2-f3f0-4ce8-a259-54e9bfd81f17","name":"Bad Request - Amount does not match availability total","originalRequest":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"body":{"mode":"raw","raw":"{\n  \"externalReference\": \"string\",\n  \"recipient\": {\n    \"name\": \"string\",\n    \"phone\": \"string\",\n    \"fulfillmentCenterId\": \"string\"\n  },\n  \"sender\": {\n    \"name\": \"string\",\n    \"email\": \"string\",\n    \"phone\": \"string\",\n    \"countryCode\": \"string\"\n  },\n  \"items\": [\n    {\n      \"productId\": \"string\",\n      \"quantity\": 2035\n    },\n    {\n      \"productId\": \"string\",\n      \"quantity\": 141\n    }\n  ],\n  \"delivery\": {\n    \"slotId\": \"string\",\n    \"deliveryDate\": \"1967-09-20T22:20:15.581Z\"\n  },\n  \"cardMessage\": {\n    \"from\": \"string\",\n    \"to\": \"string\",\n    \"message\": \"string\",\n    \"cardType\": \"string\"\n  },\n  \"amount\": 712.2471014755782,\n  \"currency\": \"string\"\n}","options":{"raw":{"headerFamily":"json","language":"json"}}},"url":"https://eservices.hoicom.net/api/v0/gifts/orders/async","description":"Submits a gift order for **asynchronous** processing. The request returns immediately once accepted; the order is then processed in the background and moves through the fulfillment stages described in the folder overview. Poll **Get Order by ID** to track progress.\n\nOrders are **idempotent** on `externalReference` — reusing a reference that has already been processed will not create a duplicate order.\n\n---\n\n## Authorization\n\nRequires Basic Authentication with your client credentials. Your account must be enabled for the Gifts service.\n\n---\n\n## Request Body\n\n| Field | Type | Required | Constraints |\n| --- | --- | --- | --- |\n| `externalReference` | `string` | Yes | Client-provided unique id. Max 100 chars. |\n| `recipient` | `object` | Yes | See **Recipient** below. |\n| `sender` | `object` | Yes | See **Sender** below. |\n| `items` | `array` | Yes | At least one item. See **Item** below. |\n| `delivery` | `object` | Yes | See **Delivery** below. |\n| `cardMessage` | `object` | No | See **Card Message** below. |\n| `amount` | `decimal` | Yes | Total order amount. Must be greater than `0`. |\n| `currency` | `string` | No | 3-letter ISO code (e.g. `SAR`, `USD`). Defaults to `SAR`. |\n\n### Recipient\n\n| Field | Type | Required | Constraints |\n| --- | --- | --- | --- |\n| `name` | `string` | Yes | Max 100 chars. |\n| `phone` | `string` | Yes | Digits and `+ - ( ) space` only. Max 20 chars. |\n| `fulfillmentCenterId` | `string` | Yes | Max 50 chars. |\n\n### Sender\n\n| Field | Type | Required | Constraints |\n| --- | --- | --- | --- |\n| `name` | `string` | Yes | Max 100 chars. |\n| `email` | `string` | Yes | Valid email. Max 150 chars. |\n| `phone` | `string` | Yes | Digits and `+ - ( ) space` only. Max 20 chars. |\n| `countryCode` | `string` | Yes | 2–3 chars (e.g. `SA`, `+966`). |\n\n### Item\n\n| Field | Type | Required | Constraints |\n| --- | --- | --- | --- |\n| `productId` | `string` | Yes | Max 50 chars. |\n| `quantity` | `int` | Yes | Between `1` and `99`. |\n\n### Delivery\n\n| Field | Type | Required | Constraints |\n| --- | --- | --- | --- |\n| `slotId` | `string` | Yes | From **Get Delivery Time Slots**. Max 50 chars. |\n| `deliveryDate` | `datetime` | Yes | Must be in the future and within 1 year. |\n\n### Card Message (optional)\n\n| Field | Type | Required | Constraints |\n| --- | --- | --- | --- |\n| `from` | `string` | Yes* | *Required when `cardMessage` is present. Max 100 chars. |\n| `to` | `string` | No | Max 100 chars. Defaults to the recipient's name. |\n| `message` | `string` | No | Max 500 chars. |\n| `cardType` | `string` | No | The card design or theme, e.g. `Birthday`. Max 50 chars. Returned as-is on order responses. |\n| `feelingLink` | `string` | No | Link to a feeling or music video to attach to the card. Must be a valid absolute URL. Max 500 chars. |\n\n`cardType` and `feelingLink` are independent. Sending only a `feelingLink` leaves `cardType` empty on the response — the link is never returned as the card design.\n\n---\n\n## Response\n\nOn acceptance `code` is `1000` and `data` contains the `transactionId` used to track the order. See the example below.\n\n### Common error codes\n\n| Code | Meaning |\n| --- | --- |\n| `1107` | Validation error (a field failed the constraints above). |\n| `1418` | Invalid external reference. |\n| `1419` | Transaction already processed (duplicate `externalReference`). |\n\n---\n\n## Amount validation\n\n`amount` must be **greater than or equal to** the availability total for this exact cart at `recipient.fulfillmentCenterId`. Get it from **Check Availability** scoped with `fulfillmentCenterId`, and send that center's `total` unchanged. A higher `amount` is accepted; a lower one is rejected.\n\n| Code | Meaning | Fix |\n| --- | --- | --- |\n| `1415` | `amount` is below the cost of this cart at this fulfillment center. Usually caused by quoting a catalogue-wide `price` or `priceFrom` instead of the availability total. | Re-run **Check Availability** with the same `fulfillmentCenterId` and resubmit with that `total` as `amount`. |\n| `1114` | The fulfillment center id is unknown, inactive, or not one your account is entitled to; **or** at least one ordered product is not stocked there, not active, or not held in sufficient quantity. | Re-run **Check Availability** with the same cart and `fulfillmentCenterId` — the per-item `reason` identifies the offending line. |\n\nBoth are synchronous `400` responses returned before any transaction is created. The error envelope carries only the code and its standard message — it does not name the failing product or field, so **Check Availability** is the diagnostic. Checking availability immediately before ordering turns both into conditions you resolve before the customer is charged rather than after."},"status":"Bad Request","code":400,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"cookie":[],"responseTime":null,"body":"{\n  \"code\": 1415,\n  \"message\": \"Invalid amount range.\",\n  \"data\": null\n}"},{"id":"6031ed71-3d6b-48b1-b85b-242c7fc84551","name":"Bad Request - Product unavailable at center","originalRequest":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"body":{"mode":"raw","raw":"{\n  \"externalReference\": \"string\",\n  \"recipient\": {\n    \"name\": \"string\",\n    \"phone\": \"string\",\n    \"fulfillmentCenterId\": \"string\"\n  },\n  \"sender\": {\n    \"name\": \"string\",\n    \"email\": \"string\",\n    \"phone\": \"string\",\n    \"countryCode\": \"string\"\n  },\n  \"items\": [\n    {\n      \"productId\": \"string\",\n      \"quantity\": 2035\n    },\n    {\n      \"productId\": \"string\",\n      \"quantity\": 141\n    }\n  ],\n  \"delivery\": {\n    \"slotId\": \"string\",\n    \"deliveryDate\": \"1967-09-20T22:20:15.581Z\"\n  },\n  \"cardMessage\": {\n    \"from\": \"string\",\n    \"to\": \"string\",\n    \"message\": \"string\",\n    \"cardType\": \"string\"\n  },\n  \"amount\": 712.2471014755782,\n  \"currency\": \"string\"\n}","options":{"raw":{"headerFamily":"json","language":"json"}}},"url":"https://eservices.hoicom.net/api/v0/gifts/orders/async","description":"Submits a gift order for **asynchronous** processing. The request returns immediately once accepted; the order is then processed in the background and moves through the fulfillment stages described in the folder overview. Poll **Get Order by ID** to track progress.\n\nOrders are **idempotent** on `externalReference` — reusing a reference that has already been processed will not create a duplicate order.\n\n---\n\n## Authorization\n\nRequires Basic Authentication with your client credentials. Your account must be enabled for the Gifts service.\n\n---\n\n## Request Body\n\n| Field | Type | Required | Constraints |\n| --- | --- | --- | --- |\n| `externalReference` | `string` | Yes | Client-provided unique id. Max 100 chars. |\n| `recipient` | `object` | Yes | See **Recipient** below. |\n| `sender` | `object` | Yes | See **Sender** below. |\n| `items` | `array` | Yes | At least one item. See **Item** below. |\n| `delivery` | `object` | Yes | See **Delivery** below. |\n| `cardMessage` | `object` | No | See **Card Message** below. |\n| `amount` | `decimal` | Yes | Total order amount. Must be greater than `0`. |\n| `currency` | `string` | No | 3-letter ISO code (e.g. `SAR`, `USD`). Defaults to `SAR`. |\n\n### Recipient\n\n| Field | Type | Required | Constraints |\n| --- | --- | --- | --- |\n| `name` | `string` | Yes | Max 100 chars. |\n| `phone` | `string` | Yes | Digits and `+ - ( ) space` only. Max 20 chars. |\n| `fulfillmentCenterId` | `string` | Yes | Max 50 chars. |\n\n### Sender\n\n| Field | Type | Required | Constraints |\n| --- | --- | --- | --- |\n| `name` | `string` | Yes | Max 100 chars. |\n| `email` | `string` | Yes | Valid email. Max 150 chars. |\n| `phone` | `string` | Yes | Digits and `+ - ( ) space` only. Max 20 chars. |\n| `countryCode` | `string` | Yes | 2–3 chars (e.g. `SA`, `+966`). |\n\n### Item\n\n| Field | Type | Required | Constraints |\n| --- | --- | --- | --- |\n| `productId` | `string` | Yes | Max 50 chars. |\n| `quantity` | `int` | Yes | Between `1` and `99`. |\n\n### Delivery\n\n| Field | Type | Required | Constraints |\n| --- | --- | --- | --- |\n| `slotId` | `string` | Yes | From **Get Delivery Time Slots**. Max 50 chars. |\n| `deliveryDate` | `datetime` | Yes | Must be in the future and within 1 year. |\n\n### Card Message (optional)\n\n| Field | Type | Required | Constraints |\n| --- | --- | --- | --- |\n| `from` | `string` | Yes* | *Required when `cardMessage` is present. Max 100 chars. |\n| `to` | `string` | No | Max 100 chars. Defaults to the recipient's name. |\n| `message` | `string` | No | Max 500 chars. |\n| `cardType` | `string` | No | The card design or theme, e.g. `Birthday`. Max 50 chars. Returned as-is on order responses. |\n| `feelingLink` | `string` | No | Link to a feeling or music video to attach to the card. Must be a valid absolute URL. Max 500 chars. |\n\n`cardType` and `feelingLink` are independent. Sending only a `feelingLink` leaves `cardType` empty on the response — the link is never returned as the card design.\n\n---\n\n## Response\n\nOn acceptance `code` is `1000` and `data` contains the `transactionId` used to track the order. See the example below.\n\n### Common error codes\n\n| Code | Meaning |\n| --- | --- |\n| `1107` | Validation error (a field failed the constraints above). |\n| `1418` | Invalid external reference. |\n| `1419` | Transaction already processed (duplicate `externalReference`). |\n\n---\n\n## Amount validation\n\n`amount` must be **greater than or equal to** the availability total for this exact cart at `recipient.fulfillmentCenterId`. Get it from **Check Availability** scoped with `fulfillmentCenterId`, and send that center's `total` unchanged. A higher `amount` is accepted; a lower one is rejected.\n\n| Code | Meaning | Fix |\n| --- | --- | --- |\n| `1415` | `amount` is below the cost of this cart at this fulfillment center. Usually caused by quoting a catalogue-wide `price` or `priceFrom` instead of the availability total. | Re-run **Check Availability** with the same `fulfillmentCenterId` and resubmit with that `total` as `amount`. |\n| `1114` | The fulfillment center id is unknown, inactive, or not one your account is entitled to; **or** at least one ordered product is not stocked there, not active, or not held in sufficient quantity. | Re-run **Check Availability** with the same cart and `fulfillmentCenterId` — the per-item `reason` identifies the offending line. |\n\nBoth are synchronous `400` responses returned before any transaction is created. The error envelope carries only the code and its standard message — it does not name the failing product or field, so **Check Availability** is the diagnostic. Checking availability immediately before ordering turns both into conditions you resolve before the customer is charged rather than after."},"status":"Bad Request","code":400,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"cookie":[],"responseTime":null,"body":"{\n  \"code\": 1114,\n  \"message\": \"Invalid parameter value.\",\n  \"data\": null\n}"}],"_postman_id":"3ad4724d-9abd-4b88-aae6-d22dc0847d6a"},{"name":"Get Order by ID","id":"504fe16d-809a-4665-9977-6f345245964e","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"GET","header":[{"key":"Accept","value":"text/plain"}],"url":"https://eservices.hoicom.net/api/v0/gifts/orders/:id?includeProducts=false&includeCardMessages=false","description":"<p>Returns a single gift order by its transaction id, including its overall <code>status</code> and detailed <code>processingStage</code> (see the folder overview for the stage lifecycle). Use this to <strong>poll</strong> an order after creating it.</p>\n<hr />\n<h2 id=\"authorization\">Authorization</h2>\n<p>Requires Basic Authentication with your client credentials. Your account must be enabled for the Gifts service.</p>\n<hr />\n<h2 id=\"path-parameters\">Path Parameters</h2>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Parameter</th>\n<th>Type</th>\n<th>Required</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>id</code></td>\n<td><code>string</code></td>\n<td>Yes</td>\n<td>The gift order transaction identifier.</td>\n</tr>\n</tbody>\n</table>\n</div><hr />\n<h2 id=\"query-parameters\">Query Parameters</h2>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Parameter</th>\n<th>Type</th>\n<th>Required</th>\n<th>Default</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>includeProducts</code></td>\n<td><code>bool</code></td>\n<td>No</td>\n<td><code>false</code></td>\n<td>Include the ordered products in the response.</td>\n</tr>\n<tr>\n<td><code>includeCardMessages</code></td>\n<td><code>bool</code></td>\n<td>No</td>\n<td><code>false</code></td>\n<td>Include attached card messages in the response.</td>\n</tr>\n</tbody>\n</table>\n</div><hr />\n<h2 id=\"response\">Response</h2>\n<p>On success <code>code</code> is <code>1000</code> and <code>data</code> holds the order — status, processing stage, timestamps, recipient, sender, delivery, and amounts. Products and card messages are included only when the matching <code>include</code> flag is <code>true</code>. If the order is not found the response carries <code>1105</code>. See the example below.</p>\n<p><strong>Status notes.</strong> An order whose placement cannot be confirmed immediately stays <code>Pending</code> (it is not marked <code>Failed</code>) — keep polling and do not create it again. A <code>Completed</code> order never goes back to <code>Pending</code>.</p>\n<hr />\n<h2 id=\"response-fields\">Response fields</h2>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Field</th>\n<th>Type</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>code</td>\n<td>int</td>\n<td>Response status code. <code>1000</code> on success; <code>1105</code> if the order id does not exist.</td>\n</tr>\n<tr>\n<td>message</td>\n<td>string</td>\n<td>Human-readable status message.</td>\n</tr>\n<tr>\n<td>data</td>\n<td>object</td>\n<td>The gift order.</td>\n</tr>\n<tr>\n<td>data.transactionId</td>\n<td>string</td>\n<td>Order transaction id.</td>\n</tr>\n<tr>\n<td>data.externalReference</td>\n<td>string</td>\n<td>The client-provided reference this order was created with.</td>\n</tr>\n<tr>\n<td>data.status</td>\n<td>string (values: Submitted</td>\n<td>Pending</td>\n</tr>\n<tr>\n<td>data.processingStage</td>\n<td>string (values: OrderSubmitted</td>\n<td>OrderConfirmed</td>\n</tr>\n<tr>\n<td>data.timestamp</td>\n<td>object</td>\n<td>Key lifecycle timestamps.</td>\n</tr>\n<tr>\n<td>data.timestamp.requestedAt</td>\n<td>string (datetime)</td>\n<td>When the order was submitted.</td>\n</tr>\n<tr>\n<td>data.timestamp.completedAt</td>\n<td>string (datetime), nullable</td>\n<td>When the order reached a terminal state. <code>null</code> while still in progress.</td>\n</tr>\n<tr>\n<td>data.recipient</td>\n<td>object</td>\n<td>The gift recipient.</td>\n</tr>\n<tr>\n<td>data.recipient.name</td>\n<td>string</td>\n<td>Recipient's name, as submitted.</td>\n</tr>\n<tr>\n<td>data.recipient.phone</td>\n<td>string</td>\n<td>Recipient's phone number, as submitted.</td>\n</tr>\n<tr>\n<td>data.sender</td>\n<td>object</td>\n<td>The gift sender.</td>\n</tr>\n<tr>\n<td>data.sender.name</td>\n<td>string</td>\n<td>Sender's name, as submitted.</td>\n</tr>\n<tr>\n<td>data.sender.email</td>\n<td>string</td>\n<td>Sender's email address, as submitted.</td>\n</tr>\n<tr>\n<td>data.sender.phone</td>\n<td>string</td>\n<td>Sender's phone number, as submitted.</td>\n</tr>\n<tr>\n<td>data.delivery</td>\n<td>object</td>\n<td>Delivery details for this order.</td>\n</tr>\n<tr>\n<td>data.delivery.deliveryTimeSlot</td>\n<td>string</td>\n<td>Human-readable name of the confirmed delivery time slot.</td>\n</tr>\n<tr>\n<td>data.delivery.deliveryDate</td>\n<td>string (datetime)</td>\n<td>Confirmed delivery date. Equals the requested date until delivery is confirmed; filled from creation.</td>\n</tr>\n<tr>\n<td>data.delivery.requestedDeliveryDate</td>\n<td>string (datetime)</td>\n<td>Delivery date you requested when creating the order. Never changes.</td>\n</tr>\n<tr>\n<td>data.delivery.actualDeliveryDate</td>\n<td>string (datetime), nullable</td>\n<td>When the order was actually delivered. <code>null</code> until delivery happens.</td>\n</tr>\n<tr>\n<td>data.delivery.fulfillmentCenter</td>\n<td>object</td>\n<td>The fulfillment center servicing this order.</td>\n</tr>\n<tr>\n<td>data.delivery.fulfillmentCenter.id</td>\n<td>string</td>\n<td>Fulfillment center id. Filled from the moment the order is created.</td>\n</tr>\n<tr>\n<td>data.delivery.fulfillmentCenter.name</td>\n<td>string</td>\n<td>Fulfillment center display name. Filled from the moment the order is created.</td>\n</tr>\n<tr>\n<td>data.delivery.fulfillmentCenter.city</td>\n<td>string</td>\n<td>City name.</td>\n</tr>\n<tr>\n<td>data.delivery.fulfillmentCenter.countryCode</td>\n<td>string</td>\n<td>Country code.</td>\n</tr>\n<tr>\n<td>data.amounts</td>\n<td>object</td>\n<td>Amounts charged for this order.</td>\n</tr>\n<tr>\n<td>data.amounts.requestedAmount</td>\n<td>object</td>\n<td>The amount charged for the order, as submitted on Create Order. Includes delivery.</td>\n</tr>\n<tr>\n<td>data.amounts.requestedAmount.amount</td>\n<td>decimal</td>\n<td>Amount value.</td>\n</tr>\n<tr>\n<td>data.amounts.requestedAmount.currency</td>\n<td>string</td>\n<td>Currency code.</td>\n</tr>\n<tr>\n<td>data.amounts.finalAmount</td>\n<td>object</td>\n<td>The amount settled for this order. Equals <code>requestedAmount</code> until the order is finalised; never <code>0</code> on a new order.</td>\n</tr>\n<tr>\n<td>data.amounts.finalAmount.amount</td>\n<td>decimal</td>\n<td>Amount value.</td>\n</tr>\n<tr>\n<td>data.amounts.finalAmount.currency</td>\n<td>string</td>\n<td>Currency code.</td>\n</tr>\n<tr>\n<td>data.amounts.pricing</td>\n<td>object</td>\n<td>Price breakdown for the order.</td>\n</tr>\n<tr>\n<td>data.amounts.pricing.subTotal</td>\n<td>decimal</td>\n<td>VAT-exclusive product subtotal. <code>0</code> until the order is finalised.</td>\n</tr>\n<tr>\n<td>data.amounts.pricing.vatAmount</td>\n<td>decimal</td>\n<td>Total VAT amount for the order.</td>\n</tr>\n<tr>\n<td>data.amounts.pricing.vatPercentage</td>\n<td>decimal</td>\n<td>VAT rate applied, as a percentage.</td>\n</tr>\n<tr>\n<td>data.amounts.pricing.deliveryFee</td>\n<td>object</td>\n<td>Delivery fee charged on this order. Replaces the former single delivery-cost number, on all orders.</td>\n</tr>\n<tr>\n<td>data.amounts.pricing.deliveryFee.amount</td>\n<td>decimal</td>\n<td>VAT-exclusive delivery fee (the value the old delivery-cost number held).</td>\n</tr>\n<tr>\n<td>data.amounts.pricing.deliveryFee.vatAmount</td>\n<td>decimal</td>\n<td>VAT on the delivery fee.</td>\n</tr>\n<tr>\n<td>data.amounts.pricing.deliveryFee.total</td>\n<td>decimal</td>\n<td>VAT-inclusive delivery fee.</td>\n</tr>\n<tr>\n<td>data.amounts.pricing.deliveryFee.currency</td>\n<td>string</td>\n<td>Currency code.</td>\n</tr>\n<tr>\n<td>data.amounts.pricing.discount</td>\n<td>decimal</td>\n<td>Discount applied, if any.</td>\n</tr>\n<tr>\n<td>data.amounts.pricing.currency</td>\n<td>string</td>\n<td>Currency code for this breakdown. <code>null</code> until the order is finalised.</td>\n</tr>\n<tr>\n<td>data.amounts.commissionApplied</td>\n<td>decimal</td>\n<td>Commission applied. <code>0</code> on new orders.</td>\n</tr>\n<tr>\n<td>data.provider</td>\n<td>object</td>\n<td>Fulfillment provider details for this order.</td>\n</tr>\n<tr>\n<td>data.provider.name</td>\n<td>string</td>\n<td>Provider name.</td>\n</tr>\n<tr>\n<td>data.provider.providerOrderId</td>\n<td>string, nullable</td>\n<td>The provider's order id. <code>null</code> until the provider's order is linked.</td>\n</tr>\n</tbody>\n</table>\n</div>","urlObject":{"path":["api","v0","gifts","orders",":id"],"host":["https://eservices.hoicom.net"],"query":[{"description":{"content":"<p>Include product details in the response (default: false).</p>\n","type":"text/plain"},"key":"includeProducts","value":"false"},{"description":{"content":"<p>Include card messages in the response (default: false).</p>\n","type":"text/plain"},"key":"includeCardMessages","value":"false"}],"variable":[{"description":{"content":"<p>The unique identifier of the gift order transaction.</p>\n","type":"text/plain"},"type":"any","value":"string","key":"id"}]}},"response":[{"id":"a65bf598-aee9-4ca8-b3c0-c77222e3e702","name":"OK","originalRequest":{"method":"GET","header":[{"key":"Accept","value":"text/plain"}],"url":{"raw":"https://eservices.hoicom.net/api/v0/gifts/orders/:id?includeProducts=false&includeCardMessages=false","host":["https://eservices.hoicom.net"],"path":["api","v0","gifts","orders",":id"],"query":[{"key":"includeProducts","value":"false","description":"Include product details in the response (default: false)."},{"key":"includeCardMessages","value":"false","description":"Include card messages in the response (default: false)."}],"variable":[{"key":"id","value":"string","description":"The unique identifier of the gift order transaction."}]},"description":"Returns a single gift order by its transaction id, including its overall `status` and detailed `processingStage` (see the folder overview for the stage lifecycle). Use this to **poll** an order after creating it.\n\n---\n\n## Authorization\n\nRequires Basic Authentication with your client credentials. Your account must be enabled for the Gifts service.\n\n---\n\n## Path Parameters\n\n| Parameter | Type | Required | Description |\n| --- | --- | --- | --- |\n| `id` | `string` | Yes | The gift order transaction identifier. |\n\n---\n\n## Query Parameters\n\n| Parameter | Type | Required | Default | Description |\n| --- | --- | --- | --- | --- |\n| `includeProducts` | `bool` | No | `false` | Include the ordered products in the response. |\n| `includeCardMessages` | `bool` | No | `false` | Include attached card messages in the response. |\n\n---\n\n## Response\n\nOn success `code` is `1000` and `data` holds the order — status, processing stage, timestamps, recipient, sender, delivery, and amounts. Products and card messages are included only when the matching `include` flag is `true`. If the order is not found the response carries `1105`. See the example below."},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"cookie":[],"responseTime":null,"body":"{\n  \"code\": 1000,\n  \"message\": \"Success\",\n  \"data\": {\n    \"transactionId\": \"gift_txn_8f3a2b7c\",\n    \"externalReference\": \"client-ref-1001\",\n    \"status\": \"Completed\",\n    \"processingStage\": \"Delivered\",\n    \"timestamp\": {\n      \"requestedAt\": \"2026-07-01T09:30:00Z\",\n      \"completedAt\": \"2026-07-02T14:05:00Z\"\n    },\n    \"recipient\": {\n      \"name\": \"Sara Al-Ahmad\",\n      \"phone\": \"+966500000000\"\n    },\n    \"sender\": {\n      \"name\": \"Omar Khan\",\n      \"email\": \"omar@example.com\",\n      \"phone\": \"+966511111111\"\n    },\n    \"delivery\": {\n      \"deliveryTimeSlot\": \"09:00 - 12:00\",\n      \"deliveryDate\": \"2026-07-02T00:00:00Z\",\n      \"requestedDeliveryDate\": \"2026-07-02T00:00:00Z\",\n      \"actualDeliveryDate\": \"2026-07-02T11:15:00Z\",\n      \"fulfillmentCenter\": {\n        \"id\": \"fc_riyadh_01\",\n        \"name\": \"Riyadh Central\",\n        \"city\": \"Riyadh\",\n        \"countryCode\": \"SA\"\n      }\n    },\n    \"amounts\": {\n      \"requestedAmount\": {\n        \"amount\": 275,\n        \"currency\": \"SAR\"\n      },\n      \"finalAmount\": {\n        \"amount\": 275,\n        \"currency\": \"SAR\"\n      },\n      \"pricing\": {\n        \"subTotal\": 217.39,\n        \"vatAmount\": 35.87,\n        \"vatPercentage\": 15,\n        \"deliveryFee\": {\n          \"amount\": 21.74,\n          \"vatAmount\": 3.26,\n          \"total\": 25,\n          \"currency\": \"SAR\"\n        },\n        \"discount\": 0,\n        \"currency\": \"SAR\"\n      },\n      \"commissionApplied\": 0\n    },\n    \"provider\": {\n      \"name\": \"Floward\",\n      \"providerOrderId\": \"884213\"\n    }\n  }\n}"},{"id":"61acd115-8b0d-4624-9b2d-0fe3e8c354b6","name":"Internal Server Error","originalRequest":{"method":"GET","header":[],"url":{"raw":"https://eservices.hoicom.net/api/v0/gifts/orders/:id?includeProducts=false&includeCardMessages=false","host":["https://eservices.hoicom.net"],"path":["api","v0","gifts","orders",":id"],"query":[{"key":"includeProducts","value":"false","description":"Include product details in the response (default: false)."},{"key":"includeCardMessages","value":"false","description":"Include card messages in the response (default: false)."}],"variable":[{"key":"id","value":"string","description":"The unique identifier of the gift order transaction."}]},"description":"Returns a single gift order by its transaction id, including its overall `status` and detailed `processingStage` (see the folder overview for the stage lifecycle). Use this to **poll** an order after creating it.\n\n---\n\n## Authorization\n\nRequires Basic Authentication with your client credentials. Your account must be enabled for the Gifts service.\n\n---\n\n## Path Parameters\n\n| Parameter | Type | Required | Description |\n| --- | --- | --- | --- |\n| `id` | `string` | Yes | The gift order transaction identifier. |\n\n---\n\n## Query Parameters\n\n| Parameter | Type | Required | Default | Description |\n| --- | --- | --- | --- | --- |\n| `includeProducts` | `bool` | No | `false` | Include the ordered products in the response. |\n| `includeCardMessages` | `bool` | No | `false` | Include attached card messages in the response. |\n\n---\n\n## Response\n\nOn success `code` is `1000` and `data` holds the order — status, processing stage, timestamps, recipient, sender, delivery, and amounts. Products and card messages are included only when the matching `include` flag is `true`. If the order is not found the response carries `1105`. See the example below."},"status":"Internal Server Error","code":500,"_postman_previewlanguage":"text","header":[],"cookie":[],"responseTime":null,"body":""},{"id":"b1b67ce8-6710-431e-bdc7-fd22eb55c16f","name":"Service Unavailable","originalRequest":{"method":"GET","header":[],"url":{"raw":"https://eservices.hoicom.net/api/v0/gifts/orders/:id?includeProducts=false&includeCardMessages=false","host":["https://eservices.hoicom.net"],"path":["api","v0","gifts","orders",":id"],"query":[{"key":"includeProducts","value":"false","description":"Include product details in the response (default: false)."},{"key":"includeCardMessages","value":"false","description":"Include card messages in the response (default: false)."}],"variable":[{"key":"id","value":"string","description":"The unique identifier of the gift order transaction."}]},"description":"Returns a single gift order by its transaction id, including its overall `status` and detailed `processingStage` (see the folder overview for the stage lifecycle). Use this to **poll** an order after creating it.\n\n---\n\n## Authorization\n\nRequires Basic Authentication with your client credentials. Your account must be enabled for the Gifts service.\n\n---\n\n## Path Parameters\n\n| Parameter | Type | Required | Description |\n| --- | --- | --- | --- |\n| `id` | `string` | Yes | The gift order transaction identifier. |\n\n---\n\n## Query Parameters\n\n| Parameter | Type | Required | Default | Description |\n| --- | --- | --- | --- | --- |\n| `includeProducts` | `bool` | No | `false` | Include the ordered products in the response. |\n| `includeCardMessages` | `bool` | No | `false` | Include attached card messages in the response. |\n\n---\n\n## Response\n\nOn success `code` is `1000` and `data` holds the order — status, processing stage, timestamps, recipient, sender, delivery, and amounts. Products and card messages are included only when the matching `include` flag is `true`. If the order is not found the response carries `1105`. See the example below."},"status":"Service Unavailable","code":503,"_postman_previewlanguage":"text","header":[],"cookie":[],"responseTime":null,"body":""}],"_postman_id":"504fe16d-809a-4665-9977-6f345245964e"},{"name":"Get Order Products","id":"45d16dd2-ef31-4f1f-80ac-52048f9a796a","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"GET","header":[],"url":"https://eservices.hoicom.net/api/v0/gifts/orders/:id/products","description":"<p>Returns just the <strong>products</strong> belonging to a gift order. Equivalent to calling <strong>Get Order by ID</strong> with <code>includeProducts=true</code> and reading only the products.</p>\n<hr />\n<h2 id=\"authorization\">Authorization</h2>\n<p>Requires Basic Authentication with your client credentials. Your account must be enabled for the Gifts service.</p>\n<hr />\n<h2 id=\"path-parameters\">Path Parameters</h2>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Parameter</th>\n<th>Type</th>\n<th>Required</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>id</code></td>\n<td><code>string</code></td>\n<td>Yes</td>\n<td>The gift order transaction identifier.</td>\n</tr>\n</tbody>\n</table>\n</div><hr />\n<h2 id=\"response\">Response</h2>\n<p>On success <code>code</code> is <code>1000</code> and <code>data</code> holds the order's <code>transactionId</code> and its list of products (details, quantity, pricing). See the example below.</p>\n<hr />\n<h2 id=\"response-fields\">Response fields</h2>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Field</th>\n<th>Type</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>code</td>\n<td>int</td>\n<td>Response status code. <code>1000</code> on success.</td>\n</tr>\n<tr>\n<td>message</td>\n<td>string</td>\n<td>Human-readable status message.</td>\n</tr>\n<tr>\n<td>data</td>\n<td>object</td>\n<td>The order's product list.</td>\n</tr>\n<tr>\n<td>data.transactionId</td>\n<td>string</td>\n<td>Order transaction id.</td>\n</tr>\n<tr>\n<td>data.products</td>\n<td>array</td>\n<td>Products included in the order.</td>\n</tr>\n<tr>\n<td>data.products[].id</td>\n<td>string</td>\n<td>Product id.</td>\n</tr>\n<tr>\n<td>data.products[].details</td>\n<td>object</td>\n<td>Descriptive product fields.</td>\n</tr>\n<tr>\n<td>data.products[].details.name</td>\n<td>string</td>\n<td>Product display name.</td>\n</tr>\n<tr>\n<td>data.products[].details.nameAr</td>\n<td>string</td>\n<td>Product name in Arabic.</td>\n</tr>\n<tr>\n<td>data.products[].details.mainImage</td>\n<td>string</td>\n<td>URL of the primary product image.</td>\n</tr>\n<tr>\n<td>data.products[].details.sku</td>\n<td>string</td>\n<td>Product SKU.</td>\n</tr>\n<tr>\n<td>data.products[].quantity</td>\n<td>int</td>\n<td>Quantity of this product on the order.</td>\n</tr>\n<tr>\n<td>data.products[].pricing</td>\n<td>object</td>\n<td>Pricing for this line, as charged on the order.</td>\n</tr>\n<tr>\n<td>data.products[].pricing.currency</td>\n<td>string</td>\n<td>Currency code.</td>\n</tr>\n<tr>\n<td>data.products[].pricing.unitPrice</td>\n<td>decimal</td>\n<td>VAT-exclusive unit price.</td>\n</tr>\n<tr>\n<td>data.products[].pricing.totalPrice</td>\n<td>decimal</td>\n<td>Total price for this line at the ordered quantity.</td>\n</tr>\n<tr>\n<td>data.products[].pricing.vat</td>\n<td>decimal</td>\n<td>VAT amount applied to this line.</td>\n</tr>\n</tbody>\n</table>\n</div>","urlObject":{"path":["api","v0","gifts","orders",":id","products"],"host":["https://eservices.hoicom.net"],"query":[],"variable":[{"description":{"content":"<p>The unique identifier of the gift order transaction.</p>\n","type":"text/plain"},"type":"any","value":"string","key":"id"}]}},"response":[{"id":"3b5b9656-3b28-4d44-b230-30019c88380f","name":"OK","originalRequest":{"method":"GET","header":[],"url":{"raw":"https://eservices.hoicom.net/api/v0/gifts/orders/:id/products","host":["https://eservices.hoicom.net"],"path":["api","v0","gifts","orders",":id","products"],"variable":[{"key":"id","value":"string","description":"The unique identifier of the gift order transaction."}]},"description":"Returns just the **products** belonging to a gift order. Equivalent to calling **Get Order by ID** with `includeProducts=true` and reading only the products.\n\n---\n\n## Authorization\n\nRequires Basic Authentication with your client credentials. Your account must be enabled for the Gifts service.\n\n---\n\n## Path Parameters\n\n| Parameter | Type | Required | Description |\n| --- | --- | --- | --- |\n| `id` | `string` | Yes | The gift order transaction identifier. |\n\n---\n\n## Response\n\nOn success `code` is `1000` and `data` holds the order's `transactionId` and its list of products (details, quantity, pricing). See the example below."},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"cookie":[],"responseTime":null,"body":"{\n  \"code\": 1000,\n  \"message\": \"Success\",\n  \"data\": {\n    \"transactionId\": \"gift_txn_8f3a2b7c\",\n    \"products\": [\n      {\n        \"id\": \"prod_10021\",\n        \"details\": {\n          \"name\": \"Red Roses Bouquet\",\n          \"nameAr\": \"باقة ورد أحمر\",\n          \"mainImage\": \"https://cdn.example.com/products/roses-red.jpg\",\n          \"sku\": \"FLW-ROSE-RED-12\"\n        },\n        \"quantity\": 1,\n        \"pricing\": {\n          \"currency\": \"SAR\",\n          \"unitPrice\": 199,\n          \"totalPrice\": 199,\n          \"vat\": 29.85\n        }\n      }\n    ]\n  }\n}"},{"id":"c2765b3d-74fe-42db-909f-1826b85e10fc","name":"Internal Server Error","originalRequest":{"method":"GET","header":[],"url":{"raw":"https://eservices.hoicom.net/api/v0/gifts/orders/:id/products","host":["https://eservices.hoicom.net"],"path":["api","v0","gifts","orders",":id","products"],"variable":[{"key":"id","value":"string","description":"The unique identifier of the gift order transaction."}]},"description":"Returns just the **products** belonging to a gift order. Equivalent to calling **Get Order by ID** with `includeProducts=true` and reading only the products.\n\n---\n\n## Authorization\n\nRequires Basic Authentication with your client credentials. Your account must be enabled for the Gifts service.\n\n---\n\n## Path Parameters\n\n| Parameter | Type | Required | Description |\n| --- | --- | --- | --- |\n| `id` | `string` | Yes | The gift order transaction identifier. |\n\n---\n\n## Response\n\nOn success `code` is `1000` and `data` holds the order's `transactionId` and its list of products (details, quantity, pricing). See the example below."},"status":"Internal Server Error","code":500,"_postman_previewlanguage":"text","header":[],"cookie":[],"responseTime":null,"body":""},{"id":"1e9e3c4a-433b-4682-97ea-6f608b347c54","name":"Service Unavailable","originalRequest":{"method":"GET","header":[],"url":{"raw":"https://eservices.hoicom.net/api/v0/gifts/orders/:id/products","host":["https://eservices.hoicom.net"],"path":["api","v0","gifts","orders",":id","products"],"variable":[{"key":"id","value":"string","description":"The unique identifier of the gift order transaction."}]},"description":"Returns just the **products** belonging to a gift order. Equivalent to calling **Get Order by ID** with `includeProducts=true` and reading only the products.\n\n---\n\n## Authorization\n\nRequires Basic Authentication with your client credentials. Your account must be enabled for the Gifts service.\n\n---\n\n## Path Parameters\n\n| Parameter | Type | Required | Description |\n| --- | --- | --- | --- |\n| `id` | `string` | Yes | The gift order transaction identifier. |\n\n---\n\n## Response\n\nOn success `code` is `1000` and `data` holds the order's `transactionId` and its list of products (details, quantity, pricing). See the example below."},"status":"Service Unavailable","code":503,"_postman_previewlanguage":"text","header":[],"cookie":[],"responseTime":null,"body":""}],"_postman_id":"45d16dd2-ef31-4f1f-80ac-52048f9a796a"},{"name":"Get Order Card Messages","id":"ea378616-0852-4440-8beb-e87508e4921e","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"GET","header":[],"url":"https://eservices.hoicom.net/api/v0/gifts/orders/:id/card-messages","description":"<p>Returns just the <strong>card / gift messages</strong> attached to a gift order. Equivalent to calling <strong>Get Order by ID</strong> with <code>includeCardMessages=true</code> and reading only the card messages.</p>\n<hr />\n<h2 id=\"authorization\">Authorization</h2>\n<p>Requires Basic Authentication with your client credentials. Your account must be enabled for the Gifts service.</p>\n<hr />\n<h2 id=\"path-parameters\">Path Parameters</h2>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Parameter</th>\n<th>Type</th>\n<th>Required</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>id</code></td>\n<td><code>string</code></td>\n<td>Yes</td>\n<td>The gift order transaction identifier.</td>\n</tr>\n</tbody>\n</table>\n</div><hr />\n<h2 id=\"response\">Response</h2>\n<p>On success <code>code</code> is <code>1000</code> and <code>data</code> holds the order's <code>transactionId</code> and its list of card messages (<code>from</code>, <code>to</code>, <code>message</code>, <code>cardType</code>, <code>feelingLink</code>). See the example below.</p>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Field</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>cardType</code></td>\n<td>The card design or theme you supplied on the order, or <code>null</code> if you did not supply one.</td>\n</tr>\n<tr>\n<td><code>feelingLink</code></td>\n<td>The feeling or music-video link you supplied on the order, or <code>null</code>.</td>\n</tr>\n</tbody>\n</table>\n</div><p>These are independent fields. A card carrying only a feeling link returns <code>cardType: null</code> — the link is never surfaced as the card design.</p>\n<hr />\n<h2 id=\"response-fields\">Response fields</h2>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Field</th>\n<th>Type</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>code</td>\n<td>int</td>\n<td>Response status code. <code>1000</code> on success.</td>\n</tr>\n<tr>\n<td>message</td>\n<td>string</td>\n<td>Human-readable status message.</td>\n</tr>\n<tr>\n<td>data</td>\n<td>object</td>\n<td>The order's card messages.</td>\n</tr>\n<tr>\n<td>data.transactionId</td>\n<td>string</td>\n<td>Order transaction id.</td>\n</tr>\n<tr>\n<td>data.cardMessages</td>\n<td>array</td>\n<td>Card/gift messages attached to the order.</td>\n</tr>\n<tr>\n<td>data.cardMessages[].from</td>\n<td>string</td>\n<td>Name shown as the card's sender.</td>\n</tr>\n<tr>\n<td>data.cardMessages[].to</td>\n<td>string</td>\n<td>Name shown as the card's recipient.</td>\n</tr>\n<tr>\n<td>data.cardMessages[].message</td>\n<td>string</td>\n<td>The message text.</td>\n</tr>\n<tr>\n<td>data.cardMessages[].cardType</td>\n<td>string, nullable</td>\n<td>The card design or theme submitted with the order, or <code>null</code> if none was supplied.</td>\n</tr>\n<tr>\n<td>data.cardMessages[].feelingLink</td>\n<td>string, nullable</td>\n<td>Link to a feeling/music-video greeting submitted with the order, or <code>null</code> if none was supplied.</td>\n</tr>\n</tbody>\n</table>\n</div>","urlObject":{"path":["api","v0","gifts","orders",":id","card-messages"],"host":["https://eservices.hoicom.net"],"query":[],"variable":[{"description":{"content":"<p>The unique identifier of the gift order transaction.</p>\n","type":"text/plain"},"type":"any","value":"string","key":"id"}]}},"response":[{"id":"77d08a3a-f8bf-4c78-a994-a2211d0aa191","name":"OK","originalRequest":{"method":"GET","header":[],"url":{"raw":"https://eservices.hoicom.net/api/v0/gifts/orders/:id/card-messages","host":["https://eservices.hoicom.net"],"path":["api","v0","gifts","orders",":id","card-messages"],"variable":[{"key":"id","value":"string","description":"The unique identifier of the gift order transaction."}]},"description":"Returns just the **card / gift messages** attached to a gift order. Equivalent to calling **Get Order by ID** with `includeCardMessages=true` and reading only the card messages.\n\n---\n\n## Authorization\n\nRequires Basic Authentication with your client credentials. Your account must be enabled for the Gifts service.\n\n---\n\n## Path Parameters\n\n| Parameter | Type | Required | Description |\n| --- | --- | --- | --- |\n| `id` | `string` | Yes | The gift order transaction identifier. |\n\n---\n\n## Response\n\nOn success `code` is `1000` and `data` holds the order's `transactionId` and its list of card messages (`from`, `to`, `message`, `cardType`, `feelingLink`). See the example below.\n\n| Field | Description |\n| --- | --- |\n| `cardType` | The card design or theme you supplied on the order, or `null` if you did not supply one. |\n| `feelingLink` | The feeling or music-video link you supplied on the order, or `null`. |\n\nThese are independent fields. A card carrying only a feeling link returns `cardType: null` — the link is never surfaced as the card design."},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"cookie":[],"responseTime":null,"body":"{\n  \"code\": 1000,\n  \"message\": \"Success\",\n  \"data\": {\n    \"transactionId\": \"gift_txn_8f3a2b7c\",\n    \"cardMessages\": [\n      {\n        \"from\": \"Omar\",\n        \"to\": \"Sara\",\n        \"message\": \"Happy Birthday!\",\n        \"cardType\": \"Birthday\",\n        \"feelingLink\": \"https://links.example.com/feelings/birthday-01\"\n      },\n      {\n        \"from\": \"Layla\",\n        \"to\": \"Sara\",\n        \"message\": \"Congratulations!\",\n        \"cardType\": null,\n        \"feelingLink\": \"https://links.example.com/feelings/congrats-04\"\n      }\n    ]\n  }\n}"},{"id":"a668c31a-68c4-4869-921a-f1834ace7408","name":"Internal Server Error","originalRequest":{"method":"GET","header":[],"url":{"raw":"https://eservices.hoicom.net/api/v0/gifts/orders/:id/card-messages","host":["https://eservices.hoicom.net"],"path":["api","v0","gifts","orders",":id","card-messages"],"variable":[{"key":"id","value":"string","description":"The unique identifier of the gift order transaction."}]},"description":"Returns just the **card / gift messages** attached to a gift order. Equivalent to calling **Get Order by ID** with `includeCardMessages=true` and reading only the card messages.\n\n---\n\n## Authorization\n\nRequires Basic Authentication with your client credentials. Your account must be enabled for the Gifts service.\n\n---\n\n## Path Parameters\n\n| Parameter | Type | Required | Description |\n| --- | --- | --- | --- |\n| `id` | `string` | Yes | The gift order transaction identifier. |\n\n---\n\n## Response\n\nOn success `code` is `1000` and `data` holds the order's `transactionId` and its list of card messages (`from`, `to`, `message`, `cardType`, `feelingLink`). See the example below.\n\n| Field | Description |\n| --- | --- |\n| `cardType` | The card design or theme you supplied on the order, or `null` if you did not supply one. |\n| `feelingLink` | The feeling or music-video link you supplied on the order, or `null`. |\n\nThese are independent fields. A card carrying only a feeling link returns `cardType: null` — the link is never surfaced as the card design."},"status":"Internal Server Error","code":500,"_postman_previewlanguage":"text","header":[],"cookie":[],"responseTime":null,"body":""},{"id":"1b198d97-6bb6-41c6-b026-a20e4da4c503","name":"Service Unavailable","originalRequest":{"method":"GET","header":[],"url":{"raw":"https://eservices.hoicom.net/api/v0/gifts/orders/:id/card-messages","host":["https://eservices.hoicom.net"],"path":["api","v0","gifts","orders",":id","card-messages"],"variable":[{"key":"id","value":"string","description":"The unique identifier of the gift order transaction."}]},"description":"Returns just the **card / gift messages** attached to a gift order. Equivalent to calling **Get Order by ID** with `includeCardMessages=true` and reading only the card messages.\n\n---\n\n## Authorization\n\nRequires Basic Authentication with your client credentials. Your account must be enabled for the Gifts service.\n\n---\n\n## Path Parameters\n\n| Parameter | Type | Required | Description |\n| --- | --- | --- | --- |\n| `id` | `string` | Yes | The gift order transaction identifier. |\n\n---\n\n## Response\n\nOn success `code` is `1000` and `data` holds the order's `transactionId` and its list of card messages (`from`, `to`, `message`, `cardType`, `feelingLink`). See the example below.\n\n| Field | Description |\n| --- | --- |\n| `cardType` | The card design or theme you supplied on the order, or `null` if you did not supply one. |\n| `feelingLink` | The feeling or music-video link you supplied on the order, or `null`. |\n\nThese are independent fields. A card carrying only a feeling link returns `cardType: null` — the link is never surfaced as the card design."},"status":"Service Unavailable","code":503,"_postman_previewlanguage":"text","header":[],"cookie":[],"responseTime":null,"body":""}],"_postman_id":"ea378616-0852-4440-8beb-e87508e4921e"},{"name":"Get Orders","id":"e5dc07e1-57f7-4abe-b84a-80325961cc82","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"GET","header":[{"key":"Accept","value":"text/plain"}],"url":"https://eservices.hoicom.net/api/v0/gifts/orders?transactionId=string&externalReference=string&status=string&fromDate=2024-09-26T09:33:32.577Z&toDate=2024-09-26T09:33:32.577Z&page=1&pageSize=50&includeProducts=false&includeCardMessages=false","description":"<p>Returns a paginated, filterable list of gift orders for your account. Use it to look up orders by transaction id, external reference, status, or date range.</p>\n<hr />\n<h2 id=\"authorization\">Authorization</h2>\n<p>Requires Basic Authentication with your client credentials. Your account must be enabled for the Gifts service.</p>\n<hr />\n<h2 id=\"query-parameters\">Query Parameters</h2>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Parameter</th>\n<th>Type</th>\n<th>Required</th>\n<th>Default</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>transactionId</code></td>\n<td><code>string</code></td>\n<td>No</td>\n<td>—</td>\n<td>Filter by transaction id.</td>\n</tr>\n<tr>\n<td><code>externalReference</code></td>\n<td><code>string</code></td>\n<td>No</td>\n<td>—</td>\n<td>Filter by your external reference.</td>\n</tr>\n<tr>\n<td><code>status</code></td>\n<td><code>string</code></td>\n<td>No</td>\n<td>—</td>\n<td>Filter by status (e.g. <code>Completed</code>).</td>\n</tr>\n<tr>\n<td><code>fromDate</code></td>\n<td><code>datetime</code></td>\n<td>No</td>\n<td>—</td>\n<td>Start of the creation-date range.</td>\n</tr>\n<tr>\n<td><code>toDate</code></td>\n<td><code>datetime</code></td>\n<td>No</td>\n<td>—</td>\n<td>End of the creation-date range.</td>\n</tr>\n<tr>\n<td><code>page</code></td>\n<td><code>int</code></td>\n<td>No</td>\n<td><code>1</code></td>\n<td>Page number for pagination.</td>\n</tr>\n<tr>\n<td><code>pageSize</code></td>\n<td><code>int</code></td>\n<td>No</td>\n<td><code>50</code></td>\n<td>Number of items per page.</td>\n</tr>\n<tr>\n<td><code>includeProducts</code></td>\n<td><code>bool</code></td>\n<td>No</td>\n<td><code>false</code></td>\n<td>Include ordered products for each order.</td>\n</tr>\n<tr>\n<td><code>includeCardMessages</code></td>\n<td><code>bool</code></td>\n<td>No</td>\n<td><code>false</code></td>\n<td>Include card messages for each order.</td>\n</tr>\n</tbody>\n</table>\n</div><hr />\n<h2 id=\"response\">Response</h2>\n<p>On success <code>code</code> is <code>1000</code> and <code>data</code> holds a paginated list of orders. Valid <code>status</code> values: <code>Submitted</code>, <code>Pending</code>, <code>Completed</code>, <code>Failed</code>, <code>Cancelled</code>, <code>Refunded</code>. An order whose placement cannot be confirmed immediately stays <code>Pending</code> rather than <code>Failed</code>. See the example below.</p>\n<hr />\n<h2 id=\"response-fields\">Response fields</h2>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Field</th>\n<th>Type</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>code</td>\n<td>int</td>\n<td>Response status code. <code>1000</code> on success.</td>\n</tr>\n<tr>\n<td>message</td>\n<td>string</td>\n<td>Human-readable status message.</td>\n</tr>\n<tr>\n<td>data</td>\n<td>object</td>\n<td>Paginated list of orders matching the filters.</td>\n</tr>\n<tr>\n<td>data.items</td>\n<td>array</td>\n<td>Order items on this page - same shape as Get Order by ID's <code>data</code>.</td>\n</tr>\n<tr>\n<td>data.items[].transactionId</td>\n<td>string</td>\n<td>Order transaction id.</td>\n</tr>\n<tr>\n<td>data.items[].externalReference</td>\n<td>string</td>\n<td>The client-provided reference this order was created with.</td>\n</tr>\n<tr>\n<td>data.items[].status</td>\n<td>string (values: Submitted</td>\n<td>Pending</td>\n</tr>\n<tr>\n<td>data.items[].processingStage</td>\n<td>string (values: OrderSubmitted</td>\n<td>OrderConfirmed</td>\n</tr>\n<tr>\n<td>data.items[].timestamp</td>\n<td>object</td>\n<td>Key lifecycle timestamps.</td>\n</tr>\n<tr>\n<td>data.items[].timestamp.requestedAt</td>\n<td>string (datetime)</td>\n<td>When the order was submitted.</td>\n</tr>\n<tr>\n<td>data.items[].timestamp.completedAt</td>\n<td>string (datetime), nullable</td>\n<td>When the order reached a terminal state. <code>null</code> while still in progress.</td>\n</tr>\n<tr>\n<td>data.items[].recipient</td>\n<td>object</td>\n<td>The gift recipient.</td>\n</tr>\n<tr>\n<td>data.items[].recipient.name</td>\n<td>string</td>\n<td>Recipient's name, as submitted.</td>\n</tr>\n<tr>\n<td>data.items[].recipient.phone</td>\n<td>string</td>\n<td>Recipient's phone number, as submitted.</td>\n</tr>\n<tr>\n<td>data.items[].sender</td>\n<td>object</td>\n<td>The gift sender.</td>\n</tr>\n<tr>\n<td>data.items[].sender.name</td>\n<td>string</td>\n<td>Sender's name, as submitted.</td>\n</tr>\n<tr>\n<td>data.items[].sender.email</td>\n<td>string</td>\n<td>Sender's email address, as submitted.</td>\n</tr>\n<tr>\n<td>data.items[].sender.phone</td>\n<td>string</td>\n<td>Sender's phone number, as submitted.</td>\n</tr>\n<tr>\n<td>data.items[].delivery</td>\n<td>object</td>\n<td>Delivery details for this order.</td>\n</tr>\n<tr>\n<td>data.items[].delivery.deliveryTimeSlot</td>\n<td>string</td>\n<td>Human-readable name of the confirmed delivery time slot.</td>\n</tr>\n<tr>\n<td>data.items[].delivery.deliveryDate</td>\n<td>string (datetime)</td>\n<td>Confirmed delivery date. Equals the requested date until delivery is confirmed; filled from creation.</td>\n</tr>\n<tr>\n<td>data.items[].delivery.requestedDeliveryDate</td>\n<td>string (datetime)</td>\n<td>Delivery date you requested when creating the order. Never changes.</td>\n</tr>\n<tr>\n<td>data.items[].delivery.actualDeliveryDate</td>\n<td>string (datetime), nullable</td>\n<td>When the order was actually delivered. <code>null</code> until delivery happens.</td>\n</tr>\n<tr>\n<td>data.items[].delivery.fulfillmentCenter</td>\n<td>object</td>\n<td>The fulfillment center servicing this order.</td>\n</tr>\n<tr>\n<td>data.items[].delivery.fulfillmentCenter.id</td>\n<td>string</td>\n<td>Fulfillment center id. Filled from the moment the order is created.</td>\n</tr>\n<tr>\n<td>data.items[].delivery.fulfillmentCenter.name</td>\n<td>string</td>\n<td>Fulfillment center display name. Filled from the moment the order is created.</td>\n</tr>\n<tr>\n<td>data.items[].delivery.fulfillmentCenter.city</td>\n<td>string</td>\n<td>City name.</td>\n</tr>\n<tr>\n<td>data.items[].delivery.fulfillmentCenter.countryCode</td>\n<td>string</td>\n<td>Country code.</td>\n</tr>\n<tr>\n<td>data.items[].amounts</td>\n<td>object</td>\n<td>Amounts charged for this order.</td>\n</tr>\n<tr>\n<td>data.items[].amounts.requestedAmount</td>\n<td>object</td>\n<td>The amount charged for the order, as submitted on Create Order. Includes delivery.</td>\n</tr>\n<tr>\n<td>data.items[].amounts.requestedAmount.amount</td>\n<td>decimal</td>\n<td>Amount value.</td>\n</tr>\n<tr>\n<td>data.items[].amounts.requestedAmount.currency</td>\n<td>string</td>\n<td>Currency code.</td>\n</tr>\n<tr>\n<td>data.items[].amounts.finalAmount</td>\n<td>object</td>\n<td>The amount settled for this order. Equals <code>requestedAmount</code> until the order is finalised; never <code>0</code> on a new order.</td>\n</tr>\n<tr>\n<td>data.items[].amounts.finalAmount.amount</td>\n<td>decimal</td>\n<td>Amount value.</td>\n</tr>\n<tr>\n<td>data.items[].amounts.finalAmount.currency</td>\n<td>string</td>\n<td>Currency code.</td>\n</tr>\n<tr>\n<td>data.items[].amounts.pricing</td>\n<td>object</td>\n<td>Price breakdown for the order.</td>\n</tr>\n<tr>\n<td>data.items[].amounts.pricing.subTotal</td>\n<td>decimal</td>\n<td>VAT-exclusive product subtotal. <code>0</code> until the order is finalised.</td>\n</tr>\n<tr>\n<td>data.items[].amounts.pricing.vatAmount</td>\n<td>decimal</td>\n<td>Total VAT amount for the order.</td>\n</tr>\n<tr>\n<td>data.items[].amounts.pricing.vatPercentage</td>\n<td>decimal</td>\n<td>VAT rate applied, as a percentage.</td>\n</tr>\n<tr>\n<td>data.items[].amounts.pricing.deliveryFee</td>\n<td>object</td>\n<td>Delivery fee charged on this order. Replaces the former single delivery-cost number, on all orders.</td>\n</tr>\n<tr>\n<td>data.items[].amounts.pricing.deliveryFee.amount</td>\n<td>decimal</td>\n<td>VAT-exclusive delivery fee (the value the old delivery-cost number held).</td>\n</tr>\n<tr>\n<td>data.items[].amounts.pricing.deliveryFee.vatAmount</td>\n<td>decimal</td>\n<td>VAT on the delivery fee.</td>\n</tr>\n<tr>\n<td>data.items[].amounts.pricing.deliveryFee.total</td>\n<td>decimal</td>\n<td>VAT-inclusive delivery fee.</td>\n</tr>\n<tr>\n<td>data.items[].amounts.pricing.deliveryFee.currency</td>\n<td>string</td>\n<td>Currency code.</td>\n</tr>\n<tr>\n<td>data.items[].amounts.pricing.discount</td>\n<td>decimal</td>\n<td>Discount applied, if any.</td>\n</tr>\n<tr>\n<td>data.items[].amounts.pricing.currency</td>\n<td>string</td>\n<td>Currency code for this breakdown. <code>null</code> until the order is finalised.</td>\n</tr>\n<tr>\n<td>data.items[].amounts.commissionApplied</td>\n<td>decimal</td>\n<td>Commission applied. <code>0</code> on new orders.</td>\n</tr>\n<tr>\n<td>data.items[].provider</td>\n<td>object</td>\n<td>Fulfillment provider details for this order.</td>\n</tr>\n<tr>\n<td>data.items[].provider.name</td>\n<td>string</td>\n<td>Provider name.</td>\n</tr>\n<tr>\n<td>data.items[].provider.providerOrderId</td>\n<td>string, nullable</td>\n<td>The provider's order id. <code>null</code> until the provider's order is linked.</td>\n</tr>\n<tr>\n<td>data.count</td>\n<td>int</td>\n<td>Number of order items on this page.</td>\n</tr>\n<tr>\n<td>data.page</td>\n<td>int</td>\n<td>Current page number.</td>\n</tr>\n<tr>\n<td>data.pageSize</td>\n<td>int</td>\n<td>Requested page size.</td>\n</tr>\n<tr>\n<td>data.totalPages</td>\n<td>int</td>\n<td>Total number of pages available.</td>\n</tr>\n<tr>\n<td>data.totalItems</td>\n<td>int</td>\n<td>Total number of matching orders across all pages.</td>\n</tr>\n</tbody>\n</table>\n</div>","urlObject":{"path":["api","v0","gifts","orders"],"host":["https://eservices.hoicom.net"],"query":[{"description":{"content":"<p>Optional transaction ID to filter by.</p>\n","type":"text/plain"},"key":"transactionId","value":"string"},{"description":{"content":"<p>Optional external reference to filter by.</p>\n","type":"text/plain"},"key":"externalReference","value":"string"},{"description":{"content":"<p>Optional transaction status to filter by (enum name, e.g. \"Completed\").</p>\n","type":"text/plain"},"key":"status","value":"string"},{"description":{"content":"<p>Optional start date for filtering.</p>\n","type":"text/plain"},"key":"fromDate","value":"2024-09-26T09:33:32.577Z"},{"description":{"content":"<p>Optional end date for filtering.</p>\n","type":"text/plain"},"key":"toDate","value":"2024-09-26T09:33:32.577Z"},{"description":{"content":"<p>Page number for pagination (default: 1).</p>\n","type":"text/plain"},"key":"page","value":"1"},{"description":{"content":"<p>Number of items per page (default: 50).</p>\n","type":"text/plain"},"key":"pageSize","value":"50"},{"description":{"content":"<p>Include product details in the response (default: false).</p>\n","type":"text/plain"},"key":"includeProducts","value":"false"},{"description":{"content":"<p>Include card messages in the response (default: false).</p>\n","type":"text/plain"},"key":"includeCardMessages","value":"false"}],"variable":[]}},"response":[{"id":"477c62bb-2ddd-4662-9eae-d0acc4f43851","name":"OK","originalRequest":{"method":"GET","header":[{"key":"Accept","value":"text/plain"}],"url":{"raw":"https://eservices.hoicom.net/api/v0/gifts/orders?transactionId=string&externalReference=string&status=string&fromDate=2024-09-26T09:33:32.577Z&toDate=2024-09-26T09:33:32.577Z&page=1&pageSize=50&includeProducts=false&includeCardMessages=false","host":["https://eservices.hoicom.net"],"path":["api","v0","gifts","orders"],"query":[{"key":"transactionId","value":"string","description":"Optional transaction ID to filter by."},{"key":"externalReference","value":"string","description":"Optional external reference to filter by."},{"key":"status","value":"string","description":"Optional transaction status to filter by (enum name, e.g. \"Completed\")."},{"key":"fromDate","value":"2024-09-26T09:33:32.577Z","description":"Optional start date for filtering."},{"key":"toDate","value":"2024-09-26T09:33:32.577Z","description":"Optional end date for filtering."},{"key":"page","value":"1","description":"Page number for pagination (default: 1)."},{"key":"pageSize","value":"50","description":"Number of items per page (default: 50)."},{"key":"includeProducts","value":"false","description":"Include product details in the response (default: false)."},{"key":"includeCardMessages","value":"false","description":"Include card messages in the response (default: false)."}]},"description":"Returns a paginated, filterable list of gift orders for your account. Use it to look up orders by transaction id, external reference, status, or date range.\n\n---\n\n## Authorization\n\nRequires Basic Authentication with your client credentials. Your account must be enabled for the Gifts service.\n\n---\n\n## Query Parameters\n\n| Parameter | Type | Required | Default | Description |\n| --- | --- | --- | --- | --- |\n| `transactionId` | `string` | No | — | Filter by transaction id. |\n| `externalReference` | `string` | No | — | Filter by your external reference. |\n| `status` | `string` | No | — | Filter by status (enum name, e.g. `Completed`). |\n| `fromDate` | `datetime` | No | — | Start of the creation-date range. |\n| `toDate` | `datetime` | No | — | End of the creation-date range. |\n| `page` | `int` | No | `1` | Page number for pagination. |\n| `pageSize` | `int` | No | `50` | Number of items per page. |\n| `includeProducts` | `bool` | No | `false` | Include ordered products for each order. |\n| `includeCardMessages` | `bool` | No | `false` | Include card messages for each order. |\n\n---\n\n## Response\n\nOn success `code` is `1000` and `data` holds a paginated list of orders. Valid `status` values: `Submitted`, `Pending`, `Completed`, `Failed`, `Cancelled`. See the example below."},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"cookie":[],"responseTime":null,"body":"{\n  \"code\": 1000,\n  \"message\": \"Success\",\n  \"data\": {\n    \"items\": [\n      {\n        \"transactionId\": \"gift_txn_8f3a2b7c\",\n        \"externalReference\": \"client-ref-1001\",\n        \"status\": \"Completed\",\n        \"processingStage\": \"Delivered\",\n        \"timestamp\": {\n          \"requestedAt\": \"2026-07-01T09:30:00Z\",\n          \"completedAt\": \"2026-07-02T14:05:00Z\"\n        },\n        \"recipient\": {\n          \"name\": \"Sara Al-Ahmad\",\n          \"phone\": \"+966500000000\"\n        },\n        \"sender\": {\n          \"name\": \"Omar Khan\",\n          \"email\": \"omar@example.com\",\n          \"phone\": \"+966511111111\"\n        },\n        \"delivery\": {\n          \"deliveryTimeSlot\": \"09:00 - 12:00\",\n          \"deliveryDate\": \"2026-07-02T00:00:00Z\",\n          \"requestedDeliveryDate\": \"2026-07-02T00:00:00Z\",\n          \"actualDeliveryDate\": \"2026-07-02T11:15:00Z\",\n          \"fulfillmentCenter\": {\n            \"id\": \"fc_riyadh_01\",\n            \"name\": \"Riyadh Central\",\n            \"city\": \"Riyadh\",\n            \"countryCode\": \"SA\"\n          }\n        },\n        \"amounts\": {\n          \"requestedAmount\": {\n            \"amount\": 275,\n            \"currency\": \"SAR\"\n          },\n          \"finalAmount\": {\n            \"amount\": 275,\n            \"currency\": \"SAR\"\n          },\n          \"pricing\": {\n            \"subTotal\": 217.39,\n            \"vatAmount\": 35.87,\n            \"vatPercentage\": 15,\n            \"deliveryFee\": {\n              \"amount\": 21.74,\n              \"vatAmount\": 3.26,\n              \"total\": 25,\n              \"currency\": \"SAR\"\n            },\n            \"discount\": 0,\n            \"currency\": \"SAR\"\n          },\n          \"commissionApplied\": 0\n        },\n        \"provider\": {\n          \"name\": \"Floward\",\n          \"providerOrderId\": \"884213\"\n        }\n      }\n    ],\n    \"count\": 1,\n    \"page\": 1,\n    \"pageSize\": 50,\n    \"totalPages\": 1,\n    \"totalItems\": 1\n  }\n}"},{"id":"8c0b81ae-e137-46c2-8635-da6ea42f9452","name":"Internal Server Error","originalRequest":{"method":"GET","header":[],"url":{"raw":"https://eservices.hoicom.net/api/v0/gifts/orders?transactionId=string&externalReference=string&status=string&fromDate=2024-09-26T09:33:32.577Z&toDate=2024-09-26T09:33:32.577Z&page=1&pageSize=50&includeProducts=false&includeCardMessages=false","host":["https://eservices.hoicom.net"],"path":["api","v0","gifts","orders"],"query":[{"key":"transactionId","value":"string","description":"Optional transaction ID to filter by."},{"key":"externalReference","value":"string","description":"Optional external reference to filter by."},{"key":"status","value":"string","description":"Optional transaction status to filter by (enum name, e.g. \"Completed\")."},{"key":"fromDate","value":"2024-09-26T09:33:32.577Z","description":"Optional start date for filtering."},{"key":"toDate","value":"2024-09-26T09:33:32.577Z","description":"Optional end date for filtering."},{"key":"page","value":"1","description":"Page number for pagination (default: 1)."},{"key":"pageSize","value":"50","description":"Number of items per page (default: 50)."},{"key":"includeProducts","value":"false","description":"Include product details in the response (default: false)."},{"key":"includeCardMessages","value":"false","description":"Include card messages in the response (default: false)."}]},"description":"Returns a paginated, filterable list of gift orders for your account. Use it to look up orders by transaction id, external reference, status, or date range.\n\n---\n\n## Authorization\n\nRequires Basic Authentication with your client credentials. Your account must be enabled for the Gifts service.\n\n---\n\n## Query Parameters\n\n| Parameter | Type | Required | Default | Description |\n| --- | --- | --- | --- | --- |\n| `transactionId` | `string` | No | — | Filter by transaction id. |\n| `externalReference` | `string` | No | — | Filter by your external reference. |\n| `status` | `string` | No | — | Filter by status (enum name, e.g. `Completed`). |\n| `fromDate` | `datetime` | No | — | Start of the creation-date range. |\n| `toDate` | `datetime` | No | — | End of the creation-date range. |\n| `page` | `int` | No | `1` | Page number for pagination. |\n| `pageSize` | `int` | No | `50` | Number of items per page. |\n| `includeProducts` | `bool` | No | `false` | Include ordered products for each order. |\n| `includeCardMessages` | `bool` | No | `false` | Include card messages for each order. |\n\n---\n\n## Response\n\nOn success `code` is `1000` and `data` holds a paginated list of orders. Valid `status` values: `Submitted`, `Pending`, `Completed`, `Failed`, `Cancelled`. See the example below."},"status":"Internal Server Error","code":500,"_postman_previewlanguage":"text","header":[],"cookie":[],"responseTime":null,"body":""},{"id":"4b496f94-6768-4da4-a80c-b23a25fd5b57","name":"Service Unavailable","originalRequest":{"method":"GET","header":[],"url":{"raw":"https://eservices.hoicom.net/api/v0/gifts/orders?transactionId=string&externalReference=string&status=string&fromDate=2024-09-26T09:33:32.577Z&toDate=2024-09-26T09:33:32.577Z&page=1&pageSize=50&includeProducts=false&includeCardMessages=false","host":["https://eservices.hoicom.net"],"path":["api","v0","gifts","orders"],"query":[{"key":"transactionId","value":"string","description":"Optional transaction ID to filter by."},{"key":"externalReference","value":"string","description":"Optional external reference to filter by."},{"key":"status","value":"string","description":"Optional transaction status to filter by (enum name, e.g. \"Completed\")."},{"key":"fromDate","value":"2024-09-26T09:33:32.577Z","description":"Optional start date for filtering."},{"key":"toDate","value":"2024-09-26T09:33:32.577Z","description":"Optional end date for filtering."},{"key":"page","value":"1","description":"Page number for pagination (default: 1)."},{"key":"pageSize","value":"50","description":"Number of items per page (default: 50)."},{"key":"includeProducts","value":"false","description":"Include product details in the response (default: false)."},{"key":"includeCardMessages","value":"false","description":"Include card messages in the response (default: false)."}]},"description":"Returns a paginated, filterable list of gift orders for your account. Use it to look up orders by transaction id, external reference, status, or date range.\n\n---\n\n## Authorization\n\nRequires Basic Authentication with your client credentials. Your account must be enabled for the Gifts service.\n\n---\n\n## Query Parameters\n\n| Parameter | Type | Required | Default | Description |\n| --- | --- | --- | --- | --- |\n| `transactionId` | `string` | No | — | Filter by transaction id. |\n| `externalReference` | `string` | No | — | Filter by your external reference. |\n| `status` | `string` | No | — | Filter by status (enum name, e.g. `Completed`). |\n| `fromDate` | `datetime` | No | — | Start of the creation-date range. |\n| `toDate` | `datetime` | No | — | End of the creation-date range. |\n| `page` | `int` | No | `1` | Page number for pagination. |\n| `pageSize` | `int` | No | `50` | Number of items per page. |\n| `includeProducts` | `bool` | No | `false` | Include ordered products for each order. |\n| `includeCardMessages` | `bool` | No | `false` | Include card messages for each order. |\n\n---\n\n## Response\n\nOn success `code` is `1000` and `data` holds a paginated list of orders. Valid `status` values: `Submitted`, `Pending`, `Completed`, `Failed`, `Cancelled`. See the example below."},"status":"Service Unavailable","code":503,"_postman_previewlanguage":"text","header":[],"cookie":[],"responseTime":null,"body":""}],"_postman_id":"e5dc07e1-57f7-4abe-b84a-80325961cc82"}],"id":"929999d6-c4ee-4663-9e8d-79bb2ffaefb2","description":"<p>The Gifts service enables ordering and delivering physical gift products (flowers, chocolates, gift baskets, etc.) to recipients. It covers the full lifecycle — from browsing the catalogue and confirming what can actually be delivered to a recipient's city, to placing orders and tracking their fulfillment status.</p>\n<hr />\n<h2 id=\"two-ways-to-build\">Two ways to build</h2>\n<p>Both paths are fully supported. Pick the one that matches when your application learns the recipient's location.</p>\n<h3 id=\"a-location-first\">A. Location-first</h3>\n<p>Use this when the recipient's city is known before the shopper browses.</p>\n<ol>\n<li><strong>Get Locations</strong> — pick a country, city, and fulfillment center</li>\n<li><strong>Get Products by Fulfillment Center</strong> — every price is exact</li>\n<li><strong>Check Availability</strong> — confirm the cart and get the binding total (products plus delivery)</li>\n<li><strong>Get Delivery Time Slots</strong> — for that fulfillment center and date</li>\n<li><strong>Create Order</strong> — submit using the availability <code>total</code> as <code>amount</code></li>\n<li><strong>Track order</strong> — poll the order status and processing stage until fulfillment</li>\n</ol>\n<h3 id=\"b-product-first\">B. Product-first</h3>\n<p>Use this when shoppers browse a full catalogue and the recipient's address is captured at checkout.</p>\n<ol>\n<li><strong>Get Products</strong> — no scope, browse the whole catalogue. Prices come back as a <strong>range</strong></li>\n<li><strong>Get Locations</strong> — capture the recipient's city and read its numeric <code>id</code></li>\n<li><strong>Check Availability</strong> — post the cart with <code>cityId</code>. Returns the fulfillment centers that can serve it, the <strong>binding total</strong> (products plus delivery), and the <code>fulfillmentCenterId</code> to order from</li>\n<li><strong>Get Delivery Time Slots</strong> — for the chosen fulfillment center and date</li>\n<li><strong>Create Order</strong> — submit using the availability <code>total</code> as <code>amount</code></li>\n<li><strong>Track order</strong> — poll the order status and processing stage until fulfillment</li>\n</ol>\n<hr />\n<h2 id=\"pricing-browse-ranges-delivery-fee-and-binding-totals\">Pricing: browse ranges, delivery fee and binding totals</h2>\n<p>The same product genuinely costs different amounts at different fulfillment centers. <strong>Get Products</strong> therefore returns a price <strong>range</strong> alongside a single headline price.</p>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Field</th>\n<th>Meaning</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>price</code></td>\n<td>The headline price. Unscoped this is the lowest purchasable price; scoped to one fulfillment center it is that center's exact price.</td>\n</tr>\n<tr>\n<td><code>priceFrom</code></td>\n<td>The lowest price across the fulfillment centers in scope.</td>\n</tr>\n<tr>\n<td><code>priceTo</code></td>\n<td>The highest price across the fulfillment centers in scope.</td>\n</tr>\n<tr>\n<td><code>vat</code></td>\n<td>VAT amount applied to <code>price</code>.</td>\n</tr>\n<tr>\n<td><code>total</code></td>\n<td><code>price</code> plus VAT — a VAT-inclusive <strong>unit</strong> price, not a cart total.</td>\n</tr>\n<tr>\n<td><code>currency</code></td>\n<td>Currency code for all amounts on the item.</td>\n</tr>\n<tr>\n<td><code>deliveryFee</code></td>\n<td>The delivery fee of the fulfillment center the price comes from: <code>{ amount, vatAmount, total, currency }</code>. <code>amount</code> is VAT-exclusive, <code>total</code> is VAT-inclusive. Charged <strong>once per order</strong>, not per item.</td>\n</tr>\n</tbody>\n</table>\n</div><p>How scope narrows the range:</p>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Request</th>\n<th>Range behaviour</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>GET /products</code></td>\n<td><code>price</code> = <code>priceFrom</code> = lowest purchasable price; <code>priceTo</code> = highest. Widest range.</td>\n</tr>\n<tr>\n<td><code>GET /products?cityId=2</code></td>\n<td>Range narrows to the fulfillment centers in that city. Collapses to a single value only when the city has one center.</td>\n</tr>\n<tr>\n<td><code>GET /products?fulfillmentCenterId=2</code></td>\n<td>Exact. <code>price</code> = <code>priceFrom</code> = <code>priceTo</code>.</td>\n</tr>\n<tr>\n<td><code>GET /products/fc/{id}</code></td>\n<td><strong>No range at all.</strong> <code>priceFrom</code> and <code>priceTo</code> are not present in the response.</td>\n</tr>\n<tr>\n<td><code>GET /products?categoryId=6988</code></td>\n<td>Range unchanged: it still spans the fulfillment centers in scope. Only the set of products narrows, not the range.</td>\n</tr>\n</tbody>\n</table>\n</div><p>The range is a browse-time artefact, so it belongs only to <strong>Get Products</strong>. <strong>Get Products by Fulfillment Center</strong> already has a center fixed, meaning there is exactly one price — it returns <code>price</code>, <code>vat</code>, <code>currency</code> and <code>total</code>, and omits <code>priceFrom</code> and <code>priceTo</code> entirely. Do not write an integration that expects those two keys on that endpoint.</p>\n<blockquote>\n<h3 id=\"charge-and-order-off-the-availability-total--never-the-browse-price\">Charge and order off the availability total — never the browse price</h3>\n<p>A price from <strong>Get Products</strong> is <strong>indicative only</strong>. It tells a shopper roughly what a product costs; it is not a quote. Its <code>total</code> is a unit price including VAT and <strong>excludes delivery</strong>.</p>\n<p>The only binding amount is the <code>total</code> returned by <strong>Check Availability</strong> for a specific cart at a specific fulfillment center. It is the products including VAT <strong>plus the delivery fee</strong> (<code>deliveryFee.total</code>). That is the figure to display at checkout, to capture from the customer, and to send as <code>amount</code> on <strong>Create Order</strong>.</p>\n<p><code>amount</code> must <strong>equal</strong> the availability <code>total</code> (a difference of up to 0.01 is accepted). An <code>amount</code> that is higher <strong>or</strong> lower is rejected with <strong>HTTP 400 / code 1415</strong>. Ordering off a browse price or <code>priceFrom</code> is the most common way to hit it, because those figures leave out delivery and <code>priceFrom</code> is by definition the cheapest center in the catalogue.</p>\n</blockquote>\n<p>Example for one product at one fulfillment center: price 217.39 + VAT 15 % = 250.00, plus a delivery fee of 21.74 + VAT 3.26 = 25.00, gives an availability <code>total</code> of <strong>275.00</strong>. Send <code>amount: 275.00</code>.</p>\n<p>If the delivery prices cannot be read, <strong>Check Availability</strong>, <strong>Create Order</strong> and <strong>Get Products by Fulfillment Center</strong> return <strong>HTTP 404 / code 1303</strong>, and an unscoped <strong>Get Products</strong> returns an empty page. Retry later.</p>\n<hr />\n<h2 id=\"product-fields\">Product fields</h2>\n<p>Every product item — on both <strong>Get Products</strong> and <strong>Get Products by Fulfillment Center</strong> — carries a <code>categories</code> array as the last field in the item object:</p>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Field</th>\n<th>Meaning</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>categories[].id</code></td>\n<td>Stable opaque category id (a string). Use this to filter with <code>categoryId</code> — see <strong>Browsing by category</strong> below.</td>\n</tr>\n<tr>\n<td><code>categories[].name</code></td>\n<td>Category display name, resolved for the request's <code>lang</code>.</td>\n</tr>\n</tbody>\n</table>\n</div><p><code>categories</code> is always present — a product with no categories returns <code>categories: []</code>, never an omitted key and never <code>null</code>.</p>\n<hr />\n<h2 id=\"browsing-by-category\">Browsing by category</h2>\n<p>Products can be tagged with one or more categories. <strong>Get Categories</strong> returns the tree; take a node's <code>id</code> and pass it back as <code>categoryId</code> to narrow either product endpoint to that category.</p>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Parameter</th>\n<th>Default</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>categoryId</code></td>\n<td><em>(none)</em></td>\n<td>Filter products to those tagged with this category id. Optional on both <strong>Get Products</strong> (<code>GET /products?categoryId=6988</code>) and <strong>Get Products by Fulfillment Center</strong> (<code>GET /products/fc/{id}?categoryId=6988</code>).</td>\n</tr>\n</tbody>\n</table>\n</div><blockquote>\n<h3 id=\"read-the-tree-with-two-caveats\">Read the tree with two caveats</h3>\n<p>The tree reflects only categories seen on products we have actually received — it is <strong>not</strong> the fulfillment partner's full taxonomy. A category that has never been attached to a product we've ingested will not appear at all.</p>\n<p>A category whose parent category has no products of its own also will not sit under that parent — it surfaces at the <strong>root</strong> of the tree instead, since a parent node is never fabricated without a name for it.</p>\n</blockquote>\n<blockquote>\n<h3 id=\"the-same-category-id-can-carry-a-different-name-on-a-product-than-in-the-tree\">The same category <code>id</code> can carry a different <code>name</code> on a product than in the tree</h3>\n<p>When the fulfillment partner renames a category and only some products have been re-published under the new name, <strong>Get Categories</strong> and a product's <code>categories[]</code> can disagree on the <code>name</code> for the same <code>id</code>. The <code>id</code>s always agree. <strong>Key on <code>id</code>, never on <code>name</code></strong> — this is a real, observed condition, not a hypothetical, and it self-heals as products are republished.</p>\n</blockquote>\n<blockquote>\n<h3 id=\"get-productsfcid-404s-on-an-empty-category-match--get-products-does-not\"><code>GET /products/fc/{id}</code> 404s on an empty category match — <code>GET /products</code> does not</h3>\n<p><code>GET /products?categoryId=…</code> with no matching products returns <strong>HTTP 200 with an empty <code>items: []</code></strong>, same as any other filter that matches nothing.</p>\n<p><code>GET /products/fc/{id}?categoryId=…</code> with no matching products returns <strong>HTTP 404</strong> instead — that route treats <em>any</em> empty result page as \"not found\", a pre-existing behaviour unrelated to categories (an unmatched <code>searchTerm</code> 404s there too). Don't treat that 404 as a broken endpoint or a broken <code>categoryId</code> — check for zero matches, not a resource that doesn't exist.</p>\n</blockquote>\n<hr />\n<h2 id=\"get-categories\">Get Categories</h2>\n<p><code>GET /gifts/categories</code> returns the category tree so you can build navigation without pulling the whole catalogue.</p>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Parameter</th>\n<th>Default</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>cityId</code></td>\n<td><em>(none)</em></td>\n<td>Optional city id to scope categories to products available in that city. Ignored when <code>fulfillmentCenterId</code> is also supplied.</td>\n</tr>\n<tr>\n<td><code>fulfillmentCenterId</code></td>\n<td><em>(none)</em></td>\n<td>Optional fulfillment center id to scope categories to that center. Takes precedence over <code>cityId</code> when both are supplied — supplying both is not an error, <code>fulfillmentCenterId</code> simply wins and <code>cityId</code> is ignored, exactly as on <strong>Get Products</strong>.</td>\n</tr>\n<tr>\n<td><code>lang</code></td>\n<td><code>ar</code></td>\n<td>Language for category names: <code>ar</code> (Arabic) or <code>en</code> (English).</td>\n</tr>\n<tr>\n<td><code>page</code></td>\n<td><code>1</code></td>\n<td>Page number, applied to <strong>root</strong> categories only.</td>\n</tr>\n<tr>\n<td><code>pageSize</code></td>\n<td><code>50</code></td>\n<td>Root categories per page.</td>\n</tr>\n</tbody>\n</table>\n</div><pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-jsonc\">{\n  \"code\": 1000,\n  \"message\": \"Request processed successfully.\",\n  \"data\": {\n    \"items\": [\n      {\n        \"id\": \"6988\",\n        \"name\": \"Flowers &amp; Plants\",\n        \"children\": [\n          { \"id\": \"7104\", \"name\": \"Roses\", \"children\": [] },\n          { \"id\": \"7105\", \"name\": \"Tulips\", \"children\": [] }\n        ]\n      },\n      { \"id\": \"7012\", \"name\": \"Birthday\", \"children\": [] }\n    ],\n    \"count\": 2, \"page\": 1, \"pageSize\": 50, \"totalPages\": 1, \"totalItems\": 2\n  }\n}\n</code></pre>\n<ul>\n<li><code>children</code> is always present — <code>[]</code> for a leaf category, never omitted and never <code>null</code>.</li>\n<li>Pagination applies to root-level categories only. A root category that fits on the requested page ships with <strong>all</strong> of its children, however many there are — children are never truncated or paginated separately.</li>\n<li>Sort order is ordinal, not locale-aware alphabetical: names sort by raw character code, so e.g. <code>\"Zebra\"</code> sorts before <code>\"apple\"</code>, and Arabic and English orderings will differ from what looks \"alphabetical\" to a human reader. It's deterministic and stable across requests, just not dictionary order.</li>\n<li>An empty scope (an unresolvable <code>fulfillmentCenterId</code>, or a <code>cityId</code> with no active matching fulfillment centers) returns <strong>HTTP 200 with an empty <code>items: []</code></strong> — this follows <strong>Get Products</strong>' behaviour, not the 404 behaviour of <strong>Get Products by Fulfillment Center</strong> described above.</li>\n</ul>\n<hr />\n<h2 id=\"one-order-one-fulfillment-center\">One order, one fulfillment center</h2>\n<p>A gift order is picked, packed, and delivered from a <strong>single</strong> fulfillment center. There is no split shipping.</p>\n<p>A multi-item cart is therefore only orderable if <strong>one</strong> center stocks <strong>every</strong> item in the requested quantities. Two products that are each individually available in a city are not necessarily orderable together.</p>\n<p><strong>Check Availability</strong> answers exactly this question, and quotes the delivery fee once for the whole order. Called without a scope it returns only the centers that can serve the <strong>whole</strong> cart; if that list is empty, the cart cannot be ordered as-is anywhere and must be split into separate orders or amended.</p>\n<hr />\n<h2 id=\"processing-stage\">Processing Stage</h2>\n<p>The <code>processingStage</code> field provides detailed fulfillment progress, independent of the overall status. It tracks the physical journey of the order:</p>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Stage</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><strong>OrderSubmitted</strong></td>\n<td>The order has been submitted to the fulfillment partner.</td>\n</tr>\n<tr>\n<td><strong>OrderConfirmed</strong></td>\n<td>The fulfillment partner has confirmed and accepted the order.</td>\n</tr>\n<tr>\n<td><strong>PreparingOrder</strong></td>\n<td>The order is being prepared (printed, assembled, quality checked, packed).</td>\n</tr>\n<tr>\n<td><strong>OutForDelivery</strong></td>\n<td>The order has left the fulfillment center and is on its way to the recipient.</td>\n</tr>\n<tr>\n<td><strong>Delivered</strong></td>\n<td>The order has been successfully delivered to the recipient.</td>\n</tr>\n<tr>\n<td><strong>Cancelled</strong></td>\n<td>The order has been cancelled.</td>\n</tr>\n<tr>\n<td><strong>Rescheduled</strong></td>\n<td>The delivery has been rescheduled to a new date or time.</td>\n</tr>\n<tr>\n<td><strong>Returned</strong></td>\n<td>The order was returned after a failed delivery attempt.</td>\n</tr>\n</tbody>\n</table>\n</div><h3 id=\"typical-progression\">Typical progression</h3>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code>OrderSubmitted → OrderConfirmed → PreparingOrder → OutForDelivery → Delivered\n\n</code></pre><hr />\n<h2 id=\"optional-includes\">Optional Includes</h2>\n<p>Order responses can include additional detail via query parameters:</p>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Parameter</th>\n<th>Default</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>includeProducts</code></td>\n<td><code>false</code></td>\n<td>Include the list of products in the order.</td>\n</tr>\n<tr>\n<td><code>includeCardMessages</code></td>\n<td><code>false</code></td>\n<td>Include card/gift messages attached to the order. Each carries <code>from</code>, <code>to</code>, <code>message</code>, <code>cardType</code>, and <code>feelingLink</code>.</td>\n</tr>\n</tbody>\n</table>\n</div><p>These apply to both single order (<code>GET /orders/{id}</code>) and order list (<code>GET /orders</code>) endpoints. Products and card messages are also available as dedicated sub-endpoints:</p>\n<ul>\n<li><p><code>GET /orders/{id}/products</code></p>\n</li>\n<li><p><code>GET /orders/{id}/card-messages</code></p>\n</li>\n</ul>\n<hr />\n<h2 id=\"order-amounts-and-status\">Order amounts and status</h2>\n<ul>\n<li><code>amounts.requestedAmount</code> is the amount you were charged for the order, including delivery. <code>amounts.finalAmount</code> equals <code>requestedAmount</code> until the order is finalised; it is never <code>0</code> on a new order.</li>\n<li><code>amounts.pricing.deliveryFee</code> is an object <code>{ amount, vatAmount, total, currency }</code>. It replaces the old single delivery-cost number on every order. <code>deliveryFee.amount</code> holds the value that number used to hold (VAT-exclusive). The other <code>pricing</code> figures (<code>subTotal</code>, <code>vatAmount</code>, <code>vatPercentage</code>, <code>currency</code>) fill in once the order is finalised and can be <code>0</code> or <code>null</code> before that.</li>\n<li><code>delivery.fulfillmentCenter.id</code> and <code>name</code> and <code>delivery.deliveryDate</code> are filled from the moment the order is created. <code>deliveryDate</code> is the requested date until delivery is confirmed. <code>delivery.requestedDeliveryDate</code> always keeps the date you sent. <code>delivery.actualDeliveryDate</code> stays <code>null</code> until the order is delivered.</li>\n<li>An order whose placement cannot be confirmed immediately stays <strong><code>Pending</code></strong>; it is not marked <code>Failed</code>. Keep polling <strong>Get Order by ID</strong>, and <strong>do not place it again</strong>.</li>\n<li>A <code>Completed</code> order never goes back to <code>Pending</code>.</li>\n</ul>\n<hr />\n<h2 id=\"recommended-order-flow\">Recommended order flow</h2>\n<ol>\n<li><strong>Location-first:</strong> call <strong>Get Locations</strong> and pick a city and <code>fulfillmentCenterId</code>. <strong>Product-first:</strong> call <strong>Get Products</strong>, then <strong>Get Locations</strong> for the recipient's <code>cityId</code>.</li>\n<li>Call <strong>Get Products by Fulfillment Center</strong> for exact prices (<code>pricing.deliveryFee</code> is shown for information), or <strong>Get Products</strong> for an indicative range.</li>\n<li>Call <strong>Get Delivery Time Slots</strong> for the chosen fulfillment center and date, and keep the slot <code>id</code> as <code>slotId</code>.</li>\n<li>Call <strong>Check Availability</strong> with the cart and <code>cityId</code> or <code>fulfillmentCenterId</code>. Pick a fulfillment center with <code>isAvailable: true</code> and show its <code>deliveryFee</code> and <code>total</code>.</li>\n<li>Capture the customer's payment for that center's <code>total</code> (products plus delivery, including VAT).</li>\n<li>Call <strong>Create Order</strong>. <code>recipient.fulfillmentCenterId</code> is that center's id, <code>amount</code> is that <code>total</code> unchanged, and <code>externalReference</code> is unique. Code <code>1000</code> with a <code>transactionId</code> means the order was accepted, not delivered.</li>\n<li>Track the order with <strong>Get Order by ID</strong> (or <strong>Get Orders</strong> with <code>externalReference</code>) until <code>status</code> is <code>Completed</code> or <code>Failed</code>. <code>Pending</code> can last a while; keep polling. Follow <code>processingStage</code> for delivery progress.</li>\n<li>If a request returns <strong>409 / 1114</strong> for your <code>externalReference</code>, look the order up by that reference instead of sending it again.</li>\n<li>Never use <code>pricing.total</code> from the product endpoints as <code>amount</code>: it excludes delivery and is not rounded.</li>\n</ol>\n<h3 id=\"external-references\">External references</h3>\n<p><code>externalReference</code> must be unique <strong>within your account</strong>, across all the services enabled for you. Other clients' references never collide with yours. Prefixing per service (for example <code>gifts-…</code>) is recommended. Reusing one returns <strong>HTTP 409 / code 1114</strong>.</p>\n<hr />\n<h2 id=\"gifts-error-codes\">Gifts error codes</h2>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Code</th>\n<th>HTTP</th>\n<th>Meaning</th>\n<th>When</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>1000</code></td>\n<td>200</td>\n<td>Success</td>\n<td>Normal reply. On <strong>Create Order</strong> it means the order was accepted.</td>\n</tr>\n<tr>\n<td><code>1102</code></td>\n<td>400</td>\n<td>Invalid request format</td>\n<td>Validation failed on <strong>Create Order</strong> or <strong>Check Availability</strong>, or the sender phone or country code cannot be converted.</td>\n</tr>\n<tr>\n<td><code>1114</code></td>\n<td>400</td>\n<td>Invalid parameter value</td>\n<td>The fulfillment center is unknown, inactive or not enabled for you, or a product is not available there.</td>\n</tr>\n<tr>\n<td><code>1114</code></td>\n<td>409</td>\n<td>Duplicate reference</td>\n<td>The <code>externalReference</code> was already used by your account.</td>\n</tr>\n<tr>\n<td><code>1415</code></td>\n<td>400</td>\n<td>Invalid amount</td>\n<td><strong>Create Order</strong> <code>amount</code> differs from the availability <code>total</code> by more than 0.01, higher or lower.</td>\n</tr>\n<tr>\n<td><code>1303</code></td>\n<td>404</td>\n<td>No results</td>\n<td>Nothing found; <strong>Get Products by Fulfillment Center</strong> returned an empty page; or delivery prices cannot be read on <strong>Check Availability</strong>, <strong>Create Order</strong> or <strong>Get Products by Fulfillment Center</strong>.</td>\n</tr>\n<tr>\n<td><code>1113</code></td>\n<td>503</td>\n<td>Service unavailable</td>\n<td>Gifts is not active for your account.</td>\n</tr>\n<tr>\n<td><code>1101</code></td>\n<td>500</td>\n<td>Internal error</td>\n<td>Unexpected failure.</td>\n</tr>\n</tbody>\n</table>\n</div>","_postman_id":"929999d6-c4ee-4663-9e8d-79bb2ffaefb2"},{"name":"Ground Transport","item":[{"name":"Get Stations","id":"e0f0422e-597d-4fd3-9457-81778f8a2e93","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"GET","header":[{"key":"Accept","value":"application/json"}],"url":"https://eservices.hoicom.net/api/v0/groundtransport/stations?countryIsoCodes=ESP&stationCodes=&cityCodes=&connectedTo=&include=mode&query=&page=1&pageSize=20","description":"<p>Returns the station catalogue within your activated countries. Stations are the origin/destination atoms for trip search — use this endpoint to build your route pickers. Each item carries the station id (code), name, country, and its city; request heavier fields (transport mode, description, coordinates, non-stop connections) via <code>include</code>.</p>\n<hr />\n<h2 id=\"response-fields\">Response fields</h2>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Field</th>\n<th>Type</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>code</td>\n<td>int</td>\n<td>Response status code — <code>1000</code> on success.</td>\n</tr>\n<tr>\n<td>message</td>\n<td>string</td>\n<td>Human-readable summary of the result.</td>\n</tr>\n<tr>\n<td>data.count</td>\n<td>int</td>\n<td>Number of station items returned on this page.</td>\n</tr>\n<tr>\n<td>data.items</td>\n<td>array</td>\n<td>The list of matching stations.</td>\n</tr>\n<tr>\n<td>data.items[].id</td>\n<td>string</td>\n<td>Opaque station code — reuse it in <code>stationCodes</code>/<code>connectedTo</code> filters and as a segment <code>stationCode</code>.</td>\n</tr>\n<tr>\n<td>data.items[].name</td>\n<td>string</td>\n<td>The station's display name.</td>\n</tr>\n<tr>\n<td>data.items[].countryIsoCode</td>\n<td>string (ISO 3166-1 alpha-3)</td>\n<td>The country the station is in.</td>\n</tr>\n<tr>\n<td>data.items[].city</td>\n<td>object</td>\n<td>The city the station belongs to.</td>\n</tr>\n<tr>\n<td>data.items[].city.code</td>\n<td>string</td>\n<td>City code — usable in Get Cities/Get Stations' <code>cityCodes</code> filter.</td>\n</tr>\n<tr>\n<td>data.items[].city.name</td>\n<td>string</td>\n<td>The city's display name.</td>\n</tr>\n<tr>\n<td>data.items[].mode</td>\n<td>string (values: bus | rail | ferry | transfer | metro | tram | cable_car), nullable</td>\n<td>The station's transport mode; present only when <code>include=mode</code> is requested.</td>\n</tr>\n<tr>\n<td>data.items[].description</td>\n<td>string, nullable</td>\n<td>Free-text description of the station's location; present only with <code>include=description</code>, omitted where the station has none on file.</td>\n</tr>\n<tr>\n<td>data.items[].location</td>\n<td>object, nullable</td>\n<td>Present only with <code>include=location</code>.</td>\n</tr>\n<tr>\n<td>data.items[].location.latitude</td>\n<td>decimal</td>\n<td>Latitude coordinate.</td>\n</tr>\n<tr>\n<td>data.items[].location.longitude</td>\n<td>decimal</td>\n<td>Longitude coordinate.</td>\n</tr>\n<tr>\n<td>data.items[].connectedStations</td>\n<td>array of string, nullable</td>\n<td>Station codes reachable non-stop from this station; present only with <code>include=connectedStations</code>.</td>\n</tr>\n<tr>\n<td>data.page</td>\n<td>int</td>\n<td>The page number returned.</td>\n</tr>\n<tr>\n<td>data.pageSize</td>\n<td>int</td>\n<td>The number of items requested per page.</td>\n</tr>\n<tr>\n<td>data.totalPages</td>\n<td>int</td>\n<td>Total number of pages available for the current filter.</td>\n</tr>\n<tr>\n<td>data.totalItems</td>\n<td>int</td>\n<td>Total number of stations matching the current filter, across all pages.</td>\n</tr>\n</tbody>\n</table>\n</div><p><code>mode</code>, <code>description</code>, <code>location</code>, and <code>connectedStations</code> are opt-in via <code>include</code> and are not shown in the example above (a default request omits them entirely rather than returning <code>null</code>).</p>\n","urlObject":{"path":["api","v0","groundtransport","stations"],"host":["https://eservices.hoicom.net"],"query":[{"description":{"content":"<p>Optional ISO 3166-1 alpha-3 country filter. Repeat the key for multiple countries (e.g. countryIsoCodes=ESP&amp;countryIsoCodes=FRA).</p>\n","type":"text/plain"},"key":"countryIsoCodes","value":"ESP"},{"description":{"content":"<p>Optional station code filter. Repeat the key for multiple codes.</p>\n","type":"text/plain"},"key":"stationCodes","value":""},{"description":{"content":"<p>Optional city code filter. Repeat the key for multiple codes.</p>\n","type":"text/plain"},"key":"cityCodes","value":""},{"description":{"content":"<p>Optional: return only stations reachable non-stop from the given station code(s). Repeat the key for up to 5 codes; results are the union.</p>\n","type":"text/plain"},"key":"connectedTo","value":""},{"description":{"content":"<p>Optional heavier fields, repeatable: mode, description, location, connectedStations. connectedStations requires stationCodes (max 5) or connectedTo in the same request.</p>\n","type":"text/plain"},"key":"include","value":"mode"},{"description":{"content":"<p>Optional free-text search over station names.</p>\n","type":"text/plain"},"key":"query","value":""},{"description":{"content":"<p>Page number for pagination (default: 1).</p>\n","type":"text/plain"},"key":"page","value":"1"},{"description":{"content":"<p>Number of items per page (default: 20).</p>\n","type":"text/plain"},"key":"pageSize","value":"20"}],"variable":[]}},"response":[{"id":"b3e5ec0a-e44f-4aef-9d55-d38a10391059","name":"200 — Success","originalRequest":{"method":"GET","header":[{"key":"Accept","value":"application/json"}],"url":{"raw":"https://eservices.hoicom.net/api/v0/groundtransport/stations?countryIsoCodes=ESP&stationCodes=&cityCodes=&connectedTo=&include=mode&query=&page=1&pageSize=20","host":["https://eservices.hoicom.net"],"path":["api","v0","groundtransport","stations"],"query":[{"key":"countryIsoCodes","value":"ESP","description":"Optional ISO 3166-1 alpha-3 country filter. Repeat the key for multiple countries (e.g. countryIsoCodes=ESP&countryIsoCodes=FRA)."},{"key":"stationCodes","value":"","description":"Optional station code filter. Repeat the key for multiple codes."},{"key":"cityCodes","value":"","description":"Optional city code filter. Repeat the key for multiple codes."},{"key":"connectedTo","value":"","description":"Optional: return only stations reachable non-stop from the given station code(s). Repeat the key for up to 5 codes; results are the union."},{"key":"include","value":"mode","description":"Optional heavier fields, repeatable: mode, description, location, connectedStations. connectedStations requires stationCodes (max 5) or connectedTo in the same request."},{"key":"query","value":"","description":"Optional free-text search over station names."},{"key":"page","value":"1","description":"Page number for pagination (default: 1)."},{"key":"pageSize","value":"20","description":"Number of items per page (default: 20)."}]},"description":"Returns the station catalogue within your activated countries. Stations are the origin/destination atoms for trip search — use this endpoint to build your route pickers. Each item carries the station id (code), name, country, and its city; request heavier fields (transport mode, description, coordinates, non-stop connections) via `include`.\n\n---\n\n## Response fields\n\n| Field | Type | Description |\n|---|---|---|\n| code | int | Response status code — `1000` on success. |\n| message | string | Human-readable summary of the result. |\n| data.count | int | Number of station items returned on this page. |\n| data.items | array | The list of matching stations. |\n| data.items[].id | string | Opaque station code — reuse it in `stationCodes`/`connectedTo` filters and as a segment `stationCode`. |\n| data.items[].name | string | The station's display name. |\n| data.items[].countryIsoCode | string (ISO 3166-1 alpha-3) | The country the station is in. |\n| data.items[].city | object | The city the station belongs to. |\n| data.items[].city.code | string | City code — usable in Get Cities/Get Stations' `cityCodes` filter. |\n| data.items[].city.name | string | The city's display name. |\n| data.items[].mode | string (values: bus \\| rail \\| ferry \\| transfer \\| metro \\| tram \\| cable_car), nullable | The station's transport mode; present only when `include=mode` is requested. |\n| data.items[].description | string, nullable | Free-text description of the station's location; present only with `include=description`, omitted where the station has none on file. |\n| data.items[].location | object, nullable | Present only with `include=location`. |\n| data.items[].location.latitude | decimal | Latitude coordinate. |\n| data.items[].location.longitude | decimal | Longitude coordinate. |\n| data.items[].connectedStations | array of string, nullable | Station codes reachable non-stop from this station; present only with `include=connectedStations`. |\n| data.page | int | The page number returned. |\n| data.pageSize | int | The number of items requested per page. |\n| data.totalPages | int | Total number of pages available for the current filter. |\n| data.totalItems | int | Total number of stations matching the current filter, across all pages. |\n\n`mode`, `description`, `location`, and `connectedStations` are opt-in via `include` and are not shown in the example above (a default request omits them entirely rather than returning `null`).\n"},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"cookie":[],"responseTime":null,"body":"{\n  \"code\": 1000,\n  \"message\": \"Request processed successfully.\",\n  \"data\": {\n    \"count\": 2,\n    \"items\": [\n      {\n        \"id\": \"ESMADMAD\",\n        \"name\": \"Madrid Avenida de America Bus Station\",\n        \"countryIsoCode\": \"ESP\",\n        \"city\": {\n          \"code\": \"ESMAD\",\n          \"name\": \"Madrid\"\n        },\n        \"mode\": \"bus\"\n      },\n      {\n        \"id\": \"ESBCNEDA\",\n        \"name\": \"Barcelona Bus Station North\",\n        \"countryIsoCode\": \"ESP\",\n        \"city\": {\n          \"code\": \"ESBCN\",\n          \"name\": \"Barcelona\"\n        },\n        \"mode\": \"bus\"\n      }\n    ],\n    \"page\": 1,\n    \"pageSize\": 20,\n    \"totalPages\": 381,\n    \"totalItems\": 7605\n  }\n}"}],"_postman_id":"e0f0422e-597d-4fd3-9457-81778f8a2e93"},{"name":"Get Cities","id":"b846a459-baf1-4827-ab74-b29b255683c6","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"GET","header":[{"key":"Accept","value":"application/json"}],"url":"https://eservices.hoicom.net/api/v0/groundtransport/cities?countryIsoCodes=ESP&cityCodes=&query=&page=1&pageSize=20","description":"<p>Returns the city catalogue within your activated countries. Cities group stations for display — a typical UI lets travellers pick a city, then a station within it.</p>\n<hr />\n<h2 id=\"response-fields\">Response fields</h2>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Field</th>\n<th>Type</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>code</td>\n<td>int</td>\n<td>Response status code — <code>1000</code> on success.</td>\n</tr>\n<tr>\n<td>message</td>\n<td>string</td>\n<td>Human-readable summary of the result.</td>\n</tr>\n<tr>\n<td>data.count</td>\n<td>int</td>\n<td>Number of city items returned on this page.</td>\n</tr>\n<tr>\n<td>data.items</td>\n<td>array</td>\n<td>The list of matching cities.</td>\n</tr>\n<tr>\n<td>data.items[].code</td>\n<td>string</td>\n<td>City code — usable in Get Stations' <code>cityCodes</code> filter.</td>\n</tr>\n<tr>\n<td>data.items[].name</td>\n<td>string</td>\n<td>The city's display name.</td>\n</tr>\n<tr>\n<td>data.items[].countryIsoCode</td>\n<td>string (ISO 3166-1 alpha-3)</td>\n<td>The country the city is in.</td>\n</tr>\n<tr>\n<td>data.page</td>\n<td>int</td>\n<td>The page number returned.</td>\n</tr>\n<tr>\n<td>data.pageSize</td>\n<td>int</td>\n<td>The number of items requested per page.</td>\n</tr>\n<tr>\n<td>data.totalPages</td>\n<td>int</td>\n<td>Total number of pages available for the current filter.</td>\n</tr>\n<tr>\n<td>data.totalItems</td>\n<td>int</td>\n<td>Total number of cities matching the current filter, across all pages.</td>\n</tr>\n</tbody>\n</table>\n</div>","urlObject":{"path":["api","v0","groundtransport","cities"],"host":["https://eservices.hoicom.net"],"query":[{"description":{"content":"<p>Optional ISO 3166-1 alpha-3 country filter. Repeat the key for multiple countries.</p>\n","type":"text/plain"},"key":"countryIsoCodes","value":"ESP"},{"description":{"content":"<p>Optional city code filter. Repeat the key for multiple codes.</p>\n","type":"text/plain"},"key":"cityCodes","value":""},{"description":{"content":"<p>Optional free-text search over city names.</p>\n","type":"text/plain"},"key":"query","value":""},{"description":{"content":"<p>Page number for pagination (default: 1).</p>\n","type":"text/plain"},"key":"page","value":"1"},{"description":{"content":"<p>Number of items per page (default: 20).</p>\n","type":"text/plain"},"key":"pageSize","value":"20"}],"variable":[]}},"response":[{"id":"7657d92c-f572-4cb8-9923-a8c8ae3293ff","name":"200 — Success","originalRequest":{"method":"GET","header":[{"key":"Accept","value":"application/json"}],"url":{"raw":"https://eservices.hoicom.net/api/v0/groundtransport/cities?countryIsoCodes=ESP&cityCodes=&query=&page=1&pageSize=20","host":["https://eservices.hoicom.net"],"path":["api","v0","groundtransport","cities"],"query":[{"key":"countryIsoCodes","value":"ESP","description":"Optional ISO 3166-1 alpha-3 country filter. Repeat the key for multiple countries."},{"key":"cityCodes","value":"","description":"Optional city code filter. Repeat the key for multiple codes."},{"key":"query","value":"","description":"Optional free-text search over city names."},{"key":"page","value":"1","description":"Page number for pagination (default: 1)."},{"key":"pageSize","value":"20","description":"Number of items per page (default: 20)."}]},"description":"Returns the city catalogue within your activated countries. Cities group stations for display — a typical UI lets travellers pick a city, then a station within it.\n\n---\n\n## Response fields\n\n| Field | Type | Description |\n|---|---|---|\n| code | int | Response status code — `1000` on success. |\n| message | string | Human-readable summary of the result. |\n| data.count | int | Number of city items returned on this page. |\n| data.items | array | The list of matching cities. |\n| data.items[].code | string | City code — usable in Get Stations' `cityCodes` filter. |\n| data.items[].name | string | The city's display name. |\n| data.items[].countryIsoCode | string (ISO 3166-1 alpha-3) | The country the city is in. |\n| data.page | int | The page number returned. |\n| data.pageSize | int | The number of items requested per page. |\n| data.totalPages | int | Total number of pages available for the current filter. |\n| data.totalItems | int | Total number of cities matching the current filter, across all pages. |\n"},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"cookie":[],"responseTime":null,"body":"{\n  \"code\": 1000,\n  \"message\": \"Request processed successfully.\",\n  \"data\": {\n    \"count\": 2,\n    \"items\": [\n      {\n        \"code\": \"ESMAD\",\n        \"name\": \"Madrid\",\n        \"countryIsoCode\": \"ESP\"\n      },\n      {\n        \"code\": \"ESBCN\",\n        \"name\": \"Barcelona\",\n        \"countryIsoCode\": \"ESP\"\n      }\n    ],\n    \"page\": 1,\n    \"pageSize\": 20,\n    \"totalPages\": 62,\n    \"totalItems\": 1240\n  }\n}"}],"_postman_id":"b846a459-baf1-4827-ab74-b29b255683c6"},{"name":"Get Carriers","id":"ee0e221b-050f-407e-b1bd-9df835bb38a6","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"GET","header":[{"key":"Accept","value":"application/json"}],"url":"https://eservices.hoicom.net/api/v0/groundtransport/carriers?countryIsoCodes=&carrierIds=&include=","description":"<p>Returns the carriers (operating companies) available on the network. Each item carries the carrier id and display name, plus (when available) countryIsoCode (alpha-3 home country), modes (the transport types it operates), seatSelectionSupported (whether Get Offer Seat Map works for its trips), and termsUrl (a link to the carrier's terms of purchase). Filter by countryIsoCodes and/or carrierIds (max 10, case-insensitive; the two combine as an intersection, never an override). Add include=logoUrls to also receive each carrier's logoUrls (URLs of its logo images, hosted by HOI; [] when the carrier has no logo) — omitted by default. Any other include value returns code 1114 (HTTP 200, see the examples). Like stations and cities, an unfiltered request defaults to your activated countries. If carrier detail data is temporarily unavailable, items are served with just id/name and country filtering is temporarily unsupported rather than silently ignored.</p>\n<hr />\n<h2 id=\"response-fields\">Response fields</h2>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Field</th>\n<th>Type</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>code</td>\n<td>int</td>\n<td>Response status code — <code>1000</code> on success.</td>\n</tr>\n<tr>\n<td>message</td>\n<td>string</td>\n<td>Human-readable summary of the result.</td>\n</tr>\n<tr>\n<td>data</td>\n<td>array</td>\n<td>The list of matching carriers (unpaged — the carrier list is bounded, ~600 today).</td>\n</tr>\n<tr>\n<td>data[].id</td>\n<td>string</td>\n<td>Carrier code — the join key with an offer's <code>carrier.id</code>.</td>\n</tr>\n<tr>\n<td>data[].name</td>\n<td>string</td>\n<td>The carrier's display name.</td>\n</tr>\n<tr>\n<td>data[].countryIsoCode</td>\n<td>string (ISO 3166-1 alpha-3), nullable/omitted</td>\n<td>The carrier's home country; omitted from the item when carrier detail data is temporarily unavailable.</td>\n</tr>\n<tr>\n<td>data[].modes</td>\n<td>array of string (values: bus | rail | ferry | transfer | metro | tram | cable_car), nullable/omitted</td>\n<td>The transport types this carrier operates; omitted from the item when carrier detail data is temporarily unavailable.</td>\n</tr>\n<tr>\n<td>data[].logoUrls</td>\n<td>array of string, omitted</td>\n<td>URLs of the carrier's logo images, hosted by HOI. Returned only when the request includes <code>include=logoUrls</code>; then present on every carrier, empty (<code>[]</code>) when the carrier has no logo. A URL never changes for a given image. When a carrier's logo is replaced it gets a new URL and the old one stops working, so re-read <code>logoUrls</code> periodically rather than storing URLs permanently.</td>\n</tr>\n<tr>\n<td>data[].seatSelectionSupported</td>\n<td>bool, nullable</td>\n<td>Whether Get Offer Seat Map works for this carrier's trips; <code>null</code> when not yet known (including while carrier detail data is temporarily unavailable).</td>\n</tr>\n<tr>\n<td>data[].termsUrl</td>\n<td>string, nullable</td>\n<td>Link to the carrier's terms of purchase; <code>null</code> when not on file (including while carrier detail data is temporarily unavailable).</td>\n</tr>\n</tbody>\n</table>\n</div><p>The examples show the full shape. When carrier detail data is momentarily unavailable (see the folder overview), items carry only <code>id</code>/<code>name</code> (plus <code>logoUrls</code> when requested). <code>seatSelectionSupported</code>/<code>termsUrl</code> serialize as explicit <code>null</code> rather than being omitted, unlike the other detail fields.</p>\n","urlObject":{"path":["api","v0","groundtransport","carriers"],"host":["https://eservices.hoicom.net"],"query":[{"description":{"content":"<p>Optional ISO 3166-1 alpha-3 country filter. Repeat the key for multiple countries.</p>\n","type":"text/plain"},"key":"countryIsoCodes","value":""},{"description":{"content":"<p>Optional carrier id filter, up to 10 entries, case-insensitive. Repeat the key for multiple ids. An id that doesn't match any carrier is simply excluded from the result (not an error). Combines with countryIsoCodes as an intersection, never an override.</p>\n","type":"text/plain"},"key":"carrierIds","value":""},{"description":{"content":"<p>Optional. Accepted value: <code>logoUrls</code> — adds each carrier's logo URLs to the response. Any other value returns code 1114.</p>\n","type":"text/plain"},"key":"include","value":""}],"variable":[]}},"response":[{"id":"fbb98aee-bd37-4688-8c6b-a0f739a372aa","name":"200 — Success","originalRequest":{"method":"GET","header":[],"url":{"raw":"https://eservices.hoicom.net/api/v0/groundtransport/carriers?countryIsoCodes=&carrierIds=&include=","host":["https://eservices.hoicom.net"],"path":["api","v0","groundtransport","carriers"],"query":[{"key":"countryIsoCodes","value":""},{"key":"carrierIds","value":""},{"key":"include","value":""}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"cookie":[],"responseTime":null,"body":"{\n  \"code\": 1000,\n  \"message\": \"Request processed successfully.\",\n  \"data\": [\n    {\n      \"id\": \"FLIX\",\n      \"name\": \"FlixBus\",\n      \"countryIsoCode\": \"DEU\",\n      \"modes\": [\n        \"bus\"\n      ],\n      \"seatSelectionSupported\": true,\n      \"termsUrl\": \"https://carrier.example/terms\"\n    },\n    {\n      \"id\": \"XYZ1\",\n      \"name\": \"Example Carrier\",\n      \"countryIsoCode\": \"FRA\",\n      \"modes\": [\n        \"bus\"\n      ],\n      \"seatSelectionSupported\": false,\n      \"termsUrl\": null\n    }\n  ]\n}"},{"id":"61447563-6b24-4828-b0f8-6ef7b637f4be","name":"200 — With logo URLs (include=logoUrls)","originalRequest":{"method":"GET","header":[],"url":{"raw":"https://eservices.hoicom.net/api/v0/groundtransport/carriers?countryIsoCodes=&carrierIds=&include=logoUrls","host":["https://eservices.hoicom.net"],"path":["api","v0","groundtransport","carriers"],"query":[{"key":"countryIsoCodes","value":""},{"key":"carrierIds","value":""},{"key":"include","value":"logoUrls"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"cookie":[],"responseTime":null,"body":"{\n  \"code\": 1000,\n  \"message\": \"Request processed successfully.\",\n  \"data\": [\n    {\n      \"id\": \"FLIX\",\n      \"name\": \"FlixBus\",\n      \"countryIsoCode\": \"DEU\",\n      \"modes\": [\n        \"bus\"\n      ],\n      \"seatSelectionSupported\": true,\n      \"termsUrl\": \"https://carrier.example/terms\",\n      \"logoUrls\": [\n        \"https://assets.hoicom.net/gt/9f2c4a7e1b0d83c5a6e4f1d2b7c9a0e3.png\"\n      ]\n    },\n    {\n      \"id\": \"XYZ1\",\n      \"name\": \"Example Carrier\",\n      \"countryIsoCode\": \"FRA\",\n      \"modes\": [\n        \"bus\"\n      ],\n      \"seatSelectionSupported\": false,\n      \"termsUrl\": null,\n      \"logoUrls\": []\n    }\n  ]\n}"},{"id":"1d6b2c51-5760-4cc1-9e95-d9d6e44ac865","name":"200 — 1114 Unsupported include","originalRequest":{"method":"GET","header":[],"url":{"raw":"https://eservices.hoicom.net/api/v0/groundtransport/carriers?countryIsoCodes=&carrierIds=&include=logo","host":["https://eservices.hoicom.net"],"path":["api","v0","groundtransport","carriers"],"query":[{"key":"countryIsoCodes","value":""},{"key":"carrierIds","value":""},{"key":"include","value":"logo"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"cookie":[],"responseTime":null,"body":"{\n  \"code\": 1114,\n  \"message\": \"Invalid parameter value.\",\n  \"data\": {\n    \"errors\": [\n      {\n        \"field\": \"include[0]\",\n        \"issue\": \"include allows: logoUrls.\"\n      }\n    ]\n  }\n}"}],"_postman_id":"ee0e221b-050f-407e-b1bd-9df835bb38a6"},{"name":"Search Trips","id":"ea57469f-7283-4543-98a0-c8a9c7c2e385","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"},{"key":"Accept","value":"application/json"}],"body":{"mode":"raw","raw":"{\n  \"originCode\": \"ESMADMAD\",\n  \"destinationCode\": \"ESBCNEDA\",\n  \"departure\": {\n    \"date\": \"2026-12-15\",\n    \"timeFrom\": \"06:00\",\n    \"timeTo\": \"22:00\"\n  },\n  \"return\": null,\n  \"passengers\": [\n    {\n      \"type\": \"adult\",\n      \"quantity\": 1\n    }\n  ],\n  \"classCodes\": null,\n  \"include\": [\n    \"amenities\",\n    \"bookingRequirements\"\n  ]\n}","options":{"raw":{"language":"json"}}},"url":"https://eservices.hoicom.net/api/v0/groundtransport/trips/search","description":"<p>Searches live trip offers between an origin and a destination. <code>originCode</code>/<code>destinationCode</code> each accept either a station code (8 characters, from Get Stations) or a city code (5 or 6 characters, from Get Cities) — the length picks which one automatically, and you can mix a city on one end with a station on the other. A city code expands the search to every station-to-station option actually served between the two cities; a station code searches just that one route. Every returned offer is anchored to real departure/arrival stations, so reserving, committing, and fetching tickets work the same either way. With a <code>return</code> leg, offers for both directions are returned — including when the return is on a different day than the departure. A search with no matching trips returns code <code>1303</code> with <code>reason: \"no_trips\"</code>. Segment stops carry <code>timeUtc</code> (the station-local wall-clock time — <strong>not</strong> UTC, name kept for compatibility), <code>timeLocal</code> (the same value), and, when known, <code>timeZone</code> (IANA) and <code>utcOffset</code> (e.g. <code>+01:00</code>). <code>1403</code> is returned with HTTP 400 and <code>1404</code> with HTTP 502. See the folder description for the full station-vs-city explanation, time-field details and worked examples.</p>\n","urlObject":{"path":["api","v0","groundtransport","trips","search"],"host":["https://eservices.hoicom.net"],"query":[],"variable":[]}},"response":[{"id":"8abc2519-bd3f-4db3-a757-5a960b8505cd","name":"200 — Success","originalRequest":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"},{"key":"Accept","value":"application/json"}],"body":{"mode":"raw","raw":"{\n  \"originStationCode\": \"ESMADMAD\",\n  \"destinationStationCode\": \"ESBCNEDA\",\n  \"departure\": {\n    \"date\": \"2026-09-15\",\n    \"timeFrom\": \"06:00\",\n    \"timeTo\": \"22:00\"\n  },\n  \"return\": null,\n  \"passengers\": [\n    {\n      \"type\": \"adult\",\n      \"quantity\": 1\n    }\n  ],\n  \"classCodes\": null,\n  \"include\": [\n    \"class\",\n    \"seatsLeft\",\n    \"amenities\"\n  ]\n}","options":{"raw":{"language":"json"}}},"url":"https://eservices.hoicom.net/api/v0/groundtransport/trips/search","description":"Searches live trip offers between an origin and a destination. `originCode`/`destinationCode` each accept either a station code (8 characters, from Get Stations) or a city code (5 or 6 characters, from Get Cities) — the length picks which one automatically, and you can mix a city on one end with a station on the other. A city code expands the search to every station-to-station option actually served between the two cities; a station code searches just that one route. Every returned offer is anchored to real departure/arrival stations, so reserving, committing, and fetching tickets work the same either way. With a `return` leg, offers for both directions are returned — including when the return is on a different day than the departure. A search with no matching trips returns code `1303` with `reason: \"no_trips\"`. Segment stops carry `timeUtc` (the station-local wall-clock time — **not** UTC, name kept for compatibility), `timeLocal` (the same value), and, when known, `timeZone` (IANA) and `utcOffset` (e.g. `+01:00`). `1403` is returned with HTTP 400 and `1404` with HTTP 502. See the folder description for the full station-vs-city explanation, time-field details and worked examples."},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"cookie":[],"responseTime":null,"body":"{\n  \"code\": 1000,\n  \"message\": \"Request processed successfully.\",\n  \"data\": [\n    {\n      \"offerId\": \"hoi-offer-eyJhbGciOi...truncated-opaque-token...\",\n      \"direction\": \"departure\",\n      \"price\": {\n        \"subTotal\": 150.58,\n        \"currency\": \"SAR\",\n        \"taxes\": [],\n        \"fees\": [\n          {\n            \"type\": \"service_fee\",\n            \"amount\": 20.06\n          }\n        ],\n        \"totalAmount\": 170.64\n      },\n      \"carrier\": {\n        \"id\": \"ALSA\",\n        \"name\": \"ALSA\"\n      },\n      \"stops\": 0,\n      \"class\": {\n        \"code\": \"ECONOMY\",\n        \"name\": \"Economy\"\n      },\n      \"seatsLeft\": 23,\n      \"amenities\": [\n        {\n          \"code\": \"wifi\",\n          \"name\": \"Wi-Fi\",\n          \"description\": \"Free on-board Wi-Fi\"\n        }\n      ],\n      \"bookingRequirements\": {\n        \"required\": {\n          \"passengers\": [\n            \"firstName\",\n            \"lastName\"\n          ],\n          \"extras\": []\n        },\n        \"optional\": {\n          \"passengers\": [\n            \"dateOfBirth\",\n            \"nationality\"\n          ],\n          \"extras\": []\n        }\n      },\n      \"segments\": [\n        {\n          \"departure\": {\n            \"stationCode\": \"ESMADMAD\",\n            \"timeUtc\": \"2026-12-15T06:30\",\n            \"timeLocal\": \"2026-12-15T06:30\",\n            \"timeZone\": \"Europe/Madrid\",\n            \"utcOffset\": \"+01:00\"\n          },\n          \"arrival\": {\n            \"stationCode\": \"ESBCNEDA\",\n            \"timeUtc\": \"2026-12-15T13:45\",\n            \"timeLocal\": \"2026-12-15T13:45\",\n            \"timeZone\": \"Europe/Madrid\",\n            \"utcOffset\": \"+01:00\"\n          },\n          \"duration\": {\n            \"days\": 0,\n            \"hours\": 7,\n            \"minutes\": 15\n          },\n          \"mode\": \"bus\"\n        }\n      ],\n      \"expiresAt\": \"2026-12-14T18:00:00Z\"\n    }\n  ]\n}"}],"_postman_id":"ea57469f-7283-4543-98a0-c8a9c7c2e385"},{"name":"Get Offer Seat Map","id":"3de2cff7-f981-453e-8b7a-ec795849f748","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"},{"key":"Accept","value":"application/json"}],"body":{"mode":"raw","raw":"{\n  \"offerId\": \"{{offerId}}\"\n}","options":{"raw":{"language":"json"}}},"url":"https://eservices.hoicom.net/api/v0/groundtransport/trips/offers/seats","description":"<p>Returns the seat layout for an offer whose trip supports seat selection: cars with rows of seats, each seat's number, coordinates, availability, and any price difference. <code>data.supported</code> is <code>false</code> (with no <code>segments</code>) when the offer's carrier doesn't support seat selection — a normal capability answer, not an error. Pass chosen seat numbers per passenger (with <code>direction</code>: <code>departure</code> or <code>return</code>) on Create Reservation.</p>\n<hr />\n<h2 id=\"response-fields\">Response fields</h2>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Field</th>\n<th>Type</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>code</td>\n<td>int</td>\n<td>Response status code — <code>1000</code> on success.</td>\n</tr>\n<tr>\n<td>message</td>\n<td>string</td>\n<td>Human-readable summary of the result.</td>\n</tr>\n<tr>\n<td>data.supported</td>\n<td>bool</td>\n<td>Whether this offer's carrier supports seat selection; <code>false</code> is a normal capability answer, not an error.</td>\n</tr>\n<tr>\n<td>data.segments</td>\n<td>array, nullable/omitted</td>\n<td>The seat layout per vehicle leg; omitted when <code>supported</code> is <code>false</code>.</td>\n</tr>\n<tr>\n<td>data.segments[].departure</td>\n<td>object</td>\n<td>Where and when this segment departs.</td>\n</tr>\n<tr>\n<td>data.segments[].departure.stationCode</td>\n<td>string</td>\n<td>Departure station code.</td>\n</tr>\n<tr>\n<td>data.segments[].departure.timeLocal</td>\n<td>string (ISO 8601, no offset)</td>\n<td>Departure time as the station's local wall-clock time.</td>\n</tr>\n<tr>\n<td>data.segments[].arrival</td>\n<td>object</td>\n<td>Where and when this segment arrives.</td>\n</tr>\n<tr>\n<td>data.segments[].arrival.stationCode</td>\n<td>string</td>\n<td>Arrival station code.</td>\n</tr>\n<tr>\n<td>data.segments[].arrival.timeLocal</td>\n<td>string (ISO 8601, no offset)</td>\n<td>Arrival time as the station's local wall-clock time.</td>\n</tr>\n<tr>\n<td>data.segments[].cars</td>\n<td>array</td>\n<td>The vehicle's cars/carriages.</td>\n</tr>\n<tr>\n<td>data.segments[].cars[].index</td>\n<td>int</td>\n<td>The car's 1-based position in the vehicle.</td>\n</tr>\n<tr>\n<td>data.segments[].cars[].label</td>\n<td>string, nullable/omitted</td>\n<td>The car's display label.</td>\n</tr>\n<tr>\n<td>data.segments[].cars[].seats</td>\n<td>array</td>\n<td>The seats in this car.</td>\n</tr>\n<tr>\n<td>data.segments[].cars[].seats[].code</td>\n<td>string</td>\n<td>The seat's identifier — send this back as <code>seatNumber</code> on Create Reservation.</td>\n</tr>\n<tr>\n<td>data.segments[].cars[].seats[].label</td>\n<td>string</td>\n<td>The seat's display label.</td>\n</tr>\n<tr>\n<td>data.segments[].cars[].seats[].available</td>\n<td>bool</td>\n<td>Whether the seat is currently free to select.</td>\n</tr>\n<tr>\n<td>data.segments[].cars[].seats[].position</td>\n<td>object</td>\n<td>The seat's grid position in the car.</td>\n</tr>\n<tr>\n<td>data.segments[].cars[].seats[].position.x</td>\n<td>int</td>\n<td>Row coordinate.</td>\n</tr>\n<tr>\n<td>data.segments[].cars[].seats[].position.y</td>\n<td>int</td>\n<td>Column coordinate.</td>\n</tr>\n<tr>\n<td>data.segments[].cars[].seats[].position.z</td>\n<td>int</td>\n<td>Deck level (for double-decker vehicles).</td>\n</tr>\n<tr>\n<td>data.segments[].cars[].seats[].class</td>\n<td>string, nullable/omitted</td>\n<td>The fare class this seat belongs to.</td>\n</tr>\n<tr>\n<td>data.segments[].cars[].seats[].price</td>\n<td>decimal, nullable/omitted</td>\n<td>Extra charge for selecting this seat, where the carrier prices seat selection; <code>null</code>/omitted when there is none.</td>\n</tr>\n</tbody>\n</table>\n</div>","urlObject":{"path":["api","v0","groundtransport","trips","offers","seats"],"host":["https://eservices.hoicom.net"],"query":[],"variable":[]}},"response":[{"id":"41122fba-e425-48a7-a318-92135158e35a","name":"200 — Success","originalRequest":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"},{"key":"Accept","value":"application/json"}],"body":{"mode":"raw","raw":"{\n  \"offerId\": \"{{offerId}}\"\n}","options":{"raw":{"language":"json"}}},"url":"https://eservices.hoicom.net/api/v0/groundtransport/trips/offers/seats","description":"Returns the seat layout for an offer whose trip supports seat selection: cars with rows of seats, each seat's number, coordinates, availability, and any price difference. `data.supported` is `false` (with no `segments`) when the offer's carrier doesn't support seat selection — a normal capability answer, not an error. Pass chosen seat numbers per passenger (with `direction`: `departure` or `return`) on Create Reservation.\n\n---\n\n## Response fields\n\n| Field | Type | Description |\n|---|---|---|\n| code | int | Response status code — `1000` on success. |\n| message | string | Human-readable summary of the result. |\n| data.supported | bool | Whether this offer's carrier supports seat selection; `false` is a normal capability answer, not an error. |\n| data.segments | array, nullable/omitted | The seat layout per vehicle leg; omitted when `supported` is `false`. |\n| data.segments[].departure | object | Where and when this segment departs. |\n| data.segments[].departure.stationCode | string | Departure station code. |\n| data.segments[].departure.timeLocal | string (ISO 8601, no offset) | Departure time as the station's local wall-clock time. |\n| data.segments[].arrival | object | Where and when this segment arrives. |\n| data.segments[].arrival.stationCode | string | Arrival station code. |\n| data.segments[].arrival.timeLocal | string (ISO 8601, no offset) | Arrival time as the station's local wall-clock time. |\n| data.segments[].cars | array | The vehicle's cars/carriages. |\n| data.segments[].cars[].index | int | The car's 1-based position in the vehicle. |\n| data.segments[].cars[].label | string, nullable/omitted | The car's display label. |\n| data.segments[].cars[].seats | array | The seats in this car. |\n| data.segments[].cars[].seats[].code | string | The seat's identifier — send this back as `seatNumber` on Create Reservation. |\n| data.segments[].cars[].seats[].label | string | The seat's display label. |\n| data.segments[].cars[].seats[].available | bool | Whether the seat is currently free to select. |\n| data.segments[].cars[].seats[].position | object | The seat's grid position in the car. |\n| data.segments[].cars[].seats[].position.x | int | Row coordinate. |\n| data.segments[].cars[].seats[].position.y | int | Column coordinate. |\n| data.segments[].cars[].seats[].position.z | int | Deck level (for double-decker vehicles). |\n| data.segments[].cars[].seats[].class | string, nullable/omitted | The fare class this seat belongs to. |\n| data.segments[].cars[].seats[].price | decimal, nullable/omitted | Extra charge for selecting this seat, where the carrier prices seat selection; `null`/omitted when there is none. |\n"},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"cookie":[],"responseTime":null,"body":"{\n  \"code\": 1000,\n  \"message\": \"Request processed successfully.\",\n  \"data\": {\n    \"supported\": true,\n    \"segments\": [\n      {\n        \"departure\": {\n          \"stationCode\": \"ESMADMAD\",\n          \"timeLocal\": \"2026-12-15T06:30\"\n        },\n        \"arrival\": {\n          \"stationCode\": \"ESBCNEDA\",\n          \"timeLocal\": \"2026-12-15T13:45\"\n        },\n        \"cars\": [\n          {\n            \"index\": 1,\n            \"label\": \"Car 1\",\n            \"seats\": [\n              {\n                \"code\": \"12A\",\n                \"label\": \"12A\",\n                \"available\": true,\n                \"position\": {\n                  \"x\": 1,\n                  \"y\": 3,\n                  \"z\": 0\n                },\n                \"class\": \"ECONOMY\",\n                \"price\": null\n              },\n              {\n                \"code\": \"12B\",\n                \"label\": \"12B\",\n                \"available\": false,\n                \"position\": {\n                  \"x\": 2,\n                  \"y\": 3,\n                  \"z\": 0\n                },\n                \"class\": \"ECONOMY\",\n                \"price\": null\n              }\n            ]\n          }\n        ]\n      }\n    ]\n  }\n}"}],"_postman_id":"3de2cff7-f981-453e-8b7a-ec795849f748"},{"name":"Create Reservation","id":"43dc67e5-daa4-4aa1-b025-9855fc7a6f6b","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"},{"key":"Accept","value":"application/json"}],"body":{"mode":"raw","raw":"{\n  \"externalReference\": \"your-unique-reference-001\",\n  \"autoCommit\": false,\n  \"offerIds\": [\n    \"{{offerId}}\"\n  ],\n  \"passengers\": [\n    {\n      \"title\": \"Mr\",\n      \"firstName\": \"John\",\n      \"lastName\": \"Doe\",\n      \"dateOfBirth\": \"1990-05-14\",\n      \"nationality\": \"SAU\",\n      \"gender\": \"M\",\n      \"governmentId\": {\n        \"type\": \"passport\",\n        \"number\": \"A12345678\",\n        \"issuingCountry\": \"SAU\",\n        \"validityExpiration\": \"2030-01-01\"\n      },\n      \"seats\": [\n        {\n          \"direction\": \"departure\",\n          \"seatNumber\": \"12A\"\n        }\n      ],\n      \"extras\": {}\n    }\n  ]\n}","options":{"raw":{"language":"json"}}},"url":"https://eservices.hoicom.net/api/v0/groundtransport/reservations","description":"<p>Reserves the selected offer(s) for the given passengers. <strong>Asynchronous</strong>: the response acknowledges with a numeric <code>reservationId</code>; poll Get Transaction for the outcome.</p>\n<ul>\n<li><code>externalReference</code> (max 50 chars) is your idempotency key — resubmitting the same value returns <code>1000</code> with the <strong>existing reservation's current state</strong> instead of creating a second booking. A reference already used on another of your services is rejected with <code>1102</code> (HTTP 200, field <code>externalReference</code>).</li>\n<li><code>offerIds</code>: one for a one-way trip, two (outbound + return) for a round trip. A round trip succeeds or fails as a unit. Its charge is the <strong>sum of both legs' totals shown at search</strong> (the acknowledgment shows one aggregated service-fee line), and the return leg may depart from a different station in the same city as the outbound arrival (a different city returns <code>1102</code>).</li>\n<li>One <code>passengers</code> entry per traveller. <code>title</code>: Mr, Mrs, Ms, Miss, Mx, Dr · <code>gender</code>: M, F, X, U · <code>governmentId.type</code>: national_id, international_passport, passport_id, drivers_license, birth_certificate, entry_visa, marine_id, military_supplement, naturalisation_certificate, permanent_resident_id, refugee_id, resident_id, tax_number, tsa_precheck_id, us_i872_card, us_tribal_card (when in doubt, <code>national_id</code> and <code>international_passport</code> are the most widely supported) · <code>seats.direction</code>: departure, return (only send <code>seats</code> when the offer's <code>seatSelectionSupported</code> was <code>true</code>). Provide any fields listed in the offer's <code>bookingRequirements</code> (top-level or via <code>extras</code>).</li>\n<li>Set <code>autoCommit: true</code> to chain the commit automatically once the reservation succeeds — no separate Commit Reservation call needed.</li>\n</ul>\n<hr />\n<h2 id=\"response-fields\">Response fields</h2>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Field</th>\n<th>Type</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>code</td>\n<td>int</td>\n<td>Response status code — <code>1000</code> on success.</td>\n</tr>\n<tr>\n<td>message</td>\n<td>string</td>\n<td>Human-readable summary of the result.</td>\n</tr>\n<tr>\n<td>data.reservationId</td>\n<td>int</td>\n<td>The booking's identifier — use it for Commit Reservation, Get Transaction, and Get Tickets.</td>\n</tr>\n<tr>\n<td>data.autoCommit</td>\n<td>bool, nullable/omitted</td>\n<td>Present (<code>true</code>) only when the commit will chain automatically once the holds land; omitted otherwise.</td>\n</tr>\n<tr>\n<td>data.status</td>\n<td>string (value: Submitted)</td>\n<td>Reservation accepted and queued — poll Get Transaction for the outcome.</td>\n</tr>\n<tr>\n<td>data.expiresAt</td>\n<td>string (ISO 8601, UTC)</td>\n<td>When this hold's price/availability quote expires if not committed in time.</td>\n</tr>\n<tr>\n<td>data.price</td>\n<td>object</td>\n<td>The priced total for this reservation.</td>\n</tr>\n<tr>\n<td>data.price.subTotal</td>\n<td>decimal</td>\n<td>The fare before taxes and fees.</td>\n</tr>\n<tr>\n<td>data.price.currency</td>\n<td>string</td>\n<td>Currency code for every amount in this price block.</td>\n</tr>\n<tr>\n<td>data.price.taxes</td>\n<td>array</td>\n<td>Itemized taxes included in <code>totalAmount</code>.</td>\n</tr>\n<tr>\n<td>data.price.taxes[].type</td>\n<td>string</td>\n<td>The tax line's type label.</td>\n</tr>\n<tr>\n<td>data.price.taxes[].amount</td>\n<td>decimal</td>\n<td>The tax line's amount.</td>\n</tr>\n<tr>\n<td>data.price.fees</td>\n<td>array</td>\n<td>Itemized fees included in <code>totalAmount</code>.</td>\n</tr>\n<tr>\n<td>data.price.fees[].type</td>\n<td>string</td>\n<td>The fee line's type label.</td>\n</tr>\n<tr>\n<td>data.price.fees[].amount</td>\n<td>decimal</td>\n<td>The fee line's amount.</td>\n</tr>\n<tr>\n<td>data.price.totalAmount</td>\n<td>decimal</td>\n<td>The final amount you will be charged.</td>\n</tr>\n<tr>\n<td>data.commissionApplied</td>\n<td>decimal, nullable/omitted</td>\n<td>Your commission on this booking, in SAR; present only when it's greater than zero.</td>\n</tr>\n</tbody>\n</table>\n</div><p>Codes: <code>1403</code> is returned with HTTP 400; validation problems return <code>1102</code> with <code>data.errors[{ field, issue }]</code>; a duplicate <code>externalReference</code> is not an error (see above).</p>\n","urlObject":{"path":["api","v0","groundtransport","reservations"],"host":["https://eservices.hoicom.net"],"query":[],"variable":[]}},"response":[{"id":"8a1bb982-5742-4b22-8ff8-9d154e6edbd3","name":"200 — Success","originalRequest":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"},{"key":"Accept","value":"application/json"}],"body":{"mode":"raw","raw":"{\n  \"externalReference\": \"your-unique-reference-001\",\n  \"autoCommit\": false,\n  \"offerIds\": [\n    \"{{offerId}}\"\n  ],\n  \"passengers\": [\n    {\n      \"title\": \"Mr\",\n      \"firstName\": \"John\",\n      \"lastName\": \"Doe\",\n      \"dateOfBirth\": \"1990-05-14\",\n      \"nationality\": \"SAU\",\n      \"gender\": \"M\",\n      \"governmentId\": {\n        \"type\": \"passport\",\n        \"number\": \"A12345678\",\n        \"issuingCountry\": \"SAU\",\n        \"validityExpiration\": \"2030-01-01\"\n      },\n      \"seats\": [\n        {\n          \"direction\": \"departure\",\n          \"seatNumber\": \"12A\"\n        }\n      ],\n      \"extras\": {}\n    }\n  ]\n}","options":{"raw":{"language":"json"}}},"url":"https://eservices.hoicom.net/api/v0/groundtransport/reservations","description":"Reserves the selected offer(s) for the given passengers. **Asynchronous**: the response acknowledges with a numeric `reservationId`; poll Get Transaction for the outcome.\n\n- `externalReference` (max 50 chars) is your idempotency key — resubmitting the same value returns `1000` with the **existing reservation's current state** instead of creating a second booking. A reference already used on another of your services is rejected with `1102` (HTTP 200, field `externalReference`).\n- `offerIds`: one for a one-way trip, two (outbound + return) for a round trip. A round trip succeeds or fails as a unit. Its charge is the **sum of both legs' totals shown at search** (the acknowledgment shows one aggregated service-fee line), and the return leg may depart from a different station in the same city as the outbound arrival (a different city returns `1102`).\n- One `passengers` entry per traveller. `title`: Mr, Mrs, Ms, Miss, Mx, Dr · `gender`: M, F, X, U · `governmentId.type`: national_id, international_passport, passport_id, drivers_license, birth_certificate, entry_visa, marine_id, military_supplement, naturalisation_certificate, permanent_resident_id, refugee_id, resident_id, tax_number, tsa_precheck_id, us_i872_card, us_tribal_card (when in doubt, `national_id` and `international_passport` are the most widely supported) · `seats.direction`: departure, return (only send `seats` when the offer's `seatSelectionSupported` was `true`). Provide any fields listed in the offer's `bookingRequirements` (top-level or via `extras`).\n- Set `autoCommit: true` to chain the commit automatically once the reservation succeeds — no separate Commit Reservation call needed.\n\n---\n\n## Response fields\n\n| Field | Type | Description |\n|---|---|---|\n| code | int | Response status code — `1000` on success. |\n| message | string | Human-readable summary of the result. |\n| data.reservationId | int | The booking's identifier — use it for Commit Reservation, Get Transaction, and Get Tickets. |\n| data.autoCommit | bool, nullable/omitted | Present (`true`) only when the commit will chain automatically once the holds land; omitted otherwise. |\n| data.status | string (value: Submitted) | Reservation accepted and queued — poll Get Transaction for the outcome. |\n| data.expiresAt | string (ISO 8601, UTC) | When this hold's price/availability quote expires if not committed in time. |\n| data.price | object | The priced total for this reservation. |\n| data.price.subTotal | decimal | The fare before taxes and fees. |\n| data.price.currency | string | Currency code for every amount in this price block. |\n| data.price.taxes | array | Itemized taxes included in `totalAmount`. |\n| data.price.taxes[].type | string | The tax line's type label. |\n| data.price.taxes[].amount | decimal | The tax line's amount. |\n| data.price.fees | array | Itemized fees included in `totalAmount`. |\n| data.price.fees[].type | string | The fee line's type label. |\n| data.price.fees[].amount | decimal | The fee line's amount. |\n| data.price.totalAmount | decimal | The final amount you will be charged. |\n| data.commissionApplied | decimal, nullable/omitted | Your commission on this booking, in SAR; present only when it's greater than zero. |\n\nCodes: `1403` is returned with HTTP 400; validation problems return `1102` with `data.errors[{ field, issue }]`; a duplicate `externalReference` is not an error (see above).\n"},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"cookie":[],"responseTime":null,"body":"{\n  \"code\": 1000,\n  \"message\": \"Request processed successfully.\",\n  \"data\": {\n    \"reservationId\": 12345,\n    \"autoCommit\": false,\n    \"status\": \"Submitted\",\n    \"expiresAt\": \"2026-09-14T18:00:00Z\",\n    \"price\": {\n      \"subTotal\": 150.58,\n      \"currency\": \"SAR\",\n      \"taxes\": [],\n      \"fees\": [\n        {\n          \"type\": \"service_fee\",\n          \"amount\": 20.06\n        }\n      ],\n      \"totalAmount\": 170.64\n    }\n  }\n}"}],"_postman_id":"43dc67e5-daa4-4aa1-b025-9855fc7a6f6b"},{"name":"Commit Reservation","id":"568686ea-a417-4b58-a271-0a067d66dc74","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"},{"key":"Accept","value":"application/json"}],"url":"https://eservices.hoicom.net/api/v0/groundtransport/reservations/:reservationId/commit","description":"<p>Confirms a successful reservation, turning the hold into a finalized booking. <strong>Asynchronous</strong>: acknowledged immediately and completed in the background — poll Get Transaction until the status is Completed. Not needed when the reservation was created with <code>autoCommit: true</code>. Idempotent by the reservation's own state: re-committing while holds or confirms are still in flight, or committing again after the booking already completed, simply returns the current status rather than an error or a second booking.</p>\n<p><strong>Error codes:</strong> <code>1403</code> (HTTP 400) when the hold has expired — search and reserve again; <code>1105</code> when the reservation does not exist; <code>1112</code> when the reservation is in a state that cannot be committed (conflict).</p>\n<hr />\n<h2 id=\"response-fields\">Response fields</h2>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Field</th>\n<th>Type</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>code</td>\n<td>int</td>\n<td>Response status code — <code>1000</code> on success.</td>\n</tr>\n<tr>\n<td>message</td>\n<td>string</td>\n<td>Human-readable summary of the result.</td>\n</tr>\n<tr>\n<td>data.reservationId</td>\n<td>int</td>\n<td>Echo of the reservation being committed.</td>\n</tr>\n<tr>\n<td>data.status</td>\n<td>string (value: Pending)</td>\n<td>Commit accepted — the confirmation runs in the background; poll Get Transaction for <code>Completed</code>/<code>Failed</code>.</td>\n</tr>\n</tbody>\n</table>\n</div>","urlObject":{"path":["api","v0","groundtransport","reservations",":reservationId","commit"],"host":["https://eservices.hoicom.net"],"query":[],"variable":[{"description":{"content":"<p>The reservationId returned by Create Reservation.</p>\n","type":"text/plain"},"type":"any","value":"12345","key":"reservationId"}]}},"response":[{"id":"c981d423-59fd-4a65-852d-21dc8e50ab22","name":"200 — Success","originalRequest":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"},{"key":"Accept","value":"application/json"}],"url":{"raw":"https://eservices.hoicom.net/api/v0/groundtransport/reservations/:reservationId/commit","host":["https://eservices.hoicom.net"],"path":["api","v0","groundtransport","reservations",":reservationId","commit"],"variable":[{"key":"reservationId","value":"12345","description":"The reservationId returned by Create Reservation."}]},"description":"Confirms a successful reservation, turning the hold into a finalized booking. **Asynchronous**: acknowledged immediately and completed in the background — poll Get Transaction until the status is Completed. Not needed when the reservation was created with `autoCommit: true`. Idempotent by the reservation's own state: re-committing while holds or confirms are still in flight, or committing again after the booking already completed, simply returns the current status rather than an error or a second booking.\n\n**Error codes:** `1403` (HTTP 400) when the hold has expired — search and reserve again; `1105` when the reservation does not exist; `1112` when the reservation is in a state that cannot be committed (conflict).\n\n---\n\n## Response fields\n\n| Field | Type | Description |\n|---|---|---|\n| code | int | Response status code — `1000` on success. |\n| message | string | Human-readable summary of the result. |\n| data.reservationId | int | Echo of the reservation being committed. |\n| data.status | string (value: Pending) | Commit accepted — the confirmation runs in the background; poll Get Transaction for `Completed`/`Failed`. |\n"},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"cookie":[],"responseTime":null,"body":"{\n  \"code\": 1000,\n  \"message\": \"Request processed successfully.\",\n  \"data\": {\n    \"reservationId\": 12345,\n    \"status\": \"Pending\"\n  }\n}"}],"_postman_id":"568686ea-a417-4b58-a271-0a067d66dc74"},{"name":"Get Transactions","id":"6c025ca9-14d8-455b-99e3-d1f3c1ce8b55","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"GET","header":[{"key":"Accept","value":"application/json"}],"url":"https://eservices.hoicom.net/api/v0/groundtransport/transactions?externalReference=&externalReferencePrefix=&status=&createdFrom=&createdTo=&page=1&pageSize=50","description":"<p>Returns a paged list of <strong>your</strong> Ground Transport bookings, newest first — useful to reconcile against your own orders or to find a booking when you only have your <code>externalReference</code>. Each item has exactly the same shape as Get Transaction (including <code>externalReference</code>). Only your own bookings are ever returned or counted.</p>\n<p>All filters are optional:</p>\n<ul>\n<li><code>externalReference</code> — exact match (max 100 characters).</li>\n<li><code>externalReferencePrefix</code> — starts-with match (3–100 characters). Cannot be combined with <code>externalReference</code> (<code>1302</code>).</li>\n<li><code>status</code> — repeatable: Submitted, Pending, Completed, Failed, Cancelled, Refunded (case-insensitive). An unknown value returns <code>1114</code>.</li>\n<li><code>createdFrom</code> / <code>createdTo</code> — ISO 8601 date (<code>yyyy-MM-dd</code>, the whole UTC day) or date-time (UTC unless an offset is given). The span may not exceed 93 days; <code>createdFrom</code> after <code>createdTo</code> returns <code>1302</code>; a bad format returns <code>1114</code>.</li>\n<li><code>page</code> (default 1; out of range returns <code>1201</code>) and <code>pageSize</code> (default 50, max 100; out of range returns <code>1202</code>).</li>\n</ul>\n<p>The list is read-only and reflects each booking as Get Transaction would show it: a hold that has lapsed is displayed as Failed and matches the <code>Failed</code> status filter. The endpoint always responds with HTTP 200 — validation errors are reported in the response <code>code</code>.</p>\n<hr />\n<h2 id=\"response-fields\">Response fields</h2>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Field</th>\n<th>Type</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>code</td>\n<td>int</td>\n<td>Response status code — <code>1000</code> on success.</td>\n</tr>\n<tr>\n<td>message</td>\n<td>string</td>\n<td>Human-readable summary of the result.</td>\n</tr>\n<tr>\n<td>data.count</td>\n<td>int</td>\n<td>Number of items returned on this page.</td>\n</tr>\n<tr>\n<td>data.items</td>\n<td>array</td>\n<td>The bookings on this page, newest first. Each item has the Get Transaction response shape (<code>reservationId</code>, <code>createdAt</code>, <code>status</code>, <code>expiresAt</code>, <code>commitRequested</code>, <code>booking</code>, <code>failure</code>, <code>price</code>, <code>commissionApplied</code>, <code>passengers[]</code>, <code>externalReference</code>).</td>\n</tr>\n<tr>\n<td>data.page</td>\n<td>int</td>\n<td>The page number returned.</td>\n</tr>\n<tr>\n<td>data.pageSize</td>\n<td>int</td>\n<td>The number of items requested per page.</td>\n</tr>\n<tr>\n<td>data.totalPages</td>\n<td>int</td>\n<td>Total number of pages for the current filter.</td>\n</tr>\n<tr>\n<td>data.totalItems</td>\n<td>int</td>\n<td>Total number of bookings matching the current filter, across all pages.</td>\n</tr>\n</tbody>\n</table>\n</div>","urlObject":{"path":["api","v0","groundtransport","transactions"],"host":["https://eservices.hoicom.net"],"query":[{"description":{"content":"<p>Optional: exact match on your externalReference (max 100 characters). Cannot be combined with externalReferencePrefix.</p>\n","type":"text/plain"},"key":"externalReference","value":""},{"description":{"content":"<p>Optional: starts-with match on your externalReference (3-100 characters). Cannot be combined with externalReference.</p>\n","type":"text/plain"},"key":"externalReferencePrefix","value":""},{"description":{"content":"<p>Optional status filter, repeatable: Submitted, Pending, Completed, Failed, Cancelled, Refunded (case-insensitive).</p>\n","type":"text/plain"},"key":"status","value":""},{"description":{"content":"<p>Optional: created on/after this ISO 8601 date (yyyy-MM-dd = start of that UTC day) or date-time (UTC unless an offset is given).</p>\n","type":"text/plain"},"key":"createdFrom","value":""},{"description":{"content":"<p>Optional: created on/before this ISO 8601 date (yyyy-MM-dd = through the end of that UTC day) or date-time. The createdFrom-createdTo span may not exceed 93 days.</p>\n","type":"text/plain"},"key":"createdTo","value":""},{"description":{"content":"<p>Page number for pagination (default: 1).</p>\n","type":"text/plain"},"key":"page","value":"1"},{"description":{"content":"<p>Number of items per page (default: 50, max: 100).</p>\n","type":"text/plain"},"key":"pageSize","value":"50"}],"variable":[]}},"response":[{"id":"40955a1e-5dae-4344-8d04-882fe37392b0","name":"200 — Success","originalRequest":{"method":"GET","header":[{"key":"Accept","value":"application/json"}],"url":{"raw":"https://eservices.hoicom.net/api/v0/groundtransport/transactions?externalReference=&externalReferencePrefix=&status=&createdFrom=&createdTo=&page=1&pageSize=50","host":["https://eservices.hoicom.net"],"path":["api","v0","groundtransport","transactions"],"query":[{"key":"externalReference","value":"","description":"Optional: exact match on your externalReference (max 100 characters). Cannot be combined with externalReferencePrefix."},{"key":"externalReferencePrefix","value":"","description":"Optional: starts-with match on your externalReference (3-100 characters). Cannot be combined with externalReference."},{"key":"status","value":"","description":"Optional status filter, repeatable: Submitted, Pending, Completed, Failed, Cancelled, Refunded (case-insensitive)."},{"key":"createdFrom","value":"","description":"Optional: created on/after this ISO 8601 date (yyyy-MM-dd = start of that UTC day) or date-time (UTC unless an offset is given)."},{"key":"createdTo","value":"","description":"Optional: created on/before this ISO 8601 date (yyyy-MM-dd = through the end of that UTC day) or date-time. The createdFrom-createdTo span may not exceed 93 days."},{"key":"page","value":"1","description":"Page number for pagination (default: 1)."},{"key":"pageSize","value":"50","description":"Number of items per page (default: 50, max: 100)."}]},"description":"Returns a paged list of **your** Ground Transport bookings, newest first — useful to reconcile against your own orders or to find a booking when you only have your `externalReference`. Each item has exactly the same shape as Get Transaction (including `externalReference`). Only your own bookings are ever returned or counted.\n\nAll filters are optional:\n\n- `externalReference` — exact match (max 100 characters).\n- `externalReferencePrefix` — starts-with match (3–100 characters). Cannot be combined with `externalReference` (`1302`).\n- `status` — repeatable: Submitted, Pending, Completed, Failed, Cancelled, Refunded (case-insensitive). An unknown value returns `1114`.\n- `createdFrom` / `createdTo` — ISO 8601 date (`yyyy-MM-dd`, the whole UTC day) or date-time (UTC unless an offset is given). The span may not exceed 93 days; `createdFrom` after `createdTo` returns `1302`; a bad format returns `1114`.\n- `page` (default 1; out of range returns `1201`) and `pageSize` (default 50, max 100; out of range returns `1202`).\n\nThe list is read-only and reflects each booking as Get Transaction would show it: a hold that has lapsed is displayed as Failed and matches the `Failed` status filter. The endpoint always responds with HTTP 200 — validation errors are reported in the response `code`.\n\n---\n\n## Response fields\n\n| Field | Type | Description |\n|---|---|---|\n| code | int | Response status code — `1000` on success. |\n| message | string | Human-readable summary of the result. |\n| data.count | int | Number of items returned on this page. |\n| data.items | array | The bookings on this page, newest first. Each item has the Get Transaction response shape (`reservationId`, `createdAt`, `status`, `expiresAt`, `commitRequested`, `booking`, `failure`, `price`, `commissionApplied`, `passengers[]`, `externalReference`). |\n| data.page | int | The page number returned. |\n| data.pageSize | int | The number of items requested per page. |\n| data.totalPages | int | Total number of pages for the current filter. |\n| data.totalItems | int | Total number of bookings matching the current filter, across all pages. |\n"},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"cookie":[],"responseTime":null,"body":"{\n  \"code\": 1000,\n  \"message\": \"Request processed successfully.\",\n  \"data\": {\n    \"count\": 2,\n    \"items\": [\n      {\n        \"reservationId\": 12346,\n        \"createdAt\": \"2026-09-14T15:30:44Z\",\n        \"status\": \"Pending\",\n        \"expiresAt\": \"2026-09-14T15:45:44Z\",\n        \"commitRequested\": true,\n        \"booking\": null,\n        \"price\": {\n          \"subTotal\": 150.58,\n          \"currency\": \"SAR\",\n          \"taxes\": [],\n          \"fees\": [\n            {\n              \"type\": \"service_fee\",\n              \"amount\": 20.06\n            }\n          ],\n          \"totalAmount\": 170.64\n        },\n        \"commissionApplied\": 8.53,\n        \"passengers\": [\n          {\n            \"title\": \"Ms\",\n            \"firstName\": \"Jane\",\n            \"lastName\": \"Doe\"\n          }\n        ],\n        \"externalReference\": \"your-unique-reference-002\"\n      },\n      {\n        \"reservationId\": 12345,\n        \"createdAt\": \"2026-09-14T15:02:11Z\",\n        \"status\": \"Completed\",\n        \"expiresAt\": null,\n        \"commitRequested\": true,\n        \"booking\": {\n          \"confirmedAt\": \"2026-09-14T15:04:38Z\",\n          \"trips\": [\n            {\n              \"bookingReference\": \"K7KJX9\",\n              \"carrier\": {\n                \"id\": \"ALSA\",\n                \"name\": \"ALSA\"\n              },\n              \"class\": {\n                \"code\": \"ECONOMY\",\n                \"name\": \"Economy\"\n              },\n              \"stops\": 0,\n              \"segments\": [\n                {\n                  \"departure\": {\n                    \"stationCode\": \"ESMADMAD\",\n                    \"timeUtc\": \"2026-12-15T06:30\",\n                    \"timeLocal\": \"2026-12-15T06:30\",\n                    \"timeZone\": \"Europe/Madrid\",\n                    \"utcOffset\": \"+01:00\"\n                  },\n                  \"arrival\": {\n                    \"stationCode\": \"ESBCNEDA\",\n                    \"timeUtc\": \"2026-12-15T13:45\",\n                    \"timeLocal\": \"2026-12-15T13:45\",\n                    \"timeZone\": \"Europe/Madrid\",\n                    \"utcOffset\": \"+01:00\"\n                  },\n                  \"duration\": {\n                    \"days\": 0,\n                    \"hours\": 7,\n                    \"minutes\": 15\n                  },\n                  \"mode\": \"bus\"\n                }\n              ]\n            }\n          ],\n          \"ticketsAvailable\": true\n        },\n        \"price\": {\n          \"subTotal\": 150.58,\n          \"currency\": \"SAR\",\n          \"taxes\": [],\n          \"fees\": [\n            {\n              \"type\": \"service_fee\",\n              \"amount\": 20.06\n            }\n          ],\n          \"totalAmount\": 170.64\n        },\n        \"commissionApplied\": 8.53,\n        \"passengers\": [\n          {\n            \"title\": \"Mr\",\n            \"firstName\": \"John\",\n            \"lastName\": \"Doe\"\n          }\n        ],\n        \"externalReference\": \"your-unique-reference-001\"\n      }\n    ],\n    \"page\": 1,\n    \"pageSize\": 50,\n    \"totalPages\": 1,\n    \"totalItems\": 2\n  }\n}"}],"_postman_id":"6c025ca9-14d8-455b-99e3-d1f3c1ce8b55"},{"name":"Get Transaction","id":"5549746c-9a58-42cf-aa1a-0cd38740c3aa","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"GET","header":[{"key":"Accept","value":"application/json"}],"url":"https://eservices.hoicom.net/api/v0/groundtransport/transactions/:reservationId","description":"<p>The single source of truth for a booking's state. Returns the status (Submitted, Pending, Completed, Failed, Cancelled), the booked trips (stations, times, carrier, class, and the <code>bookingReference</code> of each trip at <code>booking.trips[].bookingReference</code> — there is no top-level reference field), passengers, the quoted price, your <code>externalReference</code>, <code>commissionApplied</code> when a commission applies to your account, and a <code>failure</code> block (<code>code</code> + <code>errors[]</code>) when something went wrong.</p>\n<p>A booking stays <strong>Pending until every trip has its booking reference</strong>, then becomes <strong>Completed</strong> (booked, references issued, tickets ready) — typically within seconds; keep polling. <code>commitRequested</code> is <code>true</code> once a commit has been requested; <code>expiresAt</code> is the hold/quote expiry while Submitted or Pending and <code>null</code> once terminal. Unknown reservation: <code>1105</code>.</p>\n<hr />\n<h2 id=\"response-fields\">Response fields</h2>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Field</th>\n<th>Type</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>code</td>\n<td>int</td>\n<td>Response status code — <code>1000</code> on success.</td>\n</tr>\n<tr>\n<td>message</td>\n<td>string</td>\n<td>Human-readable summary of the result.</td>\n</tr>\n<tr>\n<td>data.reservationId</td>\n<td>int</td>\n<td>The booking's identifier.</td>\n</tr>\n<tr>\n<td>data.createdAt</td>\n<td>string (ISO 8601, UTC)</td>\n<td>When the reservation was created.</td>\n</tr>\n<tr>\n<td>data.status</td>\n<td>string (values: Submitted | Pending | Completed | Failed | Cancelled)</td>\n<td>The booking's current lifecycle state. Pending covers reservation/commit in progress and waiting for the booking reference(s); Completed means booked, references issued, tickets ready.</td>\n</tr>\n<tr>\n<td>data.expiresAt</td>\n<td>string (ISO 8601, UTC), nullable</td>\n<td>The hold/quote expiry while <code>Submitted</code> or <code>Pending</code>; <code>null</code> on terminal states.</td>\n</tr>\n<tr>\n<td>data.commitRequested</td>\n<td>bool, nullable/omitted</td>\n<td>Present (<code>true</code>) only once a commit has been requested (explicitly, early, or via <code>autoCommit</code>).</td>\n</tr>\n<tr>\n<td>data.booking</td>\n<td>object, nullable</td>\n<td>Populated once every trip has its booking reference — on <code>Completed</code>, and on <code>Failed</code> after a partial commit (holding only the confirmed trip); <code>null</code> otherwise (including while <code>Pending</code>).</td>\n</tr>\n<tr>\n<td>data.booking.confirmedAt</td>\n<td>string (ISO 8601, UTC), nullable/omitted</td>\n<td>When the booking was confirmed; omitted on a partial-commit <code>Failed</code> row.</td>\n</tr>\n<tr>\n<td>data.booking.trips</td>\n<td>array</td>\n<td>The booked trip(s).</td>\n</tr>\n<tr>\n<td>data.booking.trips[].direction</td>\n<td>string (values: departure | return), nullable/omitted</td>\n<td>Which leg of a round trip this is; present only on round trips.</td>\n</tr>\n<tr>\n<td>data.booking.trips[].bookingReference</td>\n<td>string</td>\n<td>The confirmed booking reference for this trip (one per leg on a round trip). This is the only place the reference appears.</td>\n</tr>\n<tr>\n<td>data.booking.trips[].carrier</td>\n<td>object</td>\n<td>The operating carrier.</td>\n</tr>\n<tr>\n<td>data.booking.trips[].carrier.id</td>\n<td>string</td>\n<td>Carrier code.</td>\n</tr>\n<tr>\n<td>data.booking.trips[].carrier.name</td>\n<td>string</td>\n<td>The carrier's display name.</td>\n</tr>\n<tr>\n<td>data.booking.trips[].class</td>\n<td>object</td>\n<td>The actually-booked fare class.</td>\n</tr>\n<tr>\n<td>data.booking.trips[].class.code</td>\n<td>string</td>\n<td>Fare class code.</td>\n</tr>\n<tr>\n<td>data.booking.trips[].class.name</td>\n<td>string</td>\n<td>Fare class display name.</td>\n</tr>\n<tr>\n<td>data.booking.trips[].stops</td>\n<td>int</td>\n<td>Number of intermediate changes of vehicle on this trip.</td>\n</tr>\n<tr>\n<td>data.booking.trips[].amenities</td>\n<td>array, nullable/omitted</td>\n<td>Fare features advertised at search time; empty when none.</td>\n</tr>\n<tr>\n<td>data.booking.trips[].amenities[].code</td>\n<td>string</td>\n<td>Opaque, carrier-defined feature code.</td>\n</tr>\n<tr>\n<td>data.booking.trips[].amenities[].name</td>\n<td>string</td>\n<td>The feature's display name.</td>\n</tr>\n<tr>\n<td>data.booking.trips[].seats</td>\n<td>array, nullable/omitted</td>\n<td>The seat assignment(s) submitted at reservation; omitted when none were selected.</td>\n</tr>\n<tr>\n<td>data.booking.trips[].seats[].passengerName</td>\n<td>string</td>\n<td>Name of the passenger the seat is assigned to.</td>\n</tr>\n<tr>\n<td>data.booking.trips[].seats[].seatNumber</td>\n<td>string</td>\n<td>The assigned seat's code.</td>\n</tr>\n<tr>\n<td>data.booking.trips[].segments</td>\n<td>array</td>\n<td>The vehicle leg(s) making up this trip.</td>\n</tr>\n<tr>\n<td>data.booking.trips[].segments[].departure</td>\n<td>object</td>\n<td>Where and when this segment departs.</td>\n</tr>\n<tr>\n<td>data.booking.trips[].segments[].departure.stationCode</td>\n<td>string</td>\n<td>Departure station code.</td>\n</tr>\n<tr>\n<td>data.booking.trips[].segments[].departure.timeUtc</td>\n<td>string (ISO 8601, no offset)</td>\n<td>Departure time as the station's <strong>local wall-clock time — not UTC</strong> (name kept for compatibility).</td>\n</tr>\n<tr>\n<td>data.booking.trips[].segments[].departure.timeLocal</td>\n<td>string (ISO 8601, no offset)</td>\n<td>Same value as <code>timeUtc</code>, under an accurate name.</td>\n</tr>\n<tr>\n<td>data.booking.trips[].segments[].departure.timeZone</td>\n<td>string, omitted when unknown</td>\n<td>The station's IANA time-zone id.</td>\n</tr>\n<tr>\n<td>data.booking.trips[].segments[].departure.utcOffset</td>\n<td>string, omitted when unknown</td>\n<td>UTC offset in force at that local time (e.g. <code>+01:00</code>).</td>\n</tr>\n<tr>\n<td>data.booking.trips[].segments[].arrival</td>\n<td>object</td>\n<td>Where and when this segment arrives.</td>\n</tr>\n<tr>\n<td>data.booking.trips[].segments[].arrival.stationCode</td>\n<td>string</td>\n<td>Arrival station code.</td>\n</tr>\n<tr>\n<td>data.booking.trips[].segments[].arrival.timeUtc</td>\n<td>string (ISO 8601, no offset)</td>\n<td>Arrival time as the station's <strong>local wall-clock time — not UTC</strong>.</td>\n</tr>\n<tr>\n<td>data.booking.trips[].segments[].arrival.timeLocal</td>\n<td>string (ISO 8601, no offset)</td>\n<td>Same value as <code>timeUtc</code>.</td>\n</tr>\n<tr>\n<td>data.booking.trips[].segments[].arrival.timeZone</td>\n<td>string, omitted when unknown</td>\n<td>The station's IANA time-zone id.</td>\n</tr>\n<tr>\n<td>data.booking.trips[].segments[].arrival.utcOffset</td>\n<td>string, omitted when unknown</td>\n<td>UTC offset in force at that local time.</td>\n</tr>\n<tr>\n<td>data.booking.trips[].segments[].duration</td>\n<td>object</td>\n<td>The segment's travel time, decomposed into <code>days</code>/<code>hours</code>/<code>minutes</code> (all int).</td>\n</tr>\n<tr>\n<td>data.booking.trips[].segments[].mode</td>\n<td>string (values: bus | rail | ferry | transfer | metro | tram | cable_car), nullable/omitted</td>\n<td>The segment's transport mode; omitted when not resolvable.</td>\n</tr>\n<tr>\n<td>data.booking.ticketsAvailable</td>\n<td>bool</td>\n<td>Whether Get Tickets can currently serve this booking's tickets.</td>\n</tr>\n<tr>\n<td>data.price</td>\n<td>object</td>\n<td>The priced total for this booking (same shape as Search Trips' <code>price</code>: <code>subTotal</code>, <code>currency</code>, <code>taxes[]</code>, <code>fees[]</code>, <code>totalAmount</code>).</td>\n</tr>\n<tr>\n<td>data.commissionApplied</td>\n<td>decimal, nullable/omitted</td>\n<td>Your commission on this booking, in SAR; present only when it's greater than zero.</td>\n</tr>\n<tr>\n<td>data.passengers</td>\n<td>array</td>\n<td>Echo of the passengers submitted at reservation.</td>\n</tr>\n<tr>\n<td>data.passengers[].title</td>\n<td>string (values: Mr | Mrs | Ms | Miss | Mx | Dr)</td>\n<td>The passenger's title.</td>\n</tr>\n<tr>\n<td>data.passengers[].firstName</td>\n<td>string</td>\n<td>The passenger's first name.</td>\n</tr>\n<tr>\n<td>data.passengers[].lastName</td>\n<td>string</td>\n<td>The passenger's last name.</td>\n</tr>\n<tr>\n<td>data.externalReference</td>\n<td>string, nullable/omitted</td>\n<td>Your own reference for this reservation, echoed back.</td>\n</tr>\n</tbody>\n</table>\n</div><p>Not present in the example above (only appears when <code>status</code> is <code>Failed</code>): <strong>data.failure</strong> (object) — the reason the booking could not be completed, with <strong>data.failure.code</strong> (int, the <code>BaseResponse</code> code describing the failure category) and <strong>data.failure.errors</strong> (array of <code>{ issue: string }</code> lines with a plain-English explanation).</p>\n","urlObject":{"path":["api","v0","groundtransport","transactions",":reservationId"],"host":["https://eservices.hoicom.net"],"query":[],"variable":[{"description":{"content":"<p>The reservationId returned by Create Reservation.</p>\n","type":"text/plain"},"type":"any","value":"12345","key":"reservationId"}]}},"response":[{"id":"fbe7db49-eff6-4cd4-bbb2-6678c24c29e3","name":"200 — Success","originalRequest":{"method":"GET","header":[{"key":"Accept","value":"application/json"}],"url":{"raw":"https://eservices.hoicom.net/api/v0/groundtransport/transactions/:reservationId","host":["https://eservices.hoicom.net"],"path":["api","v0","groundtransport","transactions",":reservationId"],"variable":[{"key":"reservationId","value":"12345","description":"The reservationId returned by Create Reservation."}]},"description":"The single source of truth for a booking's state. Returns the status (Submitted, Pending, Completed, Failed, Cancelled), the booked trips (stations, times, carrier, class, and the `bookingReference` of each trip at `booking.trips[].bookingReference` — there is no top-level reference field), passengers, the quoted price, your `externalReference`, `commissionApplied` when a commission applies to your account, and a `failure` block (`code` + `errors[]`) when something went wrong.\n\nA booking stays **Pending until every trip has its booking reference**, then becomes **Completed** (booked, references issued, tickets ready) — typically within seconds; keep polling. `commitRequested` is `true` once a commit has been requested; `expiresAt` is the hold/quote expiry while Submitted or Pending and `null` once terminal. Unknown reservation: `1105`.\n\n---\n\n## Response fields\n\n| Field | Type | Description |\n|---|---|---|\n| code | int | Response status code — `1000` on success. |\n| message | string | Human-readable summary of the result. |\n| data.reservationId | int | The booking's identifier. |\n| data.createdAt | string (ISO 8601, UTC) | When the reservation was created. |\n| data.status | string (values: Submitted \\| Pending \\| Completed \\| Failed \\| Cancelled) | The booking's current lifecycle state. Pending covers reservation/commit in progress and waiting for the booking reference(s); Completed means booked, references issued, tickets ready. |\n| data.expiresAt | string (ISO 8601, UTC), nullable | The hold/quote expiry while `Submitted` or `Pending`; `null` on terminal states. |\n| data.commitRequested | bool, nullable/omitted | Present (`true`) only once a commit has been requested (explicitly, early, or via `autoCommit`). |\n| data.booking | object, nullable | Populated once every trip has its booking reference — on `Completed`, and on `Failed` after a partial commit (holding only the confirmed trip); `null` otherwise (including while `Pending`). |\n| data.booking.confirmedAt | string (ISO 8601, UTC), nullable/omitted | When the booking was confirmed; omitted on a partial-commit `Failed` row. |\n| data.booking.trips | array | The booked trip(s). |\n| data.booking.trips[].direction | string (values: departure \\| return), nullable/omitted | Which leg of a round trip this is; present only on round trips. |\n| data.booking.trips[].bookingReference | string | The confirmed booking reference for this trip (one per leg on a round trip). This is the only place the reference appears. |\n| data.booking.trips[].carrier | object | The operating carrier. |\n| data.booking.trips[].carrier.id | string | Carrier code. |\n| data.booking.trips[].carrier.name | string | The carrier's display name. |\n| data.booking.trips[].class | object | The actually-booked fare class. |\n| data.booking.trips[].class.code | string | Fare class code. |\n| data.booking.trips[].class.name | string | Fare class display name. |\n| data.booking.trips[].stops | int | Number of intermediate changes of vehicle on this trip. |\n| data.booking.trips[].amenities | array, nullable/omitted | Fare features advertised at search time; empty when none. |\n| data.booking.trips[].amenities[].code | string | Opaque, carrier-defined feature code. |\n| data.booking.trips[].amenities[].name | string | The feature's display name. |\n| data.booking.trips[].seats | array, nullable/omitted | The seat assignment(s) submitted at reservation; omitted when none were selected. |\n| data.booking.trips[].seats[].passengerName | string | Name of the passenger the seat is assigned to. |\n| data.booking.trips[].seats[].seatNumber | string | The assigned seat's code. |\n| data.booking.trips[].segments | array | The vehicle leg(s) making up this trip. |\n| data.booking.trips[].segments[].departure | object | Where and when this segment departs. |\n| data.booking.trips[].segments[].departure.stationCode | string | Departure station code. |\n| data.booking.trips[].segments[].departure.timeUtc | string (ISO 8601, no offset) | Departure time as the station's **local wall-clock time — not UTC** (name kept for compatibility). |\n| data.booking.trips[].segments[].departure.timeLocal | string (ISO 8601, no offset) | Same value as `timeUtc`, under an accurate name. |\n| data.booking.trips[].segments[].departure.timeZone | string, omitted when unknown | The station's IANA time-zone id. |\n| data.booking.trips[].segments[].departure.utcOffset | string, omitted when unknown | UTC offset in force at that local time (e.g. `+01:00`). |\n| data.booking.trips[].segments[].arrival | object | Where and when this segment arrives. |\n| data.booking.trips[].segments[].arrival.stationCode | string | Arrival station code. |\n| data.booking.trips[].segments[].arrival.timeUtc | string (ISO 8601, no offset) | Arrival time as the station's **local wall-clock time — not UTC**. |\n| data.booking.trips[].segments[].arrival.timeLocal | string (ISO 8601, no offset) | Same value as `timeUtc`. |\n| data.booking.trips[].segments[].arrival.timeZone | string, omitted when unknown | The station's IANA time-zone id. |\n| data.booking.trips[].segments[].arrival.utcOffset | string, omitted when unknown | UTC offset in force at that local time. |\n| data.booking.trips[].segments[].duration | object | The segment's travel time, decomposed into `days`/`hours`/`minutes` (all int). |\n| data.booking.trips[].segments[].mode | string (values: bus \\| rail \\| ferry \\| transfer \\| metro \\| tram \\| cable_car), nullable/omitted | The segment's transport mode; omitted when not resolvable. |\n| data.booking.ticketsAvailable | bool | Whether Get Tickets can currently serve this booking's tickets. |\n| data.price | object | The priced total for this booking (same shape as Search Trips' `price`: `subTotal`, `currency`, `taxes[]`, `fees[]`, `totalAmount`). |\n| data.commissionApplied | decimal, nullable/omitted | Your commission on this booking, in SAR; present only when it's greater than zero. |\n| data.passengers | array | Echo of the passengers submitted at reservation. |\n| data.passengers[].title | string (values: Mr \\| Mrs \\| Ms \\| Miss \\| Mx \\| Dr) | The passenger's title. |\n| data.passengers[].firstName | string | The passenger's first name. |\n| data.passengers[].lastName | string | The passenger's last name. |\n| data.externalReference | string, nullable/omitted | Your own reference for this reservation, echoed back. |\n\nNot present in the example above (only appears when `status` is `Failed`): **data.failure** (object) — the reason the booking could not be completed, with **data.failure.code** (int, the `BaseResponse` code describing the failure category) and **data.failure.errors** (array of `{ issue: string }` lines with a plain-English explanation).\n"},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"cookie":[],"responseTime":null,"body":"{\n  \"code\": 1000,\n  \"message\": \"Request processed successfully.\",\n  \"data\": {\n    \"reservationId\": 12345,\n    \"createdAt\": \"2026-09-14T15:02:11Z\",\n    \"status\": \"Completed\",\n    \"expiresAt\": null,\n    \"commitRequested\": true,\n    \"booking\": {\n      \"confirmedAt\": \"2026-09-14T15:04:38Z\",\n      \"trips\": [\n        {\n          \"direction\": \"departure\",\n          \"bookingReference\": \"K7KJX9\",\n          \"carrier\": {\n            \"id\": \"ALSA\",\n            \"name\": \"ALSA\"\n          },\n          \"class\": {\n            \"code\": \"ECONOMY\",\n            \"name\": \"Economy\"\n          },\n          \"stops\": 0,\n          \"amenities\": [\n            {\n              \"code\": \"wifi\",\n              \"name\": \"Wi-Fi\",\n              \"description\": \"Free on-board Wi-Fi\"\n            }\n          ],\n          \"seats\": [\n            {\n              \"passengerName\": \"John Doe\",\n              \"seatNumber\": \"12A\"\n            }\n          ],\n          \"segments\": [\n            {\n              \"departure\": {\n                \"stationCode\": \"ESMADMAD\",\n                \"timeUtc\": \"2026-12-15T06:30\",\n                \"timeLocal\": \"2026-12-15T06:30\",\n                \"timeZone\": \"Europe/Madrid\",\n                \"utcOffset\": \"+01:00\"\n              },\n              \"arrival\": {\n                \"stationCode\": \"ESBCNEDA\",\n                \"timeUtc\": \"2026-12-15T13:45\",\n                \"timeLocal\": \"2026-12-15T13:45\",\n                \"timeZone\": \"Europe/Madrid\",\n                \"utcOffset\": \"+01:00\"\n              },\n              \"duration\": {\n                \"days\": 0,\n                \"hours\": 7,\n                \"minutes\": 15\n              },\n              \"mode\": \"bus\"\n            }\n          ]\n        }\n      ],\n      \"ticketsAvailable\": true\n    },\n    \"price\": {\n      \"subTotal\": 150.58,\n      \"currency\": \"SAR\",\n      \"taxes\": [],\n      \"fees\": [\n        {\n          \"type\": \"service_fee\",\n          \"amount\": 20.06\n        }\n      ],\n      \"totalAmount\": 170.64\n    },\n    \"commissionApplied\": 8.53,\n    \"passengers\": [\n      {\n        \"title\": \"Mr\",\n        \"firstName\": \"John\",\n        \"lastName\": \"Doe\"\n      }\n    ],\n    \"externalReference\": \"your-unique-reference-001\"\n  }\n}"},{"id":"2d39da3a-edbd-4ca6-b91b-9ec95355f17f","name":"200 — Pending (awaiting booking reference)","originalRequest":{"method":"GET","header":[{"key":"Accept","value":"application/json"}],"url":{"raw":"https://eservices.hoicom.net/api/v0/groundtransport/transactions/:reservationId","host":["https://eservices.hoicom.net"],"path":["api","v0","groundtransport","transactions",":reservationId"],"variable":[{"key":"reservationId","value":"12345","description":"The reservationId returned by Create Reservation."}]},"description":"The single source of truth for a booking's state. Returns the status (Submitted, Pending, Completed, Failed, Cancelled), the booked trips (stations, times, carrier, class, and the `bookingReference` of each trip at `booking.trips[].bookingReference` — there is no top-level reference field), passengers, the quoted price, your `externalReference`, `commissionApplied` when a commission applies to your account, and a `failure` block (`code` + `errors[]`) when something went wrong.\n\nA booking stays **Pending until every trip has its booking reference**, then becomes **Completed** (booked, references issued, tickets ready) — typically within seconds; keep polling. `commitRequested` is `true` once a commit has been requested; `expiresAt` is the hold/quote expiry while Submitted or Pending and `null` once terminal. Unknown reservation: `1105`.\n\n---\n\n## Response fields\n\n| Field | Type | Description |\n|---|---|---|\n| code | int | Response status code — `1000` on success. |\n| message | string | Human-readable summary of the result. |\n| data.reservationId | int | The booking's identifier. |\n| data.createdAt | string (ISO 8601, UTC) | When the reservation was created. |\n| data.status | string (values: Submitted \\| Pending \\| Completed \\| Failed \\| Cancelled) | The booking's current lifecycle state. Pending covers reservation/commit in progress and waiting for the booking reference(s); Completed means booked, references issued, tickets ready. |\n| data.expiresAt | string (ISO 8601, UTC), nullable | The hold/quote expiry while `Submitted` or `Pending`; `null` on terminal states. |\n| data.commitRequested | bool, nullable/omitted | Present (`true`) only once a commit has been requested (explicitly, early, or via `autoCommit`). |\n| data.booking | object, nullable | Populated once every trip has its booking reference — on `Completed`, and on `Failed` after a partial commit (holding only the confirmed trip); `null` otherwise (including while `Pending`). |\n| data.booking.confirmedAt | string (ISO 8601, UTC), nullable/omitted | When the booking was confirmed; omitted on a partial-commit `Failed` row. |\n| data.booking.trips | array | The booked trip(s). |\n| data.booking.trips[].direction | string (values: departure \\| return), nullable/omitted | Which leg of a round trip this is; present only on round trips. |\n| data.booking.trips[].bookingReference | string | The confirmed booking reference for this trip (one per leg on a round trip). This is the only place the reference appears. |\n| data.booking.trips[].carrier | object | The operating carrier. |\n| data.booking.trips[].carrier.id | string | Carrier code. |\n| data.booking.trips[].carrier.name | string | The carrier's display name. |\n| data.booking.trips[].class | object | The actually-booked fare class. |\n| data.booking.trips[].class.code | string | Fare class code. |\n| data.booking.trips[].class.name | string | Fare class display name. |\n| data.booking.trips[].stops | int | Number of intermediate changes of vehicle on this trip. |\n| data.booking.trips[].amenities | array, nullable/omitted | Fare features advertised at search time; empty when none. |\n| data.booking.trips[].amenities[].code | string | Opaque, carrier-defined feature code. |\n| data.booking.trips[].amenities[].name | string | The feature's display name. |\n| data.booking.trips[].seats | array, nullable/omitted | The seat assignment(s) submitted at reservation; omitted when none were selected. |\n| data.booking.trips[].seats[].passengerName | string | Name of the passenger the seat is assigned to. |\n| data.booking.trips[].seats[].seatNumber | string | The assigned seat's code. |\n| data.booking.trips[].segments | array | The vehicle leg(s) making up this trip. |\n| data.booking.trips[].segments[].departure | object | Where and when this segment departs. |\n| data.booking.trips[].segments[].departure.stationCode | string | Departure station code. |\n| data.booking.trips[].segments[].departure.timeUtc | string (ISO 8601, no offset) | Departure time as the station's **local wall-clock time — not UTC** (name kept for compatibility). |\n| data.booking.trips[].segments[].departure.timeLocal | string (ISO 8601, no offset) | Same value as `timeUtc`, under an accurate name. |\n| data.booking.trips[].segments[].departure.timeZone | string, omitted when unknown | The station's IANA time-zone id. |\n| data.booking.trips[].segments[].departure.utcOffset | string, omitted when unknown | UTC offset in force at that local time (e.g. `+01:00`). |\n| data.booking.trips[].segments[].arrival | object | Where and when this segment arrives. |\n| data.booking.trips[].segments[].arrival.stationCode | string | Arrival station code. |\n| data.booking.trips[].segments[].arrival.timeUtc | string (ISO 8601, no offset) | Arrival time as the station's **local wall-clock time — not UTC**. |\n| data.booking.trips[].segments[].arrival.timeLocal | string (ISO 8601, no offset) | Same value as `timeUtc`. |\n| data.booking.trips[].segments[].arrival.timeZone | string, omitted when unknown | The station's IANA time-zone id. |\n| data.booking.trips[].segments[].arrival.utcOffset | string, omitted when unknown | UTC offset in force at that local time. |\n| data.booking.trips[].segments[].duration | object | The segment's travel time, decomposed into `days`/`hours`/`minutes` (all int). |\n| data.booking.trips[].segments[].mode | string (values: bus \\| rail \\| ferry \\| transfer \\| metro \\| tram \\| cable_car), nullable/omitted | The segment's transport mode; omitted when not resolvable. |\n| data.booking.ticketsAvailable | bool | Whether Get Tickets can currently serve this booking's tickets. |\n| data.price | object | The priced total for this booking (same shape as Search Trips' `price`: `subTotal`, `currency`, `taxes[]`, `fees[]`, `totalAmount`). |\n| data.commissionApplied | decimal, nullable/omitted | Your commission on this booking, in SAR; present only when it's greater than zero. |\n| data.passengers | array | Echo of the passengers submitted at reservation. |\n| data.passengers[].title | string (values: Mr \\| Mrs \\| Ms \\| Miss \\| Mx \\| Dr) | The passenger's title. |\n| data.passengers[].firstName | string | The passenger's first name. |\n| data.passengers[].lastName | string | The passenger's last name. |\n| data.externalReference | string, nullable/omitted | Your own reference for this reservation, echoed back. |\n\nNot present in the example above (only appears when `status` is `Failed`): **data.failure** (object) — the reason the booking could not be completed, with **data.failure.code** (int, the `BaseResponse` code describing the failure category) and **data.failure.errors** (array of `{ issue: string }` lines with a plain-English explanation).\n"},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"cookie":[],"responseTime":null,"body":"{\n  \"code\": 1000,\n  \"message\": \"Request processed successfully.\",\n  \"data\": {\n    \"reservationId\": 12345,\n    \"createdAt\": \"2026-09-14T15:02:11Z\",\n    \"status\": \"Pending\",\n    \"expiresAt\": \"2026-12-14T18:00:00Z\",\n    \"commitRequested\": true,\n    \"booking\": null,\n    \"price\": {\n      \"subTotal\": 150.58,\n      \"currency\": \"SAR\",\n      \"taxes\": [],\n      \"fees\": [\n        {\n          \"type\": \"service_fee\",\n          \"amount\": 20.06\n        }\n      ],\n      \"totalAmount\": 170.64\n    },\n    \"passengers\": [\n      {\n        \"title\": \"Mr\",\n        \"firstName\": \"John\",\n        \"lastName\": \"Doe\"\n      }\n    ],\n    \"commissionApplied\": 8.53,\n    \"externalReference\": \"your-unique-reference-001\"\n  }\n}"}],"_postman_id":"5549746c-9a58-42cf-aa1a-0cd38740c3aa"},{"name":"Get Tickets","id":"267ec012-0d58-42aa-8eab-9393491183a9","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"GET","header":[{"key":"Accept","value":"application/json","description":"<p>application/json (or omit) = JSON ticket list · application/pdf | image/png | application/vnd.apple.pkpass = the ticket file itself</p>\n"}],"url":"https://eservices.hoicom.net/api/v0/groundtransport/transactions/:reservationId/tickets?ticketId=","description":"<p>Fetches every booked trip's ticket for a reservation, fully self-contained — a single plain GET with no Accept header or format negotiation. Each ticket's <code>formats[]</code> carries <code>pdf</code> and <code>qr-code</code> inline as base64 data-URIs (<code>data:application/pdf;base64,...</code> / <code>data:image/png;base64,...</code>) — ready to use directly, no follow-up request. Each ticket also carries <code>passengerNames[]</code> (every passenger), <code>qrCodes[]</code> (every QR code — one per passenger × segment, each <code>{ passengerName, segmentNumber, data }</code>; <code>formats[]</code> keeps only the first QR code), <code>unavailableFormats[]</code> (<code>{ type, reason }</code>) for formats that could not be served, and <code>unavailable</code> (<code>{ reason, retryAfterSeconds }</code>, with empty <code>formats</code>) when the whole ticket could not be served. If some tickets cannot be served the call still returns <code>1000</code> with the rest (partial success); only when none can does it fail. Before the booking is Completed the call returns <code>1112</code> with a <code>reason</code> (<code>not_issued_yet</code>, <code>booking_finalizing</code>, <code>cancelled</code>, <code>failed_no_booking</code>, <code>unavailable_state</code>) and, where retrying helps, <code>retryAfterSeconds</code> (30 / 10). Unknown <code>reservationId</code> or <code>ticketId</code>: <code>1105</code>. See the folder description for full base64-handling guidance and the complete list of reasons.</p>\n","urlObject":{"path":["api","v0","groundtransport","transactions",":reservationId","tickets"],"host":["https://eservices.hoicom.net"],"query":[{"description":{"content":"<p>Optional: returns only the ticket with this ticketId (from a previous call). Omit to get every ticket on the booking.</p>\n","type":"text/plain"},"key":"ticketId","value":""}],"variable":[{"description":{"content":"<p>The reservationId of a completed booking.</p>\n","type":"text/plain"},"type":"any","value":"12345","key":"reservationId"}]}},"response":[{"id":"94be5aa4-bf81-46c4-8ad7-8e8cfd7570e1","name":"200 — Ticket (self-contained base64)","originalRequest":{"method":"GET","header":[{"key":"Accept","value":"application/json","description":"application/json (or omit) = JSON ticket list · application/pdf | image/png | application/vnd.apple.pkpass = the ticket file itself"}],"url":{"raw":"https://eservices.hoicom.net/api/v0/groundtransport/transactions/:reservationId/tickets?ticketId=","host":["https://eservices.hoicom.net"],"path":["api","v0","groundtransport","transactions",":reservationId","tickets"],"query":[{"key":"ticketId","value":"","description":"Optional: returns only the ticket with this ticketId (from a previous call). Omit to get every ticket on the booking."}],"variable":[{"key":"reservationId","value":"12345","description":"The reservationId of a completed booking."}]},"description":"Fetches every booked trip's ticket for a reservation, fully self-contained — a single plain GET with no Accept header or format negotiation. Each ticket's `formats[]` carries `pdf` and `qr-code` inline as base64 data-URIs (`data:application/pdf;base64,...` / `data:image/png;base64,...`) — ready to use directly, no follow-up request. Each ticket also carries `passengerNames[]` (every passenger), `qrCodes[]` (every QR code — one per passenger × segment, each `{ passengerName, segmentNumber, data }`; `formats[]` keeps only the first QR code), `unavailableFormats[]` (`{ type, reason }`) for formats that could not be served, and `unavailable` (`{ reason, retryAfterSeconds }`, with empty `formats`) when the whole ticket could not be served. If some tickets cannot be served the call still returns `1000` with the rest (partial success); only when none can does it fail. Before the booking is Completed the call returns `1112` with a `reason` (`not_issued_yet`, `booking_finalizing`, `cancelled`, `failed_no_booking`, `unavailable_state`) and, where retrying helps, `retryAfterSeconds` (30 / 10). Unknown `reservationId` or `ticketId`: `1105`. See the folder description for full base64-handling guidance and the complete list of reasons."},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"cookie":[],"responseTime":null,"body":"{\n  \"code\": 1000,\n  \"message\": \"Request processed successfully.\",\n  \"data\": [\n    {\n      \"ticketId\": \"T1\",\n      \"passengerName\": \"John Doe\",\n      \"passengerNames\": [\n        \"John Doe\"\n      ],\n      \"formats\": [\n        {\n          \"type\": \"pdf\",\n          \"data\": \"data:application/pdf;base64,JVBERi0xLjcKJeLjz9MKMSAwIG9iago8PC9UeXBlL0NhdGFsb2c…(base64, ~218KB)\"\n        },\n        {\n          \"type\": \"qr-code\",\n          \"data\": \"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAQIAAAECAQAAAAA9NOT9AAAD…(base64)\"\n        }\n      ],\n      \"qrCodes\": [\n        {\n          \"passengerName\": \"John Doe\",\n          \"segmentNumber\": 1,\n          \"data\": \"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAQIAAAECAQAAAAA9NOT9AAAD…(base64)\"\n        }\n      ]\n    }\n  ]\n}"},{"id":"91f4cd79-5e37-4fba-ab25-bf300cd6c0dd","name":"200 — Partial success (one ticket unavailable)","originalRequest":{"method":"GET","header":[{"key":"Accept","value":"application/json","description":"application/json (or omit) = JSON ticket list · application/pdf | image/png | application/vnd.apple.pkpass = the ticket file itself"}],"url":{"raw":"https://eservices.hoicom.net/api/v0/groundtransport/transactions/:reservationId/tickets?ticketId=","host":["https://eservices.hoicom.net"],"path":["api","v0","groundtransport","transactions",":reservationId","tickets"],"query":[{"key":"ticketId","value":"","description":"Optional: returns only the ticket with this ticketId (from a previous call). Omit to get every ticket on the booking."}],"variable":[{"key":"reservationId","value":"12345","description":"The reservationId of a completed booking."}]},"description":"Fetches every booked trip's ticket for a reservation, fully self-contained — a single plain GET with no Accept header or format negotiation. Each ticket's `formats[]` carries `pdf` and `qr-code` inline as base64 data-URIs (`data:application/pdf;base64,...` / `data:image/png;base64,...`) — ready to use directly, no follow-up request. Each ticket also carries `passengerNames[]` (every passenger), `qrCodes[]` (every QR code — one per passenger × segment, each `{ passengerName, segmentNumber, data }`; `formats[]` keeps only the first QR code), `unavailableFormats[]` (`{ type, reason }`) for formats that could not be served, and `unavailable` (`{ reason, retryAfterSeconds }`, with empty `formats`) when the whole ticket could not be served. If some tickets cannot be served the call still returns `1000` with the rest (partial success); only when none can does it fail. Before the booking is Completed the call returns `1112` with a `reason` (`not_issued_yet`, `booking_finalizing`, `cancelled`, `failed_no_booking`, `unavailable_state`) and, where retrying helps, `retryAfterSeconds` (30 / 10). Unknown `reservationId` or `ticketId`: `1105`. See the folder description for full base64-handling guidance and the complete list of reasons."},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"cookie":[],"responseTime":null,"body":"{\n  \"code\": 1000,\n  \"message\": \"Request processed successfully.\",\n  \"data\": [\n    {\n      \"ticketId\": \"T1\",\n      \"passengerName\": \"John Doe\",\n      \"passengerNames\": [\n        \"John Doe\"\n      ],\n      \"formats\": [\n        {\n          \"type\": \"pdf\",\n          \"data\": \"data:application/pdf;base64,JVBERi0xLjcKJeLjz9MKMSAwIG9iago8…(base64)\"\n        }\n      ],\n      \"unavailableFormats\": [\n        {\n          \"type\": \"qr-code\",\n          \"reason\": \"not_provided_by_operator\"\n        }\n      ]\n    },\n    {\n      \"ticketId\": \"T2\",\n      \"passengerName\": \"John Doe\",\n      \"passengerNames\": [\n        \"John Doe\"\n      ],\n      \"formats\": [],\n      \"unavailable\": {\n        \"reason\": \"temporarily_unavailable\",\n        \"retryAfterSeconds\": 30\n      }\n    }\n  ]\n}"},{"id":"d6afd114-24d9-4b89-a539-f34619f84ea6","name":"200 — 1112 Not issued yet","originalRequest":{"method":"GET","header":[{"key":"Accept","value":"application/json","description":"application/json (or omit) = JSON ticket list · application/pdf | image/png | application/vnd.apple.pkpass = the ticket file itself"}],"url":{"raw":"https://eservices.hoicom.net/api/v0/groundtransport/transactions/:reservationId/tickets?ticketId=","host":["https://eservices.hoicom.net"],"path":["api","v0","groundtransport","transactions",":reservationId","tickets"],"query":[{"key":"ticketId","value":"","description":"Optional: returns only the ticket with this ticketId (from a previous call). Omit to get every ticket on the booking."}],"variable":[{"key":"reservationId","value":"12345","description":"The reservationId of a completed booking."}]},"description":"Fetches every booked trip's ticket for a reservation, fully self-contained — a single plain GET with no Accept header or format negotiation. Each ticket's `formats[]` carries `pdf` and `qr-code` inline as base64 data-URIs (`data:application/pdf;base64,...` / `data:image/png;base64,...`) — ready to use directly, no follow-up request. Each ticket also carries `passengerNames[]` (every passenger), `qrCodes[]` (every QR code — one per passenger × segment, each `{ passengerName, segmentNumber, data }`; `formats[]` keeps only the first QR code), `unavailableFormats[]` (`{ type, reason }`) for formats that could not be served, and `unavailable` (`{ reason, retryAfterSeconds }`, with empty `formats`) when the whole ticket could not be served. If some tickets cannot be served the call still returns `1000` with the rest (partial success); only when none can does it fail. Before the booking is Completed the call returns `1112` with a `reason` (`not_issued_yet`, `booking_finalizing`, `cancelled`, `failed_no_booking`, `unavailable_state`) and, where retrying helps, `retryAfterSeconds` (30 / 10). Unknown `reservationId` or `ticketId`: `1105`. See the folder description for full base64-handling guidance and the complete list of reasons."},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"cookie":[],"responseTime":null,"body":"{\n  \"code\": 1112,\n  \"message\": \"Request could not be completed in the current state.\",\n  \"data\": {\n    \"errors\": [\n      {\n        \"issue\": \"Tickets have not been issued yet — the booking is not completed. Poll the transaction and retry once it is Completed.\",\n        \"reason\": \"not_issued_yet\",\n        \"retryAfterSeconds\": 30\n      }\n    ]\n  }\n}"}],"_postman_id":"267ec012-0d58-42aa-8eab-9393491183a9"}],"id":"f18f96b7-baa0-4be3-897a-922b7cf15e9f","description":"<h1 id=\"ground-transport\">Ground Transport</h1>\n<p>The Ground Transport service enables searching and booking intercity ground travel — bus, rail, ferry, and more — across a wide international network. It covers the full journey: browsing the station and city catalogue, searching live trips with real-time prices and availability, reserving and confirming bookings, and retrieving travel tickets in multiple formats.</p>\n<hr />\n<h2 id=\"booking-journey\">Booking journey</h2>\n<ol>\n<li><strong>Get Stations / Get Cities / Get Carriers</strong> — browse the coverage catalogue to build your origin/destination pickers</li>\n<li><strong>Search Trips</strong> — get live trip offers between an origin and a destination for a date (one-way or round trip) — each end can be a specific station or a whole city</li>\n<li><strong>Get Offer Seat Map</strong> <em>(optional)</em> — fetch the seat layout for an offer when seat selection is supported</li>\n<li><strong>Create Reservation</strong> — reserve one offer (one-way) or two (round trip) with passenger details</li>\n<li><strong>Commit Reservation</strong> — confirm the reservation to finalize the booking (or skip this call by reserving with <code>autoCommit: true</code>)</li>\n<li><strong>Get Transaction</strong> — poll the booking's status until it completes</li>\n<li><strong>Get Transactions</strong> <em>(optional)</em> — list and reconcile your bookings (by your <code>externalReference</code>, status, or creation date)</li>\n<li><strong>Get Tickets</strong> — download the travel tickets</li>\n</ol>\n<hr />\n<h2 id=\"catalogue-stations-cities-carriers\">Catalogue: stations, cities, carriers</h2>\n<p>Stations are the atoms of the network — every trip runs station-to-station. Cities group stations for display, and carriers are the operating companies. You don't have to look up stations before searching, though — Search Trips also accepts city codes directly (see \"Origin and destination: station or city codes\" below).</p>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Endpoint</th>\n<th>Key filters</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>GET /stations</code></td>\n<td><code>stationCodes</code>, <code>countryIsoCodes</code>, <code>cityCodes</code>, <code>connectedTo</code> (stations reachable non-stop from a given station, up to 5 codes), <code>query</code> (name search)</td>\n</tr>\n<tr>\n<td><code>GET /cities</code></td>\n<td><code>cityCodes</code>, <code>countryIsoCodes</code>, <code>query</code></td>\n</tr>\n<tr>\n<td><code>GET /carriers</code></td>\n<td><code>countryIsoCodes</code>, <code>carrierIds</code>, <code>include=logoUrls</code></td>\n</tr>\n</tbody>\n</table>\n</div><p>List filters are repeatable query keys (e.g. <code>?countryIsoCodes=ESP&amp;countryIsoCodes=FRA</code>) and combine as intersections. Country codes are ISO 3166-1 alpha-3.</p>\n<p><strong>Carriers</strong> additionally return <code>countryIsoCode</code> (the carrier's home country, alpha-3), <code>modes</code> (the transport types it operates — bus, rail, ferry, and so on), <code>seatSelectionSupported</code> (whether Get Offer Seat Map works for its trips), and <code>termsUrl</code> (a link to the carrier's terms of purchase). Filter by <code>countryIsoCodes</code> (as above) or by <code>carrierIds</code> — up to 10 codes, case-insensitive; an id that doesn't match any carrier simply isn't included, never an error — and the two combine as an intersection, not an override. Like stations and cities, an unfiltered request defaults to your activated countries. Add <code>include=logoUrls</code> to also receive each carrier's <code>logoUrls</code> — URLs of its logo images, hosted by HOI (<code>[]</code> when the carrier has no logo); it is omitted by default to keep the list light. A logo URL never changes for a given image; when a carrier's logo is replaced it gets a new URL and the old one stops working, so re-read <code>logoUrls</code> periodically rather than storing URLs permanently. If carrier detail data is temporarily unavailable, items are served with just <code>id</code>/<code>name</code> and country filtering is temporarily unsupported rather than silently ignored.</p>\n<p><strong>Optional includes on Get Stations</strong> — request heavier fields only when you need them via <code>include</code> (repeatable):</p>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Include</th>\n<th>Adds</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>mode</code></td>\n<td>The station's transport mode (<code>bus</code>, <code>rail</code>, <code>ferry</code>, <code>transfer</code>, <code>metro</code>, <code>tram</code>, <code>cable_car</code>)</td>\n</tr>\n<tr>\n<td><code>description</code></td>\n<td>A free-text description of the station's location, where available</td>\n</tr>\n<tr>\n<td><code>location</code></td>\n<td>Latitude/longitude coordinates</td>\n</tr>\n<tr>\n<td><code>connectedStations</code></td>\n<td>The station codes reachable non-stop from each station — requires <code>stationCodes</code> (up to 5) or <code>connectedTo</code> in the same request</td>\n</tr>\n</tbody>\n</table>\n</div><p>Catalogue endpoints are paginated (<code>page</code>, <code>pageSize</code>) and reflect the countries activated for your account — explicitly requesting a country outside your activation scope returns an unsupported-country response (<code>1420</code>).</p>\n<hr />\n<h2 id=\"search-offers-and-the-offerid\">Search: offers and the <code>offerId</code></h2>\n<h3 id=\"origin-and-destination-station-or-city-codes\">Origin and destination: station or city codes</h3>\n<p><strong>Search Trips</strong> takes an <code>originCode</code> and a <code>destinationCode</code>. Each accepts either a <strong>station code</strong> or a <strong>city code</strong> — you don't need to say which; the length tells them apart automatically:</p>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Code kind</th>\n<th>Length</th>\n<th>Where to find it</th>\n<th>What it searches</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>Station code</td>\n<td>8 characters</td>\n<td><code>GET /stations</code> (<code>id</code>)</td>\n<td>That one exact station</td>\n</tr>\n<tr>\n<td>City code</td>\n<td>5 or 6 characters</td>\n<td><code>GET /cities</code> (<code>id</code>)</td>\n<td><strong>Every station pair actually served</strong> between the two cities — a single search covers everything a rider could book between them, not just one route</td>\n</tr>\n</tbody>\n</table>\n</div><p>An unrecognized code, or one whose length matches neither shape, returns a validation error naming the field (<code>originCode</code> or <code>destinationCode</code>). The two ends are resolved independently, so you can mix kinds freely — a city on one end and a station on the other.</p>\n<p>Examples:</p>\n<ul>\n<li><strong>Station → station:</strong> <code>{ \"originCode\": \"FRPARPGB\", \"destinationCode\": \"DEBERCBS\" }</code> — one specific route.</li>\n<li><strong>City → city:</strong> <code>{ \"originCode\": \"FRPAR\", \"destinationCode\": \"DEBER\" }</code> — every station-to-station option actually served between the two cities, each returned as its own offer.</li>\n<li><strong>Mixed:</strong> <code>{ \"originCode\": \"FRPAR\", \"destinationCode\": \"DEBERCBS\" }</code> — every station in the origin city that has service into that one destination station.</li>\n</ul>\n<p>Whichever you search by, every offer that comes back is anchored to real departure and arrival stations — reserving, committing, and fetching tickets work exactly the same afterward either way.</p>\n<p><strong>Search Trips</strong> returns bookable <strong>offers</strong>. Each offer carries the full trip detail — departure/arrival stations and times, duration (<code>days</code>/<code>hours</code>/<code>minutes</code>), segments with any intermediate stops, the carrier, the fare class — and a <strong>price</strong> block:</p>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Field</th>\n<th>Meaning</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>subTotal</code></td>\n<td>The fare before taxes and fees</td>\n</tr>\n<tr>\n<td><code>taxes</code></td>\n<td>Itemized taxes included in the total</td>\n</tr>\n<tr>\n<td><code>fees</code></td>\n<td>Itemized fees included in the total (e.g. a service fee, where applicable)</td>\n</tr>\n<tr>\n<td><code>currency</code></td>\n<td>Currency for all amounts</td>\n</tr>\n<tr>\n<td><code>totalAmount</code></td>\n<td>The final amount — what you will be charged on booking</td>\n</tr>\n</tbody>\n</table>\n</div><p>Every offer includes an <strong><code>offerId</code></strong> — an opaque token (up to 1024 characters) that encodes the exact trip and its quoted price. It is the only thing you pass forward to reserve. Treat it as a short-lived voucher:</p>\n<blockquote>\n<p><strong>Reserve promptly.</strong> An <code>offerId</code> reflects live inventory and pricing at search time. Reservations re-validate price and availability — a stale offer can be rejected if the price has moved or the trip has sold out. Search again to get a fresh offer rather than retrying a stale one.</p>\n</blockquote>\n<p><strong>Passengers</strong> are specified as a composition: <code>[{ \"type\": \"adult\", \"quantity\": 2 }]</code> with types <code>adult</code>, <code>child</code>, <code>senior</code>, <code>youth</code>. Every offer always carries <code>class</code> (the fare class), <code>seatsLeft</code> (live seat availability — <code>null</code> when the carrier doesn't report seat counts), and <code>seatSelectionSupported</code> (whether <code>seats</code> may be sent when reserving this offer — omitted when the capability is unknown; only send seats when it is <code>true</code>). <strong>Optional includes</strong> (<code>include</code>, repeatable) add heavier detail only when requested: <code>amenities</code> (fare features such as wifi, luggage allowance, or bicycles on board) and <code>bookingRequirements</code> (the extra passenger fields this offer's carrier needs before you can reserve).</p>\n<p><code>bookingRequirements</code> (present only with <code>include=bookingRequirements</code>) tells you which fields to collect before calling Create Reservation. It has up to four parts:</p>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Part</th>\n<th>Meaning</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>required</code></td>\n<td>Fields every booking of this offer needs: <code>passengers</code> (typed fields on the passenger object) and optionally <code>extras</code> (keys to submit inside a passenger's <code>extras</code> map)</td>\n</tr>\n<tr>\n<td><code>optional</code></td>\n<td>Same shape as <code>required</code> — fields the carrier accepts but does not insist on</td>\n</tr>\n<tr>\n<td><code>conditional[]</code></td>\n<td>Groups of fields needed <strong>only when the group's <code>when</code> condition applies</strong> to the traveller. Each entry has <code>when</code>, <code>passengers</code>, and optionally <code>extras</code> and <code>allowedValues</code>. Omitted when the carrier declares none</td>\n</tr>\n<tr>\n<td><code>governmentIdTypes[]</code></td>\n<td>The <code>governmentId.type</code> values this offer's carrier accepts. Omitted when the carrier publishes no list</td>\n</tr>\n</tbody>\n</table>\n</div><p>Example of an offer's <code>bookingRequirements</code> with one conditional group (the field lists are illustrative — always read them from the offer you received):</p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">{\n  \"bookingRequirements\": {\n    \"required\": {\n      \"passengers\": [\"title\", \"firstName\", \"lastName\"]\n    },\n    \"optional\": {\n      \"passengers\": [\"dateOfBirth\", \"nationality\"],\n      \"extras\": [\"flight_number\"]\n    },\n    \"conditional\": [\n      {\n        \"when\": \"Required data for passengers travelling from outside of Schengen into Schengen\",\n        \"passengers\": [\"dateOfBirth\", \"nationality\", \"governmentId\"],\n        \"extras\": [\"citizenship\", \"visa_permit_type\"]\n      }\n    ],\n    \"governmentIdTypes\": [\"national_id\", \"international_passport\"]\n  }\n}\n</code></pre>\n<ul>\n<li><code>title</code>, <code>firstName</code>, and <code>lastName</code> are always present under <code>required.passengers</code> — every carrier needs them.</li>\n<li><code>extras</code> keys are the carrier's own field names, passed through verbatim — treat them as opaque identifiers rather than something to translate or validate client-side.</li>\n<li><code>allowedValues</code> maps an <code>extras</code> key to the values the carrier accepts for it. When a key has an entry, present those values as a pick-list and send one of them exactly as listed.</li>\n<li><code>governmentIdTypes</code>, when present, lists the document kinds to offer in your <code>governmentId.type</code> picker. Send one of these; other document kinds will be rejected by the carrier.</li>\n<li>An offer with no advertised requirements beyond the baseline simply omits <code>bookingRequirements</code> — that's not an error.</li>\n<li>When you ask for <code>bookingRequirements</code>, every offer is returned with its carrier's requirements or the search fails with <code>1113</code> (temporarily unavailable) — retry shortly. Offers are never returned with their requirements silently left out.</li>\n</ul>\n<p><strong>Round-trip searches.</strong> When you pass a <code>return</code> leg, Search Trips returns offers for <strong>both directions</strong> (<code>direction</code>: <code>departure</code> / <code>return</code>) — including when the return is on a different day than the departure.</p>\n<p><strong>No results.</strong> A search with no matching trips returns code <code>1303</code>; the error line carries <code>reason: \"no_trips\"</code> so you can tell \"nothing available\" apart from other failures.</p>\n<h3 id=\"handling-conditional-groups\">Handling conditional groups</h3>\n<p>The <code>when</code> text of a conditional group is <strong>human-readable text for the traveller, not a rule your system can evaluate</strong>. Whether a condition applies depends on the traveller's circumstances (for example, where they are travelling from), which you generally cannot determine automatically. Recommended handling:</p>\n<ul>\n<li><strong>Always show</strong> every conditional group's fields in your booking form, marked as <em>may be required</em>, with the group's <code>when</code> text displayed next to them. Let the traveller decide whether it applies to them and fill the fields in if so.</li>\n<li><strong>Never hide or block an offer</strong> because it has conditional groups — most travellers will not be subject to them.</li>\n<li>Collect the typed fields (<code>passengers</code>) on the passenger object and the <code>extras</code> keys inside that passenger's <code>extras</code> map.</li>\n</ul>\n<h3 id=\"if-a-needed-field-is-missing\">If a needed field is missing</h3>\n<p>If a field the carrier needs was not supplied (or is invalid), the reservation is rejected with code <strong><code>1102</code></strong> (validation) and the failure names the exact field to correct in <code>errors[].field</code> — for example <code>passengers[].governmentId</code>, <code>passengers[].governmentId.type</code>, or <code>passengers[].extras</code>. Because reservations complete asynchronously, you will see this in the <code>failure</code> block when you poll <strong>Get Transaction</strong> (see Tracking below). Recommended handling: re-prompt the traveller for that specific field and create a new reservation with the corrected details. Searching again is not necessary.</p>\n<h3 id=\"passenger-extras\">Passenger <code>extras</code></h3>\n<p><code>passengers[].extras</code> is a per-passenger string map (<code>{ \"key\": \"value\" }</code>) for the additional fields listed in the offer's <code>bookingRequirements</code>. Only the keys listed in the offer's requirements are used. The keys currently supported are <code>tax_id</code>, <code>visa_permit_type</code>, <code>citizenship</code>, <code>flight_number</code>, and <code>max_age</code> (exact lowercase snake_case).</p>\n<h3 id=\"time-fields\">Time fields</h3>\n<p>Every segment stop (in offers, in booked trips, and in seat maps) carries its times like this:</p>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Field</th>\n<th>Meaning</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>timeUtc</code></td>\n<td>The station's <strong>local wall-clock time</strong>, with no offset and no “Z” (e.g. <code>2026-12-15T06:30</code>). <strong>Despite the name it is NOT UTC</strong> — the name is kept for backward compatibility. Do not convert it as if it were UTC.</td>\n</tr>\n<tr>\n<td><code>timeLocal</code></td>\n<td>The same value as <code>timeUtc</code>, under an accurate name. Prefer this field in new integrations.</td>\n</tr>\n<tr>\n<td><code>timeZone</code></td>\n<td>The station's IANA time-zone id (e.g. <code>Europe/Madrid</code>). Present <strong>only when known</strong>.</td>\n</tr>\n<tr>\n<td><code>utcOffset</code></td>\n<td>The UTC offset in force at that local time (e.g. <code>+01:00</code>). Present <strong>only when known</strong>.</td>\n</tr>\n</tbody>\n</table>\n</div><p>When <code>timeZone</code> / <code>utcOffset</code> are present, the actual instant is <code>timeLocal</code> at <code>utcOffset</code>. The fields that <strong>are</strong> true UTC (ending in “Z”) are <code>createdAt</code>, <code>expiresAt</code> (hold/quote and offer expiry), and <code>booking.confirmedAt</code>. (Get Offer Seat Map stops carry <code>timeLocal</code> only.)</p>\n<hr />\n<h2 id=\"reserving-and-committing-an-asynchronous-flow\">Reserving and committing: an asynchronous flow</h2>\n<p>Booking is a <strong>two-step, asynchronous</strong> process — both steps return an immediate acknowledgment and complete in the background:</p>\n<ol>\n<li><strong>Create Reservation</strong> (<code>POST /reservations</code>) — pass your unique <code>externalReference</code>, the <code>offerIds</code> (one for one-way, two for a round trip), and one entry per traveling passenger. The response acknowledges with a numeric <code>reservationId</code> — the reservation itself completes asynchronously.</li>\n<li><strong>Commit Reservation</strong> (<code>POST /reservations/{reservationId}/commit</code>) — confirms the reserved booking, turning the hold into a finalized purchase. Also acknowledged immediately and completed asynchronously.</li>\n</ol>\n<p>Prefer a single call? Set <strong><code>autoCommit: true</code></strong> on Create Reservation and the commit is chained automatically once the reservation succeeds.</p>\n<p>A reservation is only held for a limited time (see <code>expiresAt</code> on the acknowledgment). Committing after the hold has lapsed is rejected with <code>1403</code> (HTTP 400) — search and reserve again.</p>\n<p><strong>Poll <code>GET /transactions/{reservationId}</code></strong> after each step — never assume completion from the acknowledgment alone.</p>\n<h3 id=\"passenger-details\">Passenger details</h3>\n<p>Each passenger carries <code>title</code> (<code>Mr</code>, <code>Mrs</code>, <code>Ms</code>, <code>Miss</code>, <code>Mx</code>, <code>Dr</code>), <code>firstName</code>, <code>lastName</code>, and optionally <code>dateOfBirth</code> (<code>YYYY-MM-DD</code>), <code>nationality</code> (alpha-3), <code>gender</code> (<code>M</code>, <code>F</code>, <code>X</code>, <code>U</code>), a <code>governmentId</code> block, per-direction <code>seats</code> (<code>direction</code>: <code>departure</code> / <code>return</code> + <code>seatNumber</code> from the seat map — only when the offer's <code>seatSelectionSupported</code> is <code>true</code>; sending seats to a carrier without seat selection is rejected with a validation error), and an <code>extras</code> map for any additional fields listed in the offer's <code>bookingRequirements</code>.</p>\n<p><code>governmentId.type</code> accepts the full document-kind vocabulary: <code>national_id</code>, <code>international_passport</code>, <code>passport_id</code>, <code>drivers_license</code>, <code>birth_certificate</code>, <code>entry_visa</code>, <code>marine_id</code>, <code>military_supplement</code>, <code>naturalisation_certificate</code>, <code>permanent_resident_id</code>, <code>refugee_id</code>, <code>resident_id</code>, <code>tax_number</code>, <code>tsa_precheck_id</code>, <code>us_i872_card</code>, <code>us_tribal_card</code>. Which kinds a carrier actually accepts can vary per carrier and route — when in doubt, <code>national_id</code> and <code>international_passport</code> are the most widely supported.</p>\n<h3 id=\"round-trips\">Round trips</h3>\n<p>A round trip is booked as <strong>one reservation with two <code>offerIds</code></strong> — outbound and return — and succeeds or fails as a unit: if one leg cannot be secured, the other is automatically released.</p>\n<ul>\n<li><strong>Price.</strong> The charge is the <strong>sum of both legs' totals as shown at search</strong> (<code>leg 1 totalAmount + leg 2 totalAmount</code>). The reservation acknowledgment's <code>price.fees</code> shows one aggregated service-fee line covering both legs.</li>\n<li><strong>Return station.</strong> The return leg may depart from a <strong>different station in the same city</strong> where the outbound arrived; a return from a different city is rejected with a validation error (<code>1102</code>).</li>\n</ul>\n<hr />\n<h2 id=\"tracking-the-transaction-surface\">Tracking: the transaction surface</h2>\n<p><code>GET /transactions/{reservationId}</code> is the single source of truth for a booking's state:</p>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Status</th>\n<th>Meaning</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><strong>Submitted</strong></td>\n<td>Received and queued for processing</td>\n</tr>\n<tr>\n<td><strong>Pending</strong></td>\n<td>Reservation or commit in progress — including <strong>waiting for the booking reference(s)</strong> after a commit</td>\n</tr>\n<tr>\n<td><strong>Completed</strong></td>\n<td>Booking confirmed, the booking reference(s) issued, and tickets ready</td>\n</tr>\n<tr>\n<td><strong>Failed</strong></td>\n<td>The booking could not be completed (see <code>failure</code> for the reason)</td>\n</tr>\n<tr>\n<td><strong>Cancelled</strong></td>\n<td>The booking was cancelled</td>\n</tr>\n</tbody>\n</table>\n</div><p>A booking stays <strong>Pending until every trip has its booking reference</strong> — typically within a few seconds of the commit; if the provider is slow it simply stays Pending, so keep polling. It never reports <strong>Completed</strong> without references, and a Completed booking always has <code>booking.trips[].bookingReference</code> populated and <code>booking.ticketsAvailable</code> true.</p>\n<p>The response mirrors what you booked — trips with stations, times, carrier and class, passengers, the price you were quoted — plus:</p>\n<ul>\n<li><strong><code>booking.trips[].bookingReference</code></strong> — the confirmed reference for each trip (one per leg on a round trip). There is <strong>no</strong> top-level booking-reference field.</li>\n<li><strong><code>externalReference</code></strong> — your own reference, echoed back, so you can match a booking to your order without keeping a mapping.</li>\n<li><strong><code>commitRequested</code></strong> — present (<code>true</code>) once a commit has been requested, whether explicitly, early, or via <code>autoCommit</code>.</li>\n<li><strong><code>expiresAt</code></strong> — the hold/quote expiry while the booking is Submitted or Pending; <code>null</code> once it is terminal.</li>\n<li>A <strong><code>failure</code></strong> block (<code>code</code> + <code>errors[]</code>) when something went wrong. If only one leg of a round trip could be confirmed, the booking is Failed and <code>booking</code> holds just the confirmed trip.</li>\n<li><strong><code>commissionApplied</code></strong> when a commission applies to your account.</li>\n</ul>\n<h3 id=\"listing-your-bookings\">Listing your bookings</h3>\n<p><code>GET /transactions</code> (Get Transactions) returns a paged list of <strong>your</strong> Ground Transport bookings, newest first, each item in exactly the Get Transaction shape. All filters are optional:</p>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Filter</th>\n<th>Behaviour</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>externalReference</code></td>\n<td>Exact match (max 100 characters).</td>\n</tr>\n<tr>\n<td><code>externalReferencePrefix</code></td>\n<td>Starts-with match (3–100 characters). Cannot be combined with <code>externalReference</code> (<code>1302</code>).</td>\n</tr>\n<tr>\n<td><code>status</code></td>\n<td>Repeatable: <code>Submitted</code>, <code>Pending</code>, <code>Completed</code>, <code>Failed</code>, <code>Cancelled</code>, <code>Refunded</code> (case-insensitive; an unknown value returns <code>1114</code>).</td>\n</tr>\n<tr>\n<td><code>createdFrom</code> / <code>createdTo</code></td>\n<td>ISO 8601 date (<code>yyyy-MM-dd</code>, the whole UTC day) or date-time (UTC unless an offset is given). The span may not exceed 93 days; <code>createdFrom</code> after <code>createdTo</code> returns <code>1302</code>; a bad format returns <code>1114</code>.</td>\n</tr>\n<tr>\n<td><code>page</code> / <code>pageSize</code></td>\n<td><code>page</code> defaults to 1 (<code>1201</code> when out of range); <code>pageSize</code> defaults to 50, max 100 (<code>1202</code> when out of range).</td>\n</tr>\n</tbody>\n</table>\n</div><p>The list is read-only: a hold that has lapsed is shown as <strong>Failed</strong> and is matched by the <code>Failed</code> filter. Validation errors return HTTP 200 with the code in the body.</p>\n<hr />\n<h2 id=\"tickets\">Tickets</h2>\n<p><code>GET /transactions/{reservationId}/tickets</code> returns the actual travel documents — <strong>fully self-contained, in one call</strong>. There's no <code>Accept</code> header, no format to negotiate, and no follow-up request: every booked trip's ticket comes back inline, already encoded as printable/scannable content. A one-way booking returns one ticket; a round trip returns two.</p>\n<p><strong>Optional <code>?ticketId=</code></strong> filters the response down to a single ticket (use a <code>ticketId</code> from a previous call); omit it to get every ticket on the booking.</p>\n<p>Tickets are available as soon as a booking is <strong>Completed</strong> (booking references issued). If you request them earlier you receive code <code>1112</code> (HTTP 200) with a <code>reason</code> — and, where waiting helps, a <code>retryAfterSeconds</code> — telling you what to do:</p>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th><code>reason</code></th>\n<th><code>retryAfterSeconds</code></th>\n<th>Meaning</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>booking_finalizing</code></td>\n<td>10</td>\n<td>The booking is being finalized — retry shortly (rare).</td>\n</tr>\n<tr>\n<td><code>not_issued_yet</code></td>\n<td>30</td>\n<td>The booking is not completed yet — poll Get Transaction until it is Completed, then retry.</td>\n</tr>\n<tr>\n<td><code>cancelled</code></td>\n<td>—</td>\n<td>The booking was cancelled — no tickets exist.</td>\n</tr>\n<tr>\n<td><code>failed_no_booking</code></td>\n<td>—</td>\n<td>The reservation failed and no booking was created — no tickets exist.</td>\n</tr>\n<tr>\n<td><code>unavailable_state</code></td>\n<td>—</td>\n<td>Tickets cannot be served in the booking's current state.</td>\n</tr>\n</tbody>\n</table>\n</div><p>Requesting an unknown <code>ticketId</code> or <code>reservationId</code> returns <code>1105</code>.</p>\n<h3 id=\"response-shape\">Response shape</h3>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">{\n  \"code\": 1000,\n  \"data\": [\n    {\n      \"ticketId\": \"T1\",\n      \"passengerName\": \"Jane Doe\",\n      \"passengerNames\": [\"Jane Doe\", \"John Doe\"],\n      \"formats\": [\n        { \"type\": \"pdf\", \"data\": \"data:application/pdf;base64,JVBERi0xLjcKJeLjz9MKMSAwIG9iago8PC9UeXBlL0NhdGFsb2c...=\" },\n        { \"type\": \"qr-code\", \"data\": \"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAMgAAADICAYAAACtWK6eAAAA...=\" }\n      ],\n      \"qrCodes\": [\n        { \"passengerName\": \"Jane Doe\", \"segmentNumber\": 1, \"data\": \"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAMgAAADICAYAAACtWK6eAAAA...=\" },\n        { \"passengerName\": \"John Doe\", \"segmentNumber\": 1, \"data\": \"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAMgAAADICAYAAACtWK6eAAAA...=\" }\n      ]\n    }\n  ]\n}\n</code></pre>\n<p>One ticket is returned per booked trip (a round trip returns two). Each ticket carries:</p>\n<ul>\n<li><strong><code>passengerName</code></strong> — the primary passenger; <strong><code>passengerNames[]</code></strong> — every passenger booked on the ticket.</li>\n<li><strong><code>formats[]</code></strong> — <code>pdf</code> and <code>qr-code</code> inline as ready-to-use <strong>base64 data-URIs</strong>; nothing to fetch separately. <code>formats</code> keeps the <strong>first</strong> QR code for backward compatibility — do not assume <code>formats[0]</code> is a particular type; look entries up by <code>type</code>.</li>\n<li><strong><code>qrCodes[]</code></strong> — <strong>every</strong> QR code on the ticket: one per passenger × segment, each <code>{ passengerName, segmentNumber, data }</code> (<code>segmentNumber</code> is 1-based; <code>passengerName</code> / <code>segmentNumber</code> are omitted when the operator does not identify them).</li>\n<li><strong><code>unavailableFormats[]</code></strong> — formats that could not be served for this ticket, each <code>{ type, reason }</code> (see below).</li>\n<li><strong><code>unavailable</code></strong> — set instead of formats when the whole ticket could not be served: <code>{ reason, retryAfterSeconds? }</code>, with <code>formats</code> empty.</li>\n</ul>\n<h3 id=\"partial-success-and-unavailable-content\">Partial success and unavailable content</h3>\n<p>A request is served as far as possible. If one ticket (for example one leg of a round trip) cannot be produced, you still get code <code>1000</code> with the tickets that could be served, and the other carries <code>unavailable</code>. Only when <strong>no</strong> ticket can be served does the call fail with an error code.</p>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Where</th>\n<th><code>reason</code></th>\n<th>Meaning</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>unavailableFormats[]</code></td>\n<td><code>temporarily_unavailable</code></td>\n<td>The format could not be fetched right now — retry.</td>\n</tr>\n<tr>\n<td><code>unavailableFormats[]</code></td>\n<td><code>too_large</code></td>\n<td>The PDF exceeds the 10 MiB limit.</td>\n</tr>\n<tr>\n<td><code>unavailableFormats[]</code></td>\n<td><code>not_provided_by_operator</code></td>\n<td>The operator issues no QR code for this ticket (use the PDF).</td>\n</tr>\n<tr>\n<td><code>unavailable</code></td>\n<td><code>temporarily_unavailable</code></td>\n<td>The ticket could not be fetched right now; retry after <code>retryAfterSeconds</code> (30).</td>\n</tr>\n<tr>\n<td><code>unavailable</code></td>\n<td><code>not_provided_by_operator</code></td>\n<td>The operator issues no ticket document.</td>\n</tr>\n<tr>\n<td><code>unavailable</code></td>\n<td><code>not_available</code></td>\n<td>The ticket is not available.</td>\n</tr>\n</tbody>\n</table>\n</div><p><strong>Optional <code>?ticketId=</code></strong> filters the response down to a single ticket (use a <code>ticketId</code> from a previous call); omit it to get every ticket on the booking.</p>\n<h3 id=\"handling-qr-code\">Handling <code>qr-code</code></h3>\n<p>Each QR value is already a displayable PNG image — no conversion needed, it <em>is</em> the QR code. A ticket can carry <strong>several</strong> QR codes (one per passenger per segment), so iterate <code>qrCodes[]</code> rather than reading a single value, and show each passenger their own code (match on <code>passengerName</code> / <code>segmentNumber</code>). Fall back to the <code>qr-code</code> entry in <code>formats[]</code> only if <code>qrCodes</code> is absent.</p>\n<p><strong>Web / webview</strong> — use it directly as an image source:</p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-html\">&lt;img src=\"data:image/png;base64,iVBORw0KGgo...\" alt=\"Boarding QR code\" /&gt;\n</code></pre>\n<p><strong>Native / server-side</strong> — strip the <code>data:image/png;base64,</code> prefix and decode the remainder to bytes to render or save it as a <code>.png</code>:</p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-js\">// JavaScript\nfor (const qr of ticket.qrCodes ?? []) {\n  const base64 = qr.data.replace(/^data:image\\/png;base64,/, \"\");\n  const bytes = Buffer.from(base64, \"base64\"); // write, render, or embed as needed\n}\n</code></pre>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-csharp\">// C#\nforeach (var qr in ticket.QrCodes ?? new())\n{\n    var base64 = qr.Data.Replace(\"data:image/png;base64,\", \"\");\n    var bytes = Convert.FromBase64String(base64);\n}\n</code></pre>\n<h3 id=\"handling-pdf\">Handling <code>pdf</code></h3>\n<p>Strip the <code>data:application/pdf;base64,</code> prefix and base64-decode the remainder to get the original PDF bytes — byte-identical to the source document, safe to save, print, or hand to the customer as-is.</p>\n<p><strong>Save as a file:</strong></p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-js\">// JavaScript / Node\nconst fs = require(\"fs\");\nconst base64 = format.data.replace(/^data:application\\/pdf;base64,/, \"\");\nfs.writeFileSync(\"ticket.pdf\", Buffer.from(base64, \"base64\"));\n</code></pre>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-csharp\">// C#\nvar base64 = format.Data.Replace(\"data:application/pdf;base64,\", \"\");\nFile.WriteAllBytes(\"ticket.pdf\", Convert.FromBase64String(base64));\n</code></pre>\n<p><strong>Or display inline</strong>, without decoding at all — embed the full data-URI directly:</p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-html\">&lt;iframe src=\"data:application/pdf;base64,JVBERi0xLjcK...\"&gt;&lt;/iframe&gt;\n</code></pre>\n<hr />\n<h2 id=\"idempotency\">Idempotency</h2>\n<p><code>externalReference</code> (max 50 characters) is your idempotency key, scoped to your account and the Ground Transport service:</p>\n<ul>\n<li><strong>Resubmitting the same reference</strong> returns code <code>1000</code> with the <strong>existing reservation's current state</strong> (the same acknowledgment shape, reflecting its present status) — no second booking is created. It is safe to retry a timed-out Create Reservation with the same reference.</li>\n<li><strong>A reference already used on another of your services</strong> is rejected with a validation error (<code>1102</code>, HTTP 200, field <code>externalReference</code>).</li>\n</ul>\n","_postman_id":"f18f96b7-baa0-4be3-897a-922b7cf15e9f"}],"variable":[{"key":"baseUrl","value":"https://eservices.hoicom.net"}]}