{
  "info": {
    "name": "AletaPlanet API — available operations",
    "_postman_id": "9f2c1d84-5b7e-4a30-9c61-3d8e0b5a7f42",
    "description": "AletaPlanet API v1.0.0.\n\nThis collection contains the 43 operations the API routes today.\n\nThe specification publishes 46. The other 3 are\ndocumented but not yet routed and return 404 — they are omitted here\ndeliberately, so that every request in this collection is one that can\nactually run. See PROCESSOR-COVERAGE.md for which they are and why.\n\nSome of the requests here are capability-gated: they are mounted only on\na program whose processor backs them, and answer 404 on one that does\nnot. The API reference marks each operation that depends on one; send\nit once and read the status, which is the answer that cannot be stale.\n\nSet access_token in the environment before running anything. Obtain one\nfrom POST /oauth/token with an assertion signed by your private key — the\nquickstart shows how in Python and Node. Postman cannot sign it for you,\nwhich is why that request is not in this collection. The token\ndecides your organization and environment; base_url must match. It does\nnot decide a program: Create an account carries program_id in its body,\nand it is the only request here that does. Run List your programs first\nto read the ids your organization may use in this environment; Settings >\nPrograms in the cockpit shows the same list. POST /v1/pin_keys accepts an\noptional program_id too, and is sent with no body because one program is\nthe common case.\n\nGenerated by scripts/gen-postman.mjs. Do not edit by hand.",
    "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
  },
  "item": [
    {
      "name": "Programs",
      "item": [
        {
          "name": "List your programs",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Authorization",
                "value": "Bearer {{access_token}}"
              }
            ],
            "url": {
              "raw": "{{base_url}}/v1/programs",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "v1",
                "programs"
              ]
            },
            "description": "Every program your organization can issue against in this environment.\n\nA program's ID is different in sandbox and production, so read it here\ninstead of hard-coding it.\n\nYour access token determines the organization and environment, so you\ndon't need to pass anything else. Use your production credentials to get\nyour production program IDs. The same products will have different\n`prog_` IDs."
          },
          "response": []
        }
      ]
    },
    {
      "name": "Cardholders",
      "item": [
        {
          "name": "List cardholders",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Authorization",
                "value": "Bearer {{access_token}}"
              }
            ],
            "url": {
              "raw": "{{base_url}}/v1/cardholders",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "v1",
                "cardholders"
              ],
              "query": [
                {
                  "key": "limit",
                  "value": "",
                  "description": "Page size. Values above the maximum are rejected, not clamped.",
                  "disabled": true
                },
                {
                  "key": "starting_after",
                  "value": "",
                  "description": "Opaque cursor for the next page. Valid for 24 hours.",
                  "disabled": true
                },
                {
                  "key": "ending_before",
                  "value": "",
                  "description": "Opaque cursor for the previous page. Mutually exclusive with `starting_after`.",
                  "disabled": true
                },
                {
                  "key": "kyc_status",
                  "value": "",
                  "description": "Filter by verification state.",
                  "disabled": true
                },
                {
                  "key": "reference",
                  "value": "",
                  "description": "Filter by your own identifier.",
                  "disabled": true
                }
              ]
            },
            "description": "Returns a page of cardholders, most recently created first.\nCursor-paginated: loop while `has_more`, passing `next_cursor` as\n`starting_after`."
          },
          "response": []
        },
        {
          "name": "Create a cardholder",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Authorization",
                "value": "Bearer {{access_token}}"
              },
              {
                "key": "Idempotency-Key",
                "value": "{{$guid}}"
              },
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"type\": \"individual\",\n  \"first_name\": \"Test\",\n  \"last_name\": \"Approved\",\n  \"email\": \"test.approved@example.com\",\n  \"address\": {\n    \"line1\": \"350 Orchard Road\",\n    \"city\": \"Singapore\",\n    \"postal_code\": \"238868\",\n    \"country\": \"SGP\"\n  },\n  \"identity_document\": {\n    \"type\": \"national_id\",\n    \"number\": \"S1234567D\"\n  }\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "url": {
              "raw": "{{base_url}}/v1/cardholders",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "v1",
                "cardholders"
              ]
            },
            "description": "Creates the cardholder record that accounts and cards belong to.\n\nA new cardholder starts with a `kyc_status` of `not_started` or\n`pending`, depending on the program. A card can't be issued until the\nstatus reaches `approved`.\n\nOnly individual cardholders are supported. Business cardholders will be\nsupported in the future."
          },
          "response": []
        },
        {
          "name": "Retrieve a cardholder",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Authorization",
                "value": "Bearer {{access_token}}"
              }
            ],
            "url": {
              "raw": "{{base_url}}/v1/cardholders/:cardholder_id",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "v1",
                "cardholders",
                ":cardholder_id"
              ],
              "variable": [
                {
                  "key": "cardholder_id",
                  "value": "{{cardholder_id}}"
                }
              ]
            },
            "description": "Returns a single cardholder, including its current verification state."
          },
          "response": []
        },
        {
          "name": "Update a cardholder",
          "request": {
            "method": "PATCH",
            "header": [
              {
                "key": "Authorization",
                "value": "Bearer {{access_token}}"
              },
              {
                "key": "Idempotency-Key",
                "value": "{{$guid}}"
              },
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"email\": \"<email>\",\n  \"phone\": \"<phone>\",\n  \"address\": {\n    \"line1\": \"<line1>\",\n    \"line2\": \"<line2>\",\n    \"city\": \"<city>\",\n    \"state\": \"<state>\",\n    \"postal_code\": \"<postal_code>\",\n    \"country\": \"<country>\"\n  },\n  \"reference\": \"<reference>\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "url": {
              "raw": "{{base_url}}/v1/cardholders/:cardholder_id",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "v1",
                "cardholders",
                ":cardholder_id"
              ],
              "variable": [
                {
                  "key": "cardholder_id",
                  "value": "{{cardholder_id}}"
                }
              ]
            },
            "description": "Only the fields supplied are changed."
          },
          "response": []
        },
        {
          "name": "List a cardholder's cards",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Authorization",
                "value": "Bearer {{access_token}}"
              }
            ],
            "url": {
              "raw": "{{base_url}}/v1/cardholders/:cardholder_id/cards",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "v1",
                "cardholders",
                ":cardholder_id",
                "cards"
              ],
              "query": [
                {
                  "key": "limit",
                  "value": "",
                  "description": "Page size. Values above the maximum are rejected, not clamped.",
                  "disabled": true
                },
                {
                  "key": "starting_after",
                  "value": "",
                  "description": "Opaque cursor for the next page. Valid for 24 hours.",
                  "disabled": true
                }
              ],
              "variable": [
                {
                  "key": "cardholder_id",
                  "value": "{{cardholder_id}}"
                }
              ]
            },
            "description": "Returns every card issued to this cardholder, across all of its\naccounts."
          },
          "response": []
        },
        {
          "name": "List KYC attestations",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Authorization",
                "value": "Bearer {{access_token}}"
              }
            ],
            "url": {
              "raw": "{{base_url}}/v1/cardholders/:cardholder_id/kyc",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "v1",
                "cardholders",
                ":cardholder_id",
                "kyc"
              ],
              "query": [
                {
                  "key": "limit",
                  "value": "",
                  "description": "Page size. Values above the maximum are rejected, not clamped.",
                  "disabled": true
                },
                {
                  "key": "starting_after",
                  "value": "",
                  "description": "Opaque cursor for the next page. Valid for 24 hours.",
                  "disabled": true
                }
              ],
              "variable": [
                {
                  "key": "cardholder_id",
                  "value": "{{cardholder_id}}"
                }
              ]
            },
            "description": "Returns all identity verification attestations recorded for the\ncardholder, newest first.\n\nThe first item is the current one.\n\nIf a cardholder is verified again later, each verification is kept. This\ngives you the full history an auditor may need, without having to\nrebuild it from webhook events."
          },
          "response": []
        },
        {
          "name": "Report a KYC outcome",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Authorization",
                "value": "Bearer {{access_token}}"
              },
              {
                "key": "Idempotency-Key",
                "value": "{{$guid}}"
              },
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"status\": \"approved\",\n  \"verified_at\": \"2026-07-29T11:04:00Z\",\n  \"provider\": \"Acme Identity\",\n  \"provider_reference\": \"chk_9f31c7\",\n  \"method\": \"document_and_selfie\",\n  \"expires_at\": \"2028-07-29T00:00:00Z\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "url": {
              "raw": "{{base_url}}/v1/cardholders/:cardholder_id/kyc",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "v1",
                "cardholders",
                ":cardholder_id",
                "kyc"
              ],
              "variable": [
                {
                  "key": "cardholder_id",
                  "value": "{{cardholder_id}}"
                }
              ]
            },
            "description": "Records the result of an identity check you performed and updates the\ncardholder's `kyc_status`.\n\n**You run the verification; we record the result.** The request is an\nattestation that says who verified the person, when, how, and what the\nresult was. Because this is a compliance record, `provider` and\n`verified_at` are required.\n\nReporting `approved` allows cards to be issued. If you report a new\nresult for a cardholder who was already verified, the new attestation\nreplaces the previous one as the current result. Both records are still\nkept and can be read.\n\n### When you also send the identity and documents\n\nUsually, you only send the attestation. The identity documents stay with\nyou and your verification provider.\n\nSome processors do their own identity checks and need the person's\ndetails and documents before opening an account. For those programs, you\ncan send that information here:\n\n- `identity` contains the required identity fields.\n- `documents` contains the document images.\n\nIf the program requires this evidence and you don't provide it, creating\nan account is rejected with `kyc_identity_required`. The attestation is\nstill recorded normally.\n\nThis is the only API request that accepts files, so it has a larger\nrequest size limit. It's designed for up to three documents, with each\nfile up to 20 MiB, base64 encoded.\n\nDocuments are stored encrypted outside the main database. We don't\nreturn the files later. The `documents` field in responses only contains\nmetadata, with no URL or file content."
          },
          "response": []
        }
      ]
    },
    {
      "name": "Accounts",
      "item": [
        {
          "name": "List accounts",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Authorization",
                "value": "Bearer {{access_token}}"
              }
            ],
            "url": {
              "raw": "{{base_url}}/v1/accounts",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "v1",
                "accounts"
              ],
              "query": [
                {
                  "key": "limit",
                  "value": "",
                  "description": "Page size. Values above the maximum are rejected, not clamped.",
                  "disabled": true
                },
                {
                  "key": "starting_after",
                  "value": "",
                  "description": "Opaque cursor for the next page. Valid for 24 hours.",
                  "disabled": true
                },
                {
                  "key": "cardholder_id",
                  "value": "",
                  "description": "Return only accounts belonging to this cardholder.",
                  "disabled": true
                },
                {
                  "key": "program_id",
                  "value": "",
                  "description": "Return only accounts opened under this program. Omit it and the page",
                  "disabled": true
                }
              ]
            },
            "description": "Returns a page of accounts. Filter by `cardholder_id` to get the\naccounts belonging to one cardholder, or by `program_id` to get one\nproduct's accounts."
          },
          "response": []
        },
        {
          "name": "Create an account",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Authorization",
                "value": "Bearer {{access_token}}"
              },
              {
                "key": "Idempotency-Key",
                "value": "{{$guid}}"
              },
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"program_id\": \"prog_01HX8ZQ2K4M7P9RSTVWXYZABCD\",\n  \"cardholder_id\": \"chd_01HX8ZQ2K4M7P9RSTVWXYZABCD\",\n  \"currency\": \"SGD\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "url": {
              "raw": "{{base_url}}/v1/accounts",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "v1",
                "accounts"
              ]
            },
            "description": "Opens a stored-value account for a cardholder in one currency.\n\nIf a cardholder needs two currencies, they need two separate accounts.\nThe API never converts between currencies automatically.\n\n**This is where you set the program.** `program_id` tells us which of\nyour products the account belongs to. Everything connected to the\naccount — its cards, authorizations, and transactions — inherits that\nprogram.\n\nIf `program_id` isn't one of your programs, the API returns\n`invalid_parameter`. It uses the same response whether the program\ndoesn't exist or simply isn't yours, so the API won't reveal whether\nanother program exists on the platform."
          },
          "response": []
        },
        {
          "name": "Retrieve an account",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Authorization",
                "value": "Bearer {{access_token}}"
              }
            ],
            "url": {
              "raw": "{{base_url}}/v1/accounts/:account_id",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "v1",
                "accounts",
                ":account_id"
              ],
              "variable": [
                {
                  "key": "account_id",
                  "value": "{{account_id}}"
                }
              ]
            },
            "description": "Returns a single account, including its current balances.\n\nThe `ledger_balance` is the total value in the account. The\n`available_balance` is the value that can be spent, which is the ledger\nbalance minus any funds held by pending authorizations."
          },
          "response": []
        },
        {
          "name": "Credit an account",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Authorization",
                "value": "Bearer {{access_token}}"
              },
              {
                "key": "Idempotency-Key",
                "value": "{{$guid}}"
              },
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"amount\": {\n    \"amount\": 0,\n    \"currency\": \"<currency>\"\n  }\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "url": {
              "raw": "{{base_url}}/v1/accounts/:account_id/credit",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "v1",
                "accounts",
                ":account_id",
                "credit"
              ],
              "variable": [
                {
                  "key": "account_id",
                  "value": "{{account_id}}"
                }
              ]
            },
            "description": "Adds money to an account, increasing both `ledger_balance` and\n`available_balance`.\n\nThere are two ways to prevent duplicate credits, and you should use\nboth:\n\n- `Idempotency-Key` protects against retries. Using the same key within\n24 hours returns the stored response instead of creating another credit.\n- `client_transaction_id` identifies the actual credit. It must be\nunique for the account and doesn't expire. Reusing the same ID with the\nsame amount returns `200` with `Idempotent-Replay: true` and doesn't\nmove any money. Reusing it with a different amount returns `409\nadjustment_already_applied`.\n\nSend both on every funding request."
          },
          "response": []
        },
        {
          "name": "Debit an account",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Authorization",
                "value": "Bearer {{access_token}}"
              },
              {
                "key": "Idempotency-Key",
                "value": "{{$guid}}"
              },
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"amount\": {\n    \"amount\": 0,\n    \"currency\": \"<currency>\"\n  }\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "url": {
              "raw": "{{base_url}}/v1/accounts/:account_id/debit",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "v1",
                "accounts",
                ":account_id",
                "debit"
              ],
              "variable": [
                {
                  "key": "account_id",
                  "value": "{{account_id}}"
                }
              ]
            },
            "description": "Removes money from an account. If the `available_balance` is too low,\nthe request fails with `insufficient_funds` and a `402`. Money held by\npending authorizations can't be debited.\n\nThere are two ways to prevent duplicate debits, and you should use both:\n\n- `Idempotency-Key` protects against retries. Using the same key within\n24 hours returns the stored response instead of creating another debit.\n- `client_transaction_id` identifies the actual debit. It must be unique\nfor the account and doesn't expire. Reusing the same ID with the same\namount returns `200` with `Idempotent-Replay: true` and doesn't move any\nmoney. Reusing it with a different amount returns `409\nadjustment_already_applied`.\n\nSend both on every debit request."
          },
          "response": []
        },
        {
          "name": "List an account's cards",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Authorization",
                "value": "Bearer {{access_token}}"
              }
            ],
            "url": {
              "raw": "{{base_url}}/v1/accounts/:account_id/cards",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "v1",
                "accounts",
                ":account_id",
                "cards"
              ],
              "query": [
                {
                  "key": "limit",
                  "value": "",
                  "description": "Page size. Values above the maximum are rejected, not clamped.",
                  "disabled": true
                },
                {
                  "key": "starting_after",
                  "value": "",
                  "description": "Opaque cursor for the next page. Valid for 24 hours.",
                  "disabled": true
                }
              ],
              "variable": [
                {
                  "key": "account_id",
                  "value": "{{account_id}}"
                }
              ]
            },
            "description": "Returns every card that spends from this account. An account can fund\nseveral cards; a card spends from exactly one account."
          },
          "response": []
        },
        {
          "name": "Block an account",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Authorization",
                "value": "Bearer {{access_token}}"
              },
              {
                "key": "Idempotency-Key",
                "value": "{{$guid}}"
              },
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"reason\": \"Suspected compromise, pending review\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "url": {
              "raw": "{{base_url}}/v1/accounts/:account_id/block",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "v1",
                "accounts",
                ":account_id",
                "block"
              ],
              "variable": [
                {
                  "key": "account_id",
                  "value": "{{account_id}}"
                }
              ]
            },
            "description": "Suspends the account. Every card funded by it declines with\n`account_blocked` until the account is unblocked, and credits and debits\nare refused.\n\nBlocking is reversible and does not touch the balances. Holds already\nplaced remain in force and still release on clearing or expiry."
          },
          "response": []
        },
        {
          "name": "Unblock an account",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Authorization",
                "value": "Bearer {{access_token}}"
              },
              {
                "key": "Idempotency-Key",
                "value": "{{$guid}}"
              }
            ],
            "url": {
              "raw": "{{base_url}}/v1/accounts/:account_id/unblock",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "v1",
                "accounts",
                ":account_id",
                "unblock"
              ],
              "variable": [
                {
                  "key": "account_id",
                  "value": "{{account_id}}"
                }
              ]
            },
            "description": "Returns a blocked account to `active`. Cards funded by it resume\nauthorizing immediately."
          },
          "response": []
        }
      ]
    },
    {
      "name": "Cards",
      "item": [
        {
          "name": "List cards",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Authorization",
                "value": "Bearer {{access_token}}"
              }
            ],
            "url": {
              "raw": "{{base_url}}/v1/cards",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "v1",
                "cards"
              ],
              "query": [
                {
                  "key": "limit",
                  "value": "",
                  "description": "Page size. Values above the maximum are rejected, not clamped.",
                  "disabled": true
                },
                {
                  "key": "starting_after",
                  "value": "",
                  "description": "Opaque cursor for the next page. Valid for 24 hours.",
                  "disabled": true
                },
                {
                  "key": "status",
                  "value": "",
                  "description": "Return only cards in this status.",
                  "disabled": true
                },
                {
                  "key": "form_factor",
                  "value": "",
                  "description": "Return only cards of this form factor.",
                  "disabled": true
                },
                {
                  "key": "account_id",
                  "value": "",
                  "description": "Return only cards that spend from this account.",
                  "disabled": true
                },
                {
                  "key": "program_id",
                  "value": "",
                  "description": "Return only cards belonging to this program. Omit it and the page",
                  "disabled": true
                }
              ]
            },
            "description": "Returns a page of cards. Filter by `status` to find, for example,\nevery frozen card, or by `program_id` to narrow to one product."
          },
          "response": []
        },
        {
          "name": "Issue a card",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Authorization",
                "value": "Bearer {{access_token}}"
              },
              {
                "key": "Idempotency-Key",
                "value": "{{$guid}}"
              },
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"cardholder_id\": \"chd_01HX8ZQ2K4M7P9RSTVWXYZABCD\",\n  \"account_id\": \"acct_01HX8ZQ2K4M7P9RSTVWXYZABCD\",\n  \"form_factor\": \"virtual\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "url": {
              "raw": "{{base_url}}/v1/cards",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "v1",
                "cards"
              ]
            },
            "description": "Issues a virtual or a physical card for an account.\n\nA virtual card needs no more than the cardholder and the account. A\nphysical card also needs `embossed_name`, the name printed on it, and a\n`delivery_address`. To have plastic made for a card you already hold, use\n`POST /v1/cards/{card_id}/request-physical` instead.\n\nThe response only includes `last_four`. The full card number and CVV are\nnever returned here. Getting them is a separate, separately scoped and\naudited operation.\n\nA card is never usable straight away. It goes through the same statuses\non every program:\n\n1. It starts as `pending` while the processor issues it. On a program\n   that issues at once, the response already says `inactive`.\n2. It becomes `inactive` when the processor has the card, and you get\n   `card.issued`.\n3. It becomes `active` when you call `POST /v1/cards/{card_id}/activate`,\n   and you get `card.activated`. Until then every authorization is\n   declined."
          },
          "response": []
        },
        {
          "name": "Retrieve a card",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Authorization",
                "value": "Bearer {{access_token}}"
              }
            ],
            "url": {
              "raw": "{{base_url}}/v1/cards/:card_id",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "v1",
                "cards",
                ":card_id"
              ],
              "variable": [
                {
                  "key": "card_id",
                  "value": "{{card_id}}"
                }
              ]
            },
            "description": "Returns a single card. The full card number is never included —\n`last_four` is the only part of the number returned here."
          },
          "response": []
        },
        {
          "name": "Freeze a card",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Authorization",
                "value": "Bearer {{access_token}}"
              },
              {
                "key": "Idempotency-Key",
                "value": "{{$guid}}"
              }
            ],
            "url": {
              "raw": "{{base_url}}/v1/cards/:card_id/freeze",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "v1",
                "cards",
                ":card_id",
                "freeze"
              ],
              "variable": [
                {
                  "key": "card_id",
                  "value": "{{card_id}}"
                }
              ]
            },
            "description": "Temporarily blocks the card. Reversible — use this rather than closing\nfor a card the cardholder has merely mislaid."
          },
          "response": []
        },
        {
          "name": "Unfreeze a card",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Authorization",
                "value": "Bearer {{access_token}}"
              },
              {
                "key": "Idempotency-Key",
                "value": "{{$guid}}"
              }
            ],
            "url": {
              "raw": "{{base_url}}/v1/cards/:card_id/unfreeze",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "v1",
                "cards",
                ":card_id",
                "unfreeze"
              ],
              "variable": [
                {
                  "key": "card_id",
                  "value": "{{card_id}}"
                }
              ]
            },
            "description": "Returns a frozen card to `active`.\n\nNote that the card returns to `active` regardless of what its state was\nbefore it was frozen — lifecycle and freeze state share one field. See\nthe card lifecycle guide."
          },
          "response": []
        },
        {
          "name": "Replace a card",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Authorization",
                "value": "Bearer {{access_token}}"
              },
              {
                "key": "Idempotency-Key",
                "value": "{{$guid}}"
              },
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"reason\": \"lost\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "url": {
              "raw": "{{base_url}}/v1/cards/:card_id/replace",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "v1",
                "cards",
                ":card_id",
                "replace"
              ],
              "variable": [
                {
                  "key": "card_id",
                  "value": "{{card_id}}"
                }
              ]
            },
            "description": "Issues a new card against the same cardholder and account, then closes\nthis one. Returns the new card. The new card has a new `id`, number and\nexpiry, and keeps the original's `reference`.\n\nThe new card follows the usual issuing flow: `active` straight away, or\n`pending` and then `active` with `card.issued` on a program that issues\nasynchronously. The original is closed and emits `card.closed`.\n\nThe new card is issued before the original is closed, so a failure never\nleaves the cardholder without a card. If the close fails, the response\nis an error naming both cards and the original stays `active`: close it\nwith `POST /v1/cards/{card_id}/close` and do not repeat the replacement,\nwhich would issue another card.\n\nA closed card cannot be replaced."
          },
          "response": []
        },
        {
          "name": "Close a card",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Authorization",
                "value": "Bearer {{access_token}}"
              },
              {
                "key": "Idempotency-Key",
                "value": "{{$guid}}"
              }
            ],
            "url": {
              "raw": "{{base_url}}/v1/cards/:card_id/close",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "v1",
                "cards",
                ":card_id",
                "close"
              ],
              "variable": [
                {
                  "key": "card_id",
                  "value": "{{card_id}}"
                }
              ]
            },
            "description": "Permanently terminates the card. **Not reversible.** Any network tokens\nderived from it are invalidated. To block temporarily, freeze instead."
          },
          "response": []
        },
        {
          "name": "Activate a card",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Authorization",
                "value": "Bearer {{access_token}}"
              },
              {
                "key": "Idempotency-Key",
                "value": "{{$guid}}"
              }
            ],
            "url": {
              "raw": "{{base_url}}/v1/cards/:card_id/activate",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "v1",
                "cards",
                ":card_id",
                "activate"
              ],
              "variable": [
                {
                  "key": "card_id",
                  "value": "{{card_id}}"
                }
              ]
            },
            "description": "Makes an `inactive` card spendable. It is a server-to-server call: there is\nno hosted page and no URL to open, and the response is the card.\n\nThe same call activates a virtual card and a physical one. Call it when\nyou receive `card.issued` and you are ready for the card to be used.\n\n- A `pending` card is refused with `card_invalid_state`. Wait for\n  `card.issued`; the card is never issued by calling this endpoint.\n- A card that is already `active` is refused with `card_already_activated`.\n- The cardholder must still be verified. A cardholder who is no longer\n  `approved` is refused with `kyc_not_approved`.\n\nActivation takes effect at once. A card that fails to activate stays\n`inactive` and can be activated again.\n\nRequires the `cards:write` scope."
          },
          "response": []
        },
        {
          "name": "Request a physical card",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Authorization",
                "value": "Bearer {{access_token}}"
              },
              {
                "key": "Idempotency-Key",
                "value": "{{$guid}}"
              }
            ],
            "url": {
              "raw": "{{base_url}}/v1/cards/:card_id/request-physical",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "v1",
                "cards",
                ":card_id",
                "request-physical"
              ],
              "variable": [
                {
                  "key": "card_id",
                  "value": "{{card_id}}"
                }
              ]
            },
            "description": "Orders plastic for a card issued without it. The response is the same\ncard, not a new one: same `id`, same number, same balance, with\n`form_factor` now `physical` and `fulfillment.status` `pending`. It keeps\nworking while the plastic is made.\n\nThere is no request body. The name printed on the card and the address it\nis posted to were both fixed when the card was issued, and this operation\ncannot revise either.\n\n- A card that is not `active` is refused with `card_invalid_state`. So is\n  a card that is already `physical`, which is what a second request gets.\n- A closed card is refused with `card_closed`.\n- A program that does not issue physical cards is refused with\n  `unsupported_form_factor`.\n\nNo event is emitted. Nothing reports when a card is posted, so the next\nthing you learn is the cardholder telling you it arrived — call\n`POST /v1/cards/{card_id}/activate` then to enable the card for use in\nperson.\n\nYou can also issue a physical card directly, without a virtual card\nfirst, with `POST /v1/cards` and `form_factor: physical`.\n\nRequires the `cards:write` scope."
          },
          "response": []
        },
        {
          "name": "Set a PIN",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Authorization",
                "value": "Bearer {{access_token}}"
              },
              {
                "key": "Idempotency-Key",
                "value": "{{$guid}}"
              },
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"key_id\": \"3f9c0a6e1b7d4e2a\",\n  \"encrypted_pin\": \"q3G1...base64...\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "url": {
              "raw": "{{base_url}}/v1/cards/:card_id/pin",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "v1",
                "cards",
                ":card_id",
                "pin"
              ],
              "variable": [
                {
                  "key": "card_id",
                  "value": "{{card_id}}"
                }
              ]
            },
            "description": "Sets the PIN of a physical card from a PIN you have encrypted. It is a\nserver-to-server call: there is no page to open. The same call sets a first\nPIN and resets a forgotten one.\n\n1. Get a key with `POST /v1/cards/{card_id}/pin-key`.\n2. Encrypt the PIN, as its digits, to that key with RSA-OAEP using SHA-256,\n   and encode the result as base64.\n3. Send `key_id` and the encrypted PIN here.\n\n**Encrypt on the cardholder's device.** The PIN is ciphertext while it\npasses through your systems, and it stays out of PCI DSS scope only while\nyour servers never see it in the clear. A server that handles the PIN\nunencrypted is in scope.\n\nWe check only what a PIN needs to be usable: digits, in the length the key\nresponse gives as `pin_length`. Anything else is your policy, such as whether\nto refuse repeated digits or sequences, and is yours to validate before you\nencrypt. A PIN that isn't digits of that length is refused with\n`pin_invalid`. A key that is unknown, already used or expired is refused with\n`invalid_parameter`; get a new one.\n\nOnly a physical card that is `active` has a PIN to set. Any other card is\nrefused with `card_invalid_state`, and a closed card with `card_closed`.\n\nNever write the PIN, encrypted or not, to a log, an analytics event, web\nstorage or a support ticket.\n\nRequires the `cards:secrets` scope."
          },
          "response": []
        },
        {
          "name": "Reveal card secrets",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Authorization",
                "value": "Bearer {{access_token}}"
              },
              {
                "key": "Idempotency-Key",
                "value": "{{$guid}}"
              },
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"public_key\": \"<public_key>\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "url": {
              "raw": "{{base_url}}/v1/cards/:card_id/secrets",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "v1",
                "cards",
                ":card_id",
                "secrets"
              ],
              "variable": [
                {
                  "key": "card_id",
                  "value": "{{card_id}}"
                }
              ]
            },
            "description": "Returns the card's number and security code, each encrypted to a public key\nyou supply. It is a server-to-server call: there is no page to open, and\nonly the holder of the matching private key can read the values.\n\nSend an RSA public key in PEM form, of at least 2048 bits. The response\ncarries `encrypted_pan` and `encrypted_cvv`, each encrypted with RSA-OAEP\nusing SHA-256 and encoded as base64. `last_four` and `expires_at` come back\nin the clear.\n\nOnly an `active` card has details to show. Any other card is refused with\n`card_invalid_state`, and a closed card with `card_closed`.\n\nThe response is never cached. `Idempotency-Key` is accepted like on every\nother `POST`, but it is not used here: a replay would have to keep a copy of\nthe first response, so every call is answered afresh with a new ciphertext.\n\nNever write the decrypted values to a log, an analytics event, web storage\nor a support ticket.\n\nRequires the `cards:secrets` scope. A program whose processor cannot\nreturn card details does not have this endpoint at all."
          },
          "response": []
        }
      ]
    },
    {
      "name": "3-D Secure",
      "item": [
        {
          "name": "List authentications",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Authorization",
                "value": "Bearer {{access_token}}"
              }
            ],
            "url": {
              "raw": "{{base_url}}/v1/authentications",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "v1",
                "authentications"
              ],
              "query": [
                {
                  "key": "limit",
                  "value": "",
                  "description": "Page size. Values above the maximum are rejected, not clamped.",
                  "disabled": true
                },
                {
                  "key": "starting_after",
                  "value": "",
                  "description": "Opaque cursor for the next page. Valid for 24 hours.",
                  "disabled": true
                },
                {
                  "key": "card_id",
                  "value": "",
                  "description": "",
                  "disabled": true
                },
                {
                  "key": "status",
                  "value": "",
                  "description": "",
                  "disabled": true
                }
              ]
            },
            "description": "Returns a page of out-of-band authentications, newest first.\n\nThis is a recovery path for a broken push channel, not a polling loop. A\nchallenge expires in minutes, so polling often enough to catch one costs\nmore rate limit than it is worth; subscribe to\n`authentication.challenged` and read this when your own notifications\nfail.\n\nRequires the `authentications:read` scope."
          },
          "response": []
        },
        {
          "name": "Retrieve an authentication",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Authorization",
                "value": "Bearer {{access_token}}"
              }
            ],
            "url": {
              "raw": "{{base_url}}/v1/authentications/:authentication_id",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "v1",
                "authentications",
                ":authentication_id"
              ],
              "variable": [
                {
                  "key": "authentication_id",
                  "value": "{{authentication_id}}"
                }
              ]
            },
            "description": "Returns a single authentication. `authentication.challenged` already\ncarries the whole object, so a handler that trusts the event does not\nneed this call.\n\nRequires the `authentications:read` scope."
          },
          "response": []
        },
        {
          "name": "Approve an authentication",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Authorization",
                "value": "Bearer {{access_token}}"
              },
              {
                "key": "Idempotency-Key",
                "value": "{{$guid}}"
              }
            ],
            "url": {
              "raw": "{{base_url}}/v1/authentications/:authentication_id/approve",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "v1",
                "authentications",
                ":authentication_id",
                "approve"
              ],
              "variable": [
                {
                  "key": "authentication_id",
                  "value": "{{authentication_id}}"
                }
              ]
            },
            "description": "Tells the Access Control Server the cardholder proved who they are, and\nreleases the merchant's checkout to continue.\n\nCall it only after a step-up on the device, immediately before: a\nbiometric or the device passcode. An application that approves because\nit happens to be unlocked has removed the authentication rather than\nmoved it.\n\nAnswer once. A second answer under a different `Idempotency-Key` returns\n`422 authentication_not_pending`.\n\nRequires the `authentications:write` scope."
          },
          "response": []
        },
        {
          "name": "Decline an authentication",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Authorization",
                "value": "Bearer {{access_token}}"
              },
              {
                "key": "Idempotency-Key",
                "value": "{{$guid}}"
              }
            ],
            "url": {
              "raw": "{{base_url}}/v1/authentications/:authentication_id/decline",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "v1",
                "authentications",
                ":authentication_id",
                "decline"
              ],
              "variable": [
                {
                  "key": "authentication_id",
                  "value": "{{authentication_id}}"
                }
              ]
            },
            "description": "Tells the Access Control Server the cardholder refused, or that your\nstep-up failed. The purchase fails at the merchant.\n\nDeclining is worth doing rather than letting the challenge expire: the\ncardholder who taps \"this wasn't me\" gets an immediate answer, and you\nget a record of a refusal instead of a timeout.\n\nRequires the `authentications:write` scope."
          },
          "response": []
        }
      ]
    },
    {
      "name": "Transactions",
      "item": [
        {
          "name": "List transactions",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Authorization",
                "value": "Bearer {{access_token}}"
              }
            ],
            "url": {
              "raw": "{{base_url}}/v1/transactions",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "v1",
                "transactions"
              ],
              "query": [
                {
                  "key": "limit",
                  "value": "",
                  "description": "Page size. Values above the maximum are rejected, not clamped.",
                  "disabled": true
                },
                {
                  "key": "starting_after",
                  "value": "",
                  "description": "Opaque cursor for the next page. Valid for 24 hours.",
                  "disabled": true
                },
                {
                  "key": "card_id",
                  "value": "",
                  "description": "",
                  "disabled": true
                },
                {
                  "key": "account_id",
                  "value": "",
                  "description": "",
                  "disabled": true
                }
              ]
            },
            "description": "Returns a page of transactions, most recently settled first.\nTransactions are read-only."
          },
          "response": []
        },
        {
          "name": "Retrieve a transaction",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Authorization",
                "value": "Bearer {{access_token}}"
              }
            ],
            "url": {
              "raw": "{{base_url}}/v1/transactions/:transaction_id",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "v1",
                "transactions",
                ":transaction_id"
              ],
              "variable": [
                {
                  "key": "transaction_id",
                  "value": "{{transaction_id}}"
                }
              ]
            },
            "description": "Returns a single transaction."
          },
          "response": []
        }
      ]
    },
    {
      "name": "eSIM Packages",
      "item": [
        {
          "name": "List eSIM packages",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Authorization",
                "value": "Bearer {{access_token}}"
              }
            ],
            "url": {
              "raw": "{{base_url}}/v1/esim/packages",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "v1",
                "esim",
                "packages"
              ],
              "query": [
                {
                  "key": "country",
                  "value": "",
                  "description": "Return only packages valid in this country, whether they are",
                  "disabled": true
                }
              ]
            },
            "description": "Returns the packages on sale — where each one works, how long it\nlasts, and what it costs you.\n\n**Only `status: available` is listed.** A package we have frozen or\nwithdrawn is not here, so a storefront can render this response\nwholesale without checking each row. To read one anyway — an order\nfrom last month references it — retrieve it by id.\n\n**This list is not paginated, and it is not sortable.** The catalog is\nsmall and bounded, so the response carries all of it. There is no\n`limit`, no cursor, and no `has_more` to loop on. Narrow it with\n`country`; sort it yourself — you already hold every row, so a server\nround trip to reorder them would buy nothing.\n\nPackages come back ordered by `name`, ascending. The order is stable,\nso two calls with the same filter return the same sequence.\n\nNothing is provisioned here. A package becomes an eSIM profile only\nwhen it is ordered.\n\n`volume` is in megabytes, and it carries its own `type`. Read both:\nthe same `1024` is 1 GB on a `total` plan and 30 GB on a 30-day\n`daily` one.\n\nThe catalog is shared and changes rarely. Cache it and refresh on a\ntimer rather than calling this on every page view."
          },
          "response": []
        },
        {
          "name": "Retrieve an eSIM package",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Authorization",
                "value": "Bearer {{access_token}}"
              }
            ],
            "url": {
              "raw": "{{base_url}}/v1/esim/packages/:package_id",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "v1",
                "esim",
                "packages",
                ":package_id"
              ],
              "variable": [
                {
                  "key": "package_id",
                  "value": "{{package_id}}"
                }
              ]
            },
            "description": "Returns a single package, **whatever its status**. Unlike the list,\nthis resolves a package we have frozen or withdrawn, so an order\nplaced months ago still names something readable.\n\nRead a package here immediately before you charge for it. A cached\nlist can be stale on the two fields that matter at that moment —\n`price` and `status` — and neither changes in a way your copy can\ndetect on its own."
          },
          "response": []
        },
        {
          "name": "List supported countries",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Authorization",
                "value": "Bearer {{access_token}}"
              }
            ],
            "url": {
              "raw": "{{base_url}}/v1/esim/countries",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "v1",
                "esim",
                "countries"
              ]
            },
            "description": "Returns every country the eSIM catalog covers.\n\nThis is the vocabulary the `country` filter on\n[list packages](https://developer.aletaplanet.com/api-reference/resources/list-esim-packages) accepts. A code\nthat is not here matches nothing, which is why it is worth reading\nonce at integration time rather than hardcoding a list of your own:\ncoverage moves as packages are added and withdrawn, and this list\nmoves with it.\n\nEvery country here has at least one `available` package. A country\nwhose only packages are frozen or withdrawn drops out.\n\nNot paginated — there are fewer than two hundred of these. Ordered by\n`name`, ascending, and stably."
          },
          "response": []
        }
      ]
    },
    {
      "name": "eSIM Orders",
      "item": [
        {
          "name": "List eSIM orders",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Authorization",
                "value": "Bearer {{access_token}}"
              }
            ],
            "url": {
              "raw": "{{base_url}}/v1/esim/orders",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "v1",
                "esim",
                "orders"
              ],
              "query": [
                {
                  "key": "limit",
                  "value": "",
                  "description": "Page size. Values above the maximum are rejected, not clamped.",
                  "disabled": true
                },
                {
                  "key": "starting_after",
                  "value": "",
                  "description": "Opaque cursor for the next page. Valid for 24 hours.",
                  "disabled": true
                },
                {
                  "key": "reference",
                  "value": "",
                  "description": "Return only the order carrying this reference.",
                  "disabled": true
                }
              ]
            },
            "description": "Returns a page of your orders, newest first.\n\nFilter by `reference` to answer the question this endpoint exists\nfor: **did my order go through?** A request that timed out has an\nunknown outcome, and your own order id is the only handle you are\nguaranteed to still hold. `reference` is unique within your\norganization, so this returns one row or none.\n\nIt answers in three ways, and the third is why the row exists:\n\n- **no row** — we never took the order; nothing was charged.\n- **a settled row** — it went through. A package order carries an\n  `esim_id`; a top-up carries a `package_id` and a `price`.\n- **an unsettled row** — we do not know yet. The provisioning\n  network timed out and we are settling it, usually within minutes.\n  Ask again rather than re-ordering; a new `reference` would be a\n  second purchase.\n\n**Branch on `object` before you check**, because there is no single\nfield that answers it for both. The two order kinds learn things in\nopposite orders, so each is still missing what the other already\nknows — see `EsimOrderSummary` and `EsimTopUpOrder` for which is\nwhich.\n\n`Idempotency-Key` covers the same ground for 24 hours and returns the\noriginal response outright, so reach for that first if you still have\nthe key. This is what is left when you do not.\n\nPackage purchases and top-ups share this ledger. **Branch on\n`object`** — `esim_order` against `esim_top_up_order` — rather than\nassuming every row has the same fields.\n\nNo row carries an `activation_code`, for the reason a list of eSIMs\ndoes not carry one either. Retrieve the order, or the eSIM, when you\nneed to deliver install instructions."
          },
          "response": []
        },
        {
          "name": "Order an eSIM package",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Authorization",
                "value": "Bearer {{access_token}}"
              },
              {
                "key": "Idempotency-Key",
                "value": "{{$guid}}"
              },
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"package_id\": \"epkg_01HX8ZQ2K4M7P9RSTVWXYZABCD\",\n  \"reference\": \"order-4471\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "url": {
              "raw": "{{base_url}}/v1/esim/orders",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "v1",
                "esim",
                "orders"
              ]
            },
            "description": "Buys one package.\n\n`package_id` names what you are buying; the package must be\n`available` at the moment of the call, which is why it is worth\n[retrieving it](https://developer.aletaplanet.com/api-reference/resources/get-esim-package)\nimmediately beforehand rather than trusting a cached list. Ordering a\nfrozen or withdrawn package is refused with\n`esim_package_unavailable`.\n\nAn eSIM is allocated from our inventory and the package provisioned\nonto it before this call returns. There is no queue and no callback:\na `201` means the eSIM is ready, and almost every failure means nothing\nwas bought.\n\n**The exception is a `502` from a timeout** against the network that\nprovisions the profile. We cannot tell in that moment whether it took\nthe order, so we neither charge you nor claim it failed. The order\nappears in your order list without an `esim_id` until we settle it.\nLook it up by your own `reference`. Do not re-send under a new\n`reference` — that is a second purchase. If you still hold the\n`Idempotency-Key`, replaying it is the better move.\n\n`reference` is your order id, and it must be unique within your\norganization.\n\n`activation_code` on the response is the LPA string a traveller\nscans. Encode it as a QR yourself — it is a short string, every\nplatform has a one-line library for it, and a hosted image would be a\nURL that installs somebody's eSIM for whoever opens it.\n\n`price` on the response is the price charged, captured at order time.\nIt does not track the catalog afterwards.\n\n**Send an `Idempotency-Key`.** A timed-out order retried without one\nis a second purchase, not a second look at the first."
          },
          "response": []
        },
        {
          "name": "Retrieve an eSIM order",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Authorization",
                "value": "Bearer {{access_token}}"
              }
            ],
            "url": {
              "raw": "{{base_url}}/v1/esim/orders/:order_id",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "v1",
                "esim",
                "orders",
                ":order_id"
              ],
              "variable": [
                {
                  "key": "order_id",
                  "value": "{{order_id}}"
                }
              ]
            },
            "description": "Returns one order. **Branch on `object`:** a package purchase comes\nback as `esim_order` and carries the `activation_code` the create\ncall returned, while a top-up comes back as `esim_top_up_order` and\ncarries none — it added data to a profile that was already\ninstalled.\n\nRe-reading a package order is how you recover install instructions\nwithout keeping the secret yourself.\n\nIf you are here because a create request timed out and you no longer\nhave its `Idempotency-Key`, you will not have this id either — look\nthe order up by your own `reference` instead.\n\nAn order found that way may still be settling, in which case it comes\nback without an `esim_id` or an `activation_code` (without a\n`top_up_id`, for a top-up). That is not an error and not a `404`; it\nmeans the answer is not in yet."
          },
          "response": []
        }
      ]
    },
    {
      "name": "eSIM Profiles",
      "item": [
        {
          "name": "List allocated eSIMs",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Authorization",
                "value": "Bearer {{access_token}}"
              }
            ],
            "url": {
              "raw": "{{base_url}}/v1/esims",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "v1",
                "esims"
              ],
              "query": [
                {
                  "key": "limit",
                  "value": "",
                  "description": "Page size. Values above the maximum are rejected, not clamped.",
                  "disabled": true
                },
                {
                  "key": "starting_after",
                  "value": "",
                  "description": "Opaque cursor for the next page. Valid for 24 hours.",
                  "disabled": true
                },
                {
                  "key": "order_reference",
                  "value": "",
                  "description": "Return only the eSIM allocated to the order carrying this",
                  "disabled": true
                },
                {
                  "key": "iccid",
                  "value": "",
                  "description": "Return only the eSIM with this ICCID.",
                  "disabled": true
                }
              ]
            },
            "description": "Returns a page of the eSIMs allocated to you, newest first.\n\nRows are `EsimSummary`, which leaves out two fields on purpose.\n`packages` is one: an eSIM accumulates them as it is topped up, and\ninlining every one on every row turns a page into a payload nobody\nasked for.\n\n`activation_code` is the other, and for a different reason. Each one\ninstalls a profile, so a page of a hundred would be a hundred secrets\nin a single response — easy to log, easy to proxy into a browser,\nimpossible to take back. Retrieve an eSIM when you need to deliver\nits install instructions.\n\nFilter by `order_reference` to find the eSIM behind one of your\norders, or by `iccid` when a traveller reads theirs off the handset."
          },
          "response": []
        },
        {
          "name": "Retrieve an eSIM",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Authorization",
                "value": "Bearer {{access_token}}"
              }
            ],
            "url": {
              "raw": "{{base_url}}/v1/esims/:esim_id",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "v1",
                "esims",
                ":esim_id"
              ],
              "variable": [
                {
                  "key": "esim_id",
                  "value": "{{esim_id}}"
                }
              ]
            },
            "description": "Returns one eSIM and every package on it.\n\n`packages` is the whole history, not just what is live — a package\nthat has expired stays listed. Read `expires_at` to tell them apart\nrather than assuming the array holds only current ones.\n\nData counters come from the network and settle with a delay. Treat\n`volume.remaining` as recent rather than exact, and never as a\nbilling figure."
          },
          "response": []
        }
      ]
    },
    {
      "name": "eSIM Top-ups",
      "item": [
        {
          "name": "List available top-ups",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Authorization",
                "value": "Bearer {{access_token}}"
              }
            ],
            "url": {
              "raw": "{{base_url}}/v1/esims/:esim_id/top_ups",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "v1",
                "esims",
                ":esim_id",
                "top_ups"
              ],
              "variable": [
                {
                  "key": "esim_id",
                  "value": "{{esim_id}}"
                }
              ]
            },
            "description": "Returns the add-ons this eSIM can take right now, **grouped by the\npackage each one extends**.\n\nAn eSIM can carry several packages at once, and an add-on belongs to\nexactly one of them — a top-up extends the package it was sold\nagainst rather than the profile as a whole. The grouping is what\ntells you which is which, so read `package_id` before you sell.\n\nOnly running packages appear. A package that has been bought but\nnever reached a network cannot be extended yet, and a package sold\nwithout add-ons is left out rather than listed empty — so an empty\n`data` means there is nothing to sell on this eSIM today.\n\nWithin a group, add-ons come smallest first. Not paginated: a package\ncarries a handful of these, not a catalog."
          },
          "response": []
        },
        {
          "name": "Order a top-up",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Authorization",
                "value": "Bearer {{access_token}}"
              },
              {
                "key": "Idempotency-Key",
                "value": "{{$guid}}"
              },
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"top_up_id\": \"etop_01HX8ZQ2K4M7P9RSTVWXYZABCD\",\n  \"reference\": \"order-4472\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "url": {
              "raw": "{{base_url}}/v1/esims/:esim_id/top_ups",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "v1",
                "esims",
                ":esim_id",
                "top_ups"
              ],
              "variable": [
                {
                  "key": "esim_id",
                  "value": "{{esim_id}}"
                }
              ]
            },
            "description": "Adds data to a package already running on this eSIM.\n\nNothing is installed and nothing is replaced: the traveller keeps the\nprofile they have, and the data lands against the package the add-on\nbelongs to. There is no new activation code because there is no new\nprofile.\n\n`top_up_id` must be one currently listed for this eSIM. An add-on\nthat has stopped being sold, or one belonging to a package that is\nnot running, is refused with `esim_top_up_unavailable` — read the\nlist immediately beforehand rather than trusting a cached one.\n\nOne top-up, bought once. A top-up lands on the allowance the\npackage is running **today** — it cannot be bought ahead for a later\nday, and it expires with the package it extends, so one bought late\nin that package's life buys less time than the same one bought\nearly.\n\n**Send an `Idempotency-Key`.** A timed-out top-up retried without one\nis a second purchase."
          },
          "response": []
        }
      ]
    }
  ]
}
