{"info":{"_postman_id":"db9946f9-b9ce-4b8f-99ca-b5ecc7ea0f1b","name":"LoyaltyLayer API Integration Guide","description":"<html><head></head><body><h2 id=\"summary\">Summary</h2>\n<p>This API provides a unified, secure interface to enrich cardholders with travel rewards. Key features include:</p>\n<ul>\n<li><p><strong>Pass Creation and Management:</strong> Create Lounge Pass, eSim and future services via a single endpoint, determined by plan_id mappings in our database. Supports batch operations for scale. For Priority Pass plans (determined by plan_id), support for tokenized enrollment via an optional enrol_token parameter, obtained from tokenized engine API, to avoid handling sensitive card data and ensure PCI de-scoping.</p>\n</li>\n<li><p><strong>Security and Compliance:</strong> OAuth 2.0 authentication</p>\n</li>\n<li><p><strong>Key Benefits:</strong> Simplifies integration, ensures idempotency for retries, and provides type-specific responses</p>\n</li>\n<li><p><strong>Scope:</strong> Covers enrollment, updates, status queries, and cancellations.</p>\n</li>\n<li><p><strong>Environments:</strong> UAT for testing; Production for live use.</p>\n</li>\n</ul>\n<h2 id=\"getting-started-guide\">Getting Started Guide</h2>\n<h3 id=\"prerequisites\">Prerequisites</h3>\n<ul>\n<li><p><strong>Credentials:</strong> During onboarding, you'll receive a <em><strong>client_id</strong></em> and <em><strong>client_secret</strong></em> for OAuth. Share <em><strong>plan_id</strong></em> mappings via secure channel for our DB configuration. For Priority Pass / LoungeKey integrations, call <code>/card/tokenize</code> to generate an <code>enrol_token</code> (see Tokenized Engine section). For <strong>eSIM integrations</strong>, the <code>enrol_token</code> is an Airalo <code>package_id</code> — no card tokenization is needed. Share <code>plan_id</code> mappings via secure channel during onboarding.</p>\n</li>\n<li><p><strong>Tools:</strong> Postman for testing. Use environment variables: base_url, client_id, client_secret, access_token (auto-set via auth request), pass_id (from create responses).</p>\n</li>\n</ul>\n<h3 id=\"step-by-step-integration\">Step-by-Step Integration</h3>\n<ol>\n<li><p><strong>Authenticate:</strong> Call LoyaltyLayer API /auth/token to get an access_token (expires in 30 minutes, control by system). Test script sets access_token.</p>\n</li>\n<li><p><strong>Tokenize Card (card-based plans only):</strong> Required for Priority Pass and LoungeKey plans. <strong>Skip this step for eSIM plans.</strong></p>\n<ol>\n<li><p>Fetch encryption keys from <code>GET /v1/card/encryption-keys</code>.</p>\n</li>\n<li><p>Encrypt card data (CardNumber, CardExpiry, NameOnCard, Cvv) into a JWE compact string using the RSA public key. See the <strong>Card Data Encryption Guide</strong> section below for code examples.</p>\n</li>\n<li><p>Call <code>POST /v1/card/tokenize</code> with the encrypted_value, plan_id, and card_type. This returns an <code>enrol_token</code>.</p>\n</li>\n</ol>\n</li>\n<li><p><strong>Create a Pass:</strong> Use <code>POST /v1/pass/create</code> with the enrol_token, along with holder details. The response shape depends on the plan type — e.g., <code>dmc_qr_data</code> for Priority Pass; <code>iccid</code> and <code>qr_code_data</code> for eSIM. <strong>For eSIM plans, <code>card_type</code> and <code>holder.address</code> are not required.</strong></p>\n</li>\n<li><p><strong>Batch Operations:</strong> For bulk, use <code>POST /v1/pass/batch-create</code> with an array of pass objects, each including enrol_token from the tokenize step.</p>\n</li>\n<li><p><strong>Manage Passes:</strong> Use <code>POST /v1/pass/status</code>, <code>POST /v1/pass/update</code>, or <code>POST /v1/pass/cancel</code>.</p>\n</li>\n<li><p><strong>Testing:</strong> For Priority Pass in UAT, use a mock enrol_token. Validate responses against updated specs, ensuring no PAN is sent.</p>\n</li>\n<li><p><strong>Go Live:</strong> Switch to Prod base URL after UAT complete.</p>\n</li>\n<li><p><strong>Postman Tips:</strong> Run \"Auth Token\" first. Use variables for chaining (e.g., set pass_id from create response). Test edge cases like invalid plan_id (expect 400).</p>\n</li>\n</ol>\n<p>For support, schedule a demo or provide logs with correlation IDs from errors.</p>\n<h1 id=\"ai-agent-development\">🤖 AI Agent Development</h1>\n<p>If you use AI agent to assiant development. You can find a .md file to pass to AI agent to overview the integration guideline.</p>\n<p><a href=\"https://drive.google.com/file/d/1SJM3Td3aQOmKSxSjmdTh4aRSQMFXuf_g/view?usp=sharing\">AI agent readme</a></p>\n<hr>\n<h2 id=\"authentication-overview\">Authentication Overview</h2>\n<p>Our API uses OAuth 2.0 Client Credentials flow. This ensures secure B2B access without user involvement.</p>\n<ul>\n<li><p><strong>Endpoint:</strong> POST /auth/token</p>\n</li>\n<li><p><strong>Request Format:</strong> application/json</p>\n<ul>\n<li><p>client_id: Required, issued during onboarding.</p>\n</li>\n<li><p>client_secret: Required, secure key.</p>\n</li>\n</ul>\n</li>\n<li><p><strong>Response:</strong> JSON with access_token (opaque string, Bearer type), expires_in (1800 seconds). Expired token in 401 error.</p>\n</li>\n<li><p><strong>Usage:</strong> Include Authorization: Bearer {{access_token}} in all subsequent headers.</p>\n</li>\n<li><p><strong>Security Notes:</strong> Tokens are reference-based (validated server-side). Use HTTPS/TLS 1.2. No session cookies; stateless.</p>\n</li>\n<li><p><strong>Best Practices:</strong> Cache tokens per client_id to reduce calls. Handle expiry with auto-refresh logic.</p>\n</li>\n<li><p><strong>Security Notes:</strong> Our API does not handle or store PANs; use of enrol_token for Priority Pass keeps integrations out of PCI scope.</p>\n</li>\n</ul>\n<h2 id=\"rate-and-usage-limits\">Rate and Usage Limits</h2>\n<p>To ensure fair usage and system stability, we enforce the following limits:</p>\n<ul>\n<li><p><strong>Rate Limiting:</strong> 100 requests per minute per IP. And 1 minute blocked traffic from same IP after exceed rate limit. Exceeded: HTTP 429 Too Many Requests.</p>\n</li>\n<li><p><strong>Error Handling:</strong> Limits reset minute. Can retry after reset period.</p>\n</li>\n<li><p><strong>Monitoring:</strong> We log usage; contact us if higher limits needed (e.g., for campaigns).</p>\n</li>\n</ul>\n<h2 id=\"common-response\">Common Response</h2>\n<p>Successful responses (200 OK) return JSON.</p>\n<h2 id=\"error-handle\">Error Handle</h2>\n<p>Errors are returned with standard HTTP status codes and JSON bodies for easy parsing. Implement retry logic for transient issues (e.g., 5xx) and backoff on 429.</p>\n<h4 id=\"common-errors\">Common Errors:</h4>\n<ul>\n<li><p><strong>400 Bad Request:</strong> Invalid or missing parameters (e.g., wrong grant_type).<br>  Example:<br>  <code>{ \"error\": \"invalid_enrol_token\", \"error_description\": \"Provided enrol_token is invalid or expired\", \"code\": 400 }</code></p>\n</li>\n<li><p><strong>401 Unauthorized:</strong> Invalid client_id or client_secret.<br>  Example:<br>  <code>{ \"error\": \"invalid_client\", \"error_description\": \"Client authentication failed.\", \"code\": 401}</code><br>  (mapped from Priority Pass/LoungeKey auth failures).</p>\n</li>\n<li><p><strong>401 Unauthorized (Bearer Token)</strong>: Missing, empty, or expired Bearer token on any protected endpoint.<br>  Examples:<br>  <code>{ \"error\": \"unauthorized\", \"error_description\": \"Missing or invalid Authorization header.\", \"code\": 401 } { \"error\": \"invalid_token\", \"error_description\": \"Access token is invalid or expired.\", \"code\": 401 }</code></p>\n</li>\n<li><p><strong>404 Not Found:</strong> Invalid pass ID.<br>  Example:<br>  <code>{ \"error\": \"invalid_pass_id\", \"error_description\": \"Invalid pass ID\", \"code\": 404}</code></p>\n</li>\n<li><p><strong>409 Already Cancelled</strong>: Pass is already cancelled.<br>  Example:<br>  <code>{ \"error\": \"already_cancelled\", \"error_description\": \"Pass {pass_id} is already cancelled.\", \"code\": 409 }</code></p>\n</li>\n<li><p><strong>429 Too Many Requests:</strong> Rate limit exceeded.<br>  Example:<br>  <code>{ \"error\": \"rate_limit_exceeded\", \"error_description\": \"Retry after 60 seconds\", \"code\": 429, \"retry_after\": 60 }</code></p>\n</li>\n<li><p><strong>500 Internal Server Error:</strong> Rare server issues (we retry calls internally).<br>  Example:<br>  <code>{ \"error\": \"server_error\", \"error_description\": \"Unexpected error; try again\", \"code\": 500 }</code></p>\n</li>\n<li><p><strong>502 Provider Unavailable</strong>: Upstream provider returned an error.<br>  Example:<br>  <code>{ \"error\": \"server_error\", \"error_description\": \"Provider operation failed.\", \"code\": 502 }</code></p>\n</li>\n<li><p><strong>504 Provider Timeout</strong>: Upstream provider did not respond in time.<br>  Example:<br>  <code>{ \"error\": \"provider_timeout\", \"error_description\": \"Provider operation failed.\", \"code\": 504 }</code></p>\n</li>\n</ul>\n</body></html>","schema":"https://schema.getpostman.com/json/collection/v2.0.0/collection.json","toc":[{"content":"🤖 AI Agent Development","slug":"ai-agent-development"}],"owner":"24716230","collectionId":"db9946f9-b9ce-4b8f-99ca-b5ecc7ea0f1b","publishedId":"2sBXwntsEp","public":true,"customColor":{"top-bar":"FFFFFF","right-sidebar":"303030","highlight":"FF6C37"},"publishDate":"2026-06-23T10:59:10.000Z"},"item":[{"name":"API Integration","item":[{"name":"Tokenized Engine","item":[{"name":"Get Encryption Keys (Card Tokenization)","id":"9c325f55-2dd2-44c8-ba71-e663acb10426","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{access_token}}"}]},"isInherited":false},"method":"GET","header":[],"url":"{{base_url}}/v1/card/encryption-keys","description":"<p>Returns the JWKS public keys required to encrypt card data before calling the Tokenize Card endpoint. Partners must encrypt sensitive card fields (CardNumber, CardExpiry, NameOnCard, Cvv) into a JWE compact string before sending to our API. This ensures no raw card data flows through LoyaltyLayer, maintaining PCI DSS compliance.</p>\n<ul>\n<li><strong>Use Case:</strong> Fetch the RSA public keys needed for JWE encryption of card data.</li>\n<li><strong>Security Notes:</strong> Keys are RSA public keys safe to cache client-side. LoyaltyLayer caches keys for 24 hours internally.</li>\n</ul>\n","urlObject":{"path":["v1","card","encryption-keys"],"host":["{{base_url}}"],"query":[],"variable":[]}},"response":[{"id":"64e3b653-e9e4-4f7f-9aa1-a24ec67650f0","name":"200 OK","originalRequest":{"method":"GET","header":[],"url":"{{base_url}}/v1/card/encryption-keys"},"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json","description":"","type":"text"}],"cookie":[{"expires":"Invalid Date","domain":"","path":""}],"responseTime":null,"body":"{\n    \"keys\": [\n        {\n            \"kty\": \"RSA\",\n            \"kid\": \"4c5b2b63-5385-4d1f-ac97-c8bcaabad76b\",\n            \"n\": \"0vx7agoebGcQSuuPiLJXZptN9nndrQmbXEps2aiAFbWhM...\",\n            \"e\": \"AQAB\",\n            \"use\": \"enc\",\n            \"alg\": \"RSA-OAEP-256\"\n        }\n    ]\n}"},{"id":"f1fb1275-fc68-475c-b3c6-0d47f483d2b3","name":"502 Bad Gateway","originalRequest":{"method":"GET","header":[],"url":"{{base_url}}/v1/card/encryption-keys"},"status":"Bad Gateway","code":502,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json","description":"","type":"text"}],"cookie":[],"responseTime":null,"body":"{\n  \"error\": \"encryption_keys_unavailable\",\n  \"error_description\": \"Failed to fetch encryption keys from provider.\",\n  \"code\": 502\n}"}],"_postman_id":"9c325f55-2dd2-44c8-ba71-e663acb10426"},{"name":"Tokenize Card","id":"9926ee5d-65ca-4553-b73d-64545abda2ce","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{access_token}}"}]},"isInherited":false},"method":"POST","header":[],"body":{"mode":"raw","raw":"{\n  \"plan_id\": \"{{plan_id}}\",\n  \"encrypted_value\": \"{{encrypted_value}}\",\n  \"card_type\": \"{{card_type}}\"\n}","options":{"raw":{"language":"json"}}},"url":"{{base_url}}/v1/card/tokenize","description":"<p>Tokenize encrypted card data to obtain an <code>enrol_token</code> for use with the Create Pass endpoint. Partners encrypt their card data client-side using JWE (JSON Web Encryption) with keys from the encryption-keys endpoint, then send the encrypted payload here. LoyaltyLayer handles the upstream provider authentication and tokenization internally.</p>\n<ul>\n<li><strong>Use Case:</strong> Convert encrypted card details into an opaque enrol_token for PCI-compliant pass creation. Partners never need provider (Collinson) credentials.</li>\n<li><strong>Security Notes:</strong> No raw card data (PAN, CVV, expiry, cardholder name) flows through LoyaltyLayer. All sensitive data is encrypted end-to-end between the partner client and the upstream provider.</li>\n</ul>\n<h2 id=\"input-params\">Input Params</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>plan_id</td>\n<td>string</td>\n<td>Yes</td>\n<td>Plan routing ID — determines the Brand and DealId for the upstream provider.</td>\n</tr>\n<tr>\n<td>encrypted_value</td>\n<td>string</td>\n<td>Yes</td>\n<td>JWE compact serialization string containing encrypted card data (CardNumber, CardExpiry, NameOnCard, Cvv). See encryption guide below.</td>\n</tr>\n<tr>\n<td>card_type</td>\n<td>string</td>\n<td>Yes</td>\n<td>Card network code: <code>VS</code> (Visa), <code>MC</code> (Mastercard), <code>AX</code> (Amex), <code>DS</code> (Discover), etc.</td>\n</tr>\n</tbody>\n</table>\n</div>","urlObject":{"path":["v1","card","tokenize"],"host":["{{base_url}}"],"query":[],"variable":[]}},"response":[{"id":"e66cc404-d4f8-4a72-9663-9b5ccb15ebc1","name":"200 OK","originalRequest":{"method":"POST","header":[],"body":{"mode":"raw","raw":"{\n  \"plan_id\": \"PP-HKTCLLSG26-MC\",\n  \"encrypted_value\": \"eyJhbGciOiJSU0EtT0FFUC0yNTYiLCJlbmMiOiJBMjU2R0NNIiwia2lkIjoiNGM1YjJiNjMtNTM4NS00ZDFmLWFjOTctYzhiY2FhYmFkNzZiIn0.UGhIOguC7IuVGUp8qSlKP...\",\n  \"card_type\": \"MC\"\n}","options":{"raw":{"language":"json"}}},"url":"{{base_url}}/v1/card/tokenize"},"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json","description":"","type":"text"}],"cookie":[],"responseTime":null,"body":"{\n  \"enrol_token\": \"692B6240E7872C8E0B5371376B917A65|MC01234|LK\"\n}"},{"id":"48db7d4f-59e6-430a-969c-705fdb0cb14b","name":"400 Bad Request","originalRequest":{"method":"POST","header":[],"body":{"mode":"raw","raw":"{\n  \"plan_id\": \"PP-HKTCLLSG26-MC\",\n  \"encrypted_value\": \"eyJhbGciOiJSU0EtT0FFUC0yNTYiLCJlbmMiOiJBMjU2R0NNIiwia2lkIjoiNGM1YjJiNjMtNTM4NS00ZDFmLWFjOTctYzhiY2FhYmFkNzZiIn0.UGhIOguC7IuVGUp8qSlKP...\",\n  \"card_type\": \"MC\"\n}","options":{"raw":{"language":"json"}}},"url":"{{base_url}}/v1/card/tokenize"},"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json","description":"","type":"text"}],"cookie":[],"responseTime":null,"body":"{\n  \"error\": \"invalid_request\",\n  \"error_description\": \"encrypted_value is required.\",\n  \"code\": 400\n}"},{"id":"08a7eef4-70d0-453e-b367-a399a9d0304d","name":"400 Invalid Plan","originalRequest":{"method":"POST","header":[],"body":{"mode":"raw","raw":"{\n  \"plan_id\": \"PP-HKTCLLSG26-MC\",\n  \"encrypted_value\": \"eyJhbGciOiJSU0EtT0FFUC0yNTYiLCJlbmMiOiJBMjU2R0NNIiwia2lkIjoiNGM1YjJiNjMtNTM4NS00ZDFmLWFjOTctYzhiY2FhYmFkNzZiIn0.UGhIOguC7IuVGUp8qSlKP...\",\n  \"card_type\": \"MC\"\n}","options":{"raw":{"language":"json"}}},"url":"{{base_url}}/v1/card/tokenize"},"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json","description":"","type":"text"}],"cookie":[],"responseTime":null,"body":"{\n  \"error\": \"invalid_plan_id\",\n  \"error_description\": \"No active routing rule found for plan_id: INVALID-PLAN\",\n  \"code\": 400\n}"},{"id":"6f9155ff-fd52-4c4f-9079-1e55c5e4ded5","name":"504 Provider Timeout","originalRequest":{"method":"POST","header":[],"body":{"mode":"raw","raw":"{\n  \"plan_id\": \"PP-HKTCLLSG26-MC\",\n  \"encrypted_value\": \"eyJhbGciOiJSU0EtT0FFUC0yNTYiLCJlbmMiOiJBMjU2R0NNIiwia2lkIjoiNGM1YjJiNjMtNTM4NS00ZDFmLWFjOTctYzhiY2FhYmFkNzZiIn0.UGhIOguC7IuVGUp8qSlKP...\",\n  \"card_type\": \"MC\"\n}","options":{"raw":{"language":"json"}}},"url":"{{base_url}}/v1/card/tokenize"},"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json","description":"","type":"text"}],"cookie":[],"responseTime":null,"body":"{\n  \"error\": \"provider_timeout\",\n  \"error_description\": \"Request timed out.\",\n  \"code\": 504\n}"}],"_postman_id":"9926ee5d-65ca-4553-b73d-64545abda2ce"}],"id":"08a8011d-e023-4c91-b560-8d9e81a7e9e6","description":"<h2 id=\"tokenized-flow\">Tokenized Flow</h2>\n<p>To maintain PCI DSS de-scoping and avoid handling sensitive Primary Account Number (PAN) data in our system, use this tokenized flow for pass creations (identified by plan_id mappings configured in our database). In this approach, client first interacts directly with tokenized engine API to tokenize the card details, obtaining an enrol_token. This token is then passed to our /passes/create or /passes/batch-create endpoints, where our backend completes the enrolment and pass creation on your behalf.</p>\n<p>This flow simplifies integration while ensuring security, idempotency, and compliance.</p>\n<h3 id=\"prerequisites\">Prerequisites</h3>\n<ul>\n<li><p>Client must have tokenized engine credentials (client_id and client_secret) for their OAuth 2.0 Client Credentials flow.</p>\n</li>\n<li><p>Ensure plan_id mappings are shared securely during onboarding for entiltment configurations.</p>\n</li>\n<li><p>Test in UAT environment first in tokenized engine API UAT entry point.</p>\n</li>\n<li><p>Switch to production.</p>\n</li>\n</ul>\n<h3 id=\"end-to-end-steps\">End-to-End Steps</h3>\n<ol>\n<li><p><strong>Authenticate with tokenized engine</strong>: Obtain a short-lived access token (expires in 30 minutes) for secure API calls.</p>\n<ul>\n<li><p>Endpoint: POST /oauth2/token</p>\n</li>\n<li><p>Request Headers: Content-Type: application/x-www-form-urlencoded</p>\n</li>\n<li><p>Request Body: grant_type=client_credentials&amp;client_id={your_client_id}&amp;client_secret={your_client_secret}</p>\n</li>\n<li><p>Response: JSON with access_token (use as Bearer in Authorization header for subsequent calls).</p>\n</li>\n</ul>\n</li>\n<li><p><strong>Tokenize Card</strong>: Validate and tokenize the cardholder's details to generate an enrol_token. This step handles PAN securely within PCI Level 1 compliant environment.</p>\n<ul>\n<li><p>Endpoint: POST /cards (or equivalent card tokenization endpoint).</p>\n</li>\n<li><p>Request Headers: Authorization: Bearer {access_token}, Content-Type: application/json</p>\n</li>\n<li><p><code>{ \"card_number\": \"4111111111111111\", \"expiry_date\": \"12/2028\", \"cardholder_name\": \"John Doe\", \"other_validation_fields\": {} // As per Collinson's requirements, e.g., CVV if needed for validation}</code></p>\n</li>\n<li><p>Response: JSON including enrol_token (an opaque string) and any validation status.</p>\n</li>\n<li><p>Error Handling: Expect 400 for invalid card details; retry transients (5xx) with backoff.</p>\n</li>\n<li><p>Note: Use mock data in UAT (e.g., card_number: \"4111111111111111\"). The enrol_token is single-use and expires; handle accordingly.</p>\n</li>\n</ul>\n</li>\n</ol>\n<h2 id=\"card-data-encryption-guide\">Card Data Encryption Guide</h2>\n<p>To tokenize a card through LoyaltyLayer, partners must encrypt the card data client-side using <strong>JWE (JSON Web Encryption)</strong>. This ensures sensitive card data never passes through LoyaltyLayer in cleartext, maintaining PCI DSS de-scoping.</p>\n<h3 id=\"encryption-overview\">Encryption Overview</h3>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Parameter</th>\n<th>Value</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>Key wrapping algorithm</td>\n<td><code>RSA-OAEP-256</code> (recommended) or <code>RSA-OAEP</code></td>\n</tr>\n<tr>\n<td>Content encryption algorithm</td>\n<td><code>A256GCM</code> (recommended), or <code>A128GCM</code>, <code>A192GCM</code>, <code>A128CBC-HS256</code>, <code>A192CBC-HS384</code>, <code>A256CBC-HS512</code></td>\n</tr>\n<tr>\n<td>Serialization</td>\n<td><strong>JWE Compact Serialization</strong> only</td>\n</tr>\n<tr>\n<td>Key source</td>\n<td><code>GET /v1/card/encryption-keys</code></td>\n</tr>\n</tbody>\n</table>\n</div><h3 id=\"step-by-step\">Step-by-Step</h3>\n<ol>\n<li><p><strong>Fetch encryption keys</strong> from <code>GET /v1/card/encryption-keys</code>. Cache the response (keys rarely change). Select the first key from the <code>keys</code> array.</p>\n</li>\n<li><p><strong>Build the JSON payload</strong> containing the sensitive card fields:</p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\"> {\n \"CardNumber\": \"5571419898406210\",\n \"CardExpiry\": \"12/2027\",\n \"NameOnCard\": \"J SMITH\",\n \"Cvv\": \"123\"\n }\n\n</code></pre>\n</li>\n<li><p><strong>Encrypt using JWE</strong> with the RSA public key from step 1:</p>\n<ul>\n<li><p>Set the JWE protected header with <code>alg</code>, <code>enc</code>, and <code>kid</code> (the key ID from the JWKS)</p>\n</li>\n<li><p>Encrypt the JSON payload string</p>\n</li>\n<li><p>Output in JWE compact serialization format (5 Base64url-encoded parts separated by dots)</p>\n</li>\n</ul>\n</li>\n<li><p><strong>Send the encrypted value</strong> as the <code>encrypted_value</code> field in the <code>POST /v1/card/tokenize</code> request.</p>\n</li>\n</ol>\n<h3 id=\"example-javascript-using-jose-library-v5\">Example: JavaScript (using jose library v5+)</h3>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-javascript\">import { importJWK, CompactEncrypt } from 'jose';\n// 1. Fetch encryption keys from LoyaltyLayer\nconst keysResponse = await fetch('https://your-api.loyaltylayer.xyz/v1/card/encryption-keys', {\n  headers: { 'Authorization': 'Bearer YOUR_LL_ACCESS_TOKEN' }\n});\nconst { keys } = await keysResponse.json();\nconst jwk = keys[0]; // Use the first available key\n// 2. Build the card payload to encrypt\nconst cardData = JSON.stringify({\n  CardNumber: '5571419898406210',\n  CardExpiry: '12/2027',\n  NameOnCard: 'J SMITH',\n  Cvv: '123'\n});\n// 3. Encrypt using JWE\nconst publicKey = await importJWK(jwk, 'RSA-OAEP-256');\nconst jwe = await new CompactEncrypt(new TextEncoder().encode(cardData))\n  .setProtectedHeader({\n    alg: 'RSA-OAEP-256',\n    enc: 'A256GCM',\n    kid: jwk.kid\n  })\n  .encrypt(publicKey);\n// 4. Call LoyaltyLayer tokenize endpoint\nconst tokenizeResponse = await fetch('https://your-api.loyaltylayer.xyz/v1/card/tokenize', {\n  method: 'POST',\n  headers: {\n    'Authorization': 'Bearer YOUR_LL_ACCESS_TOKEN',\n    'Content-Type': 'application/json'\n  },\n  body: JSON.stringify({\n    plan_id: 'PP-HKTCLLSG26-MC',\n    encrypted_value: jwe,\n    card_type: 'MC'\n  })\n});\nconst { enrol_token } = await tokenizeResponse.json();\n// Use enrol_token in POST /v1/pass/create\n\n</code></pre>\n<h3 id=\"example-python-using-jwcrypto-library\">Example: Python (using jwcrypto library)</h3>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-python\">import json, requests\nfrom jwcrypto import jwk, jwe\n# 1. Fetch encryption keys\nkeys_resp = requests.get(\n    'https://your-api.loyaltylayer.xyz/v1/card/encryption-keys',\n    headers={'Authorization': 'Bearer YOUR_LL_ACCESS_TOKEN'}\n)\njwks = keys_resp.json()['keys']\npublic_key = jwk.JWK(**jwks[0])\n# 2. Build card payload\ncard_data = json.dumps({\n    'CardNumber': '5571419898406210',\n    'CardExpiry': '12/2027',\n    'NameOnCard': 'J SMITH',\n    'Cvv': '123'\n})\n# 3. Encrypt using JWE\nprotected_header = {\n    'alg': 'RSA-OAEP-256',\n    'enc': 'A256GCM',\n    'kid': jwks[0]['kid']\n}\njwe_token = jwe.JWE(card_data.encode('utf-8'), recipient=public_key,\n                     protected=json.dumps(protected_header))\nencrypted_value = jwe_token.serialize(compact=True)\n# 4. Call tokenize endpoint\nresp = requests.post(\n    'https://your-api.loyaltylayer.xyz/v1/card/tokenize',\n    headers={\n        'Authorization': 'Bearer YOUR_LL_ACCESS_TOKEN',\n        'Content-Type': 'application/json'\n    },\n    json={\n        'plan_id': 'PP-HKTCLLSG26-MC',\n        'encrypted_value': encrypted_value,\n        'card_type': 'MC'\n    }\n)\nenrol_token = resp.json()['enrol_token']\n\n</code></pre>\n<h3 id=\"jwe-compact-format\">JWE Compact Format</h3>\n<p>The <code>encrypted_value</code> string is a JWE compact serialization with 5 parts separated by dots:</p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code>BASE64URL(header).BASE64URL(encrypted_key).BASE64URL(iv).BASE64URL(ciphertext).BASE64URL(tag)\n\n</code></pre><p>Where:</p>\n<ul>\n<li><p><strong>header</strong>: <code>{\"alg\":\"RSA-OAEP-256\",\"enc\":\"A256GCM\",\"kid\":\"...\"}</code></p>\n</li>\n<li><p><strong>encrypted_key</strong>: Content Encryption Key (CEK) wrapped with the RSA public key</p>\n</li>\n<li><p><strong>iv</strong>: Initialization vector for AES-GCM</p>\n</li>\n<li><p><strong>ciphertext</strong>: The encrypted card data JSON</p>\n</li>\n<li><p><strong>tag</strong>: Authentication tag from AES-GCM</p>\n</li>\n</ul>\n<h3 id=\"complete-tokenized-pass-creation-flow\">Complete Tokenized Pass Creation Flow</h3>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code>Partner                          LoyaltyLayer                    Collinson\n  |                                   |                              |\n  |-- POST /auth/token ------------  --&gt;|                              |\n  |&lt;-- { access_token } --------------|                              |\n  |                                   |                              |\n  |-- GET /v1/card/encryption-keys   --&gt;|                              |\n  |                                   |-- GET /.well-known/jwks.json-&gt;|\n  |&lt;-- { keys: [...] } --------------|&lt;-- { keys: [...] } ----------|\n  |                                   |                              |\n  | [encrypt card data locally]       |                              |\n  |                                   |                              |\n  |-- POST /v1/card/tokenize -----  --&gt;|                              |\n  |   { encrypted_value, ... }       |-- POST /card/tokenize ----  --&gt;|\n  |                                   |   { EncryptedValue, ... }    |\n  |&lt;-- { enrol_token } --------------|&lt;-- { EnrolToken } -----------|\n  |                                   |                              |\n  |-- POST /v1/pass/create --------  --&gt;|                              |\n  |   { enrol_token, holder, ... }   |-- POST /v1/members -------  --&gt;|\n  |&lt;-- { pass_id, dmc_qr_data } -----|&lt;-- { MembershipNumber } -----|\n\n</code></pre>","auth":{"type":"bearer","bearer":{"basicConfig":[]},"isInherited":false},"event":[{"listen":"prerequest","script":{"type":"text/javascript","packages":{},"requests":{},"exec":[""],"id":"50b9129b-1a91-406d-80c5-61ee3529e7a0"}},{"listen":"test","script":{"type":"text/javascript","packages":{},"requests":{},"exec":[""],"id":"d63681dd-d4b0-4fb4-8718-5c0f3879e8aa"}}],"_postman_id":"08a8011d-e023-4c91-b560-8d9e81a7e9e6"},{"name":"Auth Access Token (LoyaltyLayer)","event":[{"listen":"test","script":{"exec":["pm.environment.set(\"access_token\", pm.response.json().access_token);"],"type":"text/javascript","packages":{},"requests":{},"id":"f5e4e64f-a601-4283-a289-d6b74df8782c"}}],"id":"b45e5409-06a7-4ff9-b2be-178473ff3b73","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"POST","header":[],"body":{"mode":"raw","raw":"{\n    \"client_id\": \"{{client_id}}\",\n    \"client_secret\": \"{{client_secret}}\"\n}","options":{"raw":{"language":"json"}}},"url":"{{base_url}}/auth/token","description":"<p>The Auth Token API endpoint provides secure OAuth 2.0 authentication using the Client Credentials grant type, allowing to obtain short-lived access tokens (30 minutes) for subsequent API calls, such as creating or managing Priority Pass or LoungeKey passes. Tokens are opaque and validated server-side for all requests.</p>\n<ul>\n<li><p><strong>Key Features:</strong> Stateless, HTTPS/TLS 1.2 enforced, and tied to your client_id and client_secret.</p>\n</li>\n<li><p><strong>Use Case:</strong> Call this before any protected endpoint (e.g., /passes/create). Refresh proactively to avoid 401 errors.</p>\n</li>\n<li><p><strong>Security Notes:</strong> Tokens grant access only to permitted operations per your account.</p>\n</li>\n</ul>\n<h2 id=\"prerequisites\">Prerequisites</h2>\n<p>To use this endpoint successfully:</p>\n<ul>\n<li><strong>Credentials:</strong> Obtain your unique client_id and client_secret from our onboarding team. These are securely generated, tied to your account, and used to derive plan mappings.</li>\n</ul>\n<h2 id=\"input-params\">Input Params</h2>\n<p>The request body is JSON (Content-Type: application/json). All parameters are required.</p>\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>client_id</td>\n<td>string</td>\n<td>Yes</td>\n<td>Your unique client identifier issued during onboarding. Ties to client account and provides default context for plan mappings (e.g., Priority Pass or LoungeKey).</td>\n</tr>\n<tr>\n<td>client_secret</td>\n<td>string</td>\n<td>Yes</td>\n<td>The secure secret key paired with your client_id. Keep confidential; used for authentication, similar to Collinson's setups.</td>\n</tr>\n</tbody>\n</table>\n</div><h2 id=\"response-params\">Response Params</h2>\n<p>Successful responses (200 OK) return JSON. Error responses include an error object as described above.</p>\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>Always Present</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>access_token</td>\n<td>string</td>\n<td>Yes (on success)</td>\n<td>Opaque Bearer token for authorizing subsequent calls (e.g., to /passes/create). Valid for 1800 seconds;</td>\n</tr>\n<tr>\n<td>expires_in</td>\n<td>integer</td>\n<td>Yes (on success)</td>\n<td>Token lifetime in seconds (1800 / 30 minutes).</td>\n</tr>\n<tr>\n<td>error</td>\n<td>string</td>\n<td>Yes (on error)</td>\n<td>Error type (e.g., \"invalid_client\").</td>\n</tr>\n<tr>\n<td>error_description</td>\n<td>string</td>\n<td>Yes (on error)</td>\n<td>Detailed explanation (e.g., \"Invalid credentials\").</td>\n</tr>\n<tr>\n<td>code</td>\n<td>integer</td>\n<td>Yes (on error)</td>\n<td>HTTP status code (e.g., 401).</td>\n</tr>\n</tbody>\n</table>\n</div>","urlObject":{"path":["auth","token"],"host":["{{base_url}}"],"query":[],"variable":[]}},"response":[{"id":"6de5b8a2-8da0-4434-99ad-edc7fb241609","name":"200 Success","originalRequest":{"method":"POST","header":[],"body":{"mode":"urlencoded","urlencoded":[{"key":"client_id","value":"","type":"text"},{"key":"client_secret","value":"","type":"text"},{"key":"grant_type","value":"client_credentials","type":"text"}]},"url":"/auth/token"},"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json","description":"","type":"text"}],"cookie":[],"responseTime":null,"body":"{\n    \"access_token\": \"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...\",\n    \"expires_in\": 1800\n}"},{"id":"f9677a14-9366-46cc-aeac-df4dee96869c","name":"400 Bad Request","originalRequest":{"method":"POST","header":[],"body":{"mode":"urlencoded","urlencoded":[{"key":"client_id","value":"{{client_id}}","type":"text"},{"key":"client_secret","value":"{{client_secret}}","type":"text"},{"key":"grant_type","value":"client_credentials","type":"text"}]},"url":"{{base_url}}/auth/token"},"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json","description":"","type":"text"}],"cookie":[],"responseTime":null,"body":"{\n    \"error\": \"invalid_request\",\n    \"error_description\": \"client_id and client_secret are required.\",\n    \"code\": 400\n}"},{"id":"1a2364e8-b45b-4e5a-b14d-5e76a9c96a21","name":"429 Too Many Requests","originalRequest":{"method":"POST","header":[],"body":{"mode":"urlencoded","urlencoded":[{"key":"client_id","value":"{{client_id}}","type":"text"},{"key":"client_secret","value":"{{client_secret}}","type":"text"},{"key":"grant_type","value":"client_credentials","type":"text"}]},"url":"{{base_url}}/auth/token"},"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json","description":"","type":"text"}],"cookie":[],"responseTime":null,"body":"{\n    \"error\": \"rate_limit_exceeded\",\n    \"error_description\": \"Too many requests; retry after 60 seconds\",\n    \"code\": 429,\n    \"retry_after\": 60\n}"}],"_postman_id":"b45e5409-06a7-4ff9-b2be-178473ff3b73"},{"name":"Create Pass","id":"b849bed2-feb8-4540-9dc0-766562b2be1b","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{access_token}}"}]},"isInherited":false},"method":"POST","header":[{"key":"Content-Type","value":"application/json","type":"text"}],"body":{"mode":"raw","raw":"{\n  \"plan_id\": \"{{plan_id}}\",\n  \"enrol_token\": \"ASDU78123AASDGJ\",\n  \"holder\": {\n    \"first_name\": \"John\",\n    \"last_name\": \"Doe\",\n    \"address\": {\n      \"address_line_1\": \"123 Main St\",\n      \"city\": \"Hong Kong\",\n      \"country_code\": \"HKG\"\n    }\n  },\n  \"card_type\": \"{{card_type}}\",\n  \"expiry_date\": \"2026-12-31\",\n  \"ext_card_id\": \"8712DASD7878FDD\",\n  \"extra_info\": {\n    \"BUUID\": \"COBANK01\"\n  }\n}"},"url":"{{base_url}}/v1/pass/create","description":"<p>The <strong>Create Pass</strong> API endpoint enables creation of different travel entitlements in a <strong>single, unified call</strong>:</p>\n<ul>\n<li><p><strong>Priority Pass</strong> membership (ongoing entitlements such as free lounge visits)</p>\n</li>\n<li><p><strong>LoungeKey Pass</strong> voucher (transactional / one-time access)</p>\n</li>\n<li><p><strong>eSIM data plan</strong></p>\n</li>\n</ul>\n<p>The entitlement type is <strong>determined by the</strong> <strong><code>plan_id</code></strong> (mapped in our system during onboarding).</p>\n<ul>\n<li><strong>Security Notes:</strong> Requires valid Bearer token from /auth/token.</li>\n</ul>\n<h2 id=\"bundle-plans\">Bundle Plans</h2>\n<p>A <strong>bundle plan</strong> is a special <code>plan_id</code> that maps to <strong>multiple service entitlements</strong> at once. When you call Create Pass with a bundle <code>plan_id</code>, the gateway automatically provisions all configured services (e.g., lounge access + eSIM) and returns a single parent pass.</p>\n<p><strong>No API changes required</strong> — use the same Create Pass endpoint. The <code>plan_id</code> determines whether a single or bundle plan is created.</p>\n<h2 id=\"error-handle\">Error Handle</h2>\n<h4 id=\"special-errors\">Special Errors:</h4>\n<ul>\n<li><p><strong>201 pass created:</strong><br />  <code>{ \"pass_id\": \"12345678901234567890123456789012\", \"type\": \"priority\", \"status\": \"created\", \"dmc_qr_data\": \"QR_STRING_FOR_PRIORITY\", \"expiry\": \"2026-12-31\", \"code\": 201}</code></p>\n</li>\n<li><p><strong>400 enrol_token validation failed:</strong><br />  <code>{ \"error\": \"invalid_enrol_token\", \"error_description\": \"...\", \"code\": 400 }</code></p>\n<p>  <code>{ \"error\": \"invalid_request\", \"error_description\": \"holder is required and must be an object.\", \"code\": 400 }</code></p>\n<p>  <code>{ \"error\": \"invalid_request\", \"error_description\": \"holder.first_name is required.\", \"code\": 400 }</code></p>\n<p>  <code>{ \"error\": \"invalid_request\", \"error_description\": \"holder.last_name is required.\", \"code\": 400 }</code></p>\n<p>  <code>{ \"error\": \"invalid_request\", \"error_description\": \"holder.address is required and must be an object.\", \"code\": 400 }</code></p>\n<p>  <code>{ \"error\": \"invalid_request\", \"error_description\": \"holder.address.address_line_1 is required.\", \"code\": 400 }</code></p>\n<p>  <code>{ \"error\": \"invalid_request\", \"error_description\": \"holder.address.city is required.\", \"code\": 400 }</code></p>\n<p>  <code>{ \"error\": \"invalid_request\", \"error_description\": \"holder.address.country_code is required.\", \"code\": 400 }</code></p>\n<p>  <code>{ \"error\": \"invalid_request\", \"error_description\": \"enrol_token is required.\", \"code\": 400 }</code> <em>(card-based plans only)</em></p>\n</li>\n<li><p><strong>401 provider authentication failed:</strong><br />  <code>{ \"error\": \"invalid_client\", \"error_description\": \"...\", \"code\": 401 }</code></p>\n</li>\n<li><p><strong>402 External Card ID Duplicate or Invalid:</strong> Provided external card ID is duplicate or invalid<br />  Example:<br />  <code>{ \"error\": \"invalid_ext_card_id\", \"error_description\": \"Provided external card id is duplicate or invalid\", \"code\": 402 }</code></p>\n</li>\n<li><p><strong>404 pass not found at provider:</strong><br />  <code>{ \"error\": \"invalid_pass_id\", \"error_description\": \"...\", \"code\": 404 }</code></p>\n</li>\n<li><p><strong>409 duplicate at provider:</strong><br />  <code>{ \"error\": \"invalid_ext_card_id\", \"error_description\": \"...\", \"code\": 409 }</code></p>\n</li>\n<li><p><strong>502 provider server error:</strong><br />  <code>{ \"error\": \"server_error\", \"error_description\": \"...\", \"code\": 502 }</code></p>\n</li>\n<li><p><strong>504 provider timeout:</strong><br />  <code>{ \"error\": \"provider_timeout\", \"error_description\": \"...\", \"code\": 504 }</code></p>\n</li>\n</ul>\n<h2 id=\"input-params\">Input Params</h2>\n<p>The request body is JSON (Content-Type: application/json). Required fields ensure valid creation; optional ones depend on pass type (e.g., lounge_id for LoungeKey).</p>\n<p>The parameter expiry_date default 365 days from create date. You also can configure the expiry date in passing expiry_date parameter value.</p>\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>plan_id</td>\n<td>string</td>\n<td>Yes</td>\n<td>Identify card assign to different parties and entitlements</td>\n</tr>\n<tr>\n<td>enrol_token</td>\n<td>string</td>\n<td>Conditional</td>\n<td>PCI-tokenized card number from <code>/v1/card/tokenize</code>. <strong>Required for card-based (lounge) plans only. Not required for eSIM or eSIM-only bundle plans</strong> — the eSIM package is determined by the plan configuration at the gateway level.</td>\n</tr>\n<tr>\n<td>card_type</td>\n<td>string</td>\n<td>Yes (card-based plans)</td>\n<td>Card network code: <code>VS</code> (Visa), <code>MC</code> (Mastercard), <code>AX</code> (Amex), <code>DS</code> (Discover), etc. <strong>Not required for eSIM plans.</strong></td>\n</tr>\n<tr>\n<td>expiry_date</td>\n<td>string</td>\n<td>No</td>\n<td>Card expiry in YYYY-MM-DD format (e.g., \"2028-12-31\"). Validated against regex pattern.  <br /><strong>If not provide, it will default use 365 days from create date.</strong></td>\n</tr>\n<tr>\n<td>ext_card_id</td>\n<td>string</td>\n<td>No</td>\n<td>External party card ID. If provide external card ID, system will use this ID for pass ID in LoyaltyLayer system. Must unique identifiter for whole account.</td>\n</tr>\n<tr>\n<td>extra_info</td>\n<td>object</td>\n<td>No</td>\n<td>Extra information and data to the account. JSON object for passing custom system data mappings (e.g., {\"BUUID\": \"ADV12344\", \"TIME\": 78213123123}). This data is stored in our middle-layer system for finance reporting and audits.</td>\n</tr>\n<tr>\n<td>holder</td>\n<td>object</td>\n<td>Yes</td>\n<td>Cardholder details required by the provider. See holder object below.</td>\n</tr>\n</tbody>\n</table>\n</div><h3 id=\"holder-object\">Holder Object</h3>\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>first_name</td>\n<td>string</td>\n<td>Yes</td>\n<td>Cardholder first name (e.g., \"John\").</td>\n</tr>\n<tr>\n<td>last_name</td>\n<td>string</td>\n<td>Yes</td>\n<td>Cardholder last name / surname (e.g., \"Doe\").</td>\n</tr>\n<tr>\n<td>address</td>\n<td>object</td>\n<td>Yes (card-based plans)</td>\n<td>Cardholder address details. See address object below. <strong>Not required for eSIM plans.</strong></td>\n</tr>\n</tbody>\n</table>\n</div><h3 id=\"address-object-inside-holder\">Address Object (inside holder)</h3>\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>address_line_1</td>\n<td>string</td>\n<td>Yes</td>\n<td>Street address (e.g., \"123 Main St\"). Max 30 characters</td>\n</tr>\n<tr>\n<td>address_line_2</td>\n<td>string</td>\n<td>No</td>\n<td>Street address (e.g., \"123 Main St\"). Max 30 characters</td>\n</tr>\n<tr>\n<td>address_line_3</td>\n<td>string</td>\n<td>No</td>\n<td>Street address (e.g., \"123 Main St\"). Max 30 characters</td>\n</tr>\n<tr>\n<td>city</td>\n<td>string</td>\n<td>Yes</td>\n<td>City name (e.g., \"Hong Kong\").</td>\n</tr>\n<tr>\n<td>country_code</td>\n<td>string</td>\n<td>Yes</td>\n<td>ISO 3166-1 alpha-3 country code (e.g., \"HKG\", \"SGP\", \"USA\").</td>\n</tr>\n</tbody>\n</table>\n</div><h2 id=\"response-params\">Response Params</h2>\n<p>Successful responses (201 Created) return JSON with pass details. Error responses include an error object as described above.</p>\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>Always Present</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>pass_id</td>\n<td>string</td>\n<td>Yes (on success)</td>\n<td>Unique identifier for the created pass (e.g., membership number for Priority, PASS ID for LoungeKey). Use for subsequent operations like status checks.</td>\n</tr>\n<tr>\n<td>status</td>\n<td>string</td>\n<td>Yes (on success)</td>\n<td>Initial status (e.g., \"created\" or \"issued\").</td>\n</tr>\n<tr>\n<td>type</td>\n<td>string</td>\n<td>Yes</td>\n<td>Identify entitlemet service type. (e.g., \"priority\", \"loungekey\", \"esim\", \"bundle\").  <br />\"bundle\" for bundle plans.</td>\n</tr>\n<tr>\n<td>dmc_qr_data</td>\n<td>string</td>\n<td>No</td>\n<td>For Priority Pass: Data for generating Digital Membership Card QR code. Absent for LoungeKey.</td>\n</tr>\n<tr>\n<td>barcode_string</td>\n<td>string</td>\n<td>No</td>\n<td>For LoungeKey (if delivery_method=\"barcode_string\"): String for QR/barcode generation (per Collinson section 8). Absent for Priority.</td>\n</tr>\n<tr>\n<td>expiry</td>\n<td>string</td>\n<td>No</td>\n<td>Pass expiry date (YYYY-MM-DD format), if applicable.</td>\n</tr>\n<tr>\n<td>error</td>\n<td>string</td>\n<td>Yes (on error)</td>\n<td>Error type (e.g., \"invalid_request\").</td>\n</tr>\n<tr>\n<td>error_description</td>\n<td>string</td>\n<td>Yes (on error)</td>\n<td>Detailed explanation (e.g., \"Invalid card_number\").</td>\n</tr>\n<tr>\n<td>code</td>\n<td>integer</td>\n<td>Yes (on error)</td>\n<td>HTTP status code (e.g., 400).</td>\n</tr>\n<tr>\n<td>qr_code_data</td>\n<td>string</td>\n<td>No</td>\n<td><strong>eSIM only.</strong> LPA QR install string. Present when <code>type</code> is <code>esim</code>. Same as <code>esim_data.install_qr_data</code>.</td>\n</tr>\n<tr>\n<td>entitlement</td>\n<td>array</td>\n<td>No</td>\n<td>Array of service entitlement objects created under this pass. Present on success for all pass types.</td>\n</tr>\n</tbody>\n</table>\n</div><hr />\n<h4 id=\"entitlement-object\">Entitlement Object</h4>\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>Present When</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>entitlement_id</td>\n<td>string</td>\n<td>Always</td>\n<td>Unique ID for this entitlement/service row.</td>\n</tr>\n<tr>\n<td>type</td>\n<td>string</td>\n<td>Always</td>\n<td>Service type: <code>\"lounge_access\"</code>, <code>\"esim\"</code>, etc.</td>\n</tr>\n<tr>\n<td>status</td>\n<td>string</td>\n<td>Always</td>\n<td><code>\"active\"</code> or <code>\"failed\"</code>.</td>\n</tr>\n<tr>\n<td>component</td>\n<td>string</td>\n<td>Bundle plans</td>\n<td>Bundle component key configured during onboarding. <code>null</code> for single-service plans.</td>\n</tr>\n<tr>\n<td>quantity</td>\n<td>integer</td>\n<td>Yes</td>\n<td>Service quota (e.g., 2 lounge visits or 1024 MB eSIM data).</td>\n</tr>\n<tr>\n<td>unit</td>\n<td>string</td>\n<td>Yes</td>\n<td>Quota unit: <code>\"visit\"</code>, <code>\"MB\"</code>, <code>\"GB\"</code>, etc.</td>\n</tr>\n<tr>\n<td>used</td>\n<td>integer</td>\n<td>Yes</td>\n<td>Used quantity. <code>0</code> at creation.</td>\n</tr>\n<tr>\n<td>remaining</td>\n<td>integer/string</td>\n<td>Yes</td>\n<td>Remaining quota. <code>\"unlimited\"</code> when quota is unlimited.</td>\n</tr>\n<tr>\n<td>dmc_qr_data</td>\n<td>string</td>\n<td>Active lounge service</td>\n<td>DMC QR string for lounge access.</td>\n</tr>\n<tr>\n<td>iccid</td>\n<td>string</td>\n<td>Active eSIM service</td>\n<td>eSIM ICCID.</td>\n</tr>\n<tr>\n<td>qr_code_data</td>\n<td>string</td>\n<td>Active eSIM service</td>\n<td>LPA QR install string. Same as <code>esim_data.install_qr_data</code>.</td>\n</tr>\n<tr>\n<td>esim_data</td>\n<td>object</td>\n<td>Active eSIM service</td>\n<td>eSIM provisioning details. See <code>esim_data</code> Object below.</td>\n</tr>\n<tr>\n<td>expiry</td>\n<td>string</td>\n<td>Active service</td>\n<td>Service expiry date.</td>\n</tr>\n<tr>\n<td>error</td>\n<td>string</td>\n<td>Failed service</td>\n<td>Error code (e.g., <code>\"provider_error\"</code>).</td>\n</tr>\n<tr>\n<td>error_description</td>\n<td>string</td>\n<td>Failed service</td>\n<td>Human-readable failure reason. Indicates retry status.</td>\n</tr>\n<tr>\n<td>next_retry_at</td>\n<td>string</td>\n<td>Failed + pending retry</td>\n<td>ISO datetime of next automatic retry.</td>\n</tr>\n</tbody>\n</table>\n</div><h3 id=\"esim_data-object\">esim_data Object</h3>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th><strong>Parameter</strong></th>\n<th><strong>Type</strong></th>\n<th>Always Present</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>package_name</td>\n<td>string</td>\n<td>Yes</td>\n<td>Plan name (e.g. \"Global 7 Days 1GB\")</td>\n</tr>\n<tr>\n<td>data_remaining_mb</td>\n<td>string</td>\n<td>Yes</td>\n<td>Remaining data in MB (or null if unlimited)</td>\n</tr>\n<tr>\n<td>expiry_date</td>\n<td>date</td>\n<td>Yes</td>\n<td>Validity end date (YYYY-MM-DD)</td>\n</tr>\n<tr>\n<td>activation_code</td>\n<td>string</td>\n<td>Yes</td>\n<td>Activation code for manual installation</td>\n</tr>\n<tr>\n<td>install_qr_data</td>\n<td>string</td>\n<td>Yes</td>\n<td>Data for generating install QR code.</td>\n</tr>\n</tbody>\n</table>\n</div>","urlObject":{"path":["v1","pass","create"],"host":["{{base_url}}"],"query":[],"variable":[]}},"response":[{"id":"bdb808c1-65f3-4817-8559-d130889f9447","name":"200 Success (Priority Pass)","originalRequest":{"method":"POST","header":[{"key":"Content-Type","value":"application/json","type":"text"}],"body":{"mode":"raw","raw":"{\n  \"plan_id\": \"test-priority\",\n  \"enrol_token\": \"ASDU78123AASDGJ\",\n  \"holder\": {\n    \"first_name\": \"John\",\n    \"last_name\": \"Doe\",\n    \"address\": {\n      \"address_line_1\": \"123 Main St\",\n      \"city\": \"Hong Kong\",\n      \"country_code\": \"HKG\"\n    }\n  },\n  \"card_type\": \"VS\",\n  \"ext_card_id\": \"12345678901234567890123456789012\",\n  \"extra_info\": {\n    \"BUUID\": \"12345678-1234-1234-1234-123456789012\",\n    \"time\": 12839128989\n  }\n}","options":{"raw":{"language":"json"}}},"url":"{{base_url}}/v1/pass/create"},"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json","description":"","type":"text"}],"cookie":[],"responseTime":null,"body":"{\n  \"pass_id\": \"12345678901234567890123456789012\",\n  \"type\": \"priority\",\n  \"status\": \"created\",\n  \"dmc_qr_data\": \"QR_STRING_FOR_PRIORITY\",\n  \"expiry\": \"2027-03-31\",\n  \"entitlement\": [\n    {\n      \"entitlement_id\": \"ent-uuid-001\",\n      \"type\": \"lounge_access\",\n      \"status\": \"active\",\n      \"component\": null,\n      \"quantity\": 2,\n      \"unit\": \"visit\",\n      \"used\": 0,\n      \"remaining\": 2,\n      \"dmc_qr_data\": \"QR_STRING_FOR_PRIORITY\",\n      \"barcode_string\": null,\n      \"expiry\": \"2027-03-31\"\n    }\n  ]\n}"},{"id":"9200e6d6-53a6-4b6d-ad4a-b9d665beafb3","name":"200 Success (eSim)","originalRequest":{"method":"POST","header":[{"key":"Content-Type","value":"application/json","type":"text"}],"body":{"mode":"raw","raw":"{\n    \"plan_id\": \"{{plan_id}}\",\n    \"holder\": {\n        \"first_name\": \"John\",\n        \"last_name\": \"Doe\",\n        \"address\": {\n            \"address_line_1\": \"123 Main St\",\n            \"city\": \"Hong Kong\",\n            \"country_code\": \"HKG\"\n        }\n    },\n    \"card_type\": \"{{card_type}}\",\n    \"expiry_date\": \"2026-12-31\",\n    \"ext_card_id\": \"8712DASD7878FDD\",\n    \"extra_info\": {\n        \"BUUID\": \"COBANK01\"\n    }\n}"},"url":"{{base_url}}/v1/pass/create"},"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json","description":"","type":"text"}],"cookie":[],"responseTime":null,"body":"{\n    \"pass_id\": \"sim-user-001\",\n    \"type\": \"esim\",\n    \"status\": \"created\",\n    \"qr_code_data\": \"LPA:1$sm-v4-057-a-gtm.pr.go-esim.com$OC_SAMPLE_ACTIVATION_CODE\",\n    \"expiry\": \"2027-03-31\",\n    \"entitlement\": [\n        {\n            \"entitlement_id\": \"ent-uuid-esim-001\",\n            \"type\": \"esim\",\n            \"status\": \"active\",\n            \"component\": null,\n            \"quantity\": 1024,\n            \"unit\": \"MB\",\n            \"used\": 0,\n            \"remaining\": 1024,\n            \"iccid\": \"8944501902198304826\",\n            \"qr_code_data\": \"LPA:1$sm-v4-057-a-gtm.pr.go-esim.com$OC_SAMPLE_ACTIVATION_CODE\",\n            \"esim_data\": {\n                \"package_name\": \"HK 7 Days 1GB\",\n                \"data_remaining_mb\": null,\n                \"expiry_date\": \"2027-03-31\",\n                \"activation_code\": null,\n                \"install_qr_data\": \"LPA:1$sm-v4-057-a-gtm.pr.go-esim.com$OC_SAMPLE_ACTIVATION_CODE\"\n            },\n            \"expiry\": \"2027-03-31\"\n        }\n    ]\n}"},{"id":"2f31638a-ede1-41f0-a4cd-e6fea502a275","name":"200 Success (With Set Expiry Date)","originalRequest":{"method":"POST","header":[{"key":"Content-Type","value":"application/json","type":"text"}],"body":{"mode":"raw","raw":"{\n  \"plan_id\": \"test-priority\",\n  \"enrol_token\": \"ASDU78123AASDGJ\",\n  \"holder\": {\n    \"first_name\": \"John\",\n    \"last_name\": \"Doe\",\n    \"address\": {\n      \"address_line_1\": \"123 Main St\",\n      \"city\": \"Hong Kong\",\n      \"country_code\": \"HKG\"\n    }\n  },\n  \"card_type\": \"MC\",\n  \"expiry_date\": \"2026-12-31\",\n  \"ext_card_id\": \"12345678901234567890123456789012\",\n  \"extra_info\": {\n    \"BUUID\": \"12345678-1234-1234-1234-123456789012\",\n    \"time\": 12839128989\n  }\n}","options":{"raw":{"language":"json"}}},"url":"{{base_url}}/v1/pass/create"},"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json","description":"","type":"text"}],"cookie":[],"responseTime":null,"body":"{\n  \"pass_id\": \"12345678901234567890123456789012\",\n  \"type\": \"priority\",\n  \"status\": \"created\",\n  \"dmc_qr_data\": \"QR_STRING_FOR_PRIORITY\",\n  \"expiry\": \"2026-12-31\",\n  \"entitlement\": [\n    {\n      \"entitlement_id\": \"ent-uuid-001\",\n      \"type\": \"lounge_access\",\n      \"status\": \"active\",\n      \"component\": null,\n      \"quantity\": 2,\n      \"unit\": \"visit\",\n      \"used\": 0,\n      \"remaining\": 2,\n      \"dmc_qr_data\": \"QR_STRING_FOR_PRIORITY\",\n      \"barcode_string\": null,\n      \"expiry\": \"2026-12-31\"\n    }\n  ]\n}"},{"id":"98cb24ea-5c42-469f-8b01-0c62a87feadd","name":"200 Success (Without ext card ID)","originalRequest":{"method":"POST","header":[{"key":"Content-Type","value":"application/json","type":"text"}],"body":{"mode":"raw","raw":"{\n  \"plan_id\": \"test-priority\",\n  \"enrol_token\": \"ASDU78123AASDGJ\",\n  \"holder\": {\n    \"first_name\": \"John\",\n    \"last_name\": \"Doe\",\n    \"address\": {\n      \"address_line_1\": \"123 Main St\",\n      \"city\": \"Hong Kong\",\n      \"country_code\": \"HKG\"\n    }\n  },\n  \"card_type\": \"MC\",\n  \"expiry_date\": \"2026-12-31\"\n}","options":{"raw":{"language":"json"}}},"url":"{{base_url}}/v1/pass/create"},"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json","description":"","type":"text"}],"cookie":[],"responseTime":null,"body":"{\n  \"pass_id\": \"uuiasd89123123\",\n  \"type\": \"priority\",\n  \"status\": \"created\",\n  \"dmc_qr_data\": \"QR_STRING_FOR_PRIORITY\",\n  \"expiry\": \"2026-12-31\",\n  \"entitlement\": [\n    {\n      \"entitlement_id\": \"ent-uuid-001\",\n      \"type\": \"lounge_access\",\n      \"status\": \"active\",\n      \"component\": null,\n      \"quantity\": 2,\n      \"unit\": \"visit\",\n      \"used\": 0,\n      \"remaining\": 2,\n      \"dmc_qr_data\": \"QR_STRING_FOR_PRIORITY\",\n      \"barcode_string\": null,\n      \"expiry\": \"2026-12-31\"\n    }\n  ]\n}"},{"id":"d112c8b1-665c-4ae4-ba30-22939d410445","name":"201 Created","originalRequest":{"method":"POST","header":[{"key":"Content-Type","value":"application/json","type":"text"}],"body":{"mode":"raw","raw":"{\n  \"plan_id\": \"test-priority\",\n  \"enrol_token\": \"ASDU78123AASDGJ\",\n  \"holder\": {\n    \"first_name\": \"John\",\n    \"last_name\": \"Doe\",\n    \"address\": {\n      \"address_line_1\": \"123 Main St\",\n      \"city\": \"Hong Kong\",\n      \"country_code\": \"HKG\"\n    }\n  },\n  \"card_type\": \"VS\",\n  \"expiry_date\": \"2026-12-31\",\n  \"ext_card_id\": \"12345678901234567890123456789012\"\n}","options":{"raw":{"language":"json"}}},"url":"{{base_url}}/v1/pass/create"},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json","description":"","type":"text"}],"cookie":[],"responseTime":null,"body":"{\n  \"pass_id\": \"12345678901234567890123456789012\",\n  \"type\": \"priority\",\n  \"status\": \"created\",\n  \"dmc_qr_data\": \"QR_STRING_FOR_PRIORITY\",\n  \"expiry\": \"2026-12-31\",\n  \"code\": 201,\n  \"entitlement\": [\n    {\n      \"entitlement_id\": \"ent-uuid-001\",\n      \"type\": \"lounge_access\",\n      \"status\": \"active\",\n      \"component\": null,\n      \"quantity\": 2,\n      \"unit\": \"visit\",\n      \"used\": 0,\n      \"remaining\": 2,\n      \"dmc_qr_data\": \"QR_STRING_FOR_PRIORITY\",\n      \"barcode_string\": null,\n      \"expiry\": \"2026-12-31\"\n    }\n  ]\n}"},{"id":"588ff692-f6b3-4623-88f4-7c428ac0b48d","name":"201 Created (Bundle — All Active)","originalRequest":{"method":"POST","header":[{"key":"Content-Type","value":"application/json","type":"text"}],"body":{"mode":"raw","raw":"{\n  \"plan_id\": \"PLAN-BUNDLE-LOUNGE-ESIM\",\n  \"enrol_token\": \"ASDU78123AASDGJ\",\n  \"holder\": {\n    \"first_name\": \"John\",\n    \"last_name\": \"Doe\",\n    \"address\": {\n      \"address_line_1\": \"123 Main St\",\n      \"city\": \"Hong Kong\",\n      \"country_code\": \"HKG\"\n    }\n  },\n  \"card_type\": \"VS\",\n  \"expiry_date\": \"2027-12-31\",\n  \"ext_card_id\": \"BUNDLE-USER-001\",\n  \"extra_info\": {\n    \"BUUID\": \"COBANK01\"\n  }\n}","options":{"raw":{"language":"json"}}},"url":"{{base_url}}/v1/pass/create"},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json","type":"text"}],"cookie":[],"responseTime":null,"body":"{\n    \"pass_id\": \"BUNDLE-USER-001\",\n    \"type\": \"bundle\",\n    \"status\": \"created\",\n    \"expiry\": \"2027-12-31\",\n    \"entitlement\": [\n        {\n            \"entitlement_id\": \"ent-lounge-001\",\n            \"component\": \"lounge_access\",\n            \"type\": \"lounge_access\",\n            \"status\": \"active\",\n            \"quantity\": 2,\n            \"unit\": \"visit\",\n            \"used\": 0,\n            \"remaining\": 2,\n            \"dmc_qr_data\": \"PP/070326/HKTCLLSG26/12345678\",\n            \"expiry\": \"2027-12-31\"\n        },\n        {\n            \"entitlement_id\": \"ent-esim-002\",\n            \"component\": \"global_esim_1gb\",\n            \"type\": \"esim\",\n            \"status\": \"active\",\n            \"quantity\": 1024,\n            \"unit\": \"MB\",\n            \"used\": 0,\n            \"remaining\": 1024,\n            \"iccid\": \"8944501902198304826\",\n            \"qr_code_data\": \"LPA:1$sm-v4-057-a-gtm.pr.go-esim.com$OC_SAMPLE_ACTIVATION_CODE\",\n            \"expiry\": \"2027-06-07\",\n            \"esim_data\": {\n                \"package_name\": \"Global 1GB\",\n                \"data_remaining_mb\": null,\n                \"expiry_date\": \"2027-06-07\",\n                \"activation_code\": null,\n                \"install_qr_data\": \"LPA:1$sm-v4-057-a-gtm.pr.go-esim.com$OC_SAMPLE_ACTIVATION_CODE\"\n            }\n        }\n    ]\n}"},{"id":"264d8a2c-d472-4fef-bf16-497f784eeb28","name":"201 Created (Bundle — Partial Success)","originalRequest":{"method":"POST","header":[{"key":"Content-Type","value":"application/json","type":"text"}],"body":{"mode":"raw","raw":"{\n  \"plan_id\": \"PLAN-BUNDLE-LOUNGE-ESIM\",\n  \"enrol_token\": \"ASDU78123AASDGJ\",\n  \"holder\": {\n    \"first_name\": \"John\",\n    \"last_name\": \"Doe\",\n    \"address\": {\n      \"address_line_1\": \"123 Main St\",\n      \"city\": \"Hong Kong\",\n      \"country_code\": \"HKG\"\n    }\n  },\n  \"card_type\": \"VS\",\n  \"expiry_date\": \"2027-12-31\",\n  \"ext_card_id\": \"BUNDLE-USER-001\",\n  \"extra_info\": {\n    \"BUUID\": \"COBANK01\"\n  }\n}","options":{"raw":{"language":"json"}}},"url":"{{base_url}}/v1/pass/create"},"status":"Created","code":201,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json","type":"text"}],"cookie":[],"responseTime":null,"body":"{\n    \"pass_id\": \"BUNDLE-USER-001\",\n    \"type\": \"bundle\",\n    \"status\": \"created\",\n    \"expiry\": \"2027-12-31\",\n    \"entitlement\": [\n        {\n            \"entitlement_id\": \"ent-lounge-001\",\n            \"component\": \"lounge_access\",\n            \"type\": \"lounge_access\",\n            \"status\": \"active\",\n            \"quantity\": 2,\n            \"unit\": \"visit\",\n            \"used\": 0,\n            \"remaining\": 2,\n            \"dmc_qr_data\": \"PP/070326/HKTCLLSG26/12345678\",\n            \"expiry\": \"2027-12-31\"\n        },\n        {\n            \"entitlement_id\": \"ent-esim-002\",\n            \"component\": \"global_esim_1gb\",\n            \"type\": \"esim\",\n            \"status\": \"failed\",\n            \"error\": \"provider_error\",\n            \"error_description\": \"Provider temporarily unavailable. Retry is queued.\",\n            \"next_retry_at\": \"2027-06-07T10:15:00Z\"\n        }\n    ]\n}"},{"id":"4d87a7c7-313e-4973-aa0c-3acbf0d22c9d","name":"400 Enrol Token Invalid","originalRequest":{"method":"POST","header":[{"key":"Content-Type","value":"application/json","type":"text"}],"body":{"mode":"raw","raw":"{\n  \"plan_id\": \"test-priority\",\n  \"holder\": {\n    \"first_name\": \"John\",\n    \"last_name\": \"Doe\",\n    \"address\": {\n      \"address_line_1\": \"123 Main St\",\n      \"city\": \"Hong Kong\",\n      \"country_code\": \"HKG\"\n    }\n  },\n  \"card_type\": \"VS\",\n  \"expiry_date\": \"2026-12-31\",\n  \"ext_card_id\": \"12345678901234567890123456789012\"\n}","options":{"raw":{"language":"json"}}},"url":"{{base_url}}/v1/pass/create"},"status":"Bad Request","code":400,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json","description":"","type":"text"}],"cookie":[],"responseTime":null,"body":"{ \n    \"error\": \"invalid_request\", \n    \"error_description\": \"enrol_token is required.\", \n    \"code\": 400 \n}"},{"id":"616e040e-84a1-4380-b1a9-821c865f393a","name":"402 External Card ID Duplicate or Invalid","originalRequest":{"method":"POST","header":[{"key":"Content-Type","value":"application/json","type":"text"}],"body":{"mode":"raw","raw":"{\n  \"plan_id\": \"test-priority\",\n  \"enrol_token\": \"ASDU78123AASDGJ\",\n  \"holder\": {\n    \"first_name\": \"John\",\n    \"last_name\": \"Doe\",\n    \"address\": {\n      \"address_line_1\": \"123 Main St\",\n      \"city\": \"Hong Kong\",\n      \"country_code\": \"HKG\"\n    }\n  },\n  \"card_type\": \"VS\",\n  \"expiry_date\": \"2026-12-31\",\n  \"ext_card_id\": \"12345678901234567890123456789012\"\n}","options":{"raw":{"language":"json"}}},"url":"{{base_url}}/v1/pass/create"},"status":"Bad Request","code":400,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json","description":"","type":"text"}],"cookie":[],"responseTime":null,"body":"{\n    \"error\": \"invalid_ext_card_id\",\n    \"error_description\": \"Provided external card id is duplicate or invalid\",\n    \"code\": 402\n}"}],"_postman_id":"b849bed2-feb8-4540-9dc0-766562b2be1b"},{"name":"Batch Create Passes","id":"bee91d29-9c89-449b-b6a4-69f83d6abca6","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{access_token}}"}]},"isInherited":false},"method":"POST","header":[{"key":"Content-Type","value":"application/json","type":"text"}],"body":{"mode":"raw","raw":"[\n  {\n    \"plan_id\": \"test-priority\",\n    \"enrol_token\": \"HASDT12671231ASD123\",\n    \"holder\": {\n      \"first_name\": \"John\",\n      \"last_name\": \"Doe\",\n      \"address\": {\n        \"address_line_1\": \"123 Main St\",\n        \"city\": \"Hong Kong\",\n        \"country_code\": \"HKG\"\n      }\n    },\n    \"card_type\": \"VS\",\n    \"expiry_date\": \"2026-12-31\",\n    \"ext_card_id\": \"JASD21387123AFDSAD\"\n  },\n  {\n    \"plan_id\": \"test-loungekey\",\n    \"enrol_token\": \"HGHCN7612313MXX\",\n    \"holder\": {\n      \"first_name\": \"Peter\",\n      \"last_name\": \"Wong\",\n      \"address\": {\n        \"address_line_1\": \"3223 West St\",\n        \"city\": \"Singapore\",\n        \"country_code\": \"SGP\"\n      }\n    },\n    \"card_type\": \"MC\",\n    \"expiry_date\": \"2026-12-31\",\n    \"ext_card_id\": \"787123ASDADUUIJE\",\n    \"extra_info\": {\n      \"BUUID\": \"YASD787\",\n      \"time\": 1231231231\n    }\n  },\n  {\n    \"plan_id\": \"PLAN-AIRALO-HK-7DAYS\",\n    \"holder\": {\n      \"first_name\": \"Alice\",\n      \"last_name\": \"Chan\"\n    },\n    \"ext_card_id\": \"SIM-USER-003\"\n  },\n  {\n    \"plan_id\": \"PLAN-BUNDLE-LOUNGE-ESIM\",\n    \"enrol_token\": \"ASDU78123AASDGJ\",\n    \"holder\": {\n      \"first_name\": \"Bob\",\n      \"last_name\": \"Lee\",\n      \"address\": {\n        \"address_line_1\": \"88 Queen's Road\",\n        \"city\": \"Hong Kong\",\n        \"country_code\": \"HKG\"\n      }\n    },\n    \"card_type\": \"VS\",\n    \"expiry_date\": \"2027-12-31\",\n    \"ext_card_id\": \"BUNDLE-USER-002\"\n  }\n]"},"url":"{{base_url}}/v1/pass/batch-create","description":"<p>The Batch Create Passes API endpoint allows to create multiple passes in one efficient call, with each item's type determined by its plan_id (mapped in our system. This supports bulk operations for scalability, wrapping batch capabilities. Responses return job ID in success and <code>/webhook/pass/batch-create</code> webhook will pass same job ID in request. All requests will process in queue mode.</p>\n<ul>\n<li><p><strong>Use Case:</strong> Bulk issuance during promotions; call after authentication and follow with status checks for individual passes.</p>\n</li>\n<li><p><strong>Security Notes:</strong> Requires valid Bearer token from /auth/token.</p>\n</li>\n</ul>\n<h2 id=\"error-handle\">Error Handle</h2>\n<h4 id=\"request-level-errors-entire-batch-rejected\">Request-Level Errors (entire batch rejected):</h4>\n<ul>\n<li><p><strong>400:</strong><br />  <code>{ \"error\": \"invalid_request\", \"error_description\": \"Request body must be a non-empty JSON array.\", \"code\": 400 }</code></p>\n</li>\n<li><p><strong>400:</strong><br />  <code>{ \"error\": \"invalid_request\", \"error_description\": \"Batch size cannot exceed 500 items.\", \"code\": 400 }</code></p>\n</li>\n</ul>\n<h4 id=\"per-item-validation-errors-item-marked-as-failed-in-results-other-items-still-processed\">Per-Item Validation Errors (item marked as \"failed\" in results, other items still processed):</h4>\n<ul>\n<li><p><strong>400:</strong><br />  <code>{ \"error\": \"invalid_request\", \"error_description\": \"plan_id is required.\", \"code\": 400 }</code></p>\n</li>\n<li><p><strong>400:</strong><br />  <code>{ \"error\": \"invalid_request\", \"error_description\": \"enrol_token is required.\", \"code\": 400 }</code></p>\n</li>\n<li><p><strong>404:</strong><br />  <code>{ \"error\": \"invalid_plan\", \"error_description\": \"No active routing rule found for plan_id: {plan_id}\", \"code\": 404 }</code></p>\n</li>\n</ul>\n<h2 id=\"input-params\">Input Params</h2>\n<p>The request body is a JSON array (Content-Type: application/json), where each object mirrors Create Pass params. Required per-item; supports up to 500 items.</p>\n<p><strong>eSIM plan items</strong> (<code>provider_key: airalo</code>) do not require <code>card_type</code> or <code>holder.address</code>. Only <code>holder.first_name</code> and <code>holder.last_name</code> are required for record-keeping. Mixed batches (card-based and eSIM items in the same array) are supported.</p>\n<p>The parameter expiry_date default 365 days from create date. You also can configure the expiry date in passing expiry_date parameter value.</p>\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>plan_id</td>\n<td>string</td>\n<td>Yes</td>\n<td>Identify card assign to different parties and entitlements</td>\n</tr>\n<tr>\n<td>enrol_token</td>\n<td>string</td>\n<td>Yes</td>\n<td><strong>Card-based plans:</strong> Per-item PCI-tokenized card number. <strong>eSIM plans:</strong> Airalo <code>package_id</code>.</td>\n</tr>\n<tr>\n<td>holder</td>\n<td>object</td>\n<td>Yes</td>\n<td>Cardholder details (same structure as Create Pass — see holder object above).</td>\n</tr>\n<tr>\n<td>card_type</td>\n<td>string</td>\n<td>Yes (card-based plans)</td>\n<td>Card network code: <code>VS</code> (Visa), <code>MC</code> (Mastercard), <code>AX</code> (Amex), <code>DS</code> (Discover), etc. <strong>Not required for eSIM plan items.</strong></td>\n</tr>\n<tr>\n<td>expiry_date</td>\n<td>string</td>\n<td>Yes</td>\n<td>Card expiry in YYYY-MM-DD format (e.g., \"2028-12-31\"). Validated against regex pattern.  <br /><strong>If not provide, it will default use 365 days from create date.</strong></td>\n</tr>\n<tr>\n<td>ext_card_id</td>\n<td>string</td>\n<td>No</td>\n<td>External party card ID. If provide external card ID, system will use this ID for pass ID in LoyaltyLayer system. Must unique identifiter for whole program.</td>\n</tr>\n<tr>\n<td>extra_info</td>\n<td>object</td>\n<td>No</td>\n<td>Extra information and data to the account. JSON object for passing custom system data mappings (e.g., {\"BUUID\": \"ADV12344\", \"TIME\": 78213123123}). This data is stored in our middle-layer system for finance reporting and audits.</td>\n</tr>\n</tbody>\n</table>\n</div><h3 id=\"holder-object\">Holder Object</h3>\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>first_name</td>\n<td>string</td>\n<td>Yes</td>\n<td>Cardholder first name (e.g., \"John\").</td>\n</tr>\n<tr>\n<td>last_name</td>\n<td>string</td>\n<td>Yes</td>\n<td>Cardholder last name / surname (e.g., \"Doe\").</td>\n</tr>\n<tr>\n<td>address</td>\n<td>object</td>\n<td>Yes (card-based plans)</td>\n<td>Cardholder address details. See address object below. <strong>Not required for eSIM plan items.</strong></td>\n</tr>\n</tbody>\n</table>\n</div><h3 id=\"address-object-inside-holder\">Address Object (inside holder)</h3>\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>address_line_1</td>\n<td>string</td>\n<td>Yes</td>\n<td>Street address (e.g., \"123 Main St\"). Max 30 characters.</td>\n</tr>\n<tr>\n<td>address_line_2</td>\n<td>string</td>\n<td>No</td>\n<td>Street address (e.g., \"123 Main St\"). Max 30 characters.</td>\n</tr>\n<tr>\n<td>address_line_3</td>\n<td>string</td>\n<td>No</td>\n<td>Street address (e.g., \"123 Main St\"). Max 30 characters.</td>\n</tr>\n<tr>\n<td>city</td>\n<td>string</td>\n<td>Yes</td>\n<td>City name (e.g., \"Hong Kong\").</td>\n</tr>\n<tr>\n<td>country_code</td>\n<td>string</td>\n<td>Yes</td>\n<td>ISO 3166-1 alpha-3 country code (e.g., \"HKG\", \"SGP\", \"USA\").</td>\n</tr>\n</tbody>\n</table>\n</div><h2 id=\"response-params\">Response Params</h2>\n<p>Successful responses return a JSON results. Error responses include partial results where possible, with an error object.</p>\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>Always Present</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>job_id</td>\n<td>string</td>\n<td>Yes (success)</td>\n<td>Job ID for this request.</td>\n</tr>\n<tr>\n<td>result</td>\n<td>object</td>\n<td>Yes</td>\n<td>Each create request result and status.</td>\n</tr>\n<tr>\n<td>pass_id</td>\n<td>string</td>\n<td>Yes (per create)</td>\n<td>Return pass ID if no duplicate or invalid.</td>\n</tr>\n<tr>\n<td>status</td>\n<td>string</td>\n<td>Yes (per create)</td>\n<td>Status include \"pending\", \"failed\"</td>\n</tr>\n<tr>\n<td>error</td>\n<td>string</td>\n<td>No (per create)</td>\n<td>Per-item error type (if failed).</td>\n</tr>\n<tr>\n<td>error_description</td>\n<td>string</td>\n<td>No (per create)</td>\n<td>Per-item failure details.</td>\n</tr>\n</tbody>\n</table>\n</div><p><strong>eSIM plan items</strong> do not require <code>enrol_token</code>, <code>card_type</code>, or <code>holder.address</code>. <strong>Bundle plan items</strong> automatically provision multiple services per user. Supply <code>card_type</code>, <code>enrol_token</code>, and <code>holder.address</code> when the bundle includes a card-based service component. The batch item is queued and processed asynchronously via the same cron job — no API changes required.</p>\n","urlObject":{"path":["v1","pass","batch-create"],"host":["{{base_url}}"],"query":[],"variable":[]}},"response":[{"id":"55e0deab-811c-4339-84f3-7e4ecec9772e","name":"200 Success","originalRequest":{"method":"POST","header":[{"key":"Content-Type","value":"application/json","type":"text"}],"body":{"mode":"raw","raw":"[\n    {\n        \"plan_id\": \"test-priority\",\n        \"enrol_token\": \"ASDU78123AASDGJ\",\n        \"holder\": {\n            \"first_name\": \"John\",\n            \"last_name\": \"Doe\",\n            \"address\": {\n                \"address_line_1\": \"123 Main St\",\n                \"city\": \"Hong Kong\",\n                \"country_code\": \"HKG\"\n            }\n        },\n        \"card_type\": \"MC\",\n        \"expiry_date\": \"2026-12-31\",\n        \"ext_card_id\": \"12345678901234567890123456789012\",\n        \"extra_info\": {\n            \"BUUID\": \"12345678-1234-1234-1234-123456789012\",\n            \"time\": 12839128989\n        }\n    },\n    {\n        \"plan_id\": \"test-priority\",\n        \"enrol_token\": \"HHUASDADHYWQE21313\",\n        \"holder\": {\n            \"first_name\": \"Jane\",\n            \"last_name\": \"Smith\",\n            \"address\": {\n                \"address_line_1\": \"456 Oak Ave\",\n                \"city\": \"Singapore\",\n                \"country_code\": \"SGP\"\n            }\n        },\n        \"card_type\": \"VS\",\n        \"expiry_date\": \"2027-12-31\",\n        \"ext_card_id\": \"34343321233123123787277818726\",\n        \"extra_info\": {\n            \"BUUID\": \"12345678-1234-1234-1234-123456789012\",\n            \"time\": 12839128989\n        }\n    }\n]","options":{"raw":{"language":"json"}}},"url":"{{base_url}}/v1/pass/batch-create"},"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json","description":"","type":"text"}],"cookie":[],"responseTime":null,"body":"{\n    \"job_id\": \"batch-job-789\",\n    \"result\": [\n        {\n            \"pass_id\": \"12345678901234567890123456789012\",\n            \"status\": \"pending\"\n        },\n        {\n            \"pass_id\": \"34343321233123123787277818726\",\n            \"status\": \"pending\"\n        }\n    ]\n}\n"},{"id":"183e5f20-adf2-4273-a563-9bbefde35994","name":"402 External Card ID Duplicate or Invalid Copy","originalRequest":{"method":"POST","header":[{"key":"Content-Type","value":"application/json","type":"text"}],"body":{"mode":"raw","raw":"[\n    {\n        \"plan_id\": \"test-priority\",\n        \"enrol_token\": \"ASDU78123AASDGJ\",\n        \"holder\": {\n            \"first_name\": \"John\",\n            \"last_name\": \"Doe\",\n            \"address\": {\n                \"address_line_1\": \"123 Main St\",\n                \"city\": \"Hong Kong\",\n                \"country_code\": \"HKG\"\n            }\n        },\n        \"card_type\": \"VS\",\n        \"expiry_date\": \"2026-12-31\",\n        \"ext_card_id\": \"12345678901234567890123456789012\",\n        \"extra_info\": {\n            \"BUUID\": \"12345678-1234-1234-1234-123456789012\",\n            \"time\": 12839128989\n        }\n    },\n    {\n        \"plan_id\": \"test-priority\",\n        \"enrol_token\": \"HHUASDADHYWQE21313\",\n        \"holder\": {\n            \"first_name\": \"Jane\",\n            \"last_name\": \"Smith\",\n            \"address\": {\n                \"address_line_1\": \"456 Oak Ave\",\n                \"city\": \"Singapore\",\n                \"country_code\": \"SGP\"\n            }\n        },\n        \"card_type\": \"MC\",\n        \"expiry_date\": \"2027-12-31\",\n        \"ext_card_id\": \"34343321233123123787277818726\",\n        \"extra_info\": {\n            \"BUUID\": \"12345678-1234-1234-1234-123456789012\",\n            \"time\": 12839128989\n        }\n    }\n]","options":{"raw":{"language":"json"}}},"url":"{{base_url}}/v1/pass/batch-create"},"status":"Bad Request","code":400,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json","description":"","type":"text"}],"cookie":[],"responseTime":null,"body":"{\n    \"job_id\": \"batch-job-789\",\n    \"result\": [\n        {\n            \"pass_id\": \"12345678901234567890123456789012\",\n            \"status\": \"pending\"\n        },\n        {\n            \"pass_id\": \"34343321233123123787277818726\",\n            \"status\": \"failed\",\n            \"error\": \"invalid_ext_card_id\",\n            \"error_description\": \"Provided external card id is duplicate or invalid\",\n            \"code\": 402\n        }\n    ]\n}\n\n"}],"_postman_id":"bee91d29-9c89-449b-b6a4-69f83d6abca6"},{"name":"Check Pass Status","id":"2a212f47-2a28-46d7-b8a3-a3775458a3c7","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{access_token}}"}]},"isInherited":false},"method":"POST","header":[],"body":{"mode":"raw","raw":"{\n    \"pass_ids\": [\n        \"abc123\",\n        \"yasd76123\"\n    ]\n}","options":{"raw":{"language":"json"}}},"url":"{{base_url}}/v1/pass/status","description":"<p>The Check Pass Status API endpoint allows to query the current status, entitlements for a previously created passes.</p>\n<ul>\n<li><strong>Use Case:</strong> Post-creation monitoring (e.g., after Create Pass or Batch Create); verify if a pass is \"active\", \"expired\", or \"redeemed\" before user access.</li>\n</ul>\n<h2 id=\"input-params\">Input Params</h2>\n<p>The request body is JSON (Content-Type: application/json). Minimal input for querying.</p>\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>pass_ids</td>\n<td>array</td>\n<td>Yes</td>\n<td>Unique identifier for the pass to check (e.g., from Create Pass response).</td>\n</tr>\n</tbody>\n</table>\n</div><h2 id=\"response-params\">Response Params</h2>\n<p>Successful responses (200 OK) return JSON with status details. Error responses include an error object as described above.</p>\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>Always Present</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>pass_id</td>\n<td>string</td>\n<td>Yes</td>\n<td></td>\n</tr>\n<tr>\n<td>extra_info</td>\n<td>object</td>\n<td>No</td>\n<td>Extra information and data to the account. JSON object for passing custom system data mappings (e.g., {\"BUUID\": \"ADV12344\", \"TIME\": 78213123123}). This data is stored in our middle-layer system for finance reporting and audits.</td>\n</tr>\n<tr>\n<td>dmc_qr_data</td>\n<td>string</td>\n<td>No</td>\n<td>Digital QR Code for lounge access (Collinson passes). <code>null</code> for eSIM passes.</td>\n</tr>\n<tr>\n<td>status</td>\n<td>string</td>\n<td>Yes</td>\n<td>Current status (e.g., \"active\", \"expired\", \"pending\"), \"pending\" is queueing to process entitlement.</td>\n</tr>\n<tr>\n<td>expiry_date</td>\n<td>string</td>\n<td>No</td>\n<td>Pass expiry date (YYYY-MM-DD), if applicable.</td>\n</tr>\n<tr>\n<td>entitlement</td>\n<td>array</td>\n<td>Yes</td>\n<td>Array of entitlement objects. Empty array <code>[]</code> when no entitlements synced.</td>\n</tr>\n<tr>\n<td>error</td>\n<td>string</td>\n<td>Yes (on error)</td>\n<td>Error type per pass (e.g., \"external_card_id_invalid\").</td>\n</tr>\n<tr>\n<td>error_description</td>\n<td>string</td>\n<td>Yes (on error)</td>\n<td>Detailed explanation (e.g., \"Provide pass ID invalid\").</td>\n</tr>\n</tbody>\n</table>\n</div><h3 id=\"priority-pass-entitlment-object\">Priority Pass Entitlment Object</h3>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th><strong>Parameter</strong></th>\n<th><strong>Type</strong></th>\n<th>Always Present</th>\n<th><strong>Description</strong></th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>type</td>\n<td>string</td>\n<td>Yes (per item)</td>\n<td>Entitlement type (e.g., \"lounge_access\").</td>\n</tr>\n<tr>\n<td>total</td>\n<td>integer or string</td>\n<td>Yes (per item)</td>\n<td>Total entitlement quantity. <code>\"unlimited\"</code> when unlimited.</td>\n</tr>\n<tr>\n<td>used</td>\n<td>integer</td>\n<td>Yes (per item)</td>\n<td>Number of entitlements used.</td>\n</tr>\n<tr>\n<td>remaining</td>\n<td>integer or string</td>\n<td>Yes (per item)</td>\n<td>Remaining entitlements. <code>\"unlimited\"</code> when unlimited.</td>\n</tr>\n</tbody>\n</table>\n</div><h3 id=\"esim-entitlement-object\">eSim Entitlement Object</h3>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th><strong>Parameter</strong></th>\n<th><strong>Type</strong></th>\n<th>Always Present</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>package_name</td>\n<td>string</td>\n<td>Yes</td>\n<td>Plan name (e.g. \"Global 7 Days 1GB\")</td>\n</tr>\n<tr>\n<td>data_remaining_mb</td>\n<td>string</td>\n<td>Yes</td>\n<td>Remaining data in MB (or null if unlimited)</td>\n</tr>\n<tr>\n<td>expiry_date</td>\n<td>date</td>\n<td>Yes</td>\n<td>Validity end date (YYYY-MM-DD)</td>\n</tr>\n<tr>\n<td>activation_code</td>\n<td>string</td>\n<td>Yes</td>\n<td>Activation code for manual installation</td>\n</tr>\n<tr>\n<td>install_qr_data</td>\n<td>string</td>\n<td>Yes</td>\n<td>Data for generating install QR code.</td>\n</tr>\n</tbody>\n</table>\n</div>","urlObject":{"path":["v1","pass","status"],"host":["{{base_url}}"],"query":[],"variable":[]}},"response":[{"id":"5674edfa-de4b-4efe-a174-c5268f3ea30c","name":"200 Success (Bundle Pass)","originalRequest":{"method":"POST","header":[{"key":"Content-Type","value":"application/json","type":"text"}],"body":{"mode":"raw","raw":"{\n    \"pass_ids\": [\n        \"BUNDLE-USER-001\"\n    ]\n}","options":{"raw":{"language":"json"}}},"url":"{{base_url}}/v1/pass/status"},"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json","type":"text"}],"cookie":[],"responseTime":null,"body":"[\n  {\n    \"pass_id\": \"BUNDLE-USER-001\",\n    \"type\": \"bundle\",\n    \"status\": \"active\",\n    \"expiry_date\": \"2027-12-31\",\n    \"extra_info\": null,\n    \"entitlement\": [\n      {\n        \"entitlement_id\": \"ent-lounge-001\",\n        \"component\": \"lounge_access\",\n        \"type\": \"lounge_access\",\n        \"status\": \"active\",\n        \"quantity\": 2,\n        \"unit\": \"visit\",\n        \"used\": 1,\n        \"remaining\": 1,\n        \"dmc_qr_data\": \"PP/070326/HKTCLLSG26/12345678\",\n        \"expiry\": \"2027-12-31\"\n      },\n      {\n        \"entitlement_id\": \"ent-esim-002\",\n        \"component\": \"global_esim_1gb\",\n        \"type\": \"esim\",\n        \"status\": \"active\",\n        \"quantity\": 1024,\n        \"unit\": \"MB\",\n        \"used\": 256,\n        \"remaining\": 768,\n        \"iccid\": \"8944501902198304826\",\n        \"qr_code_data\": \"LPA:1$sm-v4-057-a-gtm.pr.go-esim.com$OC_SAMPLE_ACTIVATION_CODE\",\n        \"expiry\": \"2027-06-07\"\n      }\n    ],\n    \"services\": [\n      {\n        \"entitlement_id\": \"ent-lounge-001\",\n        \"component\": \"lounge_access\",\n        \"type\": \"lounge_access\",\n        \"status\": \"active\",\n        \"quantity\": 2,\n        \"unit\": \"visit\",\n        \"used\": 1,\n        \"remaining\": 1,\n        \"dmc_qr_data\": \"PP/070326/HKTCLLSG26/12345678\",\n        \"expiry\": \"2027-12-31\"\n      },\n      {\n        \"entitlement_id\": \"ent-esim-002\",\n        \"component\": \"global_esim_1gb\",\n        \"type\": \"esim\",\n        \"status\": \"active\",\n        \"quantity\": 1024,\n        \"unit\": \"MB\",\n        \"used\": 256,\n        \"remaining\": 768,\n        \"iccid\": \"8944501902198304826\",\n        \"qr_code_data\": \"LPA:1$sm-v4-057-a-gtm.pr.go-esim.com$OC_SAMPLE_ACTIVATION_CODE\",\n        \"expiry\": \"2027-06-07\"\n      }\n    ]\n  }\n]"},{"id":"8f909a44-2cde-44bb-a130-8f8d2ef8f2ca","name":"200 Success","originalRequest":{"method":"POST","header":[{"key":"Content-Type","value":"application/json","type":"text"}],"body":{"mode":"raw","raw":"{\n    \"pass_ids\": [\n        \"abc123\",\n        \"yasd76123\"\n    ]\n}","options":{"raw":{"language":"json"}}},"url":"{{base_url}}/v1/pass/status"},"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json","description":"","type":"text"}],"cookie":[],"responseTime":null,"body":"[\n    {\n        \"pass_id\": \"abc123\",\n        \"extra_info\": {\n            \"BUUID\": \"ASDHADS1231\",\n            \"time\": 12321312312\n        },\n        \"dmc_qr_data\": \"QR_STRING_FOR_PRIORITY\",\n        \"status\": \"active\",\n        \"expiry_date\": \"2026-12-31\",\n        \"entitlement\": [\n            {\n                \"type\": \"lounge_access\",\n                \"total\": 10,\n                \"used\": 3,\n                \"remaining\": 7\n            }\n        ]\n    },\n    {\n        \"pass_id\": \"yasd76123\",\n        \"extra_info\": {\n            \"BUUID\": \"ASDHADS1231\",\n            \"time\": 123545454\n        },\n        \"dmc_qr_data\": \"QR_STRING_FOR_PRIORITY\",\n        \"status\": \"active\",\n        \"expiry_date\": \"2027-11-30\",\n        \"entitlement\": [\n            {\n                \"type\": \"lounge_access\",\n                \"total\": \"unlimited\",\n                \"used\": 10,\n                \"remaining\": \"unlimited\"\n            }\n        ]\n    }\n]"},{"id":"e6fb64ae-2380-4b5d-8649-65c9a965130a","name":"200 Success (Multiple Entitlements)","originalRequest":{"method":"POST","header":[{"key":"Content-Type","value":"application/json","type":"text"}],"body":{"mode":"raw","raw":"{\n    \"pass_ids\": [\n        \"abc123\",\n        \"yasd76123\"\n    ]\n}","options":{"raw":{"language":"json"}}},"url":"{{base_url}}/v1/pass/status"},"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json","description":"","type":"text"}],"cookie":[],"responseTime":null,"body":"[\n    {\n        \"pass_id\": \"abc123\",\n        \"extra_info\": {\n            \"BUUID\": \"ASDHADS1231\",\n            \"time\": 12321312312\n        },\n        \"dmc_qr_data\": \"QR_STRING_FOR_PRIORITY\",\n        \"status\": \"active\",\n        \"expiry_date\": \"2026-12-31\",\n        \"entitlement\": [\n            {\n                \"type\": \"lounge_access\",\n                \"total\": 10,\n                \"used\": 3,\n                \"remaining\": 7\n            },\n            {\n                \"type\": \"esim\",\n                \"package_name\": \"Global 7 Days 1GB\",\n                \"data_remaining_mb\": 1024,\n                \"valid_until\": \"2026-12-31\",\n                \"activation_code\": \"ABCD-EFGH-IJKL\",\n                \"install_qr_data\": \"ESIM_INSTALL_QR_DATA\"\n            }\n        ]\n    },\n    {\n        \"pass_id\": \"yasd76123\",\n        \"extra_info\": {\n            \"BUUID\": \"ASDHADS1231\",\n            \"time\": 123545454\n        },\n        \"dmc_qr_data\": \"QR_STRING_FOR_PRIORITY\",\n        \"status\": \"active\",\n        \"expiry_date\": \"2027-11-30\",\n        \"entitlement\": [\n            {\n                \"type\": \"lounge_access\",\n                \"total\": \"unlimited\",\n                \"used\": 10,\n                \"remaining\": \"unlimited\"\n            }\n        ]\n    }\n]"},{"id":"76b65341-4c0f-41ca-99e0-897f38e45dfb","name":"402 Pass ID Invalid","originalRequest":{"method":"POST","header":[{"key":"Content-Type","value":"application/json","type":"text"}],"body":{"mode":"raw","raw":"{\n    \"pass_ids\": [\n        \"abc123\",\n        \"yasd76123\"\n    ]\n}","options":{"raw":{"language":"json"}}},"url":"{{base_url}}/v1/pass/status"},"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json","description":"","type":"text"}],"cookie":[],"responseTime":null,"body":"[\n    {\n        \"pass_id\": \"abc123\",\n        \"extra_info\": {\n            \"BUUID\": \"ADC213123\",\n            \"time\": 1231231231\n        },\n        \"dmc_qr_data\": \"QR_STRING_FOR_PRIORITY\",\n        \"status\": \"active\",\n        \"expiry_date\": \"2026-12-31\",\n        \"entitlement\": [\n            {\n                \"type\": \"lounge_access\",\n                \"total\": \"unlimited\",\n                \"used\": 5,\n                \"remaining\": \"unlimited\"\n            }\n        ]\n    },\n    {\n        \"pass_id\": \"yasd76123\",\n        \"error\": \"external_card_id_invalid\",\n        \"error_description\": \"Provide pass ID invalid\"\n    }\n]"}],"_postman_id":"2a212f47-2a28-46d7-b8a3-a3775458a3c7"},{"name":"Update Pass Details","id":"3cb6b56a-5759-470d-9555-691c104c11f8","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{access_token}}"}]},"isInherited":false},"method":"POST","header":[{"key":"Content-Type","value":"application/json","type":"text"}],"body":{"mode":"raw","raw":"{\n    \"pass_id\": \"ASDY12313\",\n    \"expiry_date\": \"2028-01-30\"\n}"},"url":"{{base_url}}/v1/pass/update","description":"<p>The Update Pass Details API endpoint enables to perform partial updates to an existing pass, such as changing email, card expiry, or phone, without recreating the pass.</p>\n<ul>\n<li><strong>Use Case:</strong> Handle cardholder changes (e.g., expiry renewal or email update) post-creation; use after querying status to verify current details.</li>\n</ul>\n<h2 id=\"input-params\">Input Params</h2>\n<p>The request body is JSON (Content-Type: application/json). Include pass_id and only the fields to update (partial).</p>\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>pass_id</td>\n<td>string</td>\n<td>Yes</td>\n<td>Unique identifier of the pass to update (e.g., from Create Pass).</td>\n</tr>\n<tr>\n<td>expiry_date</td>\n<td>string</td>\n<td>No</td>\n<td>Updated card expiry in YYYY-MM-DD format (e.g., 2028-12-31).</td>\n</tr>\n<tr>\n<td>extra_info</td>\n<td>object</td>\n<td>No</td>\n<td>Extra information and data to the account. JSON object for passing custom system data mappings (e.g., {\"BUUID\": \"ADV12344\", \"TIME\": 78213123123}). This data is stored in our middle-layer system for finance reporting and audits.</td>\n</tr>\n</tbody>\n</table>\n</div><h2 id=\"response-params\">Response Params</h2>\n<p>Successful responses (200 OK) return JSON with the updated pass details. Error responses include an error object as described above.</p>\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>Always Present</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>pass_id</td>\n<td>string</td>\n<td>Yes</td>\n<td>The updated pass ID (unchanged).</td>\n</tr>\n<tr>\n<td>status</td>\n<td>string</td>\n<td>Yes</td>\n<td>Updated status (e.g., \"updated\").</td>\n</tr>\n<tr>\n<td>expiry_date</td>\n<td>string</td>\n<td>No</td>\n<td>Updated expiry, if changed.</td>\n</tr>\n<tr>\n<td>extra_info</td>\n<td>object</td>\n<td>No</td>\n<td>Extra information and data to the account. JSON object for passing custom system data mappings (e.g., {\"BUUID\": \"ADV12344\", \"TIME\": 78213123123}). This data is stored in our middle-layer system for finance reporting and audits.</td>\n</tr>\n<tr>\n<td>error_description</td>\n<td>string</td>\n<td>Yes (on error)</td>\n<td>Detailed explanation (e.g., \"Invalid expiry_date\").</td>\n</tr>\n<tr>\n<td>code</td>\n<td>integer</td>\n<td>Yes (on error)</td>\n<td>HTTP status code (e.g., 400).</td>\n</tr>\n</tbody>\n</table>\n</div>","urlObject":{"path":["v1","pass","update"],"host":["{{base_url}}"],"query":[],"variable":[]}},"response":[{"id":"ddb3bc0a-3073-4de6-9540-65b6425eb57f","name":"200 Success","originalRequest":{"method":"POST","header":[{"key":"Content-Type","value":"application/json","type":"text"}],"body":{"mode":"raw","raw":"{\n  \"pass_id\": \"abc123sadadasdae2131\",\n  \"expiry_date\": \"2028-01-30\",\n  \"extra_info\": {\n    \"BUUID\": \"ASDH12738123\",\n    \"time\": 12312312312\n  }\n\n}","options":{"raw":{"language":"json"}}},"url":"{{base_url}}/v1/pass/update"},"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json","description":"","type":"text"}],"cookie":[],"responseTime":null,"body":"{\n  \"pass_id\": \"abc123sadadasdae2131\",\n  \"status\": \"updated\",\n  \"expiry_date\": \"2028-01-30\",\n  \"extra_info\": {\n    \"BUUID\": \"ASDH12738123\",\n    \"time\": 12312312312\n  }\n}"}],"_postman_id":"3cb6b56a-5759-470d-9555-691c104c11f8"},{"name":"Cancel Pass","id":"0a140afe-f369-4d80-9540-a3f5cca31b48","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{access_token}}"}]},"isInherited":false},"method":"POST","header":[{"key":"Content-Type","value":"application/json","type":"text"}],"body":{"mode":"raw","raw":"{\n  \"pass_id\": \"abc123\",\n  \"reason\": \"User request\"\n}"},"url":"{{base_url}}/v1/passes/cancel","description":"<p>The Cancel Pass API endpoint allows to cancel an existing pass.</p>\n<ul>\n<li><p><strong>Use Case:</strong> Revoke passes due to user request, fraud, or expiry; use after status check to confirm eligibility (e.g., not already redeemed).</p>\n</li>\n<li><p><strong>eSIM Note:</strong> eSIM cancellation is <strong>not supported</strong>. Calling this endpoint for an eSIM pass returns <code>400 not_supported</code>. The eSIM remains active; users must manage cancellation from their device settings.</p>\n</li>\n</ul>\n<h2 id=\"input-params\">Input Params</h2>\n<p>The request body is JSON (Content-Type: application/json). pass_id required; reason optional for logging.</p>\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>pass_id</td>\n<td>string</td>\n<td>Yes</td>\n<td>Unique identifier of the pass to cancel (e.g., from Create Pass).</td>\n</tr>\n<tr>\n<td>reason</td>\n<td>string</td>\n<td>No</td>\n<td>Optional reason for cancellation (e.g., \"User request\"; for auditing and transaction logs).</td>\n</tr>\n</tbody>\n</table>\n</div><h2 id=\"response-params\">Response Params</h2>\n<p>Successful responses (200 OK) return JSON with cancellation confirmation. Error responses include an error object as described above.</p>\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>Always Present</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>status</td>\n<td>string</td>\n<td>Yes (on success)</td>\n<td>Confirmation status (e.g., \"cancelled\").</td>\n</tr>\n<tr>\n<td>pass_id</td>\n<td>string</td>\n<td>Yes (on success)</td>\n<td>The cancelled pass ID.</td>\n</tr>\n<tr>\n<td>error</td>\n<td>string</td>\n<td>Yes (on error)</td>\n<td>Error code (e.g., \"already_cancelled\", \"not_supported\").</td>\n</tr>\n<tr>\n<td>error_description</td>\n<td>string</td>\n<td>Yes (on error)</td>\n<td>Detailed explanation (e.g., \"Pass already redeemed\").</td>\n</tr>\n<tr>\n<td>code</td>\n<td>integer</td>\n<td>Yes (on error)</td>\n<td>HTTP status code (e.g., 400, 403, 409).</td>\n</tr>\n</tbody>\n</table>\n</div><h2 id=\"esim-passes\">eSIM Passes</h2>\n<p>eSIM cancellation is <strong>not supported</strong>. Calling this endpoint on an eSIM pass returns a <code>400 not_supported</code> error and does not change the pass status.</p>\n<ul>\n<li><strong>400 eSIM cancel not supported:</strong><br />  <code>{ \"error\": \"not_supported\", \"error_description\": \"Airalo eSIM cancellation is not supported.\", \"code\": 400 }</code></li>\n</ul>\n<blockquote>\n<p><strong>Bundle passes:</strong> Cancel is not supported directly on a bundle parent pass. Each child service must be cancelled individually (future feature). Returns <code>400 unsupported_provider_operation</code> if attempted.</p>\n</blockquote>\n","urlObject":{"path":["v1","passes","cancel"],"host":["{{base_url}}"],"query":[],"variable":[]}},"response":[{"id":"f9976ff7-da12-4cab-823f-5183c19f1afa","name":"Cancel Pass","originalRequest":{"method":"POST","header":[{"key":"Content-Type","value":"application/json","type":"text"}],"body":{"mode":"raw","raw":"{\n  \"pass_id\": \"abc123\",\n  \"reason\": \"User request\"\n}","options":{"raw":{"language":"json"}}},"url":"{{base_url}}/v1/passes/cancel"},"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json","description":"","type":"text"}],"cookie":[{"expires":"Invalid Date","domain":"","path":""}],"responseTime":null,"body":"{\n  \"status\": \"cancelled\",\n  \"pass_id\": \"abc123\"\n}"},{"id":"81b787e9-42a8-4216-8cb7-023b4f9a8824","name":"400 eSIM Cancel Not Supported","originalRequest":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"},{"key":"Authorization","value":"Bearer {{access_token}}"}],"body":{"mode":"raw","raw":"{\n  \"pass_id\": \"sim-user-001\",\n  \"reason\": \"User request\"\n}"},"url":"{{base_url}}/v1/pass/cancel"},"status":"Bad Request","code":400,"_postman_previewlanguage":"Text","header":[{"key":"Content-Type","value":"application/json"}],"cookie":[],"responseTime":null,"body":"{\n  \"error\": \"not_supported\",\n  \"error_description\": \"Airalo eSIM cancellation is not supported.\",\n  \"code\": 400\n}"}],"_postman_id":"0a140afe-f369-4d80-9540-a3f5cca31b48"},{"name":"Query Transactions","id":"71c1ed63-906f-4071-9f41-43a4e7d6d102","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{access_token}}"}]},"isInherited":false},"method":"POST","header":[],"body":{"mode":"raw","raw":"{\n    \"start_date\": \"\",\n    \"end_date\": \"\",\n    \"pass_ids\": [\n        \"asdb12312\",\n        \"bdfb1231\"\n    ],\n    \"offset\": 0,\n    \"limit\": 100\n}","options":{"raw":{"language":"json"}}},"url":"{{base_url}}/v1/pass/transactions","description":"<p>The Query Transactions API endpoint enables client to fetch lounge visit and transaction history for cardholders within a specified date range. It supports querying by a single pass_id or aggregating across all cards linked to your client account. Transactions include details like visit dates, lounges, guests, and costs, abstracted from Collinson's backends (e.g., Priority Pass transaction history with dates/guests/transactions, or LoungeKey status-derived usage). This facilitates finance reporting, audits, and loyalty monitoring, aligning with Collinson's emphasis on enriching cardholders through rewards (e.g., tracking high-value benefits like lounge access).</p>\n<ul>\n<li><p><strong>Key Features:</strong> Flexible filtering (single card or all); pagination support; returns aggregated summaries if requested.</p>\n</li>\n<li><p><strong>Use Case:</strong> Retrieve period-based reports for billing, compliance, or user insights; e.g., all December visits across cards.</p>\n</li>\n</ul>\n<h2 id=\"input-params\">Input Params</h2>\n<p>The request body is JSON (Content-Type: application/json). Dates required; card_id optional for single vs. all.</p>\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>start_date</td>\n<td>string</td>\n<td>Yes</td>\n<td>Start of period (YYYY-MM-DD; e.g., \"2025-01-01\").</td>\n</tr>\n<tr>\n<td>end_date</td>\n<td>string</td>\n<td>Yes</td>\n<td>End of period (YYYY-MM-DD; e.g., \"2025-12-31\").</td>\n</tr>\n<tr>\n<td>pass_ids</td>\n<td>array (string)</td>\n<td>No</td>\n<td>Optional array of pass IDs for multi-card query (or single as [\"id\"]); omit for all cards under client.</td>\n</tr>\n<tr>\n<td>offset</td>\n<td>integer</td>\n<td>No</td>\n<td>Optional starting offset for pagination (default 0).</td>\n</tr>\n<tr>\n<td>limit</td>\n<td>integer</td>\n<td>No</td>\n<td>Optional results per page (default 50, max 500).</td>\n</tr>\n</tbody>\n</table>\n</div><h2 id=\"response-params\">Response Params</h2>\n<p>Successful responses (200 OK) return JSON with transaction array. Error responses as above.</p>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th></th>\n<th>Type</th>\n<th>Always Present</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>transactions</td>\n<td>array</td>\n<td>Yes</td>\n<td>Array of transaction objects (e.g., visits with details).</td>\n</tr>\n<tr>\n<td>- date</td>\n<td>string</td>\n<td>Yes (per tx)</td>\n<td>Visit date (YYYY-MM-DD).</td>\n</tr>\n<tr>\n<td>- type</td>\n<td>string</td>\n<td>Yes (per tx)</td>\n<td>Transaction type (e.g. lounge)</td>\n</tr>\n<tr>\n<td>- lounge_id</td>\n<td>string</td>\n<td>Yes (per tx)</td>\n<td>Lounge identifier.</td>\n</tr>\n<tr>\n<td>- lounge_name</td>\n<td>string</td>\n<td>Yes (per tx)</td>\n<td>Lounge name.</td>\n</tr>\n<tr>\n<td>- guests</td>\n<td>integer</td>\n<td>Yes (per tx)</td>\n<td>Number of guests.</td>\n</tr>\n<tr>\n<td>- cost</td>\n<td>number</td>\n<td>No</td>\n<td>Transaction cost.</td>\n</tr>\n<tr>\n<td>- transaction_id</td>\n<td>string</td>\n<td>Yes (per tx)</td>\n<td>Unique ID.</td>\n</tr>\n<tr>\n<td>- pass_id</td>\n<td>string</td>\n<td>No</td>\n<td>Associated pass_id (included for multi-card queries).</td>\n</tr>\n<tr>\n<td>- extra_info</td>\n<td>object</td>\n<td>No</td>\n<td>Extra information and data to the account. JSON object for passing custom system data mappings (e.g., {\"BUUID\": \"ADV12344\", \"TIME\": 78213123123}). This data is stored in our middle-layer system for finance reporting and audits.</td>\n</tr>\n<tr>\n<td>total_count</td>\n<td>integer</td>\n<td>Yes</td>\n<td>Total transactions in period.</td>\n</tr>\n<tr>\n<td>offset</td>\n<td>integer</td>\n<td>Yes</td>\n<td>Current offset.</td>\n</tr>\n<tr>\n<td>next_offset</td>\n<td>integer</td>\n<td>No</td>\n<td>Next offset for pagination (null if end).</td>\n</tr>\n<tr>\n<td>error</td>\n<td>string</td>\n<td>Yes (on error)</td>\n<td>Error type.</td>\n</tr>\n<tr>\n<td>error_description</td>\n<td>string</td>\n<td>Yes (on error)</td>\n<td>Details.</td>\n</tr>\n<tr>\n<td>code</td>\n<td>integer</td>\n<td>Yes (on error)</td>\n<td>HTTP code.</td>\n</tr>\n</tbody>\n</table>\n</div>","urlObject":{"path":["v1","pass","transactions"],"host":["{{base_url}}"],"query":[],"variable":[]}},"response":[{"id":"adafd002-47d5-4aca-8d0f-7e026382928b","name":"Success (multi-card)","originalRequest":{"method":"POST","header":[],"body":{"mode":"raw","raw":"{\n    \"start_date\": \"2025-01-01\",\n    \"end_date\": \"2025-12-31\",\n    \"pass_ids\": [\n        \"asdsa12313\",\n        \"ajjjhhj12778s\"\n    ],\n    \"offset\": 0,\n    \"limit\": 100\n}","options":{"raw":{"language":"json"}}},"url":"{{base_url}}/v1/pass/transactions"},"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json","description":"","type":"text"}],"cookie":[],"responseTime":null,"body":"{\n  \"transactions\": [\n    {\n        \"date\": \"2025-11-01\",\n        \"lounge_id\": \"LAX001\",\n        \"lounge_name\": \"LAX Lounge\",\n        \"guests\": 1,\n        \"cost\": 80,\n        \"transaction_id\": \"tx123\",\n        \"pass_id\": \"tokenized_pan_123\",\n        \"extra_info\": {\n            \"BUUID\": \"ASDHADS1231\",\n            \"time\": 12321312312\n        }\n    },\n    {\n        \"date\": \"2025-12-05\",\n        \"lounge_id\": \"JFK002\",\n        \"lounge_name\": \"JFK Lounge\",\n        \"guests\": 0,\n        \"cost\": 40,\n        \"transaction_id\": \"tx456\",\n        \"pass_id\": \"tokenized_pan_456\",\n        \"extra_info\": {\n            \"BUUID\": \"ASDHADS1231\",\n            \"time\": 12321312312\n        }\n    }\n  ],\n  \"total_count\": 120,\n  \"offset\": 0,\n  \"next_offset\": 50\n}"},{"id":"f2dc53b1-d6a1-4148-9873-69b156c69273","name":"Success (all-card)","originalRequest":{"method":"POST","header":[],"body":{"mode":"raw","raw":"{\n    \"start_date\": \"2025-01-01\",\n    \"end_date\": \"2025-12-31\",\n    \"offset\": 0,\n    \"limit\": 100\n}","options":{"raw":{"language":"json"}}},"url":"{{base_url}}/v1/pass/transactions"},"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json","description":"","type":"text"}],"cookie":[],"responseTime":null,"body":"{\n  \"transactions\": [\n    {\n        \"date\": \"2025-11-01\",\n        \"lounge_id\": \"LAX001\",\n        \"lounge_name\": \"LAX Lounge\",\n        \"guests\": 1,\n        \"cost\": 80,\n        \"transaction_id\": \"tx123\",\n        \"pass_id\": \"ouasd78123\",\n        \"extra_info\": {\n            \"BUUID\": \"ASDHADS1231\",\n            \"time\": 12321312312\n        }\n    },\n    {\n        \"date\": \"2025-12-05\",\n        \"lounge_id\": \"JFK002\",\n        \"lounge_name\": \"JFK Lounge\",\n        \"guests\": 0,\n        \"cost\": 40,\n        \"transaction_id\": \"tx456\",\n        \"pass_id\": \"hyasd7812321\",\n        \"extra_info\": {\n            \"BUUID\": \"ASDHADS1231\",\n            \"time\": 12321312312\n        }\n    }\n  ],\n  \"total_count\": 150,\n  \"offset\": 0,\n  \"next_offset\": 50\n}"}],"_postman_id":"71c1ed63-906f-4071-9f41-43a4e7d6d102"},{"name":"Top Up Pass","id":"6ff186c9-40e8-4881-bc9b-62372f6d6e3c","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{access_token}}"}]},"isInherited":false},"method":"POST","header":[{"key":"Content-Type","value":"application/json","type":"text"}],"body":{"mode":"raw","raw":"{\n  \"pass_id\": \"{{pass_id}}\",\n  \"plan_id\": \"{{plan_id}}\",\n  \"enrol_token\": \"ASDU78123AASDGJ\",\n  \"card_type\": \"MC\",\n  \"holder\": {\n    \"first_name\": \"John\",\n    \"last_name\": \"Doe\",\n    \"address\": {\n      \"address_line_1\": \"123 Main St\",\n      \"city\": \"Hong Kong\",\n      \"country_code\": \"HKG\"\n    }\n  }\n}"},"url":"{{base_url}}/pass/topup","description":"<p>The Top Up Pass API endpoint enables renewal of an existing pass by cancelling the current provider membership and re-enrolling with a new plan and token. The same pass_id is preserved — all transaction history remains under the same pass account.</p>\n<ul>\n<li><strong>Security Notes:</strong> Requires valid Bearer token from /auth/token.</li>\n</ul>\n<h2 id=\"how-it-works\">How It Works</h2>\n<p>The topup behaviour depends on the provider determined by the new <code>plan_id</code>:</p>\n<h3 id=\"collinson-priority-pass--loungekey\">Collinson (Priority Pass / LoungeKey)</h3>\n<ol>\n<li><p>Syncs transaction history from current membership (best-effort)</p>\n</li>\n<li><p>Archives old provider membership ID to <code>pass_provider_history</code></p>\n</li>\n<li><p>Cancels current membership at the provider</p>\n</li>\n<li><p>Re-enrols with the new plan_id and enrol_token</p>\n</li>\n<li><p>Updates existing pass record with new provider data</p>\n</li>\n</ol>\n<p><strong>Note:</strong> If cancel succeeds but re-enrolment fails, the pass is marked <code>cancelled</code> (old membership already terminated).</p>\n<h3 id=\"airalo-esim\">Airalo (eSIM)</h3>\n<ol>\n<li><p>Archives the current ICCID to <code>pass_provider_history</code> (action: <code>topup_esim</code>)</p>\n</li>\n<li><p><strong>Skips cancel</strong> — the existing ICCID is preserved</p>\n</li>\n<li><p>Calls the Airalo top-up API to add data/days to the same SIM card</p>\n</li>\n<li><p>Updates expiry and plan details on the existing pass record</p>\n</li>\n</ol>\n<p>The <code>pass_id</code> and <code>iccid</code> never change on eSIM topup. Each topup increments <code>topup_count</code>.</p>\n<h2 id=\"error-handle\">Error Handle</h2>\n<h4 id=\"success\">Success:</h4>\n<ul>\n<li><strong>200 pass topped up:</strong><br />  <code>{ \"pass_id\": \"abc-123\", \"type\": \"priority\", \"status\": \"active\", \"dmc_qr_data\": \"PP/260326/NEWQR\", \"topup_count\": 1, \"expiry\": \"2027-03-26\" }</code></li>\n</ul>\n<h4 id=\"errors\">Errors:</h4>\n<ul>\n<li><p><strong>400 invalid_request — missing required fields:</strong><br />  <code>{ \"error\": \"invalid_request\", \"error_description\": \"pass_id is required.\", \"code\": 400 }</code></p>\n</li>\n<li><p><strong>400 invalid_state — pass has no provider membership:</strong><br />  <code>{ \"error\": \"invalid_state\", \"error_description\": \"Pass has no provider membership to cancel.\", \"code\": 400 }</code></p>\n</li>\n<li><p><strong>404 pass_not_found:</strong><br />  <code>{ \"error\": \"pass_not_found\", \"error_description\": \"Pass not found: abc-123\", \"code\": 404 }</code></p>\n</li>\n<li><p><strong>404 invalid_plan — no routing rule for plan_id:</strong><br />  <code>{ \"error\": \"invalid_plan\", \"error_description\": \"No active routing rule found for plan_id: XYZ\", \"code\": 404 }</code></p>\n</li>\n<li><p><strong>409 already_cancelled:</strong><br />  <code>{ \"error\": \"already_cancelled\", \"error_description\": \"Pass is already cancelled.\", \"code\": 409 }</code></p>\n</li>\n<li><p><strong>4xx/5xx provider errors — cancel or enrol failure forwarded from provider:</strong><br />  <code>{ \"error\": \"cancel_forbidden\", \"error_description\": \"Not allowed in UAT\", \"code\": 403 }</code></p>\n</li>\n</ul>\n<p><strong>Note:</strong> If the cancel succeeds but re-enrolment fails, the pass is marked as <code>cancelled</code> because the old membership has already been terminated at the provider.</p>\n<h2 id=\"input-params\">Input Params</h2>\n<p>The request body is JSON (Content-Type: application/json).</p>\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>pass_id</td>\n<td>string</td>\n<td>Yes</td>\n<td>The existing pass ID to top up. Must be an active pass with a provider membership.</td>\n</tr>\n<tr>\n<td>plan_id</td>\n<td>string</td>\n<td>Yes</td>\n<td>The new plan to enrol into. Determines provider routing and entitlements.</td>\n</tr>\n<tr>\n<td>enrol_token</td>\n<td>string</td>\n<td>Conditional</td>\n<td>PCI-tokenized card number for the new enrolment. <strong>Required for card-based (lounge) plans only. Not required for eSIM plans</strong> — the Airalo package is determined by the plan configuration at the gateway level.</td>\n</tr>\n<tr>\n<td>card_type</td>\n<td>string</td>\n<td>Yes (card-based plans)</td>\n<td>Card type code (e.g., \"MC\", \"VI\", \"AX\"). <strong>Not required for eSIM plans.</strong></td>\n</tr>\n<tr>\n<td>holder</td>\n<td>object</td>\n<td>Yes</td>\n<td>Cardholder details (see below).</td>\n</tr>\n<tr>\n<td>holder.first_name</td>\n<td>string</td>\n<td>Yes</td>\n<td>Cardholder first name.</td>\n</tr>\n<tr>\n<td>holder.last_name</td>\n<td>string</td>\n<td>Yes</td>\n<td>Cardholder last name.</td>\n</tr>\n<tr>\n<td>holder.address</td>\n<td>object</td>\n<td>Yes (card-based plans)</td>\n<td>Cardholder address (see below). <strong>Not required for eSIM plans.</strong></td>\n</tr>\n<tr>\n<td>holder.address.address_line_1</td>\n<td>string</td>\n<td>Yes (card-based plans)</td>\n<td>Address line 1 (max 30 characters). <strong>Not required for eSIM plans.</strong></td>\n</tr>\n<tr>\n<td>holder.address.address_line_2</td>\n<td>string</td>\n<td>No</td>\n<td>Address line 2 (max 30 characters).</td>\n</tr>\n<tr>\n<td>holder.address.address_line_3</td>\n<td>string</td>\n<td>No</td>\n<td>Address line 3 (max 30 characters).</td>\n</tr>\n<tr>\n<td>holder.address.city</td>\n<td>string</td>\n<td>Yes</td>\n<td>City name.</td>\n</tr>\n<tr>\n<td>holder.address.country_code</td>\n<td>string</td>\n<td>Yes</td>\n<td>ISO country code (e.g., \"HKG\", \"USA\").</td>\n</tr>\n<tr>\n<td>expiry_date</td>\n<td>string</td>\n<td>No</td>\n<td>New expiry in YYYY-MM-DD format. <strong>Defaults to 365 days from topup date.</strong></td>\n</tr>\n<tr>\n<td>extra_info</td>\n<td>object</td>\n<td>No</td>\n<td>Extra information stored for reporting/audits (e.g., {\"BUUID\": \"COBANK01\"}).</td>\n</tr>\n</tbody>\n</table>\n</div><h2 id=\"response-params\">Response Params</h2>\n<p>Successful responses (200 OK) return JSON with updated pass details.</p>\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>Always Present</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>pass_id</td>\n<td>string</td>\n<td>Yes</td>\n<td>Same pass_id as input (unchanged).</td>\n</tr>\n<tr>\n<td>type</td>\n<td>string</td>\n<td>Yes</td>\n<td>Pass type: <code>priority</code>, <code>loungekey</code>, or <code>esim</code>.</td>\n</tr>\n<tr>\n<td>status</td>\n<td>string</td>\n<td>Yes</td>\n<td>Always \"active\" on success.</td>\n</tr>\n<tr>\n<td>dmc_qr_data</td>\n<td>string</td>\n<td>No</td>\n<td>New DMC QR barcode string (Collinson passes only). <code>null</code> for eSIM.</td>\n</tr>\n<tr>\n<td>barcode_string</td>\n<td>string</td>\n<td>No</td>\n<td>Barcode string (same as dmc_qr_data for Priority Pass).</td>\n</tr>\n<tr>\n<td>topup_count</td>\n<td>integer</td>\n<td>Yes</td>\n<td>Number of topups performed on this pass.</td>\n</tr>\n<tr>\n<td>expiry</td>\n<td>string</td>\n<td>Yes</td>\n<td>New expiry date in YYYY-MM-DD format.</td>\n</tr>\n<tr>\n<td>iccid</td>\n<td>string</td>\n<td>No</td>\n<td><strong>eSIM only.</strong> Unchanged ICCID of the SIM card that received the top-up.</td>\n</tr>\n<tr>\n<td>esim_data</td>\n<td>object</td>\n<td>No</td>\n<td><strong>eSIM only.</strong> Present when <code>type</code> is <code>esim</code>. Contains eSIM provisioning details.</td>\n</tr>\n</tbody>\n</table>\n</div><blockquote>\n<p><strong>Bundle passes:</strong> Topup is not supported directly on a bundle parent pass. Each child service must be topped up individually (future feature). Returns <code>400 unsupported_provider_operation</code> if attempted. </p>\n</blockquote>\n<h3 id=\"esim_data-object\">esim_data Object</h3>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th><strong>Parameter</strong></th>\n<th><strong>Type</strong></th>\n<th>Always Present</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>package_name</td>\n<td>string</td>\n<td>Yes</td>\n<td>Plan name (e.g. \"Global 7 Days 1GB\")</td>\n</tr>\n<tr>\n<td>data_remaining_mb</td>\n<td>string</td>\n<td>Yes</td>\n<td>Remaining data in MB (or null if unlimited)</td>\n</tr>\n<tr>\n<td>expiry_date</td>\n<td>date</td>\n<td>Yes</td>\n<td>Validity end date (YYYY-MM-DD)</td>\n</tr>\n<tr>\n<td>activation_code</td>\n<td>string</td>\n<td>Yes</td>\n<td>Activation code for manual installation</td>\n</tr>\n<tr>\n<td>install_qr_data</td>\n<td>string</td>\n<td>Yes</td>\n<td>Data for generating install QR code.</td>\n</tr>\n</tbody>\n</table>\n</div>","urlObject":{"path":["pass","topup"],"host":["{{base_url}}"],"query":[],"variable":[]}},"response":[{"id":"4aebe6fa-2c22-4801-8b02-bf09f23bb1cf","name":"200 Success (Priority Pass)","originalRequest":{"method":"POST","header":[{"key":"Content-Type","value":"application/json","type":"text"}],"body":{"mode":"raw","raw":"{\n  \"pass_id\": \"a1b2c3d4-e5f6-7890-abcd-ef1234567890\",\n  \"plan_id\": \"test-priority\",\n  \"enrol_token\": \"ASDU78123AASDGJ\",\n  \"card_type\": \"MC\",\n  \"holder\": {\n    \"first_name\": \"John\",\n    \"last_name\": \"Doe\",\n    \"address\": {\n      \"address_line_1\": \"123 Main St\",\n      \"city\": \"Hong Kong\",\n      \"country_code\": \"HKG\"\n    }\n  }\n}","options":{"raw":{"language":"json"}}},"url":"{{base_url}}/pass/topup"},"code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json","description":"","type":"text"}],"cookie":[],"responseTime":null,"body":"{\n  \"pass_id\": \"a1b2c3d4-e5f6-7890-abcd-ef1234567890\",\n  \"type\": \"priority\",\n  \"status\": \"active\",\n  \"dmc_qr_data\": \"PP/260326/ABC123DEF456\",\n  \"barcode_string\": \"PP/260326/ABC123DEF456\",\n  \"topup_count\": 1,\n  \"expiry\": \"2027-03-26\"\n}"},{"id":"8763cabc-47d1-48d9-bd77-09db2eea4329","name":"200 Success (eSim)","originalRequest":{"method":"POST","header":[{"key":"Content-Type","value":"application/json","type":"text"}],"body":{"mode":"raw","raw":"{\n    \"pass_id\": \"a1b2c3d4-e5f6-7890-abcd-ef1234567890\",\n    \"plan_id\": \"test-priority\",\n    \"card_type\": \"MC\",\n    \"holder\": {\n        \"first_name\": \"John\",\n        \"last_name\": \"Doe\",\n        \"address\": {\n            \"address_line_1\": \"123 Main St\",\n            \"city\": \"Hong Kong\",\n            \"country_code\": \"HKG\"\n        }\n    }\n}","options":{"raw":{"language":"json"}}},"url":"{{base_url}}/pass/topup"},"code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json","description":"","type":"text"}],"cookie":[],"responseTime":null,"body":"{\n    \"pass_id\": \"sim-user-001\",\n    \"type\": \"esim\",\n    \"status\": \"active\",\n    \"iccid\": \"8944501902198304826\",\n    \"expiry\": \"2027-04-15\",\n    \"topup_count\": 1,\n    \"esim_data\": {\n        \"package_name\": \"HK 7 Days 1GB\",\n        \"data_remaining_mb\": null,\n        \"expiry_date\": \"2027-04-15\",\n        \"activation_code\": null,\n        \"install_qr_data\": null\n    }\n}"},{"id":"45c7a41b-bb78-48c8-99ce-16bdfb60399f","name":"200 Success (With Expiry Date & Extra Info)","originalRequest":{"method":"POST","header":[{"key":"Content-Type","value":"application/json","type":"text"}],"body":{"mode":"raw","raw":"{\n  \"pass_id\": \"a1b2c3d4-e5f6-7890-abcd-ef1234567890\",\n  \"plan_id\": \"test-priority\",\n  \"enrol_token\": \"ASDU78123AASDGJ\",\n  \"card_type\": \"VI\",\n  \"expiry_date\": \"2027-12-31\",\n  \"extra_info\": {\n    \"BUUID\": \"COBANK01\"\n  },\n  \"holder\": {\n    \"first_name\": \"Jane\",\n    \"last_name\": \"Smith\",\n    \"address\": {\n      \"address_line_1\": \"456 Queens Road\",\n      \"address_line_2\": \"Flat 12A\",\n      \"city\": \"Hong Kong\",\n      \"country_code\": \"HKG\"\n    }\n  }\n}","options":{"raw":{"language":"json"}}},"url":"{{base_url}}/pass/topup"},"code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json","description":"","type":"text"}],"cookie":[],"responseTime":null,"body":"{\n  \"pass_id\": \"a1b2c3d4-e5f6-7890-abcd-ef1234567890\",\n  \"type\": \"priority\",\n  \"status\": \"active\",\n  \"dmc_qr_data\": \"PP/260326/XYZ789GHI012\",\n  \"barcode_string\": \"PP/260326/XYZ789GHI012\",\n  \"topup_count\": 2,\n  \"expiry\": \"2027-12-31\"\n}"},{"id":"781ae611-84b4-41e9-8d09-a97724e0d51e","name":"400 Missing Required Fields","originalRequest":{"method":"POST","header":[{"key":"Content-Type","value":"application/json","type":"text"}],"body":{"mode":"raw","raw":"{\n  \"pass_id\": \"a1b2c3d4-e5f6-7890-abcd-ef1234567890\",\n  \"plan_id\": \"test-priority\"\n}","options":{"raw":{"language":"json"}}},"url":"{{base_url}}/pass/topup"},"code":400,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json","description":"","type":"text"}],"cookie":[],"responseTime":null,"body":"{\n  \"error\": \"invalid_request\",\n  \"error_description\": \"enrol_token is required.\",\n  \"code\": 400\n}"},{"id":"2ebae069-bbb0-4a0c-96c4-d4670548dbbc","name":"404 Pass Not Found","originalRequest":{"method":"POST","header":[{"key":"Content-Type","value":"application/json","type":"text"}],"body":{"mode":"raw","raw":"{\n  \"pass_id\": \"nonexistent-pass-id\",\n  \"plan_id\": \"test-priority\",\n  \"enrol_token\": \"ASDU78123AASDGJ\",\n  \"card_type\": \"MC\",\n  \"holder\": {\n    \"first_name\": \"John\",\n    \"last_name\": \"Doe\",\n    \"address\": {\n      \"address_line_1\": \"123 Main St\",\n      \"city\": \"Hong Kong\",\n      \"country_code\": \"HKG\"\n    }\n  }\n}","options":{"raw":{"language":"json"}}},"url":"{{base_url}}/pass/topup"},"code":404,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json","description":"","type":"text"}],"cookie":[],"responseTime":null,"body":"{\n  \"error\": \"pass_not_found\",\n  \"error_description\": \"Pass not found: nonexistent-pass-id\",\n  \"code\": 404\n}"},{"id":"5c098307-5789-4afd-9ab7-eba22b54b69b","name":"404 Invalid Plan","originalRequest":{"method":"POST","header":[{"key":"Content-Type","value":"application/json","type":"text"}],"body":{"mode":"raw","raw":"{\n  \"pass_id\": \"a1b2c3d4-e5f6-7890-abcd-ef1234567890\",\n  \"plan_id\": \"nonexistent-plan\",\n  \"enrol_token\": \"ASDU78123AASDGJ\",\n  \"card_type\": \"MC\",\n  \"holder\": {\n    \"first_name\": \"John\",\n    \"last_name\": \"Doe\",\n    \"address\": {\n      \"address_line_1\": \"123 Main St\",\n      \"city\": \"Hong Kong\",\n      \"country_code\": \"HKG\"\n    }\n  }\n}","options":{"raw":{"language":"json"}}},"url":"{{base_url}}/pass/topup"},"code":404,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json","description":"","type":"text"}],"cookie":[],"responseTime":null,"body":"{\n  \"error\": \"invalid_plan\",\n  \"error_description\": \"No active routing rule found for plan_id: nonexistent-plan\",\n  \"code\": 404\n}"},{"id":"7d358598-69dc-43ee-a183-3cf60a5da92e","name":"409 Already Cancelled","originalRequest":{"method":"POST","header":[{"key":"Content-Type","value":"application/json","type":"text"}],"body":{"mode":"raw","raw":"{\n  \"pass_id\": \"cancelled-pass-id\",\n  \"plan_id\": \"test-priority\",\n  \"enrol_token\": \"ASDU78123AASDGJ\",\n  \"card_type\": \"MC\",\n  \"holder\": {\n    \"first_name\": \"John\",\n    \"last_name\": \"Doe\",\n    \"address\": {\n      \"address_line_1\": \"123 Main St\",\n      \"city\": \"Hong Kong\",\n      \"country_code\": \"HKG\"\n    }\n  }\n}","options":{"raw":{"language":"json"}}},"url":"{{base_url}}/pass/topup"},"code":409,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json","description":"","type":"text"}],"cookie":[],"responseTime":null,"body":"{\n  \"error\": \"already_cancelled\",\n  \"error_description\": \"Pass cancelled-pass-id is already cancelled.\",\n  \"code\": 409\n}"},{"id":"5a356c1a-c9d7-4016-b007-af6a895da1c3","name":"403 Provider Cancel Forbidden","originalRequest":{"method":"POST","header":[{"key":"Content-Type","value":"application/json","type":"text"}],"body":{"mode":"raw","raw":"{\n  \"pass_id\": \"a1b2c3d4-e5f6-7890-abcd-ef1234567890\",\n  \"plan_id\": \"test-priority\",\n  \"enrol_token\": \"ASDU78123AASDGJ\",\n  \"card_type\": \"MC\",\n  \"holder\": {\n    \"first_name\": \"John\",\n    \"last_name\": \"Doe\",\n    \"address\": {\n      \"address_line_1\": \"123 Main St\",\n      \"city\": \"Hong Kong\",\n      \"country_code\": \"HKG\"\n    }\n  }\n}","options":{"raw":{"language":"json"}}},"url":"{{base_url}}/pass/topup"},"code":403,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json","description":"","type":"text"}],"cookie":[],"responseTime":null,"body":"{\n  \"error\": \"cancel_forbidden\",\n  \"error_description\": \"Cancellation not permitted for this membership in UAT environment.\",\n  \"code\": 403\n}"}],"_postman_id":"6ff186c9-40e8-4881-bc9b-62372f6d6e3c"},{"name":"Daily Report","id":"74dba7fb-ed66-4e15-bb84-f65715c8f9ba","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{access_token}}"}]},"isInherited":false},"method":"POST","header":[{"key":"Content-Type","value":"application/json","type":"text"}],"body":{"mode":"raw","raw":"{\n  \"date\": \"2026-03-26\",\n  \"page\": 1\n}"},"url":"{{base_url}}/pass/daily-report","description":"<p>The Daily Report API returns pass transaction records for a specific date, scoped to the authenticated partner. Useful for daily reconciliation and reporting.</p>\n<ul>\n<li><strong>Security Notes:</strong> Requires valid Bearer token from /auth/token. Results are scoped to the authenticated partner's client_id only.</li>\n</ul>\n<h2 id=\"pagination\">Pagination</h2>\n<p>Results are returned in pages of <strong>200 records</strong>. Use the <code>page</code> parameter to navigate through results. The response includes <code>total_count</code>, <code>total_pages</code>, and <code>page_size</code> for easy pagination handling.</p>\n<h2 id=\"input-params\">Input Params</h2>\n<p>The request body is JSON (Content-Type: application/json).</p>\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>date</td>\n<td>string</td>\n<td>No</td>\n<td>Query date in YYYY-MM-DD format. <strong>Defaults to current date if omitted.</strong></td>\n</tr>\n<tr>\n<td>page</td>\n<td>integer</td>\n<td>No</td>\n<td>Page number (starting from 1). <strong>Defaults to 1.</strong></td>\n</tr>\n</tbody>\n</table>\n</div><h2 id=\"response-params\">Response Params</h2>\n<p>Successful responses (200 OK) return JSON with transaction records and pagination metadata.</p>\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>Always Present</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>date</td>\n<td>string</td>\n<td>Yes</td>\n<td>The queried date in YYYY-MM-DD format.</td>\n</tr>\n<tr>\n<td>transactions</td>\n<td>array</td>\n<td>Yes</td>\n<td>Array of transaction records (see below).</td>\n</tr>\n<tr>\n<td>total_count</td>\n<td>integer</td>\n<td>Yes</td>\n<td>Total number of transactions for this date and partner.</td>\n</tr>\n<tr>\n<td>page</td>\n<td>integer</td>\n<td>Yes</td>\n<td>Current page number.</td>\n</tr>\n<tr>\n<td>page_size</td>\n<td>integer</td>\n<td>Yes</td>\n<td>Records per page (always 200).</td>\n</tr>\n<tr>\n<td>total_pages</td>\n<td>integer</td>\n<td>Yes</td>\n<td>Total number of pages available (minimum 1).</td>\n</tr>\n</tbody>\n</table>\n</div><h3 id=\"transaction-object\">Transaction Object</h3>\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>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>transaction_id</td>\n<td>string</td>\n<td>Unique transaction identifier from provider.</td>\n</tr>\n<tr>\n<td>pass_id</td>\n<td>string</td>\n<td>The pass that this transaction belongs to.</td>\n</tr>\n<tr>\n<td>date</td>\n<td>string</td>\n<td>Transaction date (YYYY-MM-DD).</td>\n</tr>\n<tr>\n<td>type</td>\n<td>string</td>\n<td>Transaction type (e.g., \"VISIT\").</td>\n</tr>\n<tr>\n<td>lounge_id</td>\n<td>string</td>\n<td>Lounge identifier.</td>\n</tr>\n<tr>\n<td>lounge_name</td>\n<td>string</td>\n<td>Lounge display name.</td>\n</tr>\n<tr>\n<td>guests</td>\n<td>integer</td>\n<td>Number of guests.</td>\n</tr>\n<tr>\n<td>cost</td>\n<td>number</td>\n<td>Transaction cost.</td>\n</tr>\n<tr>\n<td>extra_info</td>\n<td>object/null</td>\n<td>Additional metadata (JSON).</td>\n</tr>\n</tbody>\n</table>\n</div><h2 id=\"error-handle\">Error Handle</h2>\n<ul>\n<li><strong>400 invalid_request — invalid date format:</strong>\n  <code>{ \"error\": \"invalid_request\", \"error_description\": \"date must be a valid date in YYYY-MM-DD format.\", \"code\": 400 }</code></li>\n</ul>\n","urlObject":{"path":["pass","daily-report"],"host":["{{base_url}}"],"query":[],"variable":[]}},"response":[{"id":"d317677d-2810-488d-ab71-936fba320dbf","name":"200 Success","originalRequest":{"method":"POST","header":[{"key":"Content-Type","value":"application/json","type":"text"}],"body":{"mode":"raw","raw":"{\n  \"date\": \"2026-03-26\"\n}","options":{"raw":{"language":"json"}}},"url":"{{base_url}}/pass/daily-report"},"code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json","description":"","type":"text"}],"cookie":[],"responseTime":null,"body":"{\n  \"date\": \"2026-03-26\",\n  \"transactions\": [\n    {\n      \"transaction_id\": \"TXN-20260326-001\",\n      \"pass_id\": \"a1b2c3d4-e5f6-7890-abcd-ef1234567890\",\n      \"date\": \"2026-03-26\",\n      \"type\": \"VISIT\",\n      \"lounge_id\": \"LNG-HKG-001\",\n      \"lounge_name\": \"Dragon Lounge\",\n      \"guests\": 2,\n      \"cost\": 45.0,\n      \"extra_info\": null\n    },\n    {\n      \"transaction_id\": \"TXN-20260326-002\",\n      \"pass_id\": \"b2c3d4e5-f6a7-8901-bcde-f12345678901\",\n      \"date\": \"2026-03-26\",\n      \"type\": \"VISIT\",\n      \"lounge_id\": \"LNG-SIN-003\",\n      \"lounge_name\": \"Jewel Lounge\",\n      \"guests\": 0,\n      \"cost\": 32.0,\n      \"extra_info\": null\n    },\n    {\n      \"transaction_id\": \"TXN-20260326-003\",\n      \"pass_id\": \"b2c3d4e5-f6a7-8901-bcde-f12345678902\",\n      \"date\": \"2026-03-26\",\n      \"type\": \"ESIM_TOP_UP\",\n      \"package_name\": \"10 Days 5GB Global\",\n      \"cost\": 20.0,\n      \"extra_info\": null\n    }\n  ],\n  \"total_count\": 2,\n  \"page\": 1,\n  \"page_size\": 200,\n  \"total_pages\": 1\n}"},{"id":"5205220c-26ab-4e33-b2ac-654fcc1a2188","name":"200 Success (Page 2)","originalRequest":{"method":"POST","header":[{"key":"Content-Type","value":"application/json","type":"text"}],"body":{"mode":"raw","raw":"{\n  \"date\": \"2026-03-25\",\n  \"page\": 2\n}","options":{"raw":{"language":"json"}}},"url":"{{base_url}}/pass/daily-report"},"code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json","description":"","type":"text"}],"cookie":[],"responseTime":null,"body":"{\n  \"date\": \"2026-03-25\",\n  \"transactions\": [\n    {\n      \"transaction_id\": \"TXN-20260325-201\",\n      \"pass_id\": \"c3d4e5f6-a7b8-9012-cdef-123456789012\",\n      \"date\": \"2026-03-25\",\n      \"type\": \"VISIT\",\n      \"lounge_id\": \"LNG-BKK-002\",\n      \"lounge_name\": \"Coral Lounge\",\n      \"guests\": 1,\n      \"cost\": 28.5,\n      \"extra_info\": null\n    }\n  ],\n  \"total_count\": 450,\n  \"page\": 2,\n  \"page_size\": 200,\n  \"total_pages\": 3\n}"},{"id":"183665d6-05dd-4f2e-bf5a-e63aa9a82c36","name":"200 Default Today (No Date)","originalRequest":{"method":"POST","header":[{"key":"Content-Type","value":"application/json","type":"text"}],"body":{"mode":"raw","raw":"{}","options":{"raw":{"language":"json"}}},"url":"{{base_url}}/pass/daily-report"},"code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json","description":"","type":"text"}],"cookie":[],"responseTime":null,"body":"{\n  \"date\": \"2026-03-26\",\n  \"transactions\": [],\n  \"total_count\": 0,\n  \"page\": 1,\n  \"page_size\": 200,\n  \"total_pages\": 1\n}"},{"id":"f60684c3-e26f-4146-8f1a-6bc4f70961a9","name":"400 Invalid Date Format","originalRequest":{"method":"POST","header":[{"key":"Content-Type","value":"application/json","type":"text"}],"body":{"mode":"raw","raw":"{\n  \"date\": \"26-03-2026\"\n}","options":{"raw":{"language":"json"}}},"url":"{{base_url}}/pass/daily-report"},"code":400,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json","description":"","type":"text"}],"cookie":[],"responseTime":null,"body":"{\n  \"error\": \"invalid_request\",\n  \"error_description\": \"date must be a valid date in YYYY-MM-DD format.\",\n  \"code\": 400\n}"}],"_postman_id":"74dba7fb-ed66-4e15-bb84-f65715c8f9ba"},{"name":"Lounge Finder Search","id":"a377b607-ea06-4c9b-97e8-6e89ff70767e","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{access_token}}"}]},"isInherited":false},"method":"POST","header":[],"body":{"mode":"raw","raw":"{\n\t\"pass_id\": \"{{pass_id}}\",\n\t\"language_code\": \"en-GB\"\n}","options":{"raw":{"language":"json"}}},"url":"{{base_url}}/v1/lounge/search","description":"<p>Search for lounges by various criteria. The gateway translates partner snake_case parameters to Collinson's lounge catalogue API and returns normalized snake_case data. The gateway automatically requests <code>Location</code>, <code>Facilities</code>, and <code>Media</code> detail sections — partners do not need to specify this.</p>\n<ul>\n<li><strong>Use Case:</strong> Display available lounges to a cardholder by keyword, city, country, lounge code, or by their pass membership. When <code>pass_id</code> is provided, the gateway resolves the membership number and deal ID automatically — partner clients never need to supply provider-specific identifiers.</li>\n</ul>\n<h2 id=\"input-params\">Input Params</h2>\n<p>The request body is JSON (Content-Type: application/json). <code>pass_id</code> is required. All other filters are optional.</p>\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>pass_id</td>\n<td>string</td>\n<td><strong>Yes</strong></td>\n<td>LoyaltyLayer pass identifier. The gateway resolves it to the provider membership number and deal ID internally.</td>\n</tr>\n<tr>\n<td>search_term</td>\n<td>string</td>\n<td>No*</td>\n<td>Fuzzy keyword search across lounge name, city, and country (e.g., <code>\"heathrow\"</code>).</td>\n</tr>\n<tr>\n<td>lounge_code</td>\n<td>string</td>\n<td>No*</td>\n<td>Exact lounge code (e.g., <code>\"LHR01\"</code>).</td>\n</tr>\n<tr>\n<td>city</td>\n<td>string</td>\n<td>No*</td>\n<td>Filter by city name (e.g., <code>\"Paris\"</code>).</td>\n</tr>\n<tr>\n<td>country</td>\n<td>string</td>\n<td>No*</td>\n<td>Filter by country name (e.g., <code>\"France\"</code>).</td>\n</tr>\n<tr>\n<td>country_code</td>\n<td>string</td>\n<td>No*</td>\n<td>Filter by ISO country code (e.g., <code>\"FR\"</code>).</td>\n</tr>\n<tr>\n<td>location_code</td>\n<td>string</td>\n<td>No*</td>\n<td>Filter by airport/location code (e.g., <code>\"LHR\"</code>).</td>\n</tr>\n<tr>\n<td>location_name</td>\n<td>string</td>\n<td>No*</td>\n<td>Filter by location name.</td>\n</tr>\n<tr>\n<td>language_code</td>\n<td>string</td>\n<td>No</td>\n<td>Response language (e.g., <code>\"en-GB\"</code>, <code>\"zh-HK\"</code>). Defaults to <code>en-GB</code>.</td>\n</tr>\n</tbody>\n</table>\n</div><p>* At least one starred parameter must be provided. When <code>pass_id</code> is used, the pass must exist and have an active provider membership.</p>\n<h2 id=\"response-params\">Response Params</h2>\n<p>Successful responses (200 OK) return JSON with snake_case lounge fields. The gateway always requests <code>Location</code>, <code>Facilities</code>, and <code>Media</code> from Collinson, so these fields appear in the response whenever the provider returns them.</p>\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>Always Present</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>lounges</td>\n<td>array</td>\n<td>Yes</td>\n<td>Array of lounge objects.</td>\n</tr>\n<tr>\n<td>total_count</td>\n<td>integer</td>\n<td>Yes</td>\n<td>Total number of lounges returned.</td>\n</tr>\n<tr>\n<td>error</td>\n<td>string</td>\n<td>Yes (on error)</td>\n<td>Error code (e.g., <code>\"pass_not_found\"</code>).</td>\n</tr>\n<tr>\n<td>error_description</td>\n<td>string</td>\n<td>Yes (on error)</td>\n<td>Human-readable error details.</td>\n</tr>\n<tr>\n<td>code</td>\n<td>integer</td>\n<td>Yes (on error)</td>\n<td>HTTP status code repeated in body.</td>\n</tr>\n</tbody>\n</table>\n</div><h3 id=\"lounge-object\">Lounge Object</h3>\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>Always Present</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>lounge_code</td>\n<td>string</td>\n<td>Yes</td>\n<td>Unique lounge identifier (e.g., <code>\"LHR01\"</code>).</td>\n</tr>\n<tr>\n<td>lounge_name</td>\n<td>string</td>\n<td>Yes</td>\n<td>Lounge display name.</td>\n</tr>\n<tr>\n<td>location</td>\n<td>object</td>\n<td>When available</td>\n<td>Location details returned by provider.</td>\n</tr>\n<tr>\n<td>location.city</td>\n<td>string</td>\n<td>When present</td>\n<td>City name.</td>\n</tr>\n<tr>\n<td>location.country</td>\n<td>string</td>\n<td>When present</td>\n<td>Country name.</td>\n</tr>\n<tr>\n<td>location.country_code</td>\n<td>string</td>\n<td>When present</td>\n<td>ISO country code.</td>\n</tr>\n<tr>\n<td>location.airport_code</td>\n<td>string</td>\n<td>When present</td>\n<td>Airport IATA code.</td>\n</tr>\n<tr>\n<td>location.terminal</td>\n<td>string</td>\n<td>When present</td>\n<td>Terminal identifier.</td>\n</tr>\n<tr>\n<td>location.latitude</td>\n<td>number</td>\n<td>When present</td>\n<td>Latitude coordinate.</td>\n</tr>\n<tr>\n<td>location.longitude</td>\n<td>number</td>\n<td>When present</td>\n<td>Longitude coordinate.</td>\n</tr>\n<tr>\n<td>facilities</td>\n<td>object</td>\n<td>When available</td>\n<td>Available facilities returned by provider.</td>\n</tr>\n<tr>\n<td>media</td>\n<td>object</td>\n<td>When available</td>\n<td>Images and media returned by provider.</td>\n</tr>\n<tr>\n<td>conditions</td>\n<td>object</td>\n<td>When available</td>\n<td>Access conditions returned by provider.</td>\n</tr>\n</tbody>\n</table>\n</div>","urlObject":{"path":["v1","lounge","search"],"host":["{{base_url}}"],"query":[],"variable":[]}},"response":[{"id":"e3ea41db-8b85-42ac-9e1f-7a601d7fb88e","name":"200 - Search by Keyword","originalRequest":{"method":"POST","header":[{"key":"Content-Type","value":"application/json","type":"text"}],"body":{"mode":"raw","raw":"{\n\t\"pass_id\": \"{{pass_id}}\",\n\t\"search_term\": \"heathrow\",\n\t\"language_code\": \"en-GB\"\n}","options":{"raw":{"language":"json"}}},"url":"{{base_url}}/v1/lounge/search"},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"cookie":[],"responseTime":null,"body":"{\n    \"lounges\": [\n        {\n            \"lounge_code\": \"LHR01\",\n            \"lounge_name\": \"No1 Traveller Lounge Heathrow T3\",\n            \"location\": {\n                \"city\": \"London\",\n                \"country\": \"United Kingdom\",\n                \"country_code\": \"GB\",\n                \"airport_code\": \"LHR\",\n                \"terminal\": \"T3\",\n                \"latitude\": 51.4775,\n                \"longitude\": -0.4614\n            },\n            \"facilities\": {\n                \"WiFi\": true,\n                \"Shower\": true,\n                \"Food\": true,\n                \"Bar\": true\n            },\n            \"media\": {\n                \"image_url\": \"https://cdn.collinson.com/lounges/lhr01.jpg\"\n            }\n        }\n    ],\n    \"total_count\": 1\n}"},{"id":"1321b754-808d-4a7e-bdae-57c1b5342453","name":"200 - Search by City","originalRequest":{"method":"POST","header":[{"key":"Content-Type","value":"application/json","type":"text"}],"body":{"mode":"raw","raw":"{\n\t\"pass_id\": \"{{pass_id}}\",\n\t\"city\": \"Paris\",\n\t\"language_code\": \"en-GB\"\n}","options":{"raw":{"language":"json"}}},"url":"{{base_url}}/v1/lounge/search"},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"cookie":[],"responseTime":null,"body":"{\n    \"lounges\": [\n        {\n            \"lounge_code\": \"CDG03\",\n            \"lounge_name\": \"Paris CDG Premium Lounge\",\n            \"location\": {\n                \"city\": \"Paris\",\n                \"country\": \"France\",\n                \"country_code\": \"FR\",\n                \"airport_code\": \"CDG\",\n                \"terminal\": \"2E\"\n            },\n            \"facilities\": {\n                \"WiFi\": true,\n                \"Shower\": false,\n                \"Food\": true\n            },\n            \"media\": {\n                \"image_url\": \"https://cdn.collinson.com/lounges/cdg03.jpg\"\n            }\n        }\n    ],\n    \"total_count\": 1\n}"},{"id":"1e79ffa6-969d-4ddc-b5d4-cf996d966651","name":"200 - Search by Country Code","originalRequest":{"method":"POST","header":[{"key":"Content-Type","value":"application/json","type":"text"}],"body":{"mode":"raw","raw":"{\n\t\"pass_id\": \"{{pass_id}}\",\n\t\"country_code\": \"HK\"\n}","options":{"raw":{"language":"json"}}},"url":"{{base_url}}/v1/lounge/search"},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"cookie":[],"responseTime":null,"body":"{\n    \"lounges\": [\n        {\n            \"lounge_code\": \"HKG01\",\n            \"lounge_name\": \"Hong Kong International Premium Lounge\",\n            \"location\": {\n                \"city\": \"Hong Kong\",\n                \"country\": \"Hong Kong SAR\",\n                \"country_code\": \"HK\",\n                \"airport_code\": \"HKG\",\n                \"terminal\": \"T1\",\n                \"latitude\": 22.3089,\n                \"longitude\": 113.9145\n            },\n            \"facilities\": {\n                \"WiFi\": true,\n                \"Shower\": true,\n                \"Food\": true,\n                \"Bar\": true,\n                \"Spa\": true\n            },\n            \"media\": {\n                \"image_url\": \"https://cdn.collinson.com/lounges/hkg01.jpg\"\n            }\n        }\n    ],\n    \"total_count\": 1\n}"},{"id":"bbd3293a-d957-4fd7-8600-e3f4e278bf6d","name":"200 - Search by Airport Code","originalRequest":{"method":"POST","header":[{"key":"Content-Type","value":"application/json","type":"text"}],"body":{"mode":"raw","raw":"{\n\t\"pass_id\": \"{{pass_id}}\",\n\t\"location_code\": \"LHR\"\n}","options":{"raw":{"language":"json"}}},"url":"{{base_url}}/v1/lounge/search"},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"cookie":[],"responseTime":null,"body":"{\n    \"lounges\": [\n        {\n            \"lounge_code\": \"LHR01\",\n            \"lounge_name\": \"No1 Traveller Lounge Heathrow T3\",\n            \"location\": {\n                \"city\": \"London\",\n                \"country\": \"United Kingdom\",\n                \"country_code\": \"GB\",\n                \"airport_code\": \"LHR\",\n                \"terminal\": \"T3\",\n                \"latitude\": 51.4775,\n                \"longitude\": -0.4614\n            },\n            \"facilities\": {\n                \"WiFi\": true,\n                \"Shower\": true,\n                \"Food\": true,\n                \"Bar\": true\n            },\n            \"media\": {\n                \"image_url\": \"https://cdn.collinson.com/lounges/lhr01.jpg\"\n            }\n        }\n    ],\n    \"total_count\": 1\n}"},{"id":"5debeffb-698a-4091-9204-ff4e0c393494","name":"200 - Search by Exact Lounge Code","originalRequest":{"method":"POST","header":[{"key":"Content-Type","value":"application/json","type":"text"}],"body":{"mode":"raw","raw":"{\n\t\"pass_id\": \"{{pass_id}}\",\n\t\"lounge_code\": \"HKG01\"\n}","options":{"raw":{"language":"json"}}},"url":"{{base_url}}/v1/lounge/search"},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"cookie":[],"responseTime":null,"body":"{\n    \"lounges\": [\n        {\n            \"lounge_code\": \"HKG01\",\n            \"lounge_name\": \"Hong Kong International Premium Lounge\",\n            \"location\": {\n                \"city\": \"Hong Kong\",\n                \"country\": \"Hong Kong SAR\",\n                \"country_code\": \"HK\",\n                \"airport_code\": \"HKG\",\n                \"terminal\": \"T1\",\n                \"latitude\": 22.3089,\n                \"longitude\": 113.9145\n            },\n            \"facilities\": {\n                \"WiFi\": true,\n                \"Shower\": true,\n                \"Food\": true,\n                \"Bar\": true,\n                \"Spa\": true\n            },\n            \"media\": {\n                \"image_url\": \"https://cdn.collinson.com/lounges/hkg01.jpg\"\n            }\n        }\n    ],\n    \"total_count\": 1\n}"},{"id":"89226bce-aebb-46e7-8f85-8af0e6a6be38","name":"200 - Search by Pass ID","originalRequest":{"method":"POST","header":[{"key":"Content-Type","value":"application/json","type":"text"}],"body":{"mode":"raw","raw":"{\n    \"pass_id\": \"{{pass_id}}\"\n}","options":{"raw":{"language":"json"}}},"url":"{{base_url}}/v1/lounge/search"},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"cookie":[],"responseTime":null,"body":"{\n    \"lounges\": [\n        {\n            \"lounge_code\": \"LHR01\",\n            \"lounge_name\": \"No1 Traveller Lounge Heathrow T3\",\n            \"location\": {\n                \"city\": \"London\",\n                \"country\": \"United Kingdom\",\n                \"country_code\": \"GB\",\n                \"airport_code\": \"LHR\",\n                \"terminal\": \"T3\",\n                \"latitude\": 51.4775,\n                \"longitude\": -0.4614\n            },\n            \"facilities\": {\n                \"WiFi\": true,\n                \"Shower\": true,\n                \"Food\": true,\n                \"Bar\": true\n            },\n            \"media\": {\n                \"image_url\": \"https://cdn.collinson.com/lounges/lhr01.jpg\"\n            }\n        },\n        {\n            \"lounge_code\": \"HKG01\",\n            \"lounge_name\": \"Hong Kong International Premium Lounge\",\n            \"location\": {\n                \"city\": \"Hong Kong\",\n                \"country\": \"Hong Kong SAR\",\n                \"country_code\": \"HK\",\n                \"airport_code\": \"HKG\",\n                \"terminal\": \"T1\",\n                \"latitude\": 22.3089,\n                \"longitude\": 113.9145\n            },\n            \"facilities\": {\n                \"WiFi\": true,\n                \"Shower\": true,\n                \"Food\": true,\n                \"Bar\": true,\n                \"Spa\": true\n            },\n            \"media\": {\n                \"image_url\": \"https://cdn.collinson.com/lounges/hkg01.jpg\"\n            }\n        }\n    ],\n    \"total_count\": 2\n}"},{"id":"e64c96db-d6c9-4973-bc0d-1d84a52d4a42","name":"400 - Missing pass_id","originalRequest":{"method":"POST","header":[{"key":"Content-Type","value":"application/json","type":"text"}],"body":{"mode":"raw","raw":"{\n    \"language_code\": \"en-GB\"\n}","options":{"raw":{"language":"json"}}},"url":"{{base_url}}/v1/lounge/search"},"status":"Bad Request","code":400,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"cookie":[],"responseTime":null,"body":"{\n\t\"error\": \"invalid_request\",\n\t\"error_description\": \"pass_id is required.\",\n\t\"code\": 400\n}"},{"id":"615bc150-7882-43e3-bf10-a2959633df16","name":"401 - Invalid Token","originalRequest":{"method":"POST","header":[{"key":"Content-Type","value":"application/json","type":"text"}],"body":{"mode":"raw","raw":"{\n    \"search_term\": \"heathrow\"\n}","options":{"raw":{"language":"json"}}},"url":"{{base_url}}/v1/lounge/search"},"status":"Unauthorized","code":401,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"cookie":[],"responseTime":null,"body":"{\n    \"error\": \"invalid_token\",\n    \"error_description\": \"Token not found or expired.\",\n    \"code\": 401\n}"},{"id":"7493e94a-64c7-4fba-9f45-10c6ca938a0a","name":"404 - Pass Not Found","originalRequest":{"method":"POST","header":[{"key":"Content-Type","value":"application/json","type":"text"}],"body":{"mode":"raw","raw":"{\n    \"pass_id\": \"nonexistent-pass\"\n}","options":{"raw":{"language":"json"}}},"url":"{{base_url}}/v1/lounge/search"},"status":"Not Found","code":404,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"cookie":[],"responseTime":null,"body":"{\n    \"error\": \"pass_not_found\",\n    \"error_description\": \"Pass not found: nonexistent-pass.\",\n    \"code\": 404\n}"},{"id":"35e8a33e-119a-4e89-bb3e-d10256a65bf4","name":"422 - Pass Not Active","originalRequest":{"method":"POST","header":[{"key":"Content-Type","value":"application/json","type":"text"}],"body":{"mode":"raw","raw":"{\n    \"pass_id\": \"pending-pass-id\"\n}","options":{"raw":{"language":"json"}}},"url":"{{base_url}}/v1/lounge/search"},"status":"Unprocessable Entity","code":422,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"cookie":[],"responseTime":null,"body":"{\n    \"error\": \"pass_not_active\",\n    \"error_description\": \"Pass pending-pass-id has no active provider membership.\",\n    \"code\": 422\n}"}],"_postman_id":"a377b607-ea06-4c9b-97e8-6e89ff70767e"},{"name":"Lounge Nearby Search","id":"c590cfdd-fdcd-43a6-946d-08ac771ab9b5","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"auth":{"type":"bearer","bearer":{"basicConfig":[{"key":"token","value":"{{access_token}}"}]},"isInherited":false},"method":"POST","header":[],"body":{"mode":"raw","raw":"{\n\t\"pass_id\": \"{{pass_id}}\",\n\t\"latitude\": 22.308,\n\t\"longitude\": 113.9185,\n\t\"language_code\": \"en-GB\"\n}","options":{"raw":{"language":"json"}}},"url":"{{base_url}}/v1/lounge/nearby-search","description":"<p>Find lounges at the nearest airport to the user's current GPS coordinates. The gateway resolves the coordinates to the closest airport via Google Places, queries Collinson for all lounges at that airport, and returns them sorted by distance from the submitted location (nearest first).</p>\n<ul>\n<li><strong>Use Case:</strong> Display the lounges available at the airport closest to where the cardholder currently is. Useful for mobile apps where the device GPS is available.</li>\n</ul>\n<h2 id=\"input-params\">Input Params</h2>\n<p>The request body is JSON (Content-Type: application/json). <code>pass_id</code>, <code>latitude</code>, and <code>longitude</code> are required.</p>\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>pass_id</td>\n<td>string</td>\n<td><strong>Yes</strong></td>\n<td>LoyaltyLayer pass identifier. The gateway resolves it to the provider membership number and deal ID internally. The pass must exist and have an active provider membership.</td>\n</tr>\n<tr>\n<td>latitude</td>\n<td>number</td>\n<td><strong>Yes</strong></td>\n<td>User's current latitude. Must be between -90 and 90.</td>\n</tr>\n<tr>\n<td>longitude</td>\n<td>number</td>\n<td><strong>Yes</strong></td>\n<td>User's current longitude. Must be between -180 and 180.</td>\n</tr>\n<tr>\n<td>language_code</td>\n<td>string</td>\n<td>No</td>\n<td>Response language (e.g., <code>\"en-GB\"</code>, <code>\"zh-HK\"</code>). Defaults to <code>en-GB</code>.</td>\n</tr>\n</tbody>\n</table>\n</div><h2 id=\"response-params\">Response Params</h2>\n<p>Successful responses (200 OK) return a <code>nearest_airport</code> block and an array of lounges sorted by <code>distance_km</code> ascending. Lounges without GPS coordinates are included but appear at the end of the list.</p>\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>Always Present</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>nearest_airport</td>\n<td>object</td>\n<td>Yes</td>\n<td>Details of the resolved nearest airport.</td>\n</tr>\n<tr>\n<td>nearest_airport.airport_code</td>\n<td>string</td>\n<td>Yes</td>\n<td>Airport IATA code (e.g., <code>\"HKG\"</code>).</td>\n</tr>\n<tr>\n<td>nearest_airport.name</td>\n<td>string</td>\n<td>When available</td>\n<td>Airport display name.</td>\n</tr>\n<tr>\n<td>nearest_airport.distance_km</td>\n<td>number</td>\n<td>When available</td>\n<td>Distance in km from submitted coordinates to the airport.</td>\n</tr>\n<tr>\n<td>lounges</td>\n<td>array</td>\n<td>Yes</td>\n<td>Lounge objects sorted by <code>distance_km</code> ascending.</td>\n</tr>\n<tr>\n<td>total_count</td>\n<td>integer</td>\n<td>Yes</td>\n<td>Total number of lounges returned.</td>\n</tr>\n<tr>\n<td>error</td>\n<td>string</td>\n<td>Yes (on error)</td>\n<td>Error code (e.g., <code>\"airport_not_found\"</code>).</td>\n</tr>\n<tr>\n<td>error_description</td>\n<td>string</td>\n<td>Yes (on error)</td>\n<td>Human-readable error details.</td>\n</tr>\n<tr>\n<td>code</td>\n<td>integer</td>\n<td>Yes (on error)</td>\n<td>HTTP status code repeated in body.</td>\n</tr>\n</tbody>\n</table>\n</div><h3 id=\"lounge-object\">Lounge Object</h3>\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>Always Present</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>lounge_code</td>\n<td>string</td>\n<td>Yes</td>\n<td>Unique lounge identifier.</td>\n</tr>\n<tr>\n<td>lounge_name</td>\n<td>string</td>\n<td>Yes</td>\n<td>Lounge display name.</td>\n</tr>\n<tr>\n<td>distance_km</td>\n<td>number</td>\n<td>When available</td>\n<td>Distance in km from submitted coordinates to this lounge. Omitted when the lounge has no GPS coordinates.</td>\n</tr>\n<tr>\n<td>location</td>\n<td>object</td>\n<td>When available</td>\n<td>Location details returned by provider.</td>\n</tr>\n<tr>\n<td>location.city</td>\n<td>string</td>\n<td>When present</td>\n<td>City name.</td>\n</tr>\n<tr>\n<td>location.country</td>\n<td>string</td>\n<td>When present</td>\n<td>Country name.</td>\n</tr>\n<tr>\n<td>location.country_code</td>\n<td>string</td>\n<td>When present</td>\n<td>ISO country code.</td>\n</tr>\n<tr>\n<td>location.airport_code</td>\n<td>string</td>\n<td>When present</td>\n<td>Airport IATA code.</td>\n</tr>\n<tr>\n<td>location.terminal</td>\n<td>string</td>\n<td>When present</td>\n<td>Terminal identifier.</td>\n</tr>\n<tr>\n<td>location.latitude</td>\n<td>number</td>\n<td>When present</td>\n<td>Lounge latitude coordinate.</td>\n</tr>\n<tr>\n<td>location.longitude</td>\n<td>number</td>\n<td>When present</td>\n<td>Lounge longitude coordinate.</td>\n</tr>\n<tr>\n<td>facilities</td>\n<td>object</td>\n<td>When available</td>\n<td>Available facilities returned by provider.</td>\n</tr>\n<tr>\n<td>media</td>\n<td>object</td>\n<td>When available</td>\n<td>Images and media returned by provider.</td>\n</tr>\n<tr>\n<td>conditions</td>\n<td>object</td>\n<td>When available</td>\n<td>Access conditions returned by provider.</td>\n</tr>\n</tbody>\n</table>\n</div>","urlObject":{"path":["v1","lounge","nearby-search"],"host":["{{base_url}}"],"query":[],"variable":[]}},"response":[{"id":"af8ae3fa-d06a-4761-abe5-813be016dd58","name":"200 - Search Near Hong Kong (HKG)","originalRequest":{"method":"POST","header":[{"key":"Content-Type","value":"application/json","type":"text"}],"body":{"mode":"raw","raw":"{\n\t\"pass_id\": \"{{pass_id}}\",\n\t\"latitude\": 22.308,\n\t\"longitude\": 113.9185,\n\t\"language_code\": \"en-GB\"\n}","options":{"raw":{"language":"json"}}},"url":"{{base_url}}/v1/lounge/nearby-search"},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"cookie":[],"responseTime":null,"body":"{\n\t\"nearest_airport\": {\n\t\t\"airport_code\": \"HKG\",\n\t\t\"name\": \"Hong Kong International Airport\",\n\t\t\"distance_km\": 0.2\n\t},\n\t\"lounges\": [\n\t\t{\n\t\t\t\"lounge_code\": \"HKG01\",\n\t\t\t\"lounge_name\": \"Plaza Premium Lounge (Terminal 1 - Departures)\",\n\t\t\t\"distance_km\": 0.3,\n\t\t\t\"location\": {\n\t\t\t\t\"city\": \"Hong Kong\",\n\t\t\t\t\"country\": \"Hong Kong\",\n\t\t\t\t\"country_code\": \"HK\",\n\t\t\t\t\"airport_code\": \"HKG\",\n\t\t\t\t\"terminal\": \"1\",\n\t\t\t\t\"latitude\": 22.308,\n\t\t\t\t\"longitude\": 113.9185\n\t\t\t},\n\t\t\t\"facilities\": {\n\t\t\t\t\"WiFi\": true,\n\t\t\t\t\"Shower\": true,\n\t\t\t\t\"Food\": true\n\t\t\t},\n\t\t\t\"media\": {\n\t\t\t\t\"images\": [\n\t\t\t\t\t{\n\t\t\t\t\t\t\"url\": \"https://cdn.example.com/lounges/hkg01.jpg\",\n\t\t\t\t\t\t\"type\": \"exterior\"\n\t\t\t\t\t}\n\t\t\t\t]\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\t\"lounge_code\": \"HKG02\",\n\t\t\t\"lounge_name\": \"Plaza Premium Lounge (Terminal 1 - Arrivals)\",\n\t\t\t\"distance_km\": 0.7,\n\t\t\t\"location\": {\n\t\t\t\t\"city\": \"Hong Kong\",\n\t\t\t\t\"country\": \"Hong Kong\",\n\t\t\t\t\"country_code\": \"HK\",\n\t\t\t\t\"airport_code\": \"HKG\",\n\t\t\t\t\"terminal\": \"1\",\n\t\t\t\t\"latitude\": 22.3095,\n\t\t\t\t\"longitude\": 113.92\n\t\t\t},\n\t\t\t\"facilities\": {\n\t\t\t\t\"WiFi\": true,\n\t\t\t\t\"Shower\": true,\n\t\t\t\t\"Food\": true\n\t\t\t},\n\t\t\t\"media\": {\n\t\t\t\t\"images\": [\n\t\t\t\t\t{\n\t\t\t\t\t\t\"url\": \"https://cdn.example.com/lounges/hkg02.jpg\",\n\t\t\t\t\t\t\"type\": \"exterior\"\n\t\t\t\t\t}\n\t\t\t\t]\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\t\"lounge_code\": \"HKG03\",\n\t\t\t\"lounge_name\": \"Sky Lounge\",\n\t\t\t\"distance_km\": 1.2,\n\t\t\t\"location\": {\n\t\t\t\t\"city\": \"Hong Kong\",\n\t\t\t\t\"country\": \"Hong Kong\",\n\t\t\t\t\"country_code\": \"HK\",\n\t\t\t\t\"airport_code\": \"HKG\",\n\t\t\t\t\"terminal\": \"2\",\n\t\t\t\t\"latitude\": 22.305,\n\t\t\t\t\"longitude\": 113.915\n\t\t\t},\n\t\t\t\"facilities\": {\n\t\t\t\t\"WiFi\": true,\n\t\t\t\t\"Shower\": true,\n\t\t\t\t\"Food\": true\n\t\t\t},\n\t\t\t\"media\": {\n\t\t\t\t\"images\": [\n\t\t\t\t\t{\n\t\t\t\t\t\t\"url\": \"https://cdn.example.com/lounges/hkg03.jpg\",\n\t\t\t\t\t\t\"type\": \"exterior\"\n\t\t\t\t\t}\n\t\t\t\t]\n\t\t\t}\n\t\t}\n\t],\n\t\"total_count\": 3\n}"},{"id":"5eb51752-cc02-4bb0-8fc8-0f54a2b1bb47","name":"200 - Search Near London Heathrow (LHR)","originalRequest":{"method":"POST","header":[{"key":"Content-Type","value":"application/json","type":"text"}],"body":{"mode":"raw","raw":"{\n\t\"pass_id\": \"{{pass_id}}\",\n\t\"latitude\": 51.47,\n\t\"longitude\": -0.4543,\n\t\"language_code\": \"en-GB\"\n}","options":{"raw":{"language":"json"}}},"url":"{{base_url}}/v1/lounge/nearby-search"},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"cookie":[],"responseTime":null,"body":"{\n\t\"nearest_airport\": {\n\t\t\"airport_code\": \"LHR\",\n\t\t\"name\": \"Heathrow Airport\",\n\t\t\"distance_km\": 1.8\n\t},\n\t\"lounges\": [\n\t\t{\n\t\t\t\"lounge_code\": \"LHR05\",\n\t\t\t\"lounge_name\": \"No1 Traveller Lounge Terminal 3\",\n\t\t\t\"distance_km\": 1.1,\n\t\t\t\"location\": {\n\t\t\t\t\"city\": \"London\",\n\t\t\t\t\"country\": \"United Kingdom\",\n\t\t\t\t\"country_code\": \"GB\",\n\t\t\t\t\"airport_code\": \"LHR\",\n\t\t\t\t\"terminal\": \"3\",\n\t\t\t\t\"latitude\": 51.4745,\n\t\t\t\t\"longitude\": -0.4564\n\t\t\t},\n\t\t\t\"facilities\": {\n\t\t\t\t\"WiFi\": true,\n\t\t\t\t\"Shower\": true,\n\t\t\t\t\"Food\": true\n\t\t\t},\n\t\t\t\"media\": {\n\t\t\t\t\"images\": [\n\t\t\t\t\t{\n\t\t\t\t\t\t\"url\": \"https://cdn.example.com/lounges/lhr05.jpg\",\n\t\t\t\t\t\t\"type\": \"exterior\"\n\t\t\t\t\t}\n\t\t\t\t]\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\t\"lounge_code\": \"LHR08\",\n\t\t\t\"lounge_name\": \"Aspire Lounge Terminal 5\",\n\t\t\t\"distance_km\": 2.4,\n\t\t\t\"location\": {\n\t\t\t\t\"city\": \"London\",\n\t\t\t\t\"country\": \"United Kingdom\",\n\t\t\t\t\"country_code\": \"GB\",\n\t\t\t\t\"airport_code\": \"LHR\",\n\t\t\t\t\"terminal\": \"5\",\n\t\t\t\t\"latitude\": 51.4706,\n\t\t\t\t\"longitude\": -0.4882\n\t\t\t},\n\t\t\t\"facilities\": {\n\t\t\t\t\"WiFi\": true,\n\t\t\t\t\"Shower\": true,\n\t\t\t\t\"Food\": true\n\t\t\t},\n\t\t\t\"media\": {\n\t\t\t\t\"images\": [\n\t\t\t\t\t{\n\t\t\t\t\t\t\"url\": \"https://cdn.example.com/lounges/lhr08.jpg\",\n\t\t\t\t\t\t\"type\": \"exterior\"\n\t\t\t\t\t}\n\t\t\t\t]\n\t\t\t}\n\t\t}\n\t],\n\t\"total_count\": 2\n}"},{"id":"3dfda6ca-2ee2-45e4-9618-18ae64fbeb63","name":"200 - Search Near Singapore Changi (SIN)","originalRequest":{"method":"POST","header":[{"key":"Content-Type","value":"application/json","type":"text"}],"body":{"mode":"raw","raw":"{\n\t\"pass_id\": \"{{pass_id}}\",\n\t\"latitude\": 1.3644,\n\t\"longitude\": 103.9915,\n\t\"language_code\": \"en-GB\"\n}","options":{"raw":{"language":"json"}}},"url":"{{base_url}}/v1/lounge/nearby-search"},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"cookie":[],"responseTime":null,"body":"{\n\t\"nearest_airport\": {\n\t\t\"airport_code\": \"SIN\",\n\t\t\"name\": \"Singapore Changi Airport\",\n\t\t\"distance_km\": 0.6\n\t},\n\t\"lounges\": [\n\t\t{\n\t\t\t\"lounge_code\": \"SIN01\",\n\t\t\t\"lounge_name\": \"SATS Premier Lounge Terminal 3\",\n\t\t\t\"distance_km\": 0.5,\n\t\t\t\"location\": {\n\t\t\t\t\"city\": \"Singapore\",\n\t\t\t\t\"country\": \"Singapore\",\n\t\t\t\t\"country_code\": \"SG\",\n\t\t\t\t\"airport_code\": \"SIN\",\n\t\t\t\t\"terminal\": \"3\",\n\t\t\t\t\"latitude\": 1.3592,\n\t\t\t\t\"longitude\": 103.9894\n\t\t\t},\n\t\t\t\"facilities\": {\n\t\t\t\t\"WiFi\": true,\n\t\t\t\t\"Shower\": true,\n\t\t\t\t\"Food\": true\n\t\t\t},\n\t\t\t\"media\": {\n\t\t\t\t\"images\": [\n\t\t\t\t\t{\n\t\t\t\t\t\t\"url\": \"https://cdn.example.com/lounges/sin01.jpg\",\n\t\t\t\t\t\t\"type\": \"exterior\"\n\t\t\t\t\t}\n\t\t\t\t]\n\t\t\t}\n\t\t}\n\t],\n\t\"total_count\": 1\n}"},{"id":"c491df24-5dec-499b-b203-8d11db5b9413","name":"200 - No Lounges at Nearest Airport","originalRequest":{"method":"POST","header":[{"key":"Content-Type","value":"application/json","type":"text"}],"body":{"mode":"raw","raw":"{\n\t\"pass_id\": \"{{pass_id}}\",\n\t\"latitude\": 25.2528,\n\t\"longitude\": 55.3644,\n\t\"language_code\": \"en-GB\"\n}","options":{"raw":{"language":"json"}}},"url":"{{base_url}}/v1/lounge/nearby-search"},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"cookie":[],"responseTime":null,"body":"{\n\t\"nearest_airport\": {\n\t\t\"airport_code\": \"DXB\",\n\t\t\"name\": \"Dubai International Airport\",\n\t\t\"distance_km\": 3.1\n\t},\n\t\"lounges\": [],\n\t\"total_count\": 0\n}"},{"id":"3289715c-03eb-47a8-bb62-a42fd96ef35f","name":"200 - Using Chinese Language Code","originalRequest":{"method":"POST","header":[{"key":"Content-Type","value":"application/json","type":"text"}],"body":{"mode":"raw","raw":"{\n\t\"pass_id\": \"{{pass_id}}\",\n\t\"latitude\": 22.308,\n\t\"longitude\": 113.9185,\n\t\"language_code\": \"zh-HK\"\n}","options":{"raw":{"language":"json"}}},"url":"{{base_url}}/v1/lounge/nearby-search"},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"cookie":[],"responseTime":null,"body":"{\n\t\"nearest_airport\": {\n\t\t\"airport_code\": \"HKG\",\n\t\t\"name\": \"\\u9999\\u6e2f\\u570b\\u969b\\u6a5f\\u5834\",\n\t\t\"distance_km\": 0.2\n\t},\n\t\"lounges\": [\n\t\t{\n\t\t\t\"lounge_code\": \"HKG01\",\n\t\t\t\"lounge_name\": \"\\u7ff1\\u7fd4\\u5eca \\u8cb4\\u8cd3\\u5ba4 (\\u4e00\\u865f\\u5ba2\\u904b\\u5927\\u6a13)\",\n\t\t\t\"distance_km\": 0.3,\n\t\t\t\"location\": {\n\t\t\t\t\"city\": \"\\u9999\\u6e2f\",\n\t\t\t\t\"country\": \"\\u9999\\u6e2f\",\n\t\t\t\t\"country_code\": \"HK\",\n\t\t\t\t\"airport_code\": \"HKG\",\n\t\t\t\t\"terminal\": \"1\",\n\t\t\t\t\"latitude\": 22.308,\n\t\t\t\t\"longitude\": 113.9185\n\t\t\t},\n\t\t\t\"facilities\": {\n\t\t\t\t\"WiFi\": true,\n\t\t\t\t\"Shower\": true,\n\t\t\t\t\"Food\": true\n\t\t\t},\n\t\t\t\"media\": {\n\t\t\t\t\"images\": [\n\t\t\t\t\t{\n\t\t\t\t\t\t\"url\": \"https://cdn.example.com/lounges/hkg01.jpg\",\n\t\t\t\t\t\t\"type\": \"exterior\"\n\t\t\t\t\t}\n\t\t\t\t]\n\t\t\t}\n\t\t}\n\t],\n\t\"total_count\": 1\n}"},{"id":"61945b22-02d3-4716-ad69-4c75b7664e27","name":"400 - Missing pass_id","originalRequest":{"method":"POST","header":[{"key":"Content-Type","value":"application/json","type":"text"}],"body":{"mode":"raw","raw":"{\n\t\"latitude\": 22.308,\n\t\"longitude\": 113.9185\n}","options":{"raw":{"language":"json"}}},"url":"{{base_url}}/v1/lounge/nearby-search"},"status":"Bad Request","code":400,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"cookie":[],"responseTime":null,"body":"{\n\t\"error\": \"invalid_request\",\n\t\"error_description\": \"pass_id is required.\",\n\t\"code\": 400\n}"},{"id":"9891dec1-7220-4cbf-8402-2bcaf7e0eec6","name":"400 - Missing latitude","originalRequest":{"method":"POST","header":[{"key":"Content-Type","value":"application/json","type":"text"}],"body":{"mode":"raw","raw":"{\n\t\"pass_id\": \"{{pass_id}}\",\n\t\"longitude\": 113.9185\n}","options":{"raw":{"language":"json"}}},"url":"{{base_url}}/v1/lounge/nearby-search"},"status":"Bad Request","code":400,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"cookie":[],"responseTime":null,"body":"{\n\t\"error\": \"invalid_request\",\n\t\"error_description\": \"latitude is required.\",\n\t\"code\": 400\n}"},{"id":"0d9287a6-ab5f-45c3-af0d-d92d93dbbc65","name":"400 - Missing longitude","originalRequest":{"method":"POST","header":[{"key":"Content-Type","value":"application/json","type":"text"}],"body":{"mode":"raw","raw":"{\n\t\"pass_id\": \"{{pass_id}}\",\n\t\"latitude\": 22.308\n}","options":{"raw":{"language":"json"}}},"url":"{{base_url}}/v1/lounge/nearby-search"},"status":"Bad Request","code":400,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"cookie":[],"responseTime":null,"body":"{\n\t\"error\": \"invalid_request\",\n\t\"error_description\": \"longitude is required.\",\n\t\"code\": 400\n}"},{"id":"1433c3fb-2de5-48d6-9f82-6dc7e008c43a","name":"400 - Latitude Out of Range","originalRequest":{"method":"POST","header":[{"key":"Content-Type","value":"application/json","type":"text"}],"body":{"mode":"raw","raw":"{\n\t\"pass_id\": \"{{pass_id}}\",\n\t\"latitude\": 91.0,\n\t\"longitude\": 113.9185\n}","options":{"raw":{"language":"json"}}},"url":"{{base_url}}/v1/lounge/nearby-search"},"status":"Bad Request","code":400,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"cookie":[],"responseTime":null,"body":"{\n\t\"error\": \"invalid_request\",\n\t\"error_description\": \"latitude must be between -90 and 90.\",\n\t\"code\": 400\n}"},{"id":"1fb925bf-55ad-436e-8480-59e5ee7e9582","name":"401 - Invalid Token","originalRequest":{"method":"POST","header":[{"key":"Content-Type","value":"application/json","type":"text"}],"body":{"mode":"raw","raw":"{\n\t\"pass_id\": \"{{pass_id}}\",\n\t\"latitude\": 22.308,\n\t\"longitude\": 113.9185\n}","options":{"raw":{"language":"json"}}},"url":"{{base_url}}/v1/lounge/nearby-search"},"status":"Unauthorized","code":401,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"cookie":[],"responseTime":null,"body":"{\n\t\"error\": \"invalid_token\",\n\t\"error_description\": \"Access token is invalid or has expired.\",\n\t\"code\": 401\n}"},{"id":"632b47da-92f3-4b5a-a82e-014186b1ef5f","name":"404 - No Airport Found Nearby","originalRequest":{"method":"POST","header":[{"key":"Content-Type","value":"application/json","type":"text"}],"body":{"mode":"raw","raw":"{\n\t\"pass_id\": \"{{pass_id}}\",\n\t\"latitude\": 0.0,\n\t\"longitude\": 0.0\n}","options":{"raw":{"language":"json"}}},"url":"{{base_url}}/v1/lounge/nearby-search"},"status":"Not Found","code":404,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"cookie":[],"responseTime":null,"body":"{\n\t\"error\": \"airport_not_found\",\n\t\"error_description\": \"No nearby airport found for the provided location.\",\n\t\"code\": 404\n}"},{"id":"f6dda324-2451-493e-a286-27f39eec2ad1","name":"404 - Pass Not Found","originalRequest":{"method":"POST","header":[{"key":"Content-Type","value":"application/json","type":"text"}],"body":{"mode":"raw","raw":"{\n\t\"pass_id\": \"nonexistent-pass-id\",\n\t\"latitude\": 22.308,\n\t\"longitude\": 113.9185\n}","options":{"raw":{"language":"json"}}},"url":"{{base_url}}/v1/lounge/nearby-search"},"status":"Not Found","code":404,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"cookie":[],"responseTime":null,"body":"{\n\t\"error\": \"pass_not_found\",\n\t\"error_description\": \"Pass not found: nonexistent-pass-id.\",\n\t\"code\": 404\n}"},{"id":"9a6ab834-1654-4aaa-ae06-14695650becd","name":"422 - Pass Not Active","originalRequest":{"method":"POST","header":[{"key":"Content-Type","value":"application/json","type":"text"}],"body":{"mode":"raw","raw":"{\n\t\"pass_id\": \"pending-pass-id\",\n\t\"latitude\": 22.308,\n\t\"longitude\": 113.9185\n}","options":{"raw":{"language":"json"}}},"url":"{{base_url}}/v1/lounge/nearby-search"},"status":"Unprocessable Entity","code":422,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"cookie":[],"responseTime":null,"body":"{\n\t\"error\": \"pass_not_active\",\n\t\"error_description\": \"Pass pending-pass-id has no active provider membership.\",\n\t\"code\": 422\n}"},{"id":"2d57b477-d163-4850-96c5-f632df38508f","name":"502 - Geocoding Failed","originalRequest":{"method":"POST","header":[{"key":"Content-Type","value":"application/json","type":"text"}],"body":{"mode":"raw","raw":"{\n\t\"pass_id\": \"{{pass_id}}\",\n\t\"latitude\": 22.308,\n\t\"longitude\": 113.9185\n}","options":{"raw":{"language":"json"}}},"url":"{{base_url}}/v1/lounge/nearby-search"},"status":"Bad Gateway","code":502,"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json"}],"cookie":[],"responseTime":null,"body":"{\n\t\"error\": \"geocoding_failed\",\n\t\"error_description\": \"Unable to resolve nearest airport for the provided location.\",\n\t\"code\": 502\n}"}],"_postman_id":"c590cfdd-fdcd-43a6-946d-08ac771ab9b5"},{"name":"(Webhook) Batch Create Passes Callback","id":"a9f2b766-26b1-4fa9-b26a-698032635c64","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"POST","header":[],"body":{"mode":"raw","raw":"{\n    \"job_id\": \"batch-job-789\",\n    \"status\": \"success\",\n    \"completed_at\": \"2025-12-11T14:30:00Z\",\n    \"results\": [\n        {\n            \"item_index\": 0,\n            \"pass_id\": \"abc123\",\n            \"type\": \"priority\",\n            \"item_status\": \"created\",\n            \"dmc_qr_data\": \"PP/070326/HKTCLLSG26/abc123\",\n            \"expiry\": \"2027-03-31\"\n        },\n        {\n            \"item_index\": 1,\n            \"pass_id\": \"abc44343\",\n            \"type\": \"esim\",\n            \"item_status\": \"created\",\n            \"iccid\": \"8944501902198304826\",\n            \"qr_code_data\": \"LPA:1$sm-v4-057-a-gtm.pr.go-esim.com$OC_SAMPLE_ACTIVATION_CODE\",\n            \"expiry\": \"2027-03-31\",\n            \"esim_data\": {\n                \"package_name\": \"HK 7 Days 1GB\",\n                \"data_remaining_mb\": null,\n                \"expiry_date\": \"2027-03-31\",\n                \"activation_code\": null,\n                \"install_qr_data\": \"LPA:1$sm-v4-057-a-gtm.pr.go-esim.com$OC_SAMPLE_ACTIVATION_CODE\"\n            }\n        }\n    ]\n}","options":{"raw":{"language":"json"}}},"url":"/webhook/pass/batch-create","description":"<p>The Batch Create Passes Webhook provides asynchronous notifications to client upon completion of a batch pass creation job, delivering results (successes, failures, per-item details) without polling. This enhances efficiency for large-scale operations, abstracting batch processing into push-based updates. Notifications include aggregated status, allowing user system to handle finance reports/audits seamlessly.</p>\n<ul>\n<li><p><strong>Use Case:</strong> Receive real-time batch outcomes (e.g., for campaigns issuing 1000+ passes) to update user's systems or notify users.</p>\n</li>\n<li><p><strong>Security Notes:</strong> Attend shared secret in X-Signature header. Use HTTPS for your URL.</p>\n</li>\n</ul>\n<h2 id=\"input-params-webhook-payload\">Input Params (Webhook Payload)</h2>\n<p>Our system sends POST JSON to your URL. Verify X-Signature header (HMAC-SHA256 of body using shared secret).</p>\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>Always Present</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>job_id</td>\n<td>string</td>\n<td>Yes</td>\n<td>Batch job ID from original response.</td>\n</tr>\n<tr>\n<td>status</td>\n<td>string</td>\n<td>Yes</td>\n<td>Overall status: \"completed\", \"partial_success\", \"failed\".</td>\n</tr>\n<tr>\n<td>completed_at</td>\n<td>string</td>\n<td>Yes</td>\n<td>Timestamp (ISO 8601, e.g., \"2025-12-11T14:30:00Z\").</td>\n</tr>\n<tr>\n<td>results</td>\n<td>array</td>\n<td>Yes</td>\n<td>Array of per-item outcomes.</td>\n</tr>\n<tr>\n<td>- item_index</td>\n<td>integer</td>\n<td>Yes (per result)</td>\n<td>Original array index (0-based).</td>\n</tr>\n<tr>\n<td>- item_status</td>\n<td>string</td>\n<td>Yes (per result)</td>\n<td><code>\"created\"</code> or <code>\"failed\"</code>.</td>\n</tr>\n<tr>\n<td>- pass_id</td>\n<td>string</td>\n<td>No</td>\n<td>Created pass ID (on success).</td>\n</tr>\n<tr>\n<td>- type</td>\n<td>string</td>\n<td>No</td>\n<td>Pass type on success: <code>\"priority\"</code>, <code>\"loungekey\"</code>, <code>\"esim\"</code>, <code>\"bundle\"</code>.</td>\n</tr>\n<tr>\n<td>- status</td>\n<td>string</td>\n<td>No</td>\n<td>Pass status on success. Always <code>\"created\"</code>.</td>\n</tr>\n<tr>\n<td>- dmc_qr_data</td>\n<td>string</td>\n<td>No</td>\n<td>For Priority Pass: DMC QR data. Absent for LoungeKey and eSIM.</td>\n</tr>\n<tr>\n<td>- barcode_string</td>\n<td>string</td>\n<td>No</td>\n<td>For LoungeKey (if delivery_method=barcode_string).</td>\n</tr>\n<tr>\n<td>- qr_code_data</td>\n<td>string</td>\n<td>No</td>\n<td><strong>eSIM only.</strong> LPA QR install string.</td>\n</tr>\n<tr>\n<td>- expiry</td>\n<td>string</td>\n<td>No</td>\n<td>Pass expiry date (YYYY-MM-DD).</td>\n</tr>\n<tr>\n<td>- entitlement</td>\n<td>array</td>\n<td>No</td>\n<td>Service entitlement array. Same structure as Create Pass <code>entitlement[]</code>.</td>\n</tr>\n<tr>\n<td>- error</td>\n<td>string</td>\n<td>No</td>\n<td>Per-item error code (on failure).</td>\n</tr>\n<tr>\n<td>- error_description</td>\n<td>string</td>\n<td>No</td>\n<td>Per-item error description (on failure).</td>\n</tr>\n<tr>\n<td>- code</td>\n<td>integer</td>\n<td>No</td>\n<td>HTTP error code (on failure).</td>\n</tr>\n</tbody>\n</table>\n</div><h3 id=\"esim_data-object\">esim_data Object</h3>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th><strong>Parameter</strong></th>\n<th><strong>Type</strong></th>\n<th>Always Present</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>package_name</td>\n<td>string</td>\n<td>Yes</td>\n<td>Plan name (e.g. \"Global 7 Days 1GB\")</td>\n</tr>\n<tr>\n<td>data_remaining_mb</td>\n<td>string</td>\n<td>Yes</td>\n<td>Remaining data in MB (or null if unlimited)</td>\n</tr>\n<tr>\n<td>expiry_date</td>\n<td>date</td>\n<td>Yes</td>\n<td>Validity end date (YYYY-MM-DD)</td>\n</tr>\n<tr>\n<td>activation_code</td>\n<td>string</td>\n<td>Yes</td>\n<td>Activation code for manual installation</td>\n</tr>\n<tr>\n<td>install_qr_data</td>\n<td>string</td>\n<td>Yes</td>\n<td>Data for generating install QR code.</td>\n</tr>\n</tbody>\n</table>\n</div>","urlObject":{"path":["webhook","pass","batch-create"],"query":[],"variable":[]}},"response":[{"id":"6e289fd4-f46a-44dd-bcdd-0377d9fc9f2f","name":"Success","originalRequest":{"method":"POST","header":[{"key":"Content-Type","value":"application/json","type":"text"}],"body":{"mode":"raw","raw":"{\n  \"job_id\": \"batch-job-789\",\n  \"status\": \"success\",\n  \"completed_at\": \"2025-12-11T14:30:00Z\",\n  \"results\": [\n    {\n        \"item_index\": 0,\n        \"pass_id\": \"abc123\",\n        \"item_status\": \"created\",\n        \"dmc_qr_data\": \"QR_STRING_FOR_PRIORITY\",\n        \"expiry\":  \"2027-03-31\"\n    },\n    {\n      \"item_index\": 1,\n      \"pass_id\": \"abc44343\",\n      \"item_status\": \"created\",\n      \"esim_data\": {\n            \"package_name\": \"Global 7 Days 1GB\",\n            \"data_remaining_mb\": 1024,\n            \"valid_until\": \"2026-12-31\",\n            \"activation_code\": \"ABCD-EFGH-IJKL\",\n            \"install_qr_data\": \"ESIM_INSTALL_QR_DATA\"\n      }\n    }\n  ]\n}","options":{"raw":{"language":"json"}}},"url":"/webhook/pass/batch-create"},"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json","description":"","type":"text"}],"cookie":[],"responseTime":null,"body":"{\n    \"job_id\": \"job-uuid-001\",\n    \"status\": \"completed\",\n    \"completed_at\": \"2027-06-01T10:30:00Z\",\n    \"results\": [\n        {\n            \"item_index\": 0,\n            \"item_status\": \"created\",\n            \"pass_id\": \"12345678901234567890123456789012\",\n            \"type\": \"priority\",\n            \"status\": \"created\",\n            \"dmc_qr_data\": \"PP/010627/HKTCLLSG01/12345678\",\n            \"barcode_string\": null,\n            \"expiry\": \"2027-12-31\",\n            \"entitlement\": [\n                {\n                    \"entitlement_id\": \"ent-uuid-001\",\n                    \"type\": \"lounge_access\",\n                    \"status\": \"active\",\n                    \"component\": null,\n                    \"quantity\": 2,\n                    \"unit\": \"visit\",\n                    \"used\": 0,\n                    \"remaining\": 2,\n                    \"dmc_qr_data\": \"PP/010627/HKTCLLSG01/12345678\",\n                    \"barcode_string\": null,\n                    \"expiry\": \"2027-12-31\"\n                }\n            ]\n        },\n        {\n            \"item_index\": 1,\n            \"item_status\": \"created\",\n            \"pass_id\": \"sim-user-002\",\n            \"type\": \"esim\",\n            \"status\": \"created\",\n            \"qr_code_data\": \"LPA:1$sm-v4-057-a-gtm.pr.go-esim.com$OC_SAMPLE_ACTIVATION_CODE\",\n            \"expiry\": \"2027-06-08\",\n            \"entitlement\": [\n                {\n                    \"entitlement_id\": \"ent-uuid-esim-002\",\n                    \"type\": \"esim\",\n                    \"status\": \"active\",\n                    \"component\": null,\n                    \"quantity\": 1024,\n                    \"unit\": \"MB\",\n                    \"used\": 0,\n                    \"remaining\": 1024,\n                    \"iccid\": \"8944501902198304826\",\n                    \"qr_code_data\": \"LPA:1$sm-v4-057-a-gtm.pr.go-esim.com$OC_SAMPLE_ACTIVATION_CODE\",\n                    \"esim_data\": {\n                        \"package_name\": \"HK 7 Days 1GB\",\n                        \"data_remaining_mb\": null,\n                        \"expiry_date\": \"2027-06-08\",\n                        \"activation_code\": null,\n                        \"install_qr_data\": \"LPA:1$sm-v4-057-a-gtm.pr.go-esim.com$OC_SAMPLE_ACTIVATION_CODE\"\n                    },\n                    \"expiry\": \"2027-06-08\"\n                }\n            ]\n        }\n    ]\n}"},{"id":"d2f7e31c-ca72-4733-a6c0-6a2340f3f815","name":"Partial Success","originalRequest":{"method":"POST","header":[{"key":"Content-Type","value":"application/json","type":"text"}],"body":{"mode":"raw","raw":"{\n  \"job_id\": \"batch-job-789\",\n  \"status\": \"partial_success\",\n  \"completed_at\": \"2025-12-11T14:30:00Z\",\n  \"results\": [\n    {\n        \"item_index\": 0,\n        \"pass_id\": \"abc123\",\n        \"item_status\": \"created\",\n        \"dmc_qr_data\": \"QR_STRING_FOR_PRIORITY\",\n        \"expiry\":  \"2027-03-31\"\n    },\n    {\n        \"item_index\": 1,\n        \"item_status\": \"failed\",\n        \"error\": \"external_card_id_duplicate_invalid\",\n        \"error_description\": \"Provide external card ID duplicate or invalid\"\n    }\n  ]\n}","options":{"raw":{"language":"json"}}},"url":"/webhook/pass/batch-create"},"_postman_previewlanguage":"json","header":[{"key":"Content-Type","value":"application/json","description":"","type":"text"}],"cookie":[],"responseTime":null,"body":"{\n    \"job_id\": \"job-uuid-002\",\n    \"status\": \"partial_success\",\n    \"completed_at\": \"2027-06-01T10:35:00Z\",\n    \"results\": [\n        {\n            \"item_index\": 0,\n            \"item_status\": \"created\",\n            \"pass_id\": \"12345678901234567890123456789012\",\n            \"type\": \"priority\",\n            \"status\": \"created\",\n            \"dmc_qr_data\": \"PP/010627/HKTCLLSG01/12345678\",\n            \"barcode_string\": null,\n            \"expiry\": \"2027-12-31\",\n            \"entitlement\": [\n                {\n                    \"entitlement_id\": \"ent-uuid-001\",\n                    \"type\": \"lounge_access\",\n                    \"status\": \"active\",\n                    \"component\": null,\n                    \"quantity\": 2,\n                    \"unit\": \"visit\",\n                    \"used\": 0,\n                    \"remaining\": 2,\n                    \"dmc_qr_data\": \"PP/010627/HKTCLLSG01/12345678\",\n                    \"barcode_string\": null,\n                    \"expiry\": \"2027-12-31\"\n                }\n            ]\n        },\n        {\n            \"item_index\": 1,\n            \"item_status\": \"failed\",\n            \"error\": \"invalid_ext_card_id\",\n            \"error_description\": \"Provided external card id is duplicate or invalid\",\n            \"code\": 402\n        }\n    ]\n}"}],"_postman_id":"a9f2b766-26b1-4fa9-b26a-698032635c64"}],"id":"6c72f6c9-cb0a-443b-9bb5-8dd19a67483d","_postman_id":"6c72f6c9-cb0a-443b-9bb5-8dd19a67483d","description":""},{"name":"Core Loyalty","item":[{"name":"App - Lounges (Private Access)","item":[],"id":"d12e9db2-f005-45bf-a48b-d69d8a94d81d","_postman_id":"d12e9db2-f005-45bf-a48b-d69d8a94d81d","description":""},{"name":"App - eSim (Private Access)","item":[],"id":"0dfeed61-0854-45dc-b2c8-d62b4ae35f5f","_postman_id":"0dfeed61-0854-45dc-b2c8-d62b4ae35f5f","description":""},{"name":"App - OTA (In Development)","item":[],"id":"ff0fb15f-6692-4388-bc8b-d922acae28f1","_postman_id":"ff0fb15f-6692-4388-bc8b-d922acae28f1","description":""},{"name":"App - Fast Track (In Development)","item":[],"id":"e1664ae2-dd86-4e26-900e-7aec49b072d5","_postman_id":"e1664ae2-dd86-4e26-900e-7aec49b072d5","description":""},{"name":"App - Airport Pickups (In Development)","item":[],"id":"e57dcdf8-d38a-4324-a74f-8c6a07c54b4f","_postman_id":"e57dcdf8-d38a-4324-a74f-8c6a07c54b4f","description":""}],"id":"c4f93200-7b54-4e2f-8bf9-8a754557bb42","_postman_id":"c4f93200-7b54-4e2f-8bf9-8a754557bb42","description":""}],"event":[{"listen":"prerequest","script":{"type":"text/javascript","packages":{},"requests":{},"exec":[""],"id":"d8173940-6993-4ab6-8040-9866adc91824"}},{"listen":"test","script":{"type":"text/javascript","packages":{},"requests":{},"exec":[""],"id":"04c90e88-a2eb-4790-a1e9-2627b0ead630"}}]}