{
  "openapi": "3.1.0",
  "info": {
    "title": "Roamify API",
    "version": "1.0.0",
    "description": "OpenAPI description of the Roamify partner API (eSIMs, insurance, exchange rates, affiliate links and webhooks), derived from the documentation at https://docs.getroamify.com. The documentation is the source of truth; where this file and the docs differ, follow the docs.",
    "contact": {
      "name": "Roamify Support",
      "email": "support@getroamify.com"
    }
  },
  "externalDocs": {
    "description": "Roamify API documentation",
    "url": "https://docs.getroamify.com/"
  },
  "servers": [
    {
      "url": "https://api.getroamify.com",
      "description": "Production"
    },
    {
      "url": "https://api-dev.getroamify.com",
      "description": "Development"
    }
  ],
  "security": [
    {
      "bearerAuth": []
    }
  ],
  "tags": [
    {
      "name": "eSIM Catalog",
      "description": "Supported countries, eSIM packages and compatible devices.",
      "externalDocs": {
        "url": "https://docs.getroamify.com/esims/overview"
      }
    },
    {
      "name": "Orders",
      "description": "Create and retrieve eSIM orders, including top-up and instant orders.",
      "externalDocs": {
        "url": "https://docs.getroamify.com/esims/orders"
      }
    },
    {
      "name": "eSIMs",
      "description": "Generate eSIM profiles and manage eSIMs: usage, top-up packages, history, SMS, eSIMs Link and lifecycle events.",
      "externalDocs": {
        "url": "https://docs.getroamify.com/esims/esims"
      }
    },
    {
      "name": "Vouchers",
      "description": "Redeemable voucher codes that each hand one eSIM to whoever redeems them. Selected partners only, enabled per API key.",
      "externalDocs": {
        "url": "https://docs.getroamify.com/esims/vouchers"
      }
    },
    {
      "name": "Refunds",
      "description": "Refund requests for eSIMs on your orders. A refund happens only after Roamify support approves the request.",
      "externalDocs": {
        "url": "https://docs.getroamify.com/esims/refunds"
      }
    },
    {
      "name": "Balance",
      "description": "Your partner account balance.",
      "externalDocs": {
        "url": "https://docs.getroamify.com/esims/balance"
      }
    },
    {
      "name": "Insurance",
      "description": "Travel insurance: countries, packages, orders and policies. Saudi Arabia citizens and residents only.",
      "externalDocs": {
        "url": "https://docs.getroamify.com/insurance/overview"
      }
    },
    {
      "name": "Exchange Rates",
      "description": "Supported currencies and exchange rates.",
      "externalDocs": {
        "url": "https://docs.getroamify.com/exchange-rates/overview"
      }
    },
    {
      "name": "Affiliate",
      "description": "Affiliate referral links.",
      "externalDocs": {
        "url": "https://docs.getroamify.com/affiliate/overview"
      }
    },
    {
      "name": "Health",
      "description": "API health check.",
      "externalDocs": {
        "url": "https://docs.getroamify.com/health"
      }
    },
    {
      "name": "Webhooks",
      "description": "Event notifications Roamify sends to your webhook endpoint. Each request carries an `X-Roamify-Signature` header (HMAC-SHA256 of the raw body with your secret key).",
      "externalDocs": {
        "url": "https://docs.getroamify.com/webhooks/overview"
      }
    }
  ],
  "paths": {
    "/api/health": {
      "get": {
        "tags": [
          "Health"
        ],
        "operationId": "getHealth",
        "summary": "Health check",
        "description": "Health check endpoint that you can use to check the status of the Roamify API. You can send a `GET` request to the health check endpoint; the response will contain the status of the API.",
        "externalDocs": {
          "url": "https://docs.getroamify.com/health"
        },
        "responses": {
          "200": {
            "description": "The response contains the status of the API. The docs do not document the response body."
          }
        }
      }
    },
    "/api/esim/countries": {
      "get": {
        "tags": [
          "eSIM Catalog"
        ],
        "operationId": "getEsimCountries",
        "summary": "Get eSIM supported countries",
        "description": "Returns the list of eSIM supported countries. Use the returned `name` and `code` when querying `/api/esim/packages`: `country` must use `name` and `countryCode` must use `code`. Arbitrary country strings are not accepted.",
        "externalDocs": {
          "url": "https://docs.getroamify.com/esims/countries"
        },
        "parameters": [
          {
            "name": "geography",
            "in": "query",
            "required": false,
            "description": "Filter countries by geography scope.",
            "schema": {
              "type": "string",
              "enum": [
                "local",
                "regional",
                "global"
              ]
            },
            "example": "regional"
          }
        ],
        "responses": {
          "200": {
            "description": "List of countries.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "description": "Result of the request.",
                      "examples": [
                        "success"
                      ]
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "countries": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/EsimCountry"
                          }
                        }
                      }
                    }
                  }
                },
                "example": {
                  "status": "success",
                  "data": {
                    "countries": [
                      {
                        "code": "AF",
                        "name": "Afghanistan",
                        "geography": "local"
                      },
                      {
                        "code": "AFR",
                        "name": "Africa",
                        "geography": "regional"
                      },
                      {
                        "code": "AX",
                        "name": "Åland Islands",
                        "geography": "local"
                      },
                      {
                        "code": "AL",
                        "name": "Albania",
                        "geography": "local"
                      },
                      {
                        "code": "DZ",
                        "name": "Algeria",
                        "geography": "local"
                      },
                      {
                        "code": "AD",
                        "name": "Andorra",
                        "geography": "local"
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        }
      }
    },
    "/api/esim/packages": {
      "get": {
        "tags": [
          "eSIM Catalog"
        ],
        "operationId": "getEsimPackages",
        "summary": "Get eSIM packages",
        "description": "Returns eSIM packages, paginated. If you do not pass `page` and `pageSize`, you may only receive the first page. To fetch all packages, iterate pages until the current page returns fewer items than your `pageSize`. `country` and `countryCode` have different meanings; both must use values returned from `GET /api/esim/countries`.",
        "externalDocs": {
          "url": "https://docs.getroamify.com/esims/packages"
        },
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "required": false,
            "description": "Page number to retrieve.",
            "schema": {
              "type": "string",
              "default": "1"
            },
            "example": "1"
          },
          {
            "name": "pageSize",
            "in": "query",
            "required": false,
            "description": "Number of results per page.",
            "schema": {
              "type": "string",
              "default": "50"
            },
            "example": "50"
          },
          {
            "name": "country",
            "in": "query",
            "required": false,
            "description": "Full country name filter. Use the `name` value from `GET /api/esim/countries`.",
            "schema": {
              "type": "string"
            },
            "example": "United States"
          },
          {
            "name": "countryCode",
            "in": "query",
            "required": false,
            "description": "ISO country code filter. Use the `code` value from `GET /api/esim/countries`.",
            "schema": {
              "type": "string"
            },
            "example": "US"
          },
          {
            "name": "geography",
            "in": "query",
            "required": false,
            "description": "The geography of the eSIM packages: `local`, `regional` or `global` packages.",
            "schema": {
              "type": "string",
              "enum": [
                "local",
                "regional",
                "global"
              ]
            }
          },
          {
            "name": "days",
            "in": "query",
            "required": false,
            "description": "The number of days for which the eSIM package is valid.",
            "schema": {
              "type": "number"
            }
          },
          {
            "name": "gbs",
            "in": "query",
            "required": false,
            "description": "The amount of data in GB for which the eSIM package is valid.",
            "schema": {
              "type": "number"
            }
          },
          {
            "name": "isUnlimited",
            "in": "query",
            "required": false,
            "description": "The flag to indicate if the eSIM package is unlimited.",
            "schema": {
              "type": "boolean"
            }
          },
          {
            "name": "packageId",
            "in": "query",
            "required": false,
            "description": "The ID of the eSIM package.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "A page of eSIM packages grouped by destination.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "description": "Result of the request.",
                      "examples": [
                        "success"
                      ]
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "packages": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/EsimCountryPackages"
                          }
                        }
                      }
                    },
                    "pagination": {
                      "$ref": "#/components/schemas/Pagination"
                    }
                  }
                },
                "example": {
                  "status": "success",
                  "data": {
                    "packages": [
                      {
                        "id": "afghanistan-esims",
                        "countryName": "Afghanistan",
                        "countryCode": "AF",
                        "countrySlug": "afghanistan",
                        "region": "Asia",
                        "geography": "local",
                        "minPrice": 5,
                        "maxPrice": 5,
                        "image": "https://imagedelivery.net/uUE6LNs_ci8SFBH4_n66dQ/countries/flags/afghanistan/public",
                        "signals": [
                          {
                            "code": "AF",
                            "name": "Afghanistan",
                            "networks": [
                              "3G",
                              "4G"
                            ],
                            "carriers": [
                              "MTN"
                            ]
                          }
                        ],
                        "packages": [
                          {
                            "packageId": "esim-canada-15days-un2gb-all",
                            "package": "Unlimited Data - 15 Days (2 GB / 128 KBPS)",
                            "plan": "data-only",
                            "activation": "first-use",
                            "day": 15,
                            "price": 1.32,
                            "isUnlimited": true,
                            "isAPNAutomatic": true,
                            "apn": "drei.at",
                            "dataAmount": 9007199254740991,
                            "dataUnit": "MB",
                            "callType": "all",
                            "callAmount": -1,
                            "callUnit": "",
                            "smsType": "all",
                            "smsAmount": -1,
                            "smsUnit": "",
                            "withSMS": false,
                            "withCall": false,
                            "withHotspot": true,
                            "withDataRoaming": true,
                            "withDestinationInstall": false,
                            "withUsageCheck": true,
                            "withThrottle": true,
                            "throttle": {
                              "throttleSpeed": 128,
                              "throttleSpeedUnit": "kbps",
                              "throttleThreshold": 2,
                              "throttleThresholdUnit": "gb"
                            },
                            "notes": []
                          }
                        ]
                      }
                    ]
                  },
                  "pagination": {
                    "page": 1,
                    "pageSize": 50,
                    "totalItems": 2,
                    "totalPages": 1,
                    "hasNextPage": false,
                    "hasPreviousPage": false
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        }
      }
    },
    "/api/compatible-devices": {
      "get": {
        "tags": [
          "eSIM Catalog"
        ],
        "operationId": "getCompatibleDevices",
        "summary": "Get eSIM compatible devices",
        "description": "Returns the list of eSIM compatible devices. There are no required parameters for this endpoint.",
        "externalDocs": {
          "url": "https://docs.getroamify.com/esims/compatible-devices"
        },
        "responses": {
          "200": {
            "description": "List of compatible devices.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "description": "Result of the request.",
                      "examples": [
                        "success"
                      ]
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/CompatibleDevice"
                      }
                    }
                  }
                },
                "example": {
                  "status": "success",
                  "data": [
                    {
                      "model": "Samsung Galaxy Note 20 / Note 20 Plus / Note 20 Ultra",
                      "deviceType": "smartphone",
                      "os": "android",
                      "brand": "Samsung",
                      "name": "Samsung Galaxy Note 20 series"
                    },
                    {
                      "model": "Rakuten BIG / Rakuten BIG-S",
                      "deviceType": "smartphone",
                      "os": "android",
                      "brand": "Rakuten",
                      "name": "Rakuten BIG series"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        }
      }
    },
    "/api/esim/order": {
      "post": {
        "tags": [
          "Orders"
        ],
        "operationId": "createEsimOrder",
        "summary": "Create eSIM order",
        "description": "Creates an eSIM order. The response contains a dedicated `esimId` for each eSIM; use it (or the order's `referenceId`) with `POST /api/esim/apply` to generate the eSIM profile.",
        "externalDocs": {
          "url": "https://docs.getroamify.com/esims/orders#create-esim-order"
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "items": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "packageId": {
                          "type": "string",
                          "description": "The ID of the eSIM package you want to order."
                        },
                        "quantity": {
                          "type": "number",
                          "description": "The quantity of the eSIM package you want to order."
                        }
                      },
                      "required": [
                        "packageId",
                        "quantity"
                      ]
                    },
                    "description": "The eSIM items you want to order."
                  },
                  "referenceId": {
                    "type": "string",
                    "description": "Your custom reference ID for the order, if needed."
                  }
                },
                "required": [
                  "items"
                ]
              },
              "example": {
                "items": [
                  {
                    "packageId": "Package ID",
                    "quantity": 1
                  }
                ],
                "referenceId": "Optional Reference ID"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The created order.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "description": "Result of the request.",
                      "examples": [
                        "success"
                      ]
                    },
                    "data": {
                      "$ref": "#/components/schemas/EsimOrder"
                    }
                  }
                },
                "example": {
                  "status": "success",
                  "data": {
                    "id": "67bbabb7-e893-410a-b0a8-4fa62d347b6c",
                    "referenceId": "ref-123456",
                    "orderType": "api",
                    "status": "COMPLETED",
                    "total": 5,
                    "currency": "USD",
                    "createdAt": 1731837535,
                    "updatedAt": 1731837539,
                    "items": [
                      {
                        "esimId": "b06036c5-eadc-4f88-aa31-8c207fec91ec",
                        "packageId": "esim-cambodia-7days-1gb-all",
                        "package": "1 GB - 7 Days",
                        "type": "esim",
                        "price": 5,
                        "currency": "USD",
                        "createdAt": 1731837535,
                        "updatedAt": 1731837539
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        }
      },
      "get": {
        "tags": [
          "Orders"
        ],
        "operationId": "getEsimOrder",
        "summary": "Get eSIM order",
        "description": "Returns a specific eSIM order. You are required to provide either `orderId` or `referenceId` as a query parameter.",
        "externalDocs": {
          "url": "https://docs.getroamify.com/esims/orders#get-esim-order"
        },
        "parameters": [
          {
            "name": "orderId",
            "in": "query",
            "required": false,
            "description": "The ID of the eSIM order you want to retrieve. Provide either `orderId` or `referenceId`.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "referenceId",
            "in": "query",
            "required": false,
            "description": "The reference ID of the eSIM order you want to retrieve. Provide either `orderId` or `referenceId`.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The order.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "description": "Result of the request.",
                      "examples": [
                        "success"
                      ]
                    },
                    "data": {
                      "$ref": "#/components/schemas/EsimOrder"
                    }
                  }
                },
                "example": {
                  "status": "success",
                  "data": {
                    "id": "67bbabb7-e893-410a-b0a8-4fa62d347b6c",
                    "referenceId": "ref-123456",
                    "orderType": "api",
                    "status": "COMPLETED",
                    "total": 5,
                    "currency": "USD",
                    "createdAt": 1731837535,
                    "updatedAt": 1731837539,
                    "items": [
                      {
                        "esimId": "b06036c5-eadc-4f88-aa31-8c207fec91ec",
                        "packageId": "esim-cambodia-7days-1gb-all",
                        "package": "1 GB - 7 Days",
                        "type": "esim",
                        "price": 5,
                        "currency": "USD",
                        "createdAt": 1731837535,
                        "updatedAt": 1731837539
                      }
                    ]
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        }
      }
    },
    "/api/esim/order/topup": {
      "post": {
        "tags": [
          "Orders"
        ],
        "operationId": "createTopUpOrder",
        "summary": "Create top-up order",
        "description": "Creates a top-up order for an existing eSIM. Top-up works only for eSIMs that support top-up (`withTopUp = true`). Get compatible packages first with `GET /api/esim/topup/packages`.",
        "externalDocs": {
          "url": "https://docs.getroamify.com/esims/orders#create-top-up-order"
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "iccid": {
                    "type": "string",
                    "description": "The ICCID of the eSIM you want to top-up."
                  },
                  "packageId": {
                    "type": "string",
                    "description": "The ID of the eSIM package you want to top-up."
                  },
                  "referenceId": {
                    "type": "string",
                    "description": "Your custom reference ID for the top-up order, if needed."
                  }
                },
                "required": [
                  "iccid",
                  "packageId"
                ]
              },
              "example": {
                "iccid": "ICCID",
                "packageId": "Package ID",
                "referenceId": "Optional Reference ID"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The created top-up order.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "description": "Result of the request.",
                      "examples": [
                        "success"
                      ]
                    },
                    "data": {
                      "$ref": "#/components/schemas/EsimOrder"
                    }
                  }
                },
                "example": {
                  "status": "success",
                  "data": {
                    "id": "0501aef3-7cf1-4b4c-a293-c03a6bd7a8ab",
                    "referenceId": "ref-123456",
                    "orderType": "api",
                    "status": "COMPLETED",
                    "total": 5,
                    "currency": "USD",
                    "createdAt": 1731838277,
                    "updatedAt": 1731838280,
                    "items": [
                      {
                        "esimId": "22dcdb84-968b-415c-bb70-79e2f3ffc296",
                        "packageId": "esim-cambodia-7days-1gb-all",
                        "package": "1 GB - 7 Days",
                        "type": "esim",
                        "price": 5,
                        "currency": "USD",
                        "createdAt": 1731838277,
                        "updatedAt": 1731838280
                      }
                    ]
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        }
      }
    },
    "/api/esim/order/instant": {
      "post": {
        "tags": [
          "Orders"
        ],
        "operationId": "createInstantEsimOrder",
        "summary": "Create instant eSIM order",
        "description": "Creates an eSIM order and returns the fulfilled eSIMs. There is no need to call `/api/esim/apply` with this endpoint. Set your request timeout to at least 60 seconds; depending on what you order, the fulfillment time can vary.",
        "externalDocs": {
          "url": "https://docs.getroamify.com/esims/orders#create-instant-esim-order"
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "items": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "packageId": {
                          "type": "string",
                          "description": "The ID of the eSIM package you want to order."
                        },
                        "quantity": {
                          "type": "number",
                          "description": "The quantity of the eSIM package you want to order."
                        }
                      },
                      "required": [
                        "packageId",
                        "quantity"
                      ]
                    },
                    "description": "The eSIM items you want to order."
                  },
                  "referenceId": {
                    "type": "string",
                    "description": "Your custom reference ID for the order, if needed."
                  }
                },
                "required": [
                  "items"
                ]
              },
              "example": {
                "items": [
                  {
                    "packageId": "Package ID",
                    "quantity": 1
                  }
                ],
                "referenceId": "Optional Reference ID"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The created order with its eSIMs.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "description": "Result of the request.",
                      "examples": [
                        "success"
                      ]
                    },
                    "data": {
                      "$ref": "#/components/schemas/InstantEsimOrder"
                    }
                  }
                },
                "example": {
                  "status": "success",
                  "data": {
                    "id": "67bbabb7-e893-410a-b0a8-4fa62d347b6c",
                    "referenceId": "ref-123456",
                    "orderType": "api",
                    "status": "COMPLETED",
                    "total": 5,
                    "currency": "USD",
                    "createdAt": 1731837535,
                    "updatedAt": 1731837539,
                    "esims": [
                      {
                        "id": "b06036c5-eadc-4f88-aa31-8c207fec91ec",
                        "iccid": "894000000000029365",
                        "status": "READY",
                        "activation": "first-use",
                        "withTopUp": true,
                        "withHotspot": true,
                        "withDataRoaming": true,
                        "withDestinationInstall": false,
                        "withUsageCheck": true,
                        "esim": {
                          "lpaCode": "LPA:1$lpa.roamify.com$TEST",
                          "smdpAddress": "lpa.roamify.com",
                          "activationCode": "TEST",
                          "qrCodeUrl": "https://imagedelivery.net/uUE6LNs_ci8SFBH4_n66dQ/partners/b06036c5-eadc-4f88-aa31-8c207fec91ec/iccid/public",
                          "pin": "",
                          "puk": "",
                          "number": "",
                          "iosQuickInstall": "https://esimsetup.apple.com/esim_qrcode_provisioning?carddata=LPA:1$lpa.roamify.com$TEST",
                          "androidQuickInstall": "https://esimsetup.android.com/esim_qrcode_provisioning?carddata=LPA:1$lpa.roamify.com$TEST"
                        },
                        "apn": {
                          "apnAutomatic": true,
                          "apnName": "",
                          "apnUsername": "",
                          "apnPassword": ""
                        },
                        "data": {
                          "isUnlimited": false
                        },
                        "call": {
                          "withCall": false,
                          "callType": "all"
                        },
                        "sms": {
                          "withSMS": false,
                          "smsType": "all"
                        },
                        "notes": [],
                        "createdAt": 1731837539,
                        "updatedAt": 1731837987,
                        "expiredAt": 1763373985
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        }
      }
    },
    "/api/esim/orders": {
      "get": {
        "tags": [
          "Orders"
        ],
        "operationId": "listEsimOrders",
        "summary": "Get eSIM orders",
        "description": "Returns a list of eSIM orders. There are no required parameters for this endpoint.",
        "externalDocs": {
          "url": "https://docs.getroamify.com/esims/orders#get-esim-orders"
        },
        "parameters": [
          {
            "name": "status",
            "in": "query",
            "required": false,
            "description": "The status of the eSIM orders: `PENDING`, `COMPLETED`, `ARCHIVED`, `CANCELLED`, `REFUNDED`, or `REQUIRE_ACTION` (orders that require action).",
            "schema": {
              "type": "string",
              "enum": [
                "PENDING",
                "COMPLETED",
                "ARCHIVED",
                "CANCELLED",
                "REFUNDED",
                "REQUIRE_ACTION"
              ]
            },
            "example": "PENDING"
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "The number of eSIM orders to return.",
            "schema": {
              "type": "number",
              "default": 50
            },
            "example": 10
          },
          {
            "name": "referenceId",
            "in": "query",
            "required": false,
            "description": "The reference ID of the eSIM orders you want to retrieve.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "List of orders.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "description": "Result of the request.",
                      "examples": [
                        "success"
                      ]
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "orders": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/EsimOrder"
                          }
                        }
                      }
                    }
                  }
                },
                "example": {
                  "status": "success",
                  "data": {
                    "orders": [
                      {
                        "id": "67bbabb7-e893-410a-b0a8-4fa62d347b6c",
                        "referenceId": "ref-123456",
                        "orderType": "api",
                        "status": "COMPLETED",
                        "total": 5,
                        "currency": "USD",
                        "createdAt": 1731837535,
                        "updatedAt": 1731837539,
                        "items": [
                          {
                            "esimId": "b06036c5-eadc-4f88-aa31-8c207fec91ec",
                            "packageId": "esim-cambodia-7days-1gb-all",
                            "package": "1 GB - 7 Days",
                            "type": "esim",
                            "price": 5,
                            "currency": "USD",
                            "createdAt": 1731837535,
                            "updatedAt": 1731837539
                          }
                        ]
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        }
      }
    },
    "/api/esim/apply": {
      "post": {
        "tags": [
          "eSIMs"
        ],
        "operationId": "applyEsimProfile",
        "summary": "Generate eSIM profile",
        "description": "Generates an eSIM profile for an `esimId` from your order. If you created the order with a `referenceId`, you can use it to generate profiles for all eSIMs in the order; the response is then an array of eSIMs. Profile generation can take up to 90 seconds; set your request timeout to at least 90 seconds. If the request times out or fails with \"eSIM is still pending processing\", retrieve the eSIM with `GET /api/esim?esimId=...`.",
        "externalDocs": {
          "url": "https://docs.getroamify.com/esims/esims#generate-esim-profile"
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "esimId": {
                    "type": "string",
                    "description": "The ID of the eSIM."
                  },
                  "referenceId": {
                    "type": "string",
                    "description": "The reference ID of the eSIM order. If you do not provide a reference ID, the API generates a single eSIM profile for the provided `esimId`."
                  },
                  "startDate": {
                    "type": "string",
                    "description": "Travel start date in ISO 8601 format (for example `2026-07-01`). Required only when the package's `requirements.travelDate` is `true`."
                  }
                },
                "required": [
                  "esimId"
                ]
              },
              "example": {
                "esimId": "eSIM ID"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The generated eSIM profile, or an array of eSIM profiles when `referenceId` was used.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "description": "Result of the request.",
                      "examples": [
                        "success"
                      ]
                    },
                    "data": {
                      "oneOf": [
                        {
                          "$ref": "#/components/schemas/Esim"
                        },
                        {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/Esim"
                          }
                        }
                      ]
                    }
                  }
                },
                "examples": {
                  "withEsimId": {
                    "summary": "Response with esimId",
                    "value": {
                      "status": "success",
                      "data": {
                        "id": "b06036c5-eadc-4f88-aa31-8c207fec91ec",
                        "iccid": "894000000000029365",
                        "status": "READY",
                        "activation": "first-use",
                        "withTopUp": true,
                        "withHotspot": true,
                        "withDataRoaming": true,
                        "withDestinationInstall": false,
                        "withUsageCheck": true,
                        "esim": {
                          "lpaCode": "LPA:1$lpa.roamify.com$TEST",
                          "smdpAddress": "lpa.roamify.com",
                          "activationCode": "TEST",
                          "qrCodeUrl": "https://imagedelivery.net/uUE6LNs_ci8SFBH4_n66dQ/partners/b06036c5-eadc-4f88-aa31-8c207fec91ec/iccid/public",
                          "pin": "",
                          "puk": "",
                          "number": "",
                          "iosQuickInstall": "https://esimsetup.apple.com/esim_qrcode_provisioning?carddata=LPA:1$lpa.roamify.com$TEST",
                          "androidQuickInstall": "https://esimsetup.android.com/esim_qrcode_provisioning?carddata=LPA:1$lpa.roamify.com$TEST"
                        },
                        "apn": {
                          "apnAutomatic": true,
                          "apnName": "",
                          "apnUsername": "",
                          "apnPassword": ""
                        },
                        "data": {
                          "isUnlimited": false
                        },
                        "call": {
                          "withCall": false,
                          "callType": "all"
                        },
                        "sms": {
                          "withSMS": false,
                          "smsType": "all"
                        },
                        "notes": [],
                        "createdAt": 1731837539,
                        "updatedAt": 1731837987,
                        "expiredAt": 1763373985
                      }
                    }
                  },
                  "withReferenceId": {
                    "summary": "Response with referenceId (array of eSIMs)",
                    "value": {
                      "status": "success",
                      "data": [
                        {
                          "id": "b06036c5-eadc-4f88-aa31-8c207fec91ec",
                          "iccid": "894000000000029365",
                          "status": "READY",
                          "activation": "first-use",
                          "withTopUp": true,
                          "withHotspot": true,
                          "withDataRoaming": true,
                          "withDestinationInstall": false,
                          "withUsageCheck": true,
                          "esim": {
                            "lpaCode": "LPA:1$lpa.roamify.com$TEST",
                            "smdpAddress": "lpa.roamify.com",
                            "activationCode": "TEST",
                            "qrCodeUrl": "https://imagedelivery.net/uUE6LNs_ci8SFBH4_n66dQ/partners/b06036c5-eadc-4f88-aa31-8c207fec91ec/iccid/public",
                            "pin": "",
                            "puk": "",
                            "number": "",
                            "iosQuickInstall": "https://esimsetup.apple.com/esim_qrcode_provisioning?carddata=LPA:1$lpa.roamify.com$TEST",
                            "androidQuickInstall": "https://esimsetup.android.com/esim_qrcode_provisioning?carddata=LPA:1$lpa.roamify.com$TEST"
                          },
                          "apn": {
                            "apnAutomatic": true,
                            "apnName": "",
                            "apnUsername": "",
                            "apnPassword": ""
                          },
                          "data": {
                            "isUnlimited": false
                          },
                          "call": {
                            "withCall": false,
                            "callType": "all"
                          },
                          "sms": {
                            "withSMS": false,
                            "smsType": "all"
                          },
                          "notes": [],
                          "createdAt": 1731837539,
                          "updatedAt": 1731837987,
                          "expiredAt": 1763373985
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        }
      }
    },
    "/api/esim/usage": {
      "get": {
        "tags": [
          "eSIMs"
        ],
        "operationId": "getEsimUsage",
        "summary": "Get eSIM usage",
        "description": "Returns the usage of an eSIM. If the eSIM's `withUsageCheck` is `false`, usage check is not supported; find instructions in the `notes` property.",
        "externalDocs": {
          "url": "https://docs.getroamify.com/esims/esims#get-esim-usage"
        },
        "parameters": [
          {
            "name": "iccid",
            "in": "query",
            "required": true,
            "description": "The ICCID of the eSIM.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "eSIM usage.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "description": "Result of the request.",
                      "examples": [
                        "success"
                      ]
                    },
                    "data": {
                      "$ref": "#/components/schemas/EsimUsage"
                    }
                  }
                },
                "example": {
                  "status": "success",
                  "data": {
                    "id": "xxxxxxx-xxxxxx-xxxxxx-xxxxxx",
                    "iccid": "894000000000029365",
                    "status": "INSTALLED",
                    "startedAt": 1732442794,
                    "expiredAt": 1732442794,
                    "allowedData": 1024,
                    "remainingData": 924,
                    "allowedSms": 0,
                    "remainingSms": 0,
                    "allowedVoice": 0,
                    "remainingVoice": 0
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        }
      }
    },
    "/api/esim/usage/details": {
      "get": {
        "tags": [
          "eSIMs"
        ],
        "operationId": "getEsimUsageDetails",
        "summary": "Get eSIM usage details",
        "description": "Returns the usage of an eSIM with data usage records. If the eSIM's `withUsageCheck` is `false`, usage check is not supported; find instructions in the `notes` property.",
        "externalDocs": {
          "url": "https://docs.getroamify.com/esims/esims#get-esim-usage-details"
        },
        "parameters": [
          {
            "name": "iccid",
            "in": "query",
            "required": true,
            "description": "The ICCID of the eSIM.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "eSIM usage details.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "description": "Result of the request.",
                      "examples": [
                        "success"
                      ]
                    },
                    "data": {
                      "$ref": "#/components/schemas/EsimUsageDetails"
                    }
                  }
                },
                "example": {
                  "status": "success",
                  "data": {
                    "id": "xxxxxxx-xxxxxx-xxxxxx-xxxxxx",
                    "iccid": "894000000000029365",
                    "status": "INSTALLED",
                    "startedAt": 1732442794,
                    "expiredAt": 1732442794,
                    "allowedData": 1024,
                    "remainingData": 924,
                    "allowedSms": 0,
                    "remainingSms": 0,
                    "allowedVoice": 0,
                    "remainingVoice": 0,
                    "dataUsages": [
                      {
                        "date": "20250102",
                        "usage": 10000,
                        "location": "United Kingdom"
                      },
                      {
                        "date": "20250103",
                        "usage": 20000,
                        "location": "United Kingdom"
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        }
      }
    },
    "/api/esim/topup/packages": {
      "get": {
        "tags": [
          "eSIMs"
        ],
        "operationId": "getCompatibleTopUpPackages",
        "summary": "Get eSIM compatible top-ups",
        "description": "Returns the top-up packages compatible with an eSIM. Use a returned `packageId` with `POST /api/esim/order/topup`.",
        "externalDocs": {
          "url": "https://docs.getroamify.com/esims/esims#get-esim-compatible-top-ups"
        },
        "parameters": [
          {
            "name": "iccid",
            "in": "query",
            "required": true,
            "description": "The ICCID of the eSIM.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "days",
            "in": "query",
            "required": false,
            "description": "The number of days for which the eSIM package is valid.",
            "schema": {
              "type": "number"
            }
          },
          {
            "name": "gbs",
            "in": "query",
            "required": false,
            "description": "The amount of data in GB for which the eSIM package is valid.",
            "schema": {
              "type": "number"
            }
          },
          {
            "name": "isUnlimited",
            "in": "query",
            "required": false,
            "description": "The flag to indicate if the eSIM package is unlimited.",
            "schema": {
              "type": "boolean"
            }
          },
          {
            "name": "packageId",
            "in": "query",
            "required": false,
            "description": "The ID of the eSIM package.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Compatible top-up packages.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "description": "Result of the request.",
                      "examples": [
                        "success"
                      ]
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/TopUpPackage"
                      }
                    }
                  }
                },
                "example": {
                  "status": "success",
                  "data": [
                    {
                      "packageId": "esim-cambodia-7days-1gb-all",
                      "package": "1 GB - 7 Days",
                      "plan": "data-only",
                      "activation": "first-use",
                      "day": 7,
                      "price": 5,
                      "withHotspot": true,
                      "withDataRoaming": true,
                      "withDestinationInstall": false,
                      "withUsageCheck": true,
                      "apn": {
                        "apnAutomatic": true,
                        "apnName": "globaldata",
                        "apnUsername": "",
                        "apnPassword": ""
                      },
                      "data": {
                        "isUnlimited": false,
                        "dataAmount": 1024,
                        "dataUnit": "MB"
                      },
                      "call": {
                        "withCall": false,
                        "callType": "all",
                        "callAmount": -1,
                        "callUnit": ""
                      },
                      "sms": {
                        "withSMS": false,
                        "smsType": "all",
                        "smsAmount": -1,
                        "smsUnit": ""
                      },
                      "notes": []
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        }
      }
    },
    "/api/esim/history": {
      "get": {
        "tags": [
          "eSIMs"
        ],
        "operationId": "getEsimPackagesHistory",
        "summary": "Get eSIM packages history",
        "description": "Returns the history of eSIM packages applied to an eSIM.",
        "externalDocs": {
          "url": "https://docs.getroamify.com/esims/esims#get-esim-packages-history"
        },
        "parameters": [
          {
            "name": "iccid",
            "in": "query",
            "required": true,
            "description": "The ICCID of the eSIM.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Packages applied to the eSIM.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "description": "Result of the request.",
                      "examples": [
                        "success"
                      ]
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/OrderItem"
                      }
                    }
                  }
                },
                "example": {
                  "status": "success",
                  "data": [
                    {
                      "esimId": "b06036c5-eadc-4f88-aa31-8c207fec91ec",
                      "packageId": "esim-cambodia-7days-1gb-all",
                      "package": "1 GB - 7 Days",
                      "type": "esim",
                      "price": 5,
                      "currency": "USD",
                      "createdAt": 1731837535,
                      "updatedAt": 1731837539
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        }
      }
    },
    "/api/esim": {
      "get": {
        "tags": [
          "eSIMs"
        ],
        "operationId": "getEsim",
        "summary": "Get eSIM by ICCID or eSIM ID",
        "description": "Returns an eSIM. The endpoint requires either `iccid` or `esimId`, but not both. Use `esimId` to retrieve the eSIM when a generate eSIM profile request failed due to server load.",
        "externalDocs": {
          "url": "https://docs.getroamify.com/esims/esims#get-esim-by-iccid"
        },
        "parameters": [
          {
            "name": "iccid",
            "in": "query",
            "required": false,
            "description": "The ICCID of the eSIM. Provide either `iccid` or `esimId`, but not both.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "esimId",
            "in": "query",
            "required": false,
            "description": "The ID of the eSIM. Provide either `iccid` or `esimId`, but not both.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The eSIM.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "description": "Result of the request.",
                      "examples": [
                        "success"
                      ]
                    },
                    "data": {
                      "$ref": "#/components/schemas/Esim"
                    }
                  }
                },
                "example": {
                  "status": "success",
                  "data": {
                    "id": "b06036c5-eadc-4f88-aa31-8c207fec91ec",
                    "iccid": "894000000000029365",
                    "status": "READY",
                    "activation": "first-use",
                    "withTopUp": true,
                    "withHotspot": true,
                    "withDataRoaming": true,
                    "withDestinationInstall": false,
                    "withUsageCheck": true,
                    "esim": {
                      "lpaCode": "LPA:1$lpa.roamify.com$TEST",
                      "smdpAddress": "lpa.roamify.com",
                      "activationCode": "TEST",
                      "qrCodeUrl": "https://imagedelivery.net/uUE6LNs_ci8SFBH4_n66dQ/partners/b06036c5-eadc-4f88-aa31-8c207fec91ec/iccid/public",
                      "pin": "",
                      "puk": "",
                      "number": "",
                      "iosQuickInstall": "https://esimsetup.apple.com/esim_qrcode_provisioning?carddata=LPA:1$lpa.roamify.com$TEST",
                      "androidQuickInstall": "https://esimsetup.android.com/esim_qrcode_provisioning?carddata=LPA:1$lpa.roamify.com$TEST"
                    },
                    "apn": {
                      "apnAutomatic": true,
                      "apnName": "",
                      "apnUsername": "",
                      "apnPassword": ""
                    },
                    "data": {
                      "isUnlimited": false
                    },
                    "call": {
                      "withCall": false,
                      "callType": "all"
                    },
                    "sms": {
                      "withSMS": false,
                      "smsType": "all"
                    },
                    "notes": [],
                    "createdAt": 1731837539,
                    "updatedAt": 1731838043,
                    "expiredAt": 1732442794
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        }
      }
    },
    "/api/esims": {
      "get": {
        "tags": [
          "eSIMs"
        ],
        "operationId": "listEsims",
        "summary": "Get eSIMs list",
        "description": "Returns a list of eSIMs. There are no required parameters for this endpoint.",
        "externalDocs": {
          "url": "https://docs.getroamify.com/esims/esims#get-esims-list"
        },
        "parameters": [
          {
            "name": "status",
            "in": "query",
            "required": false,
            "description": "Filter by status: `NEW` (not yet processed), `READY` (ready to be downloaded), `INSTALLED`, `REVOKED`, `EXPIRED` or `UNKNOWN`.",
            "schema": {
              "type": "string",
              "enum": [
                "NEW",
                "READY",
                "INSTALLED",
                "REVOKED",
                "EXPIRED",
                "UNKNOWN"
              ]
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "The number of eSIMs to return.",
            "schema": {
              "type": "number",
              "default": 50
            }
          },
          {
            "name": "referenceId",
            "in": "query",
            "required": false,
            "description": "Filter the eSIMs by reference ID.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "List of eSIMs.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "description": "Result of the request.",
                      "examples": [
                        "success"
                      ]
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Esim"
                      }
                    }
                  }
                },
                "example": {
                  "status": "success",
                  "data": [
                    {
                      "id": "b06036c5-eadc-4f88-aa31-8c207fec91ec",
                      "iccid": "894000000000029365",
                      "status": "READY",
                      "activation": "first-use",
                      "withTopUp": true,
                      "withHotspot": true,
                      "withDataRoaming": true,
                      "withDestinationInstall": false,
                      "withUsageCheck": true,
                      "esim": {
                        "lpaCode": "LPA:1$lpa.roamify.com$TEST",
                        "smdpAddress": "lpa.roamify.com",
                        "activationCode": "TEST",
                        "qrCodeUrl": "https://imagedelivery.net/uUE6LNs_ci8SFBH4_n66dQ/partners/b06036c5-eadc-4f88-aa31-8c207fec91ec/iccid/public",
                        "pin": "",
                        "puk": "",
                        "number": "",
                        "iosQuickInstall": "https://esimsetup.apple.com/esim_qrcode_provisioning?carddata=LPA:1$lpa.roamify.com$TEST",
                        "androidQuickInstall": "https://esimsetup.android.com/esim_qrcode_provisioning?carddata=LPA:1$lpa.roamify.com$TEST"
                      },
                      "apn": {
                        "apnAutomatic": true,
                        "apnName": "",
                        "apnUsername": "",
                        "apnPassword": ""
                      },
                      "data": {
                        "isUnlimited": false
                      },
                      "call": {
                        "withCall": false,
                        "callType": "all"
                      },
                      "sms": {
                        "withSMS": false,
                        "smsType": "all"
                      },
                      "notes": [],
                      "createdAt": 1731837539,
                      "updatedAt": 1731838043,
                      "expiredAt": 1732442794
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        }
      }
    },
    "/api/esim/sms": {
      "post": {
        "tags": [
          "eSIMs"
        ],
        "operationId": "sendEsimSms",
        "summary": "Send SMS",
        "description": "Sends an SMS message to an eSIM. Both `iccid` and `message` are required in the request body.",
        "externalDocs": {
          "url": "https://docs.getroamify.com/esims/esims#send-sms"
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "iccid": {
                    "type": "string",
                    "description": "The ICCID of the eSIM."
                  },
                  "message": {
                    "type": "string",
                    "description": "The message content to send."
                  }
                },
                "required": [
                  "iccid",
                  "message"
                ]
              },
              "example": {
                "iccid": "871003213213123131",
                "message": "Hello Customer!"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Request accepted. The docs do not document the response body."
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        }
      }
    },
    "/api/esim/link": {
      "post": {
        "tags": [
          "eSIMs"
        ],
        "operationId": "createEsimLink",
        "summary": "Generate eSIMs Link",
        "description": "After you have created an eSIM profile, generates a link to share with your customers. The link allows them to install the eSIM profile on their devices, protected by an access code. Provide `iccid` or `esimId`; `esimId` is not needed if you included the `iccid`.",
        "externalDocs": {
          "url": "https://docs.getroamify.com/esims/esims-link"
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "iccid": {
                    "type": "string",
                    "description": "The ICCID of the eSIM."
                  },
                  "esimId": {
                    "type": "string",
                    "description": "The ID of the eSIM. No need to provide it if you included the `iccid`."
                  }
                },
                "anyOf": [
                  {
                    "required": [
                      "iccid"
                    ]
                  },
                  {
                    "required": [
                      "esimId"
                    ]
                  }
                ]
              },
              "example": {
                "iccid": "iccid here"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The generated eSIMs Link.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "description": "Result of the request.",
                      "examples": [
                        "success"
                      ]
                    },
                    "data": {
                      "$ref": "#/components/schemas/EsimLink"
                    }
                  }
                },
                "example": {
                  "status": "success",
                  "data": {
                    "iccid": "8935306745498905",
                    "esimId": "f72d9b90-52b3-47d9-95f6-2cf61ab176aa",
                    "link": "https://dev.esims.link/acme/4OYONUH79IW1",
                    "whatsappLink": "https://api.whatsapp.com/send?text=Check%20out%20your%20eSIM%3A%20https%3A%2F%2Fdev.esims.link%2Facme%2F4OYONUH79IW1%20with%20access%20code%3A%205897",
                    "key": "4OYONUH79IW1",
                    "accessCode": "5897",
                    "createdAt": 1767812581,
                    "updatedAt": 1767812581
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        }
      }
    },
    "/api/esim/event": {
      "get": {
        "tags": [
          "eSIMs"
        ],
        "operationId": "getEsimEvents",
        "summary": "Get eSIM events",
        "description": "Returns the end-to-end lifecycle events of an eSIM, when applicable, to help you and your support team understand its history. At least one of `iccid`, `esimId`, or `referenceId` is required.",
        "externalDocs": {
          "url": "https://docs.getroamify.com/esims/events"
        },
        "parameters": [
          {
            "name": "iccid",
            "in": "query",
            "required": false,
            "description": "The ICCID of the eSIM. At least one of `iccid`, `esimId`, or `referenceId` is required.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "esimId",
            "in": "query",
            "required": false,
            "description": "The esimId provided by Roamify.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "referenceId",
            "in": "query",
            "required": false,
            "description": "The referenceId provided by you when creating the order.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The eSIM events. Note: the documented response is not wrapped in `status`/`data`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EsimEvents"
                },
                "example": {
                  "iccid": "89851000000006262546",
                  "esimId": "f6d83dcb-e7b5-45f7-8c1d-b2a07ebd49f4",
                  "referenceId": "",
                  "events": [
                    {
                      "iccid": "89851000000006262546",
                      "eid": "89049032007008882600092301372109",
                      "status": "INACTIVE",
                      "timeStamp": 1756528206,
                      "dateTime": "2025-08-30 04:30:06"
                    },
                    {
                      "iccid": "89851000000006262546",
                      "eid": "89049032007008882600092301372109",
                      "status": "ACTIVATED",
                      "timeStamp": 1756528208,
                      "dateTime": "2025-08-30 04:30:08"
                    },
                    {
                      "iccid": "89851000000006262546",
                      "eid": "89049032007008882600092301372109",
                      "status": "INACTIVE",
                      "timeStamp": 1756528211,
                      "dateTime": "2025-08-30 04:30:11"
                    },
                    {
                      "iccid": "89851000000006262546",
                      "eid": "89049032007008882600092301372109",
                      "status": "ACTIVATED",
                      "timeStamp": 1756528213,
                      "dateTime": "2025-08-30 04:30:13"
                    }
                  ],
                  "locations": []
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        }
      }
    },
    "/api/balance": {
      "get": {
        "tags": [
          "Balance"
        ],
        "operationId": "getBalance",
        "summary": "Get account balance",
        "description": "Returns the remaining balance of your funds. There are no required parameters for this endpoint.",
        "externalDocs": {
          "url": "https://docs.getroamify.com/esims/balance"
        },
        "responses": {
          "200": {
            "description": "Account balance.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "description": "Result of the request.",
                      "examples": [
                        "success"
                      ]
                    },
                    "data": {
                      "$ref": "#/components/schemas/Balance"
                    }
                  }
                },
                "example": {
                  "status": "success",
                  "data": {
                    "balance": 3723.35,
                    "currency": "USD"
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        }
      }
    },
    "/api/esim/vouchers": {
      "post": {
        "tags": [
          "Vouchers"
        ],
        "operationId": "createVouchers",
        "summary": "Create vouchers",
        "description": "Mints a batch of redeemable voucher codes, each backed by a real eSIM bundle created up front. Always send a `referenceId`: creating vouchers is not idempotent on its own, and a repeat of a batch that already landed is rejected with `409`. `quantity` can come back lower than `requestedQuantity` if the batch stopped part-way; compare the two on every response and mint the shortfall as a new batch with a new `referenceId`. Selected partners only: voucher endpoints are enabled per API key; if the feature is not enabled on your key, every voucher endpoint returns `403`.",
        "externalDocs": {
          "url": "https://docs.getroamify.com/esims/vouchers#create-vouchers"
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "packageId": {
                    "type": "string",
                    "description": "The ID of the eSIM package to mint vouchers for. It must be one of the packages your API key is allowed to mint."
                  },
                  "quantity": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 10,
                    "default": 1,
                    "description": "How many vouchers to mint. A whole number between 1 and 10."
                  },
                  "referenceId": {
                    "type": "string",
                    "description": "Your own identifier for this batch. It must not have been used for a previous batch."
                  },
                  "notes": {
                    "type": "string",
                    "description": "A free-text note stored on every voucher in the batch. May be an empty string."
                  }
                },
                "required": [
                  "packageId"
                ]
              },
              "example": {
                "packageId": "esim-global-one-year-365days-0gb-all",
                "quantity": 2,
                "referenceId": "campaign-2026-03",
                "notes": "Spring campaign giveaway"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "description": "Result of the request.",
                      "examples": [
                        "success"
                      ]
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "referenceId": {
                          "type": "string",
                          "description": "The reference ID you sent, or an empty string if you did not send one."
                        },
                        "requestedQuantity": {
                          "type": "number",
                          "description": "How many vouchers you asked for."
                        },
                        "quantity": {
                          "type": "number",
                          "description": "How many vouchers were actually created."
                        },
                        "vouchers": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/Voucher"
                          },
                          "description": "The vouchers that were created."
                        }
                      }
                    }
                  }
                },
                "example": {
                  "status": "success",
                  "data": {
                    "referenceId": "campaign-2026-03",
                    "requestedQuantity": 2,
                    "quantity": 2,
                    "vouchers": [
                      {
                        "id": "b06036c5-eadc-4f88-aa31-8c207fec91ec",
                        "code": "R7K2M9QX4B1D",
                        "redeemUrl": "https://www.getroamify.com/voucher/R7K2M9QX4B1D",
                        "status": "ACTIVE",
                        "referenceId": "campaign-2026-03",
                        "packageId": "esim-global-one-year-365days-0gb-all",
                        "package": "1 GB - 365 Days",
                        "destination": "Global",
                        "price": 9,
                        "currency": "USD",
                        "esimId": "f72d9b90-52b3-47d9-95f6-2cf61ab176aa",
                        "orderId": "67bbabb7-e893-410a-b0a8-4fa62d347b6c",
                        "notes": "Spring campaign giveaway",
                        "redeemedAt": null,
                        "createdAt": 1731837535,
                        "updatedAt": 1731837535
                      },
                      {
                        "id": "3f9c1d42-6a77-4a0e-9d19-9d4c1c2f77ab",
                        "code": "T4W8ZP2N6C5H",
                        "redeemUrl": "https://www.getroamify.com/voucher/T4W8ZP2N6C5H",
                        "status": "ACTIVE",
                        "referenceId": "campaign-2026-03",
                        "packageId": "esim-global-one-year-365days-0gb-all",
                        "package": "1 GB - 365 Days",
                        "destination": "Global",
                        "price": 9,
                        "currency": "USD",
                        "esimId": "0c1a7b55-9f34-4b62-9a4e-2b7e5d0c9a11",
                        "orderId": "a1d2f3c4-5b6e-4f70-8a9b-0c1d2e3f4a5b",
                        "notes": "Spring campaign giveaway",
                        "redeemedAt": null,
                        "createdAt": 1731837535,
                        "updatedAt": 1731837535
                      }
                    ]
                  }
                }
              }
            }
          },
          "400": {
            "description": "Validation error. Documented messages: \"\"packageId\" is required\" | \"\"quantity\" must be a number\" | \"\"quantity\" must be greater than or equal to 1\" | \"\"quantity\" must be less than or equal to 10\" | \"Invalid quantity, please provide a whole number of at least 1\""
          },
          "401": {
            "description": "\"Unauthorized, please make sure your have provided the correct api key\""
          },
          "403": {
            "description": "Voucher feature not enabled, or package not allowed. Documented messages: \"Voucher creation is not enabled for this API key, please contact support to have it enabled\" | \"This packageId is not allowed for voucher creation with this API key, please use one of the packages allowed for your account\""
          },
          "409": {
            "description": "\"Vouchers with the same referenceId already exist, please make sure you have provided a unique referenceId\""
          },
          "500": {
            "description": "\"Failed to create vouchers, please try again later\""
          },
          "503": {
            "description": "\"Vouchers cannot be issued at the moment, please retry shortly or contact support\""
          }
        }
      },
      "get": {
        "tags": [
          "Vouchers"
        ],
        "operationId": "listVouchers",
        "summary": "Get vouchers",
        "description": "Returns your vouchers, newest first (sorted by `createdAt` descending). `limit` is applied after sorting; omitting `limit` returns every matching voucher. This endpoint is not paginated; if you mint large volumes, filter by `referenceId` per batch. Selected partners only: voucher endpoints are enabled per API key; if the feature is not enabled on your key, every voucher endpoint returns `403`.",
        "externalDocs": {
          "url": "https://docs.getroamify.com/esims/vouchers#get-vouchers"
        },
        "parameters": [
          {
            "name": "referenceId",
            "in": "query",
            "required": false,
            "description": "Return only the vouchers minted under this reference ID.",
            "schema": {
              "type": "string"
            },
            "example": "campaign-2026-03"
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "description": "Return only the vouchers in this status, in uppercase.",
            "schema": {
              "type": "string",
              "enum": [
                "ACTIVE",
                "REDEEMED",
                "CANCELLED"
              ]
            },
            "example": "ACTIVE"
          },
          {
            "name": "packageId",
            "in": "query",
            "required": false,
            "description": "Return only the vouchers for this package.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "The maximum number of vouchers to return. A whole number of at least 1.",
            "schema": {
              "type": "integer",
              "minimum": 1
            },
            "example": 10
          }
        ],
        "responses": {
          "200": {
            "description": "List of vouchers.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "description": "Result of the request.",
                      "examples": [
                        "success"
                      ]
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "referenceId": {
                          "type": "string",
                          "description": "Echoes back the `referenceId` you filtered on, or an empty string if you did not filter by one."
                        },
                        "vouchers": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/Voucher"
                          }
                        }
                      }
                    }
                  }
                },
                "example": {
                  "status": "success",
                  "data": {
                    "referenceId": "campaign-2026-03",
                    "vouchers": [
                      {
                        "id": "b06036c5-eadc-4f88-aa31-8c207fec91ec",
                        "code": "R7K2M9QX4B1D",
                        "redeemUrl": "https://www.getroamify.com/voucher/R7K2M9QX4B1D",
                        "status": "ACTIVE",
                        "referenceId": "campaign-2026-03",
                        "packageId": "esim-global-one-year-365days-0gb-all",
                        "package": "1 GB - 365 Days",
                        "destination": "Global",
                        "price": 9,
                        "currency": "USD",
                        "esimId": "f72d9b90-52b3-47d9-95f6-2cf61ab176aa",
                        "orderId": "67bbabb7-e893-410a-b0a8-4fa62d347b6c",
                        "notes": "Spring campaign giveaway",
                        "redeemedAt": null,
                        "createdAt": 1731837535,
                        "updatedAt": 1731837535
                      }
                    ]
                  }
                }
              }
            }
          },
          "400": {
            "description": "Validation error. Documented messages: \"\"status\" must be one of [ACTIVE, REDEEMED, CANCELLED]\" | \"\"limit\" must be greater than or equal to 1\""
          },
          "401": {
            "description": "\"Unauthorized, please make sure your have provided the correct api key\""
          },
          "403": {
            "description": "\"Voucher creation is not enabled for this API key, please contact support to have it enabled\""
          },
          "500": {
            "description": "\"Failed to get vouchers, please try again later\""
          }
        }
      }
    },
    "/api/esim/voucher/{voucherId}": {
      "get": {
        "tags": [
          "Vouchers"
        ],
        "operationId": "getVoucher",
        "summary": "Get voucher",
        "description": "Returns a single voucher by its ID. Selected partners only: voucher endpoints are enabled per API key; if the feature is not enabled on your key, every voucher endpoint returns `403`.",
        "externalDocs": {
          "url": "https://docs.getroamify.com/esims/vouchers#get-voucher"
        },
        "parameters": [
          {
            "name": "voucherId",
            "in": "path",
            "required": true,
            "description": "The ID of the voucher, as returned in the voucher's `id` field.",
            "schema": {
              "type": "string"
            },
            "example": "b06036c5-eadc-4f88-aa31-8c207fec91ec"
          }
        ],
        "responses": {
          "200": {
            "description": "The voucher.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "description": "Result of the request.",
                      "examples": [
                        "success"
                      ]
                    },
                    "data": {
                      "$ref": "#/components/schemas/Voucher"
                    }
                  }
                },
                "example": {
                  "status": "success",
                  "data": {
                    "id": "b06036c5-eadc-4f88-aa31-8c207fec91ec",
                    "code": "R7K2M9QX4B1D",
                    "redeemUrl": "https://www.getroamify.com/voucher/R7K2M9QX4B1D",
                    "status": "REDEEMED",
                    "referenceId": "campaign-2026-03",
                    "packageId": "esim-global-one-year-365days-0gb-all",
                    "package": "1 GB - 365 Days",
                    "destination": "Global",
                    "price": 9,
                    "currency": "USD",
                    "esimId": "f72d9b90-52b3-47d9-95f6-2cf61ab176aa",
                    "orderId": "67bbabb7-e893-410a-b0a8-4fa62d347b6c",
                    "notes": "Spring campaign giveaway",
                    "redeemedAt": 1731999000,
                    "createdAt": 1731837535,
                    "updatedAt": 1731999000
                  }
                }
              }
            }
          },
          "401": {
            "description": "\"Unauthorized, please make sure your have provided the correct api key\""
          },
          "403": {
            "description": "\"Voucher creation is not enabled for this API key, please contact support to have it enabled\""
          },
          "404": {
            "description": "\"Voucher not found, please make sure you have provided the correct voucher ID or code\". A voucher belonging to another partner is reported as `404`, not `403`."
          },
          "500": {
            "description": "\"Failed to get vouchers, please try again later\""
          }
        }
      }
    },
    "/api/esim/voucher/code/{code}": {
      "get": {
        "tags": [
          "Vouchers"
        ],
        "operationId": "getVoucherByCode",
        "summary": "Get voucher by code",
        "description": "Looks a voucher up by the code you handed out. The code is normalised before it is matched: trimmed, upper-cased, and every character that is not a letter or digit is stripped, so `r7k2-m9qx-4b1d` and `R7K2M9QX4B1D` resolve to the same voucher. After normalisation the code must be exactly 12 alphanumeric characters; anything else is reported as `404`. Selected partners only: voucher endpoints are enabled per API key; if the feature is not enabled on your key, every voucher endpoint returns `403`.",
        "externalDocs": {
          "url": "https://docs.getroamify.com/esims/vouchers#get-voucher-by-code"
        },
        "parameters": [
          {
            "name": "code",
            "in": "path",
            "required": true,
            "description": "The voucher code.",
            "schema": {
              "type": "string"
            },
            "example": "R7K2M9QX4B1D"
          }
        ],
        "responses": {
          "200": {
            "description": "The voucher.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "description": "Result of the request.",
                      "examples": [
                        "success"
                      ]
                    },
                    "data": {
                      "$ref": "#/components/schemas/Voucher"
                    }
                  }
                },
                "example": {
                  "status": "success",
                  "data": {
                    "id": "b06036c5-eadc-4f88-aa31-8c207fec91ec",
                    "code": "R7K2M9QX4B1D",
                    "redeemUrl": "https://www.getroamify.com/voucher/R7K2M9QX4B1D",
                    "status": "ACTIVE",
                    "referenceId": "campaign-2026-03",
                    "packageId": "esim-global-one-year-365days-0gb-all",
                    "package": "1 GB - 365 Days",
                    "destination": "Global",
                    "price": 9,
                    "currency": "USD",
                    "esimId": "f72d9b90-52b3-47d9-95f6-2cf61ab176aa",
                    "orderId": "67bbabb7-e893-410a-b0a8-4fa62d347b6c",
                    "notes": "Spring campaign giveaway",
                    "redeemedAt": null,
                    "createdAt": 1731837535,
                    "updatedAt": 1731837535
                  }
                }
              }
            }
          },
          "401": {
            "description": "\"Unauthorized, please make sure your have provided the correct api key\""
          },
          "403": {
            "description": "\"Voucher creation is not enabled for this API key, please contact support to have it enabled\""
          },
          "404": {
            "description": "\"Voucher not found, please make sure you have provided the correct voucher ID or code\". A voucher belonging to another partner is reported as `404`, not `403`."
          },
          "500": {
            "description": "\"Failed to get vouchers, please try again later\""
          }
        }
      }
    },
    "/api/esim/voucher/{voucherId}/revoke": {
      "put": {
        "tags": [
          "Vouchers"
        ],
        "operationId": "revokeVoucher",
        "summary": "Revoke voucher",
        "description": "Cancels a voucher and the eSIM behind it. Use it for a code that was distributed by mistake, leaked, or is no longer wanted. Revoking is permanent. Only `ACTIVE` vouchers can be revoked. No request body is required. Selected partners only: voucher endpoints are enabled per API key; if the feature is not enabled on your key, every voucher endpoint returns `403`.",
        "externalDocs": {
          "url": "https://docs.getroamify.com/esims/vouchers#revoke-voucher"
        },
        "parameters": [
          {
            "name": "voucherId",
            "in": "path",
            "required": true,
            "description": "The ID of the voucher to revoke.",
            "schema": {
              "type": "string"
            },
            "example": "b06036c5-eadc-4f88-aa31-8c207fec91ec"
          }
        ],
        "responses": {
          "200": {
            "description": "The revoked voucher.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "description": "Result of the request.",
                      "examples": [
                        "success"
                      ]
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string"
                        },
                        "status": {
                          "type": "string",
                          "enum": [
                            "ACTIVE",
                            "REDEEMED",
                            "CANCELLED"
                          ]
                        }
                      }
                    }
                  }
                },
                "example": {
                  "status": "success",
                  "data": {
                    "id": "b06036c5-eadc-4f88-aa31-8c207fec91ec",
                    "status": "CANCELLED"
                  }
                }
              }
            }
          },
          "401": {
            "description": "\"Unauthorized, please make sure your have provided the correct api key\""
          },
          "403": {
            "description": "\"Voucher creation is not enabled for this API key, please contact support to have it enabled\""
          },
          "404": {
            "description": "\"Voucher not found, please make sure you have provided the correct voucher ID or code\". A voucher belonging to another partner is reported as `404`, not `403`."
          },
          "409": {
            "description": "The voucher cannot be revoked. Documented messages: \"Voucher has already been redeemed and can no longer be revoked\" | \"Only active vouchers can be revoked, this voucher is no longer active\""
          },
          "500": {
            "description": "\"Failed to revoke voucher, please try again later\""
          }
        }
      }
    },
    "/api/refund": {
      "post": {
        "tags": [
          "Refunds"
        ],
        "operationId": "createRefundRequest",
        "summary": "Create a refund request",
        "description": "Asks Roamify support to refund one eSIM of one of your orders. Support reviews the request and the refund happens only after it is approved; submitting a request never moves money by itself and does not revoke the eSIM. An eSIM can have one open request at a time.",
        "externalDocs": {
          "url": "https://docs.getroamify.com/esims/refunds#create-a-refund-request"
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateRefundRequest"
              },
              "example": {
                "productType": "esim",
                "iccid": "8935303411619613",
                "reason": "UNABLE_TO_INSTALL",
                "notes": "The customer could not scan the QR code on an iPhone 12."
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "The new refund request, with a `tracking` object that tells you where to poll it.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/RefundRequest"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "tracking": {
                          "type": "object",
                          "properties": {
                            "method": {
                              "type": "string"
                            },
                            "path": {
                              "type": "string"
                            }
                          }
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "refundId": "9f3c1c0e-6a52-4b8e-9d0a-0d3f1e2a7c11",
                  "status": "PENDING",
                  "productType": "esim",
                  "item": {
                    "esimId": "74b73655-0fa7-49e4-bab6-eb80b5522104",
                    "iccid": "8935303411619613",
                    "orderId": "ee9357c2-0000-0000-0000-000000000000",
                    "countryName": "Bahrain",
                    "optionName": "5 GB - 3 Days"
                  },
                  "reason": "UNABLE_TO_INSTALL",
                  "notes": "The customer could not scan the QR code on an iPhone 12.",
                  "amount": null,
                  "currency": null,
                  "balanceCreditUsd": null,
                  "transaction": null,
                  "rejectionReason": null,
                  "rejectionNote": null,
                  "createdAt": 1762570000,
                  "updatedAt": 1762570000,
                  "processedAt": null,
                  "cancelledAt": null,
                  "history": [
                    {
                      "status": "PENDING",
                      "at": 1762570000
                    }
                  ],
                  "tracking": {
                    "method": "GET",
                    "path": "/api/refund?refundId=9f3c1c0e-6a52-4b8e-9d0a-0d3f1e2a7c11"
                  }
                }
              }
            }
          },
          "400": {
            "description": "`INVALID_PARAMETER`: a parameter is missing or invalid (for example both or neither of `iccid` and `esimId`). `REFUND_INVALID_REASON`: `reason` is not a supported reason. `REFUND_NOTES_REQUIRED`: `reason` is `OTHER` without `notes` of at least 10 characters.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RefundError"
                }
              }
            }
          },
          "401": {
            "description": "Authentication error. Carries a `code` as well.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RefundError"
                }
              }
            }
          },
          "403": {
            "description": "Authentication error. Carries a `code` as well.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RefundError"
                }
              }
            }
          },
          "404": {
            "description": "`ESIM_NOT_FOUND`: no eSIM of your account has that `iccid` or `esimId`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RefundError"
                }
              }
            }
          },
          "409": {
            "description": "`REFUND_REQUEST_ALREADY_EXISTS`: the eSIM already has an open (`PENDING` or `PROCESSING`) request. The body carries its `refundId`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RefundError"
                }
              }
            }
          },
          "422": {
            "description": "`REFUND_NOT_ELIGIBLE`: the eSIM cannot be refunded; `reasons` lists why, for example `ESIM_ALREADY_REFUNDED`. `REFUND_PRODUCT_TYPE_NOT_SUPPORTED`: only `esim` is supported.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RefundError"
                }
              }
            }
          },
          "429": {
            "description": "Authentication error. Carries a `code` as well.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RefundError"
                }
              }
            }
          },
          "500": {
            "description": "`REFUND_CREATE_FAILED`, `REFUND_GET_FAILED`, `REFUND_CANCEL_FAILED` or `REFUND_SERVICE_NOT_CONFIGURED`: a temporary failure. Try again later.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RefundError"
                }
              }
            }
          }
        }
      },
      "get": {
        "tags": [
          "Refunds"
        ],
        "operationId": "getRefundRequest",
        "summary": "Get a refund request",
        "description": "Returns one refund request. Send exactly one of `refundId`, `esimId` or `iccid`.",
        "externalDocs": {
          "url": "https://docs.getroamify.com/esims/refunds#get-a-refund-request"
        },
        "parameters": [
          {
            "name": "refundId",
            "in": "query",
            "required": false,
            "description": "The request. Send exactly one of `refundId`, `esimId` or `iccid`.",
            "schema": {
              "type": "string"
            },
            "example": "9f3c1c0e-6a52-4b8e-9d0a-0d3f1e2a7c11"
          },
          {
            "name": "esimId",
            "in": "query",
            "required": false,
            "description": "Returns the newest request for that eSIM.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "iccid",
            "in": "query",
            "required": false,
            "description": "Returns the newest request for that ICCID.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The refund request.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RefundRequest"
                }
              }
            }
          },
          "400": {
            "description": "`INVALID_PARAMETER`: a parameter is missing or invalid.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RefundError"
                }
              }
            }
          },
          "401": {
            "description": "Authentication error. Carries a `code` as well.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RefundError"
                }
              }
            }
          },
          "403": {
            "description": "Authentication error. Carries a `code` as well.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RefundError"
                }
              }
            }
          },
          "404": {
            "description": "`REFUND_REQUEST_NOT_FOUND`: no request matches the `refundId`, `esimId` or `iccid`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RefundError"
                }
              }
            }
          },
          "429": {
            "description": "Authentication error. Carries a `code` as well.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RefundError"
                }
              }
            }
          },
          "500": {
            "description": "`REFUND_CREATE_FAILED`, `REFUND_GET_FAILED`, `REFUND_CANCEL_FAILED` or `REFUND_SERVICE_NOT_CONFIGURED`: a temporary failure. Try again later.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RefundError"
                }
              }
            }
          }
        }
      }
    },
    "/api/refund/bulk": {
      "post": {
        "tags": [
          "Refunds"
        ],
        "operationId": "createBulkRefundRequests",
        "summary": "Create refund requests in bulk",
        "description": "Requests refunds for several eSIMs in one call. A bad entry fails the whole call with `400`, and nothing is created. Entries that are valid but refused individually (for example an eSIM that already has an open request) are reported in the results instead, one result per entry in the order you sent them.",
        "externalDocs": {
          "url": "https://docs.getroamify.com/esims/refunds#create-refund-requests-in-bulk"
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "productType": {
                    "type": "string",
                    "description": "What is refunded. Only `esim` is supported for now. It applies to every entry."
                  },
                  "refunds": {
                    "type": "array",
                    "items": {
                      "$ref": "#/components/schemas/BulkRefundEntry"
                    },
                    "description": "Between 1 and 20 entries.",
                    "minItems": 1,
                    "maxItems": 20
                  }
                },
                "required": [
                  "productType",
                  "refunds"
                ]
              },
              "example": {
                "productType": "esim",
                "refunds": [
                  {
                    "iccid": "8935303411619613",
                    "reason": "NO_CONNECTIVITY"
                  },
                  {
                    "esimId": "74b73655-0fa7-49e4-bab6-eb80b5522104",
                    "reason": "OTHER",
                    "notes": "Customer cancelled the trip."
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "One result per entry, in the order you sent them.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "summary": {
                      "type": "object",
                      "properties": {
                        "requested": {
                          "type": "number"
                        },
                        "created": {
                          "type": "number"
                        },
                        "failed": {
                          "type": "number"
                        },
                        "duplicates": {
                          "type": "number"
                        }
                      }
                    },
                    "results": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/BulkRefundResult"
                      }
                    }
                  }
                },
                "example": {
                  "summary": {
                    "requested": 2,
                    "created": 1,
                    "failed": 1,
                    "duplicates": 0
                  },
                  "results": [
                    {
                      "index": 0,
                      "iccid": "8935303411619613",
                      "status": "CREATED",
                      "refund": {
                        "refundId": "9f3c1c0e-6a52-4b8e-9d0a-0d3f1e2a7c11",
                        "status": "PENDING"
                      }
                    },
                    {
                      "index": 1,
                      "esimId": "74b73655-0fa7-49e4-bab6-eb80b5522104",
                      "status": "FAILED",
                      "error": {
                        "code": "REFUND_REQUEST_ALREADY_EXISTS",
                        "message": "A refund request is already open for this eSIM",
                        "refundId": "2b1d7e40-0000-0000-0000-000000000000"
                      }
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "description": "A bad entry fails the whole call and nothing is created. `INVALID_PARAMETER` (for example more than 20 entries), `REFUND_INVALID_REASON` or `REFUND_NOTES_REQUIRED`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RefundError"
                }
              }
            }
          },
          "401": {
            "description": "Authentication error. Carries a `code` as well.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RefundError"
                }
              }
            }
          },
          "403": {
            "description": "Authentication error. Carries a `code` as well.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RefundError"
                }
              }
            }
          },
          "422": {
            "description": "`REFUND_PRODUCT_TYPE_NOT_SUPPORTED`: only `esim` is supported.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RefundError"
                }
              }
            }
          },
          "429": {
            "description": "Authentication error. Carries a `code` as well.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RefundError"
                }
              }
            }
          },
          "500": {
            "description": "`REFUND_CREATE_FAILED`, `REFUND_GET_FAILED`, `REFUND_CANCEL_FAILED` or `REFUND_SERVICE_NOT_CONFIGURED`: a temporary failure. Try again later.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RefundError"
                }
              }
            }
          }
        }
      }
    },
    "/api/refunds": {
      "get": {
        "tags": [
          "Refunds"
        ],
        "operationId": "listRefundRequests",
        "summary": "List refund requests",
        "description": "Lists your refund requests, newest first. All query parameters are optional. When `nextCursor` is not `null`, send it back as `cursor` to get the next page.",
        "externalDocs": {
          "url": "https://docs.getroamify.com/esims/refunds#list-refund-requests"
        },
        "parameters": [
          {
            "name": "status",
            "in": "query",
            "required": false,
            "description": "Only requests with this status.",
            "schema": {
              "$ref": "#/components/schemas/RefundStatus"
            },
            "example": "PENDING"
          },
          {
            "name": "iccid",
            "in": "query",
            "required": false,
            "description": "Only requests for that eSIM. Send at most one of `iccid` or `esimId`.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "esimId",
            "in": "query",
            "required": false,
            "description": "Only requests for that eSIM. Send at most one of `iccid` or `esimId`.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Page size, from 1 to 100.",
            "schema": {
              "type": "number",
              "minimum": 1,
              "maximum": 100
            },
            "example": 20
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "description": "The `nextCursor` of the previous page.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "A page of refund requests.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "items": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/RefundRequest"
                      }
                    },
                    "nextCursor": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "description": "Send it back as `cursor` to get the next page. `null` on the last page."
                    }
                  }
                },
                "example": {
                  "items": [
                    {
                      "refundId": "9f3c1c0e-6a52-4b8e-9d0a-0d3f1e2a7c11",
                      "status": "PENDING"
                    }
                  ],
                  "nextCursor": null
                }
              }
            }
          },
          "400": {
            "description": "`INVALID_PARAMETER`: for example an invalid `limit`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RefundError"
                }
              }
            }
          },
          "401": {
            "description": "Authentication error. Carries a `code` as well.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RefundError"
                }
              }
            }
          },
          "403": {
            "description": "Authentication error. Carries a `code` as well.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RefundError"
                }
              }
            }
          },
          "429": {
            "description": "Authentication error. Carries a `code` as well.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RefundError"
                }
              }
            }
          },
          "500": {
            "description": "`REFUND_CREATE_FAILED`, `REFUND_GET_FAILED`, `REFUND_CANCEL_FAILED` or `REFUND_SERVICE_NOT_CONFIGURED`: a temporary failure. Try again later.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RefundError"
                }
              }
            }
          }
        }
      }
    },
    "/api/refund/{refundId}/cancel": {
      "put": {
        "tags": [
          "Refunds"
        ],
        "operationId": "cancelRefundRequest",
        "summary": "Cancel a refund request",
        "description": "Withdraws a refund request. Only a request that is still `PENDING` can be cancelled. You can submit a new request for the same eSIM afterwards.",
        "externalDocs": {
          "url": "https://docs.getroamify.com/esims/refunds#cancel-a-refund-request"
        },
        "parameters": [
          {
            "name": "refundId",
            "in": "path",
            "required": true,
            "description": "The ID of the refund request.",
            "schema": {
              "type": "string"
            },
            "example": "9f3c1c0e-6a52-4b8e-9d0a-0d3f1e2a7c11"
          }
        ],
        "responses": {
          "200": {
            "description": "The cancelled request, whose `status` is `CANCELLED`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RefundRequest"
                }
              }
            }
          },
          "401": {
            "description": "Authentication error. Carries a `code` as well.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RefundError"
                }
              }
            }
          },
          "403": {
            "description": "Authentication error. Carries a `code` as well.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RefundError"
                }
              }
            }
          },
          "404": {
            "description": "`REFUND_REQUEST_NOT_FOUND`: no request matches the `refundId`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RefundError"
                }
              }
            }
          },
          "409": {
            "description": "`REFUND_INVALID_STATUS`: only a `PENDING` request can be cancelled.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RefundError"
                }
              }
            }
          },
          "429": {
            "description": "Authentication error. Carries a `code` as well.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RefundError"
                }
              }
            }
          },
          "500": {
            "description": "`REFUND_CREATE_FAILED`, `REFUND_GET_FAILED`, `REFUND_CANCEL_FAILED` or `REFUND_SERVICE_NOT_CONFIGURED`: a temporary failure. Try again later.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RefundError"
                }
              }
            }
          }
        }
      }
    },
    "/api/insurance/countries": {
      "get": {
        "tags": [
          "Insurance"
        ],
        "operationId": "getInsuranceCountries",
        "summary": "Get insurance countries",
        "description": "Returns the countries covered by the insurance catalog. Only countries that have at least one activated insurance product are returned, deduplicated by `code` and sorted alphabetically by `name`. Use `name` as `country` and `code` as `countryCode` on `/api/insurance/packages`. Eligibility: insurance packages may only be sold to travellers who are citizens or residents of Saudi Arabia.",
        "externalDocs": {
          "url": "https://docs.getroamify.com/insurance/countries"
        },
        "parameters": [
          {
            "name": "geography",
            "in": "query",
            "required": false,
            "description": "Filter countries by geography scope. Matching is case-insensitive.",
            "schema": {
              "type": "string",
              "enum": [
                "local",
                "regional",
                "global"
              ]
            },
            "example": "local"
          }
        ],
        "responses": {
          "200": {
            "description": "List of countries.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "description": "Result of the request.",
                      "examples": [
                        "success"
                      ]
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "countries": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/InsuranceCountry"
                          }
                        }
                      }
                    }
                  }
                },
                "example": {
                  "status": "success",
                  "data": {
                    "countries": [
                      {
                        "code": "SA",
                        "name": "Saudi Arabia",
                        "slug": "saudi-arabia",
                        "geography": "local"
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        }
      }
    },
    "/api/insurance/packages": {
      "get": {
        "tags": [
          "Insurance"
        ],
        "operationId": "getInsurancePackages",
        "summary": "Get insurance packages",
        "description": "Returns insurance products with their packages. Not paginated; do not send `page` or `pageSize`. Only activated products and packages are returned; a product whose packages are all filtered out is omitted. A `country` or `countryCode` value that does not match exactly yields an empty `packages` array, not an error. Eligibility: insurance packages may only be sold to travellers who are citizens or residents of Saudi Arabia.",
        "externalDocs": {
          "url": "https://docs.getroamify.com/insurance/packages#get-insurance-packages"
        },
        "parameters": [
          {
            "name": "geography",
            "in": "query",
            "required": false,
            "description": "The geography of the insurance packages. Matching is case-insensitive.",
            "schema": {
              "type": "string",
              "enum": [
                "local",
                "regional",
                "global"
              ]
            }
          },
          {
            "name": "country",
            "in": "query",
            "required": false,
            "description": "Full country name filter. Use the `name` value from `GET /api/insurance/countries`.",
            "schema": {
              "type": "string"
            },
            "example": "Saudi Arabia"
          },
          {
            "name": "countryCode",
            "in": "query",
            "required": false,
            "description": "ISO country code filter. Use the `code` value from `GET /api/insurance/countries`.",
            "schema": {
              "type": "string"
            },
            "example": "SA"
          },
          {
            "name": "packageId",
            "in": "query",
            "required": false,
            "description": "The ID of a specific insurance package.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "day",
            "in": "query",
            "required": false,
            "description": "The coverage duration in days. Only packages whose `day` matches exactly are returned.",
            "schema": {
              "type": "integer",
              "minimum": 1
            },
            "example": 7
          }
        ],
        "responses": {
          "200": {
            "description": "Insurance products.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "description": "Result of the request.",
                      "examples": [
                        "success"
                      ]
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "packages": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/InsuranceProduct"
                          }
                        }
                      }
                    }
                  }
                },
                "example": {
                  "status": "success",
                  "data": {
                    "packages": [
                      {
                        "id": "saudi-arabia-insurance",
                        "name": "Saudi Arabia Travel Insurance",
                        "slug": "saudi-arabia-travel-insurance",
                        "countryName": "Saudi Arabia",
                        "countryCode": "SA",
                        "countrySlug": "saudi-arabia",
                        "geography": "local",
                        "region": "Middle East",
                        "description": "Travel insurance for Saudi Arabia citizens and residents.",
                        "image": "https://imagedelivery.net/uUE6LNs_ci8SFBH4_n66dQ/countries/flags/saudi-arabia/public",
                        "coverages": [
                          "Medical expenses",
                          "Trip cancellation",
                          "Lost baggage"
                        ],
                        "insuredType": "individual",
                        "eligibleNationality": [
                          "Saudi Arabia"
                        ],
                        "eligibleNationCodes": [
                          "SA"
                        ],
                        "benefits": [
                          "Emergency medical cover up to USD 50,000",
                          "24/7 assistance hotline"
                        ],
                        "minPrice": 12,
                        "maxPrice": 30,
                        "packages": [
                          {
                            "packageId": "insurance-saudi-arabia-individual-7days",
                            "package": "Individual - 7 Days",
                            "provider": "tree",
                            "type": "individual",
                            "charge": 12,
                            "day": 7,
                            "price": 12,
                            "currency": "USD",
                            "requirements": {
                              "phoneNumber": true,
                              "dateOfBirth": true,
                              "idNumber": true,
                              "passportNumber": false
                            },
                            "notes": []
                          }
                        ]
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        }
      }
    },
    "/api/insurance/package": {
      "get": {
        "tags": [
          "Insurance"
        ],
        "operationId": "getInsurancePackage",
        "summary": "Get a single insurance package",
        "description": "Returns the full product the package belongs to, with its `packages` array narrowed to the single package you requested. Eligibility: insurance packages may only be sold to travellers who are citizens or residents of Saudi Arabia.",
        "externalDocs": {
          "url": "https://docs.getroamify.com/insurance/packages#get-a-single-insurance-package"
        },
        "parameters": [
          {
            "name": "packageId",
            "in": "query",
            "required": true,
            "description": "The ID of the insurance package you want to retrieve.",
            "schema": {
              "type": "string"
            },
            "example": "insurance-saudi-arabia-individual-7days"
          }
        ],
        "responses": {
          "200": {
            "description": "The insurance product.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "description": "Result of the request.",
                      "examples": [
                        "success"
                      ]
                    },
                    "data": {
                      "$ref": "#/components/schemas/InsuranceProduct"
                    }
                  }
                },
                "example": {
                  "status": "success",
                  "data": {
                    "id": "saudi-arabia-insurance",
                    "name": "Saudi Arabia Travel Insurance",
                    "slug": "saudi-arabia-travel-insurance",
                    "countryName": "Saudi Arabia",
                    "countryCode": "SA",
                    "countrySlug": "saudi-arabia",
                    "geography": "local",
                    "region": "Middle East",
                    "description": "Travel insurance for Saudi Arabia citizens and residents.",
                    "image": "https://imagedelivery.net/uUE6LNs_ci8SFBH4_n66dQ/countries/flags/saudi-arabia/public",
                    "coverages": [
                      "Medical expenses",
                      "Trip cancellation",
                      "Lost baggage"
                    ],
                    "insuredType": "individual",
                    "eligibleNationality": [
                      "Saudi Arabia"
                    ],
                    "eligibleNationCodes": [
                      "SA"
                    ],
                    "benefits": [
                      "Emergency medical cover up to USD 50,000",
                      "24/7 assistance hotline"
                    ],
                    "minPrice": 12,
                    "maxPrice": 30,
                    "packages": [
                      {
                        "packageId": "insurance-saudi-arabia-individual-7days",
                        "package": "Individual - 7 Days",
                        "provider": "tree",
                        "type": "individual",
                        "charge": 12,
                        "day": 7,
                        "price": 12,
                        "currency": "USD",
                        "requirements": {
                          "phoneNumber": true,
                          "dateOfBirth": true,
                          "idNumber": true,
                          "passportNumber": false
                        },
                        "notes": []
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "description": "\"Insurance package not found, please make sure you have provided a valid packageId\""
          },
          "500": {
            "description": "\"Failed to get insurance packages, please try again later\""
          }
        }
      }
    },
    "/api/insurance/order": {
      "post": {
        "tags": [
          "Insurance"
        ],
        "operationId": "createInsuranceOrder",
        "summary": "Create insurance order",
        "description": "Reserves one policy per unit of quantity and debits your partner balance. It does not issue anything: issue each reserved policy (`policyId`) against a named traveller with `POST /api/insurance/apply`. Every `packageId` must start with `insurance-`. The total quantity across all items in a single order cannot exceed 5. `referenceId` must be unique across your orders; reusing one returns `409`. Eligibility: insurance packages may only be sold to travellers who are citizens or residents of Saudi Arabia.",
        "externalDocs": {
          "url": "https://docs.getroamify.com/insurance/orders#create-insurance-order"
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "items": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "packageId": {
                          "type": "string",
                          "description": "The ID of the insurance package you want to order. Must start with `insurance-`.",
                          "pattern": "^insurance-"
                        },
                        "quantity": {
                          "type": "integer",
                          "minimum": 1,
                          "description": "The number of policies to reserve for this package."
                        }
                      },
                      "required": [
                        "packageId",
                        "quantity"
                      ]
                    },
                    "description": "The insurance items you want to order. At least one item is required. Total quantity across all items cannot exceed 5.",
                    "minItems": 1
                  },
                  "referenceId": {
                    "type": "string",
                    "description": "Your custom reference ID for the order, if needed. Must be unique across your orders."
                  }
                },
                "required": [
                  "items"
                ]
              },
              "example": {
                "items": [
                  {
                    "packageId": "insurance-saudi-arabia-individual-7days",
                    "quantity": 1
                  }
                ],
                "referenceId": "Optional Reference ID"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The insurance order.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "description": "Result of the request.",
                      "examples": [
                        "success"
                      ]
                    },
                    "data": {
                      "$ref": "#/components/schemas/InsuranceOrder"
                    }
                  }
                },
                "example": {
                  "status": "success",
                  "data": {
                    "id": "67bbabb7-e893-410a-b0a8-4fa62d347b6c",
                    "referenceId": "ref-123456",
                    "orderType": "api",
                    "status": "COMPLETED",
                    "total": 12,
                    "currency": "USD",
                    "createdAt": 1731837535,
                    "updatedAt": 1731837539,
                    "items": [
                      {
                        "policyId": "b06036c5-eadc-4f88-aa31-8c207fec91ec",
                        "packageId": "insurance-saudi-arabia-individual-7days",
                        "package": "Individual - 7 Days",
                        "type": "insurance",
                        "price": 12,
                        "currency": "USD",
                        "createdAt": 1731837535,
                        "updatedAt": 1731837539
                      }
                    ]
                  }
                }
              }
            }
          },
          "400": {
            "description": "Validation error. Documented messages: \"Only insurance packages can be ordered through this endpoint. Every packageId must start with 'insurance-'; use POST /esim/order for eSIM packages\" | \"Invalid quantity, please make sure your have provided the correct quantity\" | \"Exceed maximum total quantity of 5, please make sure your have provided the correct quantity and the quantity does not exceed the maximum allowed quantity 5\" | \"Missing required fields, please provide all required fields according to the documentation\""
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "409": {
            "description": "Conflict. Documented messages: \"Order with the same referenceId already exists, please make sure your have provided a unique referenceId\" | \"Insufficient partner balance, please recharge it first before placing order\""
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        }
      },
      "get": {
        "tags": [
          "Insurance"
        ],
        "operationId": "getInsuranceOrder",
        "summary": "Get insurance order",
        "description": "Returns a specific insurance order. You must provide exactly one of `orderId` or `referenceId`; providing both, or neither, is a validation error. This endpoint only resolves insurance orders; an eSIM order ID returns `404`.",
        "externalDocs": {
          "url": "https://docs.getroamify.com/insurance/orders#get-insurance-order"
        },
        "parameters": [
          {
            "name": "orderId",
            "in": "query",
            "required": false,
            "description": "The ID of the insurance order. Provide exactly one of `orderId` or `referenceId`.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "referenceId",
            "in": "query",
            "required": false,
            "description": "The reference ID of the insurance order. Provide exactly one of `orderId` or `referenceId`.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The insurance order.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "description": "Result of the request.",
                      "examples": [
                        "success"
                      ]
                    },
                    "data": {
                      "$ref": "#/components/schemas/InsuranceOrder"
                    }
                  }
                },
                "example": {
                  "status": "success",
                  "data": {
                    "id": "67bbabb7-e893-410a-b0a8-4fa62d347b6c",
                    "referenceId": "ref-123456",
                    "orderType": "api",
                    "status": "COMPLETED",
                    "total": 12,
                    "currency": "USD",
                    "createdAt": 1731837535,
                    "updatedAt": 1731837539,
                    "items": [
                      {
                        "policyId": "b06036c5-eadc-4f88-aa31-8c207fec91ec",
                        "packageId": "insurance-saudi-arabia-individual-7days",
                        "package": "Individual - 7 Days",
                        "type": "insurance",
                        "price": 12,
                        "currency": "USD",
                        "createdAt": 1731837535,
                        "updatedAt": 1731837539
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "description": "\"Order not found, please make sure your have provided the correct orderId or referenceId\""
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        }
      }
    },
    "/api/insurance/orders": {
      "get": {
        "tags": [
          "Insurance"
        ],
        "operationId": "listInsuranceOrders",
        "summary": "Get insurance orders",
        "description": "Returns insurance orders, newest first (sorted by `createdAt` descending). Only orders you placed through the API are included.",
        "externalDocs": {
          "url": "https://docs.getroamify.com/insurance/orders#get-insurance-orders"
        },
        "parameters": [
          {
            "name": "status",
            "in": "query",
            "required": false,
            "description": "The status of the insurance orders to return. Matching is exact and case-sensitive.",
            "schema": {
              "type": "string"
            },
            "example": "COMPLETED"
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "The number of insurance orders to return.",
            "schema": {
              "type": "number",
              "default": 50
            },
            "example": 10
          }
        ],
        "responses": {
          "200": {
            "description": "List of insurance orders.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "description": "Result of the request.",
                      "examples": [
                        "success"
                      ]
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "orders": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/InsuranceOrder"
                          }
                        }
                      }
                    }
                  }
                },
                "example": {
                  "status": "success",
                  "data": {
                    "orders": [
                      {
                        "id": "67bbabb7-e893-410a-b0a8-4fa62d347b6c",
                        "referenceId": "ref-123456",
                        "orderType": "api",
                        "status": "COMPLETED",
                        "total": 12,
                        "currency": "USD",
                        "createdAt": 1731837535,
                        "updatedAt": 1731837539,
                        "items": [
                          {
                            "policyId": "b06036c5-eadc-4f88-aa31-8c207fec91ec",
                            "packageId": "insurance-saudi-arabia-individual-7days",
                            "package": "Individual - 7 Days",
                            "type": "insurance",
                            "price": 12,
                            "currency": "USD",
                            "createdAt": 1731837535,
                            "updatedAt": 1731837539
                          }
                        ]
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        }
      }
    },
    "/api/insurance/apply": {
      "post": {
        "tags": [
          "Insurance"
        ],
        "operationId": "applyInsurance",
        "summary": "Apply insurance",
        "description": "Issues a reserved policy against a named traveller. `dateOfBirth`, `idNumber`, `passportNumber` and (via `phoneNumber`) `mobile` are governed by the package's `requirements` object, snapshotted onto the policy; `mobile` and `email` are required on every call. Validation is deliberately looser than the provider's, so passing it does not guarantee issuance. Applying to a policy that is already `ISSUED`, `ACTIVE`, or `EXPIRED` returns `409`; issuance is not idempotent, so do not blindly retry on `409`; if the policy is being issued, poll `GET /api/insurance/policy`. Eligibility: insurance packages may only be sold to travellers who are citizens or residents of Saudi Arabia.",
        "externalDocs": {
          "url": "https://docs.getroamify.com/insurance/policies#apply-insurance"
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ApplyInsuranceRequest"
              },
              "example": {
                "policyId": "b06036c5-eadc-4f88-aa31-8c207fec91ec",
                "startDate": "01/08/2026",
                "endDate": "08/08/2026",
                "mobile": "966512345678",
                "email": "traveller@example.com",
                "insurer": {
                  "firstName": "Fahad",
                  "lastName": "Al Otaibi",
                  "nationality": "Saudi Arabia",
                  "dateOfBirth": "24/06/1990",
                  "idNumber": "1012345678"
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The issued policy.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "description": "Result of the request.",
                      "examples": [
                        "success"
                      ]
                    },
                    "data": {
                      "$ref": "#/components/schemas/InsurancePolicy"
                    }
                  }
                },
                "example": {
                  "status": "success",
                  "data": {
                    "policyId": "b06036c5-eadc-4f88-aa31-8c207fec91ec",
                    "orderId": "67bbabb7-e893-410a-b0a8-4fa62d347b6c",
                    "packageId": "insurance-saudi-arabia-individual-7days",
                    "package": "Individual - 7 Days",
                    "countryName": "Saudi Arabia",
                    "type": "insurance",
                    "status": "ISSUED",
                    "startDate": "01/08/2026",
                    "endDate": "08/08/2026",
                    "insurerName": "Fahad Al Otaibi",
                    "requirements": {
                      "phoneNumber": true,
                      "dateOfBirth": true,
                      "idNumber": true,
                      "passportNumber": false
                    },
                    "coverage": {
                      "insuredType": "individual",
                      "day": 7,
                      "benefits": [
                        "Emergency medical cover up to USD 50,000",
                        "24/7 assistance hotline"
                      ]
                    },
                    "policy": {
                      "policyNo": "TRV-2026-000123",
                      "policyIssuanceDate": "2026-07-10",
                      "policyLink": "https://provider.example.com/policies/TRV-2026-000123.pdf"
                    },
                    "createdAt": 1731837535,
                    "updatedAt": 1731837987,
                    "expiredAt": 1765238400
                  }
                }
              }
            }
          },
          "400": {
            "description": "Validation error. Documented messages: \"This insurance package requires idNumber, please provide insurer.idNumber\" | \"This insurance package requires passportNumber, please provide insurer.passportNumber\" | \"This insurance package requires dateOfBirth, please provide insurer.dateOfBirth in the format DD/MM/YYYY (e.g. 24/06/1990)\" | \"This insurance package requires phoneNumber, please provide mobile in international format without the leading '+' (e.g. 966512345678)\" | \"Invalid traveller name, please provide both insurer.firstName and insurer.lastName\" | \"Invalid nationality, please provide insurer.nationality\" | \"Invalid idNumber, please provide a valid identification number for the traveller\" | \"Invalid passportNumber, please provide a valid passport number for the traveller\" | \"Invalid dateOfBirth, please provide a past date in the format DD/MM/YYYY (e.g. 24/06/1990)\" | \"Invalid mobile, please provide 8 to 15 digits in international format without the leading '+' (e.g. 966512345678)\" | \"Invalid email, please provide a valid email address for the traveller\" | \"Invalid startDate, please provide the coverage start date in the format DD/MM/YYYY (e.g. 01/08/2026)\" | \"Invalid endDate, please provide the coverage end date in the format DD/MM/YYYY (e.g. 08/08/2026) and make sure it is after startDate\" | \"Coverage cannot start today, please provide a startDate at least 1 day in the future\" | \"The requested coverage window is longer than the purchased package allows, please shorten it or buy a longer package\" | \"Insurance details failed validation, please make sure you have provided all the required traveller fields\""
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "description": "\"Insurance policy not found, please make sure you have provided the correct policyId\""
          },
          "409": {
            "description": "The policy cannot be applied. Documented messages: \"This insurance policy has already been issued and cannot be applied again\" | \"This insurance policy is currently being issued, please retry with GET /insurance/policy?policyId=id after some time\" | \"A policy has already been issued for this reference, please contact support if you believe this is an error\""
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          },
          "502": {
            "description": "Provider failure. Documented messages: \"Failed to issue the insurance policy, please try again later or contact support\" | \"The insurance provider rejected the request, please verify the traveller details and try again\""
          }
        }
      }
    },
    "/api/insurance/policy": {
      "get": {
        "tags": [
          "Insurance"
        ],
        "operationId": "getInsurancePolicy",
        "summary": "Get insurance policy",
        "description": "Returns a specific insurance policy. Use it to read the `requirements` for a policy you already hold, and to poll for the issued policy document after a `409` telling you issuance is in progress. A policy belonging to another partner is reported as `404`, not `403`.",
        "externalDocs": {
          "url": "https://docs.getroamify.com/insurance/policies#get-insurance-policy"
        },
        "parameters": [
          {
            "name": "policyId",
            "in": "query",
            "required": true,
            "description": "The ID of the insurance policy you want to retrieve.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The policy.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "description": "Result of the request.",
                      "examples": [
                        "success"
                      ]
                    },
                    "data": {
                      "$ref": "#/components/schemas/InsurancePolicy"
                    }
                  }
                },
                "example": {
                  "status": "success",
                  "data": {
                    "policyId": "b06036c5-eadc-4f88-aa31-8c207fec91ec",
                    "orderId": "67bbabb7-e893-410a-b0a8-4fa62d347b6c",
                    "packageId": "insurance-saudi-arabia-individual-7days",
                    "package": "Individual - 7 Days",
                    "countryName": "Saudi Arabia",
                    "type": "insurance",
                    "status": "NEW",
                    "startDate": "",
                    "endDate": "",
                    "insurerName": "",
                    "requirements": {
                      "phoneNumber": true,
                      "dateOfBirth": true,
                      "idNumber": true,
                      "passportNumber": false
                    },
                    "coverage": {
                      "insuredType": "individual",
                      "day": 7,
                      "benefits": [
                        "Emergency medical cover up to USD 50,000",
                        "24/7 assistance hotline"
                      ]
                    },
                    "policy": null,
                    "createdAt": 1731837535,
                    "updatedAt": 1731837535,
                    "expiredAt": -1
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "description": "\"Insurance policy not found, please make sure you have provided the correct policyId\""
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        }
      }
    },
    "/api/insurance/policies": {
      "get": {
        "tags": [
          "Insurance"
        ],
        "operationId": "listInsurancePolicies",
        "summary": "Get insurance policies",
        "description": "Returns insurance policies, newest first (sorted by `createdAt` descending).",
        "externalDocs": {
          "url": "https://docs.getroamify.com/insurance/policies#get-insurance-policies"
        },
        "parameters": [
          {
            "name": "orderId",
            "in": "query",
            "required": false,
            "description": "Return only the policies reserved through this order.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "description": "The status of the policies to return. Matching is exact and case-sensitive.",
            "schema": {
              "type": "string"
            },
            "example": "ISSUED"
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "The number of policies to return.",
            "schema": {
              "type": "number",
              "default": 50
            },
            "example": 10
          }
        ],
        "responses": {
          "200": {
            "description": "List of policies.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "description": "Result of the request.",
                      "examples": [
                        "success"
                      ]
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "policies": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/InsurancePolicy"
                          }
                        }
                      }
                    }
                  }
                },
                "example": {
                  "status": "success",
                  "data": {
                    "policies": [
                      {
                        "policyId": "b06036c5-eadc-4f88-aa31-8c207fec91ec",
                        "orderId": "67bbabb7-e893-410a-b0a8-4fa62d347b6c",
                        "packageId": "insurance-saudi-arabia-individual-7days",
                        "package": "Individual - 7 Days",
                        "countryName": "Saudi Arabia",
                        "type": "insurance",
                        "status": "ISSUED",
                        "startDate": "01/08/2026",
                        "endDate": "08/08/2026",
                        "insurerName": "Fahad Al Otaibi",
                        "requirements": {
                          "phoneNumber": true,
                          "dateOfBirth": true,
                          "idNumber": true,
                          "passportNumber": false
                        },
                        "coverage": {
                          "insuredType": "individual",
                          "day": 7,
                          "benefits": [
                            "Emergency medical cover up to USD 50,000",
                            "24/7 assistance hotline"
                          ]
                        },
                        "policy": {
                          "policyNo": "TRV-2026-000123",
                          "policyIssuanceDate": "2026-07-10",
                          "policyLink": "https://provider.example.com/policies/TRV-2026-000123.pdf"
                        },
                        "createdAt": 1731837535,
                        "updatedAt": 1731837987,
                        "expiredAt": 1765238400
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        }
      }
    },
    "/api/currencies": {
      "get": {
        "tags": [
          "Exchange Rates"
        ],
        "operationId": "getCurrencies",
        "summary": "Get supported currencies",
        "description": "Returns all supported currencies. The request does not require any parameters.",
        "externalDocs": {
          "url": "https://docs.getroamify.com/exchange-rates/get-currencies"
        },
        "responses": {
          "200": {
            "description": "Supported currencies. The docs do not document the response body."
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        }
      }
    },
    "/api/rates": {
      "get": {
        "tags": [
          "Exchange Rates"
        ],
        "operationId": "getExchangeRates",
        "summary": "Get exchange rates",
        "description": "Returns exchange rates between a source and a target currency. Without `datetime`, `from`, `to` or `interval`, the latest exchange rate is used. Pass `datetime` to convert at a point in time, or `from`/`to` with `interval` for historical data. If `datetime` is provided, do not provide `from`, `to` or `interval`; if `from` or `to` is provided, also provide `interval` and do not provide `datetime`. Otherwise the API returns an error.",
        "externalDocs": {
          "url": "https://docs.getroamify.com/exchange-rates/get-exchange-rates"
        },
        "parameters": [
          {
            "name": "source",
            "in": "query",
            "required": true,
            "description": "The source currency code.",
            "schema": {
              "type": "string"
            },
            "example": "USD"
          },
          {
            "name": "target",
            "in": "query",
            "required": true,
            "description": "The target currency code.",
            "schema": {
              "type": "string"
            },
            "example": "EUR"
          },
          {
            "name": "datetime",
            "in": "query",
            "required": false,
            "description": "The date and time for which you want the exchange rate, in ISO 8601 format. If not provided, the latest exchange rate is used. Do not combine with `from`, `to` or `interval`.",
            "schema": {
              "type": "string"
            },
            "example": "2023-01-01T00:00:00Z"
          },
          {
            "name": "from",
            "in": "query",
            "required": false,
            "description": "The start date for the historical data, in ISO 8601 format.",
            "schema": {
              "type": "string"
            },
            "example": "2023-01-01T00:00:00Z"
          },
          {
            "name": "to",
            "in": "query",
            "required": false,
            "description": "The end date for the historical data, in ISO 8601 format.",
            "schema": {
              "type": "string"
            },
            "example": "2023-01-07T00:00:00Z"
          },
          {
            "name": "interval",
            "in": "query",
            "required": false,
            "description": "The interval for the historical data. Required when `from` or `to` is provided.",
            "schema": {
              "type": "string",
              "enum": [
                "day",
                "hour",
                "minute"
              ]
            },
            "example": "day"
          }
        ],
        "responses": {
          "200": {
            "description": "Exchange rate data. The docs do not document the response body."
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        }
      }
    },
    "/api/esim/{partnerSlug}/packages": {
      "get": {
        "tags": [
          "Affiliate"
        ],
        "operationId": "getAffiliatePackages",
        "summary": "Get affiliate links",
        "description": "Once onboarded, you are assigned a dedicated endpoint to fetch your affiliate links. Returns all available eSIM packages with a referral link for each package. The referral link includes your unique identifier, which is used to track the sales you make. Customers must click your referral link for the sale to be tracked.",
        "externalDocs": {
          "url": "https://docs.getroamify.com/affiliate/affiliate-links"
        },
        "parameters": [
          {
            "name": "partnerSlug",
            "in": "path",
            "required": true,
            "description": "Your dedicated unique name, assigned when you are onboarded.",
            "schema": {
              "type": "string"
            },
            "example": "esimradar"
          }
        ],
        "responses": {
          "200": {
            "description": "eSIM packages per country, each with your referral link.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "description": "Result of the request.",
                      "examples": [
                        "success"
                      ]
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "packages": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/AffiliateCountry"
                          }
                        }
                      }
                    }
                  }
                },
                "example": {
                  "status": "success",
                  "data": {
                    "packages": [
                      {
                        "id": "c21a8a20-5646-4b26-8df3-f5d37147790f",
                        "countryName": "Afghanistan",
                        "countryCode": "AF",
                        "region": "local",
                        "packages": [
                          {
                            "id": "515e279d-0c78-4d65-a45b-e7c12ca2ebea",
                            "name": "1 GB - 7 Days",
                            "price": 5.5,
                            "validity": 7,
                            "plan": "data-only",
                            "dataAmount": 1024,
                            "dataUnit": "MB",
                            "data": "1 GB",
                            "isUnlimited": false,
                            "isActivated": true,
                            "withKyc": false,
                            "withTopUp": true,
                            "withSMS": false,
                            "withCall": false,
                            "withHotspot": true,
                            "smsUnit": "",
                            "callUnit": "",
                            "smsLabel": "",
                            "callLabel": "",
                            "smsAmount": -1,
                            "callAmount": -1,
                            "coverages": [
                              "Afghanistan"
                            ],
                            "networks": [
                              "3G",
                              "4G"
                            ],
                            "signals": [
                              {
                                "code": "AF",
                                "name": "Afghanistan",
                                "networks": [
                                  "3G",
                                  "4G"
                                ],
                                "carriers": [
                                  "Roshan"
                                ]
                              }
                            ],
                            "link": "https://www.getroamify.com/esim/afghanistan/?referrer=5Spg1dU0XRhHeUJGx6JFak4zccH2"
                          },
                          {
                            "id": "92014f96-e231-4ea8-afbc-f5434dd78eee",
                            "name": "3 GB - 15 Days",
                            "price": 14.5,
                            "validity": 15,
                            "plan": "data-only",
                            "dataAmount": 3072,
                            "dataUnit": "MB",
                            "data": "3 GB",
                            "isUnlimited": false,
                            "isActivated": true,
                            "withKyc": false,
                            "withTopUp": true,
                            "withSMS": false,
                            "withCall": false,
                            "withHotspot": true,
                            "smsUnit": "",
                            "callUnit": "",
                            "smsLabel": "",
                            "callLabel": "",
                            "smsAmount": -1,
                            "callAmount": -1,
                            "coverages": [
                              "Afghanistan"
                            ],
                            "networks": [
                              "3G",
                              "4G"
                            ],
                            "signals": [
                              {
                                "code": "AF",
                                "name": "Afghanistan",
                                "networks": [
                                  "3G",
                                  "4G"
                                ],
                                "carriers": [
                                  "Roshan"
                                ]
                              }
                            ],
                            "link": "https://www.getroamify.com/esim/afghanistan/?referrer=5Spg1dU0XRhHeUJGx6JFak4zccH2"
                          },
                          {
                            "id": "b20dbf4f-415a-4545-9109-3ba9739f873b",
                            "name": "3 GB - 30 Days",
                            "price": 15.5,
                            "validity": 30,
                            "plan": "data-only",
                            "dataAmount": 3072,
                            "dataUnit": "MB",
                            "data": "3 GB",
                            "isUnlimited": false,
                            "isActivated": true,
                            "withKyc": false,
                            "withTopUp": true,
                            "withSMS": false,
                            "withCall": false,
                            "withHotspot": true,
                            "smsUnit": "",
                            "callUnit": "",
                            "smsLabel": "",
                            "callLabel": "",
                            "smsAmount": -1,
                            "callAmount": -1,
                            "coverages": [
                              "Afghanistan"
                            ],
                            "networks": [
                              "3G",
                              "4G"
                            ],
                            "signals": [
                              {
                                "code": "AF",
                                "name": "Afghanistan",
                                "networks": [
                                  "3G",
                                  "4G"
                                ],
                                "carriers": [
                                  "Roshan"
                                ]
                              }
                            ],
                            "link": "https://www.getroamify.com/esim/afghanistan/?referrer=5Spg1dU0XRhHeUJGx6JFak4zccH2"
                          }
                        ]
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        }
      }
    }
  },
  "webhooks": {
    "esimStatus": {
      "post": {
        "tags": [
          "Webhooks"
        ],
        "operationId": "esimStatusWebhook",
        "summary": "eSIM status event",
        "description": "Sent when an eSIM's status changes (activation, deactivation, suspension or other state changes). Roamify sends an HTTPS `POST` to the webhook URL configured in the Roamify dashboard. Verify the `X-Roamify-Signature` header before processing.",
        "externalDocs": {
          "url": "https://docs.getroamify.com/webhooks/types/esim-status"
        },
        "security": [],
        "parameters": [
          {
            "name": "X-Roamify-Signature",
            "in": "header",
            "required": true,
            "description": "HMAC-SHA256 of the raw request body computed with your webhook secret key, hex-encoded. Recompute it and compare in constant time; reject the request if it does not match.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/EsimStatusEvent"
              },
              "example": {
                "event_category": "esim",
                "event_type": "status",
                "data": {
                  "timestamp": 1700000000,
                  "iccid": "8991234567890123456",
                  "esim_id": "c2a9cdae-430e-4251-bf65-a84df4562ed9",
                  "reference_id": "ref_1234567890",
                  "start": 1699996800,
                  "end": 1700000400,
                  "status": "ACTIVATED"
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Acknowledge receipt with 200 OK quickly (within 3 seconds), then process the event in the background. If your endpoint does not respond in time, Roamify retries the webhook up to 3 times at increasing intervals.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WebhookAck"
                },
                "example": {
                  "code": 200,
                  "status": "success"
                }
              }
            }
          }
        }
      }
    },
    "esimUsage": {
      "post": {
        "tags": [
          "Webhooks"
        ],
        "operationId": "esimUsageWebhook",
        "summary": "eSIM usage event",
        "description": "Sent for every activated eSIM every 4 hours, and when data usage reaches 25%, 50%, 75%, 90% and 100% of the total data allocation. Roamify sends an HTTPS `POST` to the webhook URL configured in the Roamify dashboard. Verify the `X-Roamify-Signature` header before processing.",
        "externalDocs": {
          "url": "https://docs.getroamify.com/webhooks/types/esim-usage"
        },
        "security": [],
        "parameters": [
          {
            "name": "X-Roamify-Signature",
            "in": "header",
            "required": true,
            "description": "HMAC-SHA256 of the raw request body computed with your webhook secret key, hex-encoded. Recompute it and compare in constant time; reject the request if it does not match.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/EsimUsageEvent"
              },
              "example": {
                "event_category": "esim",
                "event_type": "usage",
                "data": {
                  "timestamp": 1700000000,
                  "iccid": "8991234567890123456",
                  "esim_id": "c2a9cdae-430e-4251-bf65-a84df4562ed9",
                  "reference_id": "ref_1234567890",
                  "start": 1699996800,
                  "end": 1700000400,
                  "status": "ACTIVATED",
                  "package_id": "esim-afghanistan-7days-1gb-all",
                  "package_name": "1 GB - 7 Days",
                  "data_units": "MB",
                  "voice_units": "minutes",
                  "sms_units": "sms",
                  "usage_data": {
                    "isUnlimited": false,
                    "allowed_data": 1024,
                    "remaining_data": 512,
                    "allowed_sms": 100,
                    "remaining_sms": 50,
                    "allowed_voice": 500,
                    "remaining_voice": 250
                  },
                  "usage_list": [
                    {
                      "date": "2023-11-01",
                      "data_used": 100,
                      "location": "Afghanistan"
                    },
                    {
                      "date": "2023-11-02",
                      "data_used": 200,
                      "location": "Afghanistan"
                    }
                  ]
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Acknowledge receipt with 200 OK quickly (within 3 seconds), then process the event in the background. If your endpoint does not respond in time, Roamify retries the webhook up to 3 times at increasing intervals.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WebhookAck"
                },
                "example": {
                  "code": 200,
                  "status": "success"
                }
              }
            }
          }
        }
      }
    },
    "partnerBalance": {
      "post": {
        "tags": [
          "Webhooks"
        ],
        "operationId": "partnerBalanceWebhook",
        "summary": "Partner balance event",
        "description": "Sent when your balance falls below the configured threshold (and at 75%, 50% and 25% of the threshold), when a transaction exceeds your current balance, and when funds are added to your partner account. Roamify sends an HTTPS `POST` to the webhook URL configured in the Roamify dashboard. Verify the `X-Roamify-Signature` header before processing.",
        "externalDocs": {
          "url": "https://docs.getroamify.com/webhooks/types/partner-balance"
        },
        "security": [],
        "parameters": [
          {
            "name": "X-Roamify-Signature",
            "in": "header",
            "required": true,
            "description": "HMAC-SHA256 of the raw request body computed with your webhook secret key, hex-encoded. Recompute it and compare in constant time; reject the request if it does not match.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PartnerBalanceEvent"
              },
              "example": {
                "event_type": "low_balance",
                "event_category": "partner",
                "data": {
                  "timestamp": 1673123456,
                  "balance": 50.0,
                  "threshold": 100.0,
                  "threshold_percentage": 50,
                  "currency": "USD"
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Acknowledge receipt with 200 OK quickly (within 3 seconds), then process the event in the background. If your endpoint does not respond in time, Roamify retries the webhook up to 3 times at increasing intervals.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WebhookAck"
                },
                "example": {
                  "code": 200,
                  "status": "success"
                }
              }
            }
          }
        }
      }
    },
    "affiliateOrder": {
      "post": {
        "tags": [
          "Webhooks"
        ],
        "operationId": "affiliateOrderWebhook",
        "summary": "Affiliate orders event",
        "description": "Sent when orders are placed through your affiliate links, so you can track conversions and commissions. Roamify sends an HTTPS `POST` to the webhook URL configured in the Roamify dashboard. Verify the `X-Roamify-Signature` header before processing.",
        "externalDocs": {
          "url": "https://docs.getroamify.com/webhooks/types/affiliate-orders"
        },
        "security": [],
        "parameters": [
          {
            "name": "X-Roamify-Signature",
            "in": "header",
            "required": true,
            "description": "HMAC-SHA256 of the raw request body computed with your webhook secret key, hex-encoded. Recompute it and compare in constant time; reject the request if it does not match.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AffiliateOrderEvent"
              },
              "example": {
                "event_category": "affiliate",
                "event_type": "order",
                "data": {
                  "timestamp": 1700000000,
                  "partner_name": "ACME Affiliate",
                  "partner_id": "6ImuFenqQbPjYaYyhWRIvkYdsF42",
                  "commission_rate": 10.0,
                  "commission_amount": 5.0,
                  "order_data": {
                    "order_id": "c2a9cdae-430e-4251-bf65-a84df4562ed9",
                    "order_total": 49.99,
                    "order_adjustment": 0.0,
                    "order_subtotal": 49.99,
                    "order_discount": 0.0,
                    "order_currency": "USD",
                    "order_status": "completed",
                    "order_items": [
                      {
                        "item_id": "esim-afghanistan-7days-1gb-all",
                        "item_name": "1 GB - 7 Days",
                        "item_quantity": 1,
                        "item_price": 49.99
                      }
                    ]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Acknowledge receipt with 200 OK quickly (within 3 seconds), then process the event in the background. If your endpoint does not respond in time, Roamify retries the webhook up to 3 times at increasing intervals.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WebhookAck"
                },
                "example": {
                  "code": 200,
                  "status": "success"
                }
              }
            }
          }
        }
      }
    },
    "refund": {
      "post": {
        "tags": [
          "Webhooks"
        ],
        "operationId": "refundWebhook",
        "summary": "Refund event",
        "description": "Sent when Roamify support has decided one of your refund requests (`refunded` or `rejected`). No event is sent when a request is created, approved for processing or cancelled. A delivery can be repeated; use `event_id` to drop an event you have already processed. Roamify sends an HTTPS `POST` to the webhook URL configured in the Roamify dashboard. Verify the `X-Roamify-Signature` header before processing.",
        "externalDocs": {
          "url": "https://docs.getroamify.com/webhooks/types/refund"
        },
        "security": [],
        "parameters": [
          {
            "name": "X-Roamify-Signature",
            "in": "header",
            "required": true,
            "description": "HMAC-SHA256 of the raw request body computed with your webhook secret key, hex-encoded. Recompute it and compare in constant time; reject the request if it does not match.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RefundEvent"
              },
              "examples": {
                "refunded": {
                  "value": {
                    "event_id": "rfd_9f3c1c0e-6a52-4b8e-9d0a-0d3f1e2a7c11_refunded",
                    "event_type": "refunded",
                    "event_category": "refund",
                    "data": {
                      "timestamp": 1762571000,
                      "refund_id": "9f3c1c0e-6a52-4b8e-9d0a-0d3f1e2a7c11",
                      "status": "REFUNDED",
                      "product_type": "esim",
                      "esim_id": "74b73655-0fa7-49e4-bab6-eb80b5522104",
                      "iccid": "8935303411619613",
                      "reference_id": "ref_1234567890",
                      "order_id": "ee9357c2-0000-0000-0000-000000000000",
                      "reason": "UNABLE_TO_INSTALL",
                      "amount": 1.39,
                      "currency": "USD",
                      "balance_credit_usd": 1.39,
                      "transaction_id": "rf_0000000000",
                      "payment_method": "balance",
                      "rejection_reason": null,
                      "rejection_note": null,
                      "requested_at": 1762570000,
                      "processed_at": 1762570990
                    }
                  }
                },
                "rejected": {
                  "value": {
                    "event_id": "rfd_2b1d7e40-0000-0000-0000-000000000000_rejected",
                    "event_type": "rejected",
                    "event_category": "refund",
                    "data": {
                      "timestamp": 1762571000,
                      "refund_id": "2b1d7e40-0000-0000-0000-000000000000",
                      "status": "REJECTED",
                      "product_type": "esim",
                      "esim_id": "c2a9cdae-430e-4251-bf65-a84df4562ed9",
                      "iccid": "8991234567890123456",
                      "reference_id": "",
                      "order_id": "ee9357c2-0000-0000-0000-000000000000",
                      "reason": "CUSTOMER_REQUEST",
                      "amount": null,
                      "currency": null,
                      "balance_credit_usd": null,
                      "transaction_id": null,
                      "payment_method": null,
                      "rejection_reason": "DATA_USED",
                      "rejection_note": null,
                      "requested_at": 1762570000,
                      "processed_at": 1762570990
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Acknowledge receipt with 200 OK quickly (within 3 seconds), then process the event in the background. If your endpoint does not respond in time, Roamify retries the webhook up to 3 times at increasing intervals.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WebhookAck"
                },
                "example": {
                  "code": 200,
                  "status": "success"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "description": "Send your Access Token (called API Key in the Roamify Partner Portal) in the `Authorization` header as `Bearer <token>`. The token is long-lived and stays valid until you rotate it in the Partner Portal under API Keys; after rotation the old token is invalidated immediately."
      }
    },
    "schemas": {
      "EsimCountry": {
        "type": "object",
        "properties": {
          "code": {
            "type": "string",
            "description": "Country or region code. Use it as `countryCode` on `GET /api/esim/packages`."
          },
          "name": {
            "type": "string",
            "description": "Country or region name. Use it as `country` on `GET /api/esim/packages`."
          },
          "geography": {
            "type": "string",
            "description": "Geography scope of the entry."
          }
        }
      },
      "Pagination": {
        "type": "object",
        "properties": {
          "page": {
            "type": "number"
          },
          "pageSize": {
            "type": "number"
          },
          "totalItems": {
            "type": "number"
          },
          "totalPages": {
            "type": "number"
          },
          "hasNextPage": {
            "type": "boolean"
          },
          "hasPreviousPage": {
            "type": "boolean"
          }
        },
        "description": "Pagination information returned by `GET /api/esim/packages`."
      },
      "Signal": {
        "type": "object",
        "properties": {
          "code": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "networks": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "carriers": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        },
        "description": "Network coverage for a country."
      },
      "Throttle": {
        "type": "object",
        "properties": {
          "throttleSpeed": {
            "type": "number"
          },
          "throttleSpeedUnit": {
            "type": "string"
          },
          "throttleThreshold": {
            "type": "number"
          },
          "throttleThresholdUnit": {
            "type": "string"
          }
        },
        "description": "Throttling details, in effect when `withThrottle` is `true`."
      },
      "EsimPackage": {
        "type": "object",
        "properties": {
          "packageId": {
            "type": "string",
            "description": "The ID of the eSIM package. Use it when ordering."
          },
          "package": {
            "type": "string",
            "description": "Display name of the package."
          },
          "plan": {
            "type": "string"
          },
          "activation": {
            "type": "string"
          },
          "day": {
            "type": "number"
          },
          "price": {
            "type": "number"
          },
          "isUnlimited": {
            "type": "boolean"
          },
          "isAPNAutomatic": {
            "type": "boolean"
          },
          "apn": {
            "type": "string"
          },
          "dataAmount": {
            "type": "number"
          },
          "dataUnit": {
            "type": "string"
          },
          "callType": {
            "type": "string"
          },
          "callAmount": {
            "type": "number"
          },
          "callUnit": {
            "type": "string"
          },
          "smsType": {
            "type": "string"
          },
          "smsAmount": {
            "type": "number"
          },
          "smsUnit": {
            "type": "string"
          },
          "withSMS": {
            "type": "boolean"
          },
          "withCall": {
            "type": "boolean"
          },
          "withHotspot": {
            "type": "boolean"
          },
          "withDataRoaming": {
            "type": "boolean"
          },
          "withDestinationInstall": {
            "type": "boolean"
          },
          "withUsageCheck": {
            "type": "boolean",
            "description": "If `false`, usage check is not supported; find instructions in the `notes` property."
          },
          "withThrottle": {
            "type": "boolean",
            "description": "If `true`, throttling is in effect; find more info in the `throttle` property."
          },
          "throttle": {
            "$ref": "#/components/schemas/Throttle"
          },
          "requirements": {
            "type": "object",
            "properties": {
              "travelDate": {
                "type": "boolean",
                "description": "When `true`, `startDate` (ISO 8601) is required on `POST /api/esim/apply`."
              }
            },
            "description": "Package requirements. The docs reference `requirements.travelDate`; it is not shown in the sample response."
          },
          "notes": {
            "type": "array",
            "description": "Package notes."
          }
        }
      },
      "EsimCountryPackages": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "countryName": {
            "type": "string"
          },
          "countryCode": {
            "type": "string"
          },
          "countrySlug": {
            "type": "string"
          },
          "region": {
            "type": "string"
          },
          "geography": {
            "type": "string"
          },
          "minPrice": {
            "type": "number"
          },
          "maxPrice": {
            "type": "number"
          },
          "image": {
            "type": "string"
          },
          "signals": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Signal"
            }
          },
          "packages": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/EsimPackage"
            }
          }
        },
        "description": "A destination with its eSIM packages."
      },
      "CompatibleDevice": {
        "type": "object",
        "properties": {
          "model": {
            "type": "string"
          },
          "deviceType": {
            "type": "string"
          },
          "os": {
            "type": "string"
          },
          "brand": {
            "type": "string"
          },
          "name": {
            "type": "string"
          }
        }
      },
      "Balance": {
        "type": "object",
        "properties": {
          "balance": {
            "type": "number",
            "description": "Remaining balance of your funds."
          },
          "currency": {
            "type": "string"
          }
        }
      },
      "OrderItem": {
        "type": "object",
        "properties": {
          "esimId": {
            "type": "string",
            "description": "The ID of the eSIM. Use it with `POST /api/esim/apply`."
          },
          "packageId": {
            "type": "string"
          },
          "package": {
            "type": "string"
          },
          "type": {
            "type": "string"
          },
          "price": {
            "type": "number"
          },
          "currency": {
            "type": "string"
          },
          "createdAt": {
            "type": "number",
            "description": "Unix timestamp (seconds since epoch)."
          },
          "updatedAt": {
            "type": "number",
            "description": "Unix timestamp (seconds since epoch)."
          }
        }
      },
      "EsimOrder": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "The ID of the order."
          },
          "referenceId": {
            "type": "string",
            "description": "Your reference ID for the order."
          },
          "orderType": {
            "type": "string"
          },
          "status": {
            "type": "string",
            "description": "Order status: `PENDING`, `COMPLETED`, `ARCHIVED`, `CANCELLED`, `REFUNDED` or `REQUIRE_ACTION`."
          },
          "total": {
            "type": "number"
          },
          "currency": {
            "type": "string"
          },
          "createdAt": {
            "type": "number",
            "description": "Unix timestamp (seconds since epoch)."
          },
          "updatedAt": {
            "type": "number",
            "description": "Unix timestamp (seconds since epoch)."
          },
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/OrderItem"
            }
          }
        }
      },
      "InstantEsimOrder": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "The ID of the order."
          },
          "referenceId": {
            "type": "string",
            "description": "Your reference ID for the order."
          },
          "orderType": {
            "type": "string"
          },
          "status": {
            "type": "string",
            "description": "Order status: `PENDING`, `COMPLETED`, `ARCHIVED`, `CANCELLED`, `REFUNDED` or `REQUIRE_ACTION`."
          },
          "total": {
            "type": "number"
          },
          "currency": {
            "type": "string"
          },
          "createdAt": {
            "type": "number",
            "description": "Unix timestamp (seconds since epoch)."
          },
          "updatedAt": {
            "type": "number",
            "description": "Unix timestamp (seconds since epoch)."
          },
          "esims": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Esim"
            },
            "description": "The fulfilled eSIMs, ready to use."
          }
        }
      },
      "Apn": {
        "type": "object",
        "properties": {
          "apnAutomatic": {
            "type": "boolean"
          },
          "apnName": {
            "type": "string"
          },
          "apnUsername": {
            "type": "string"
          },
          "apnPassword": {
            "type": "string"
          }
        }
      },
      "EsimProfile": {
        "type": "object",
        "properties": {
          "lpaCode": {
            "type": "string"
          },
          "smdpAddress": {
            "type": "string"
          },
          "activationCode": {
            "type": "string"
          },
          "qrCodeUrl": {
            "type": "string"
          },
          "pin": {
            "type": "string"
          },
          "puk": {
            "type": "string"
          },
          "number": {
            "type": "string"
          },
          "iosQuickInstall": {
            "type": "string"
          },
          "androidQuickInstall": {
            "type": "string"
          }
        },
        "description": "Installation details of the eSIM profile."
      },
      "Esim": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "The eSIM ID (`esimId`)."
          },
          "iccid": {
            "type": "string"
          },
          "status": {
            "type": "string",
            "description": "eSIM status, for example `NEW`, `READY`, `INSTALLED`, `REVOKED`, `EXPIRED` or `UNKNOWN`."
          },
          "activation": {
            "type": "string"
          },
          "withTopUp": {
            "type": "boolean",
            "description": "Whether the eSIM supports top-up."
          },
          "withHotspot": {
            "type": "boolean"
          },
          "withDataRoaming": {
            "type": "boolean"
          },
          "withDestinationInstall": {
            "type": "boolean"
          },
          "withUsageCheck": {
            "type": "boolean",
            "description": "If `false`, usage check is not supported; find instructions in the `notes` property."
          },
          "esim": {
            "$ref": "#/components/schemas/EsimProfile"
          },
          "apn": {
            "$ref": "#/components/schemas/Apn"
          },
          "data": {
            "type": "object",
            "properties": {
              "isUnlimited": {
                "type": "boolean"
              }
            }
          },
          "call": {
            "type": "object",
            "properties": {
              "withCall": {
                "type": "boolean"
              },
              "callType": {
                "type": "string"
              }
            }
          },
          "sms": {
            "type": "object",
            "properties": {
              "withSMS": {
                "type": "boolean"
              },
              "smsType": {
                "type": "string"
              }
            }
          },
          "notes": {
            "type": "array"
          },
          "createdAt": {
            "type": "number",
            "description": "Unix timestamp (seconds since epoch)."
          },
          "updatedAt": {
            "type": "number",
            "description": "Unix timestamp (seconds since epoch)."
          },
          "expiredAt": {
            "type": "number",
            "description": "Unix timestamp (seconds since epoch)."
          }
        }
      },
      "EsimUsage": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "iccid": {
            "type": "string"
          },
          "status": {
            "type": "string"
          },
          "startedAt": {
            "type": "number",
            "description": "Unix timestamp (seconds since epoch)."
          },
          "expiredAt": {
            "type": "number",
            "description": "Unix timestamp (seconds since epoch)."
          },
          "allowedData": {
            "type": "number"
          },
          "remainingData": {
            "type": "number"
          },
          "allowedSms": {
            "type": "number"
          },
          "remainingSms": {
            "type": "number"
          },
          "allowedVoice": {
            "type": "number"
          },
          "remainingVoice": {
            "type": "number"
          }
        }
      },
      "EsimUsageDetails": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "iccid": {
            "type": "string"
          },
          "status": {
            "type": "string"
          },
          "startedAt": {
            "type": "number",
            "description": "Unix timestamp (seconds since epoch)."
          },
          "expiredAt": {
            "type": "number",
            "description": "Unix timestamp (seconds since epoch)."
          },
          "allowedData": {
            "type": "number"
          },
          "remainingData": {
            "type": "number"
          },
          "allowedSms": {
            "type": "number"
          },
          "remainingSms": {
            "type": "number"
          },
          "allowedVoice": {
            "type": "number"
          },
          "remainingVoice": {
            "type": "number"
          },
          "dataUsages": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "date": {
                  "type": "string"
                },
                "usage": {
                  "type": "number"
                },
                "location": {
                  "type": "string"
                }
              }
            },
            "description": "Data usage records."
          }
        }
      },
      "TopUpPackage": {
        "type": "object",
        "properties": {
          "packageId": {
            "type": "string",
            "description": "Use it as `packageId` on `POST /api/esim/order/topup`."
          },
          "package": {
            "type": "string"
          },
          "plan": {
            "type": "string"
          },
          "activation": {
            "type": "string"
          },
          "day": {
            "type": "number"
          },
          "price": {
            "type": "number"
          },
          "withHotspot": {
            "type": "boolean"
          },
          "withDataRoaming": {
            "type": "boolean"
          },
          "withDestinationInstall": {
            "type": "boolean"
          },
          "withUsageCheck": {
            "type": "boolean",
            "description": "If `false`, usage check is not supported; find instructions in the `notes` property."
          },
          "apn": {
            "$ref": "#/components/schemas/Apn"
          },
          "data": {
            "type": "object",
            "properties": {
              "isUnlimited": {
                "type": "boolean"
              },
              "dataAmount": {
                "type": "number"
              },
              "dataUnit": {
                "type": "string"
              }
            }
          },
          "call": {
            "type": "object",
            "properties": {
              "withCall": {
                "type": "boolean"
              },
              "callType": {
                "type": "string"
              },
              "callAmount": {
                "type": "number"
              },
              "callUnit": {
                "type": "string"
              }
            }
          },
          "sms": {
            "type": "object",
            "properties": {
              "withSMS": {
                "type": "boolean"
              },
              "smsType": {
                "type": "string"
              },
              "smsAmount": {
                "type": "number"
              },
              "smsUnit": {
                "type": "string"
              }
            }
          },
          "notes": {
            "type": "array"
          }
        }
      },
      "EsimEvent": {
        "type": "object",
        "properties": {
          "iccid": {
            "type": "string"
          },
          "eid": {
            "type": "string"
          },
          "status": {
            "type": "string"
          },
          "timeStamp": {
            "type": "number",
            "description": "Unix timestamp (seconds since epoch)."
          },
          "dateTime": {
            "type": "string"
          }
        }
      },
      "EsimEvents": {
        "type": "object",
        "properties": {
          "iccid": {
            "type": "string"
          },
          "esimId": {
            "type": "string"
          },
          "referenceId": {
            "type": "string"
          },
          "events": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/EsimEvent"
            },
            "description": "Lifecycle events of the eSIM."
          },
          "locations": {
            "type": "array"
          }
        }
      },
      "EsimLink": {
        "type": "object",
        "properties": {
          "iccid": {
            "type": "string"
          },
          "esimId": {
            "type": "string"
          },
          "link": {
            "type": "string",
            "description": "The eSIMs Link URL to share with your customer."
          },
          "whatsappLink": {
            "type": "string",
            "description": "A WhatsApp message URL containing the link and access code."
          },
          "key": {
            "type": "string"
          },
          "accessCode": {
            "type": "string",
            "description": "Access code the customer needs to open the link."
          },
          "createdAt": {
            "type": "number",
            "description": "Unix timestamp (seconds since epoch)."
          },
          "updatedAt": {
            "type": "number",
            "description": "Unix timestamp (seconds since epoch)."
          }
        }
      },
      "Voucher": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "The ID of the voucher. Use it with Get Voucher and Revoke Voucher."
          },
          "code": {
            "type": "string",
            "description": "The 12-character redemption code. This is what you hand to your customer."
          },
          "redeemUrl": {
            "type": "string",
            "description": "The redemption link, `https://www.getroamify.com/voucher/{code}`."
          },
          "status": {
            "type": "string",
            "description": "The voucher's status.",
            "enum": [
              "ACTIVE",
              "REDEEMED",
              "CANCELLED"
            ]
          },
          "referenceId": {
            "type": "string",
            "description": "The reference ID of the batch this voucher was minted in, or an empty string."
          },
          "packageId": {
            "type": "string",
            "description": "The ID of the eSIM package the voucher is worth."
          },
          "package": {
            "type": "string",
            "description": "The display name of the package, for example `1 GB - 365 Days`."
          },
          "destination": {
            "type": "string",
            "description": "The country or region the package covers."
          },
          "price": {
            "type": "number",
            "description": "The price of the package."
          },
          "currency": {
            "type": "string",
            "description": "The currency of `price`. Always `USD`."
          },
          "esimId": {
            "type": "string",
            "description": "The ID of the eSIM backing this voucher."
          },
          "orderId": {
            "type": "string",
            "description": "The ID of the order the eSIM was created under."
          },
          "notes": {
            "type": "string",
            "description": "The note you stored on the batch, or an empty string."
          },
          "redeemedAt": {
            "type": [
              "number",
              "null"
            ],
            "description": "The Unix timestamp of redemption, or `null` if the voucher has not been redeemed."
          },
          "createdAt": {
            "type": "number",
            "description": "The Unix timestamp of when the voucher was created."
          },
          "updatedAt": {
            "type": "number",
            "description": "The Unix timestamp of when the voucher was last updated."
          }
        },
        "description": "Every voucher endpoint returns the same voucher shape. Statuses: `ACTIVE` (minted, not yet claimed; can be redeemed and revoked), `REDEEMED` (claimed by a customer; can no longer be revoked), `CANCELLED` (revoked; the code and the eSIM behind it are dead)."
      },
      "RefundReason": {
        "type": "string",
        "description": "Why you are asking for the refund. `UNABLE_TO_INSTALL`: the eSIM could not be installed or activated on the device. `NO_CONNECTIVITY`: installed but no data connection at the destination. `WRONG_PACKAGE`: the wrong destination or data plan was purchased. `DUPLICATE_PURCHASE`: purchased more than once by mistake. `TRIP_CANCELLED`: the trip was cancelled or changed. `DEVICE_NOT_COMPATIBLE`: the device does not support eSIM or is locked. `CUSTOMER_REQUEST`: the customer changed their mind. `OTHER`: anything else; `notes` of at least 10 characters are required.",
        "enum": [
          "UNABLE_TO_INSTALL",
          "NO_CONNECTIVITY",
          "WRONG_PACKAGE",
          "DUPLICATE_PURCHASE",
          "TRIP_CANCELLED",
          "DEVICE_NOT_COMPATIBLE",
          "CUSTOMER_REQUEST",
          "OTHER"
        ]
      },
      "RefundStatus": {
        "type": "string",
        "description": "`PENDING`: submitted, not yet acted on; can be cancelled. `PROCESSING`: approved, refund being processed. `REFUNDED`: refund complete and the eSIM was deactivated. `REJECTED`: support rejected the request (see `rejectionReason`, `rejectionNote`). `CANCELLED`: you cancelled the request before review.",
        "enum": [
          "PENDING",
          "PROCESSING",
          "REFUNDED",
          "REJECTED",
          "CANCELLED"
        ]
      },
      "RefundRequest": {
        "type": "object",
        "properties": {
          "refundId": {
            "type": "string",
            "description": "The ID of the request."
          },
          "status": {
            "$ref": "#/components/schemas/RefundStatus"
          },
          "productType": {
            "type": "string",
            "description": "Always `esim` for now."
          },
          "item": {
            "type": "object",
            "properties": {
              "esimId": {
                "type": "string"
              },
              "orderId": {
                "type": "string"
              },
              "iccid": {
                "type": "string",
                "description": "Only once the eSIM was redeemed."
              },
              "referenceId": {
                "type": "string",
                "description": "When known."
              },
              "countryName": {
                "type": "string",
                "description": "When known."
              },
              "optionName": {
                "type": "string",
                "description": "When known."
              }
            },
            "description": "The eSIM: `esimId`, `orderId`, and when known `iccid` (only once the eSIM was redeemed), `referenceId`, `countryName` and `optionName`."
          },
          "reason": {
            "$ref": "#/components/schemas/RefundReason"
          },
          "notes": {
            "type": "string",
            "description": "Your notes."
          },
          "amount": {
            "type": [
              "number",
              "null"
            ],
            "description": "The amount refunded, in `currency`. `null` until the request is `REFUNDED`."
          },
          "currency": {
            "type": [
              "string",
              "null"
            ],
            "description": "The currency of `amount`."
          },
          "balanceCreditUsd": {
            "type": [
              "number",
              "null"
            ],
            "description": "The amount credited to your balance in USD, for orders paid with your balance."
          },
          "transaction": {
            "type": [
              "object",
              "null"
            ],
            "description": "The refund of the payment: `id`, `paymentMethod`, `paymentStatus` and `refundedAt`.",
            "properties": {
              "id": {},
              "paymentMethod": {},
              "paymentStatus": {},
              "refundedAt": {}
            }
          },
          "rejectionReason": {
            "type": [
              "string",
              "null"
            ],
            "description": "Why support rejected it.",
            "enum": [
              "DATA_USED",
              "ESIM_ACTIVATED",
              "OUTSIDE_REFUND_WINDOW",
              "ESIM_EXPIRED",
              "NETWORK_CONDITIONS_ONLY",
              "INSUFFICIENT_INFORMATION",
              "DUPLICATE_REQUEST",
              "OTHER",
              null
            ]
          },
          "rejectionNote": {
            "type": [
              "string",
              "null"
            ],
            "description": "Support's explanation, when given."
          },
          "createdAt": {
            "type": [
              "number",
              "null"
            ],
            "description": "Unix timestamp in seconds."
          },
          "updatedAt": {
            "type": [
              "number",
              "null"
            ],
            "description": "Unix timestamp in seconds."
          },
          "processedAt": {
            "type": [
              "number",
              "null"
            ],
            "description": "Unix timestamp in seconds."
          },
          "cancelledAt": {
            "type": [
              "number",
              "null"
            ],
            "description": "Unix timestamp in seconds."
          },
          "history": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "status": {
                  "$ref": "#/components/schemas/RefundStatus"
                },
                "at": {
                  "type": "number",
                  "description": "Unix timestamp (seconds since epoch)."
                }
              }
            },
            "description": "Every status the request went through, as `{ status, at }`."
          }
        },
        "description": "A request asking Roamify support to refund one eSIM of one of your orders. The refund happens only after support approves it."
      },
      "RefundError": {
        "type": "object",
        "properties": {
          "message": {
            "type": "string"
          },
          "status": {
            "type": "string",
            "examples": [
              "failed"
            ]
          },
          "code": {
            "type": "string",
            "description": "Error code.",
            "enum": [
              "INVALID_PARAMETER",
              "REFUND_INVALID_REASON",
              "REFUND_NOTES_REQUIRED",
              "ESIM_NOT_FOUND",
              "REFUND_REQUEST_NOT_FOUND",
              "REFUND_REQUEST_ALREADY_EXISTS",
              "REFUND_INVALID_STATUS",
              "REFUND_NOT_ELIGIBLE",
              "REFUND_PRODUCT_TYPE_NOT_SUPPORTED",
              "REFUND_CREATE_FAILED",
              "REFUND_GET_FAILED",
              "REFUND_CANCEL_FAILED",
              "REFUND_SERVICE_NOT_CONFIGURED"
            ]
          },
          "refundId": {
            "type": "string",
            "description": "For `REFUND_REQUEST_ALREADY_EXISTS`: the `refundId` of the open request."
          },
          "reasons": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "For `REFUND_NOT_ELIGIBLE`: why the eSIM cannot be refunded, for example `ESIM_ALREADY_REFUNDED`."
          }
        },
        "description": "Every refund error has the form `{ \"message\": \"...\", \"status\": \"failed\", \"code\": \"...\" }`."
      },
      "CreateRefundRequest": {
        "type": "object",
        "properties": {
          "productType": {
            "type": "string",
            "description": "What is refunded. Only `esim` is supported for now. Any other value is answered with `422` `REFUND_PRODUCT_TYPE_NOT_SUPPORTED`."
          },
          "iccid": {
            "type": "string",
            "description": "Use `iccid` for an eSIM that was redeemed. Provide exactly one of `iccid` or `esimId`."
          },
          "esimId": {
            "type": "string",
            "description": "Use `esimId` for an eSIM that has no ICCID yet, such as a bundle that was never assigned. Provide exactly one of `iccid` or `esimId`."
          },
          "reason": {
            "$ref": "#/components/schemas/RefundReason"
          },
          "notes": {
            "type": "string",
            "description": "Free text for the support team, up to 1000 characters. Required, with at least 10 characters, when `reason` is `OTHER`.",
            "maxLength": 1000
          }
        },
        "required": [
          "productType",
          "reason"
        ],
        "oneOf": [
          {
            "required": [
              "iccid"
            ]
          },
          {
            "required": [
              "esimId"
            ]
          }
        ]
      },
      "BulkRefundEntry": {
        "type": "object",
        "properties": {
          "iccid": {
            "type": "string",
            "description": "Provide exactly one of `iccid` or `esimId`."
          },
          "esimId": {
            "type": "string",
            "description": "Provide exactly one of `iccid` or `esimId`."
          },
          "reason": {
            "$ref": "#/components/schemas/RefundReason"
          },
          "notes": {
            "type": "string",
            "description": "Free text for the support team, up to 1000 characters. Required, with at least 10 characters, when `reason` is `OTHER`.",
            "maxLength": 1000
          }
        },
        "required": [
          "reason"
        ],
        "oneOf": [
          {
            "required": [
              "iccid"
            ]
          },
          {
            "required": [
              "esimId"
            ]
          }
        ]
      },
      "BulkRefundResult": {
        "type": "object",
        "properties": {
          "index": {
            "type": "number",
            "description": "Position of the entry in the request."
          },
          "iccid": {
            "type": "string"
          },
          "esimId": {
            "type": "string"
          },
          "status": {
            "type": "string",
            "description": "`CREATED`: the request was created and `refund` holds it. `FAILED`: the request was refused and `error` holds the `code` and `message`, plus `reasons` (for `REFUND_NOT_ELIGIBLE`) or the open `refundId` (for `REFUND_REQUEST_ALREADY_EXISTS`). `DUPLICATE`: the same `iccid` or `esimId` appeared earlier in the call; only the first is created.",
            "enum": [
              "CREATED",
              "FAILED",
              "DUPLICATE"
            ]
          },
          "refund": {
            "$ref": "#/components/schemas/RefundRequest"
          },
          "error": {
            "type": "object",
            "properties": {
              "code": {
                "type": "string"
              },
              "message": {
                "type": "string"
              },
              "reasons": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              },
              "refundId": {
                "type": "string"
              }
            }
          },
          "duplicateOf": {
            "type": "number",
            "description": "For `DUPLICATE`: the index of the entry that was kept."
          }
        }
      },
      "InsuranceCountry": {
        "type": "object",
        "properties": {
          "code": {
            "type": "string",
            "description": "The ISO country code. Use this as `countryCode` on `/api/insurance/packages`."
          },
          "name": {
            "type": "string",
            "description": "The full country name. Use this as `country` on `/api/insurance/packages`."
          },
          "slug": {
            "type": "string",
            "description": "The URL-friendly form of the country name."
          },
          "geography": {
            "type": "string",
            "description": "The geography scope of the country.",
            "enum": [
              "local",
              "regional",
              "global"
            ]
          }
        }
      },
      "InsuranceRequirements": {
        "type": "object",
        "properties": {
          "phoneNumber": {
            "type": "boolean",
            "description": "When `true`, `mobile` must be supplied."
          },
          "dateOfBirth": {
            "type": "boolean",
            "description": "When `true`, `insurer.dateOfBirth` must be supplied."
          },
          "idNumber": {
            "type": "boolean",
            "description": "When `true`, `insurer.idNumber` must be supplied."
          },
          "passportNumber": {
            "type": "boolean",
            "description": "When `true`, `insurer.passportNumber` must be supplied."
          }
        },
        "description": "The traveller fields you must supply when issuing a policy for this package. Snapshotted onto every policy created from the package. `mobile` and `email` are required on every apply call regardless."
      },
      "InsurancePackage": {
        "type": "object",
        "properties": {
          "packageId": {
            "type": "string",
            "description": "The ID you pass to `POST /api/insurance/order`. Always starts with `insurance-`."
          },
          "package": {
            "type": "string",
            "description": "The display name of the package."
          },
          "provider": {
            "type": "string",
            "description": "The insurance provider that underwrites the policy."
          },
          "type": {
            "type": "string",
            "description": "The package type."
          },
          "charge": {
            "type": "number",
            "description": "The charge amount for the package, expressed in `currency`."
          },
          "day": {
            "type": "number",
            "description": "The number of days of coverage the package allows."
          },
          "price": {
            "type": "number",
            "description": "The price of the package, expressed in `currency`."
          },
          "currency": {
            "type": "string",
            "description": "The currency of `price` and `charge`. Always `USD`."
          },
          "requirements": {
            "$ref": "#/components/schemas/InsuranceRequirements"
          },
          "notes": {
            "type": "array",
            "description": "Additional provider notes for the package. Provider-defined, treat as opaque display content."
          }
        }
      },
      "InsuranceProduct": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "The ID of the insurance product."
          },
          "name": {
            "type": "string",
            "description": "The display name of the product."
          },
          "slug": {
            "type": "string",
            "description": "The URL-friendly form of the product name."
          },
          "countryName": {
            "type": "string",
            "description": "The full name of the country the product is associated with."
          },
          "countryCode": {
            "type": "string",
            "description": "The ISO code of the country the product is associated with."
          },
          "countrySlug": {
            "type": "string",
            "description": "The URL-friendly form of the country name."
          },
          "geography": {
            "type": "string",
            "description": "The geography scope.",
            "enum": [
              "local",
              "regional",
              "global"
            ]
          },
          "region": {
            "type": "string",
            "description": "The region the country belongs to."
          },
          "description": {
            "type": "string",
            "description": "A description of the product."
          },
          "image": {
            "type": "string",
            "description": "The image URL for the product."
          },
          "coverages": {
            "type": "array",
            "description": "The coverage areas included in the product. Provider-defined, treat as opaque display content."
          },
          "insuredType": {
            "type": "string",
            "description": "The type of traveller the product insures."
          },
          "eligibleNationality": {
            "type": "array",
            "description": "The nationalities eligible for this product."
          },
          "eligibleNationCodes": {
            "type": "array",
            "description": "The ISO codes of the eligible nationalities."
          },
          "benefits": {
            "type": "array",
            "description": "The benefits included in the product. Provider-defined, treat as opaque display content."
          },
          "minPrice": {
            "type": "number",
            "description": "The lowest package price for this product."
          },
          "maxPrice": {
            "type": "number",
            "description": "The highest package price for this product."
          },
          "packages": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/InsurancePackage"
            },
            "description": "The purchasable packages for this product."
          }
        }
      },
      "InsuranceOrderItem": {
        "type": "object",
        "properties": {
          "policyId": {
            "type": "string",
            "description": "The ID of the reserved policy. Pass this to `POST /api/insurance/apply`."
          },
          "packageId": {
            "type": "string",
            "description": "The ID of the insurance package that was ordered."
          },
          "package": {
            "type": "string",
            "description": "The display name of the package."
          },
          "type": {
            "type": "string",
            "description": "The service type. Always `insurance`."
          },
          "price": {
            "type": "number",
            "description": "The price of the package."
          },
          "currency": {
            "type": "string",
            "description": "The currency of `price`."
          },
          "createdAt": {
            "type": "number",
            "description": "The Unix timestamp of when the order was created."
          },
          "updatedAt": {
            "type": "number",
            "description": "The Unix timestamp of when the order was last updated."
          }
        }
      },
      "InsuranceOrder": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "The ID of the insurance order."
          },
          "referenceId": {
            "type": "string",
            "description": "The reference ID you provided, or an empty string."
          },
          "orderType": {
            "type": "string",
            "description": "How the order was placed. Always `api` for orders created through `POST /api/insurance/order`."
          },
          "status": {
            "type": "string",
            "description": "The status of the order."
          },
          "total": {
            "type": "number",
            "description": "The total charged for the order."
          },
          "currency": {
            "type": "string",
            "description": "The currency of `total`."
          },
          "createdAt": {
            "type": "number",
            "description": "The Unix timestamp of when the order was created."
          },
          "updatedAt": {
            "type": "number",
            "description": "The Unix timestamp of when the order was last updated."
          },
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/InsuranceOrderItem"
            },
            "description": "One entry per reserved policy. A `quantity` of `2` produces two entries sharing the same `packageId`, each with a distinct `policyId`."
          }
        }
      },
      "InsurancePolicyStatus": {
        "type": "string",
        "description": "`NEW`: reserved by an order, not yet issued. `PENDING`: issuance is in progress. `ISSUED`: the provider has issued the policy; `policy` is populated. `ACTIVE`: coverage is currently in effect. `EXPIRED`: coverage has ended. `CANCELLED`: the policy was cancelled. `REQUIRE_ACTION`: the policy needs attention before it can proceed. `UNKNOWN`: the status could not be determined.",
        "enum": [
          "NEW",
          "PENDING",
          "ISSUED",
          "ACTIVE",
          "EXPIRED",
          "CANCELLED",
          "REQUIRE_ACTION",
          "UNKNOWN"
        ]
      },
      "InsurancePolicy": {
        "type": "object",
        "properties": {
          "policyId": {
            "type": "string",
            "description": "The ID of the policy."
          },
          "orderId": {
            "type": "string",
            "description": "The ID of the order the policy was reserved through."
          },
          "packageId": {
            "type": "string",
            "description": "The ID of the insurance package."
          },
          "package": {
            "type": "string",
            "description": "The display name of the package."
          },
          "countryName": {
            "type": "string",
            "description": "The country the policy is associated with."
          },
          "type": {
            "type": "string",
            "description": "The service type. Always `insurance`."
          },
          "status": {
            "$ref": "#/components/schemas/InsurancePolicyStatus"
          },
          "startDate": {
            "type": "string",
            "description": "The coverage start date, `DD/MM/YYYY`."
          },
          "endDate": {
            "type": "string",
            "description": "The coverage end date, `DD/MM/YYYY`."
          },
          "insurerName": {
            "type": "string",
            "description": "The insured traveller's full name."
          },
          "requirements": {
            "$ref": "#/components/schemas/InsuranceRequirements"
          },
          "coverage": {
            "type": "object",
            "properties": {
              "insuredType": {
                "type": "string"
              },
              "day": {
                "type": "number"
              },
              "benefits": {
                "type": "array"
              }
            },
            "description": "The coverage summary, containing `insuredType`, `day`, and `benefits`."
          },
          "policy": {
            "type": [
              "object",
              "null"
            ],
            "description": "The issued policy document, or `null` if the policy has not been issued yet.",
            "properties": {
              "policyNo": {
                "type": "string",
                "description": "The provider's policy number."
              },
              "policyIssuanceDate": {
                "type": "string",
                "description": "The date the provider issued the policy."
              },
              "policyLink": {
                "type": "string",
                "description": "A link to the policy document. Pass this to your customer."
              }
            }
          },
          "createdAt": {
            "type": "number",
            "description": "The Unix timestamp of when the policy was reserved."
          },
          "updatedAt": {
            "type": "number",
            "description": "The Unix timestamp of when the policy was last updated."
          },
          "expiredAt": {
            "type": "number",
            "description": "The Unix timestamp of when coverage expires, or `-1` if not applicable."
          }
        },
        "description": "Policy responses never echo back traveller PII. Only `insurerName` and the issued policy document are exposed."
      },
      "ApplyInsuranceRequest": {
        "type": "object",
        "properties": {
          "policyId": {
            "type": "string",
            "description": "The ID of the reserved policy, returned by `POST /api/insurance/order`."
          },
          "startDate": {
            "type": "string",
            "description": "The coverage start date in `DD/MM/YYYY` format. At least 1 day in the future; coverage cannot start today.",
            "pattern": "^\\d{2}/\\d{2}/\\d{4}$"
          },
          "endDate": {
            "type": "string",
            "description": "The coverage end date in `DD/MM/YYYY` format. Must be strictly after `startDate` and fit within the purchased package's `day` allowance.",
            "pattern": "^\\d{2}/\\d{2}/\\d{4}$"
          },
          "mobile": {
            "type": "string",
            "description": "The traveller's mobile number: 8 to 15 digits, international format, no leading `+` (for example `966512345678`). Required on every apply call.",
            "pattern": "^[0-9]{8,15}$"
          },
          "email": {
            "type": "string",
            "description": "The traveller's email address. Required on every apply call.",
            "format": "email"
          },
          "insurer": {
            "type": "object",
            "properties": {
              "firstName": {
                "type": "string",
                "description": "The traveller's first name."
              },
              "lastName": {
                "type": "string",
                "description": "The traveller's last name."
              },
              "nationality": {
                "type": "string",
                "description": "The traveller's nationality."
              },
              "dateOfBirth": {
                "type": "string",
                "description": "The traveller's date of birth in `DD/MM/YYYY` format. Must be in the past, and no more than 120 years ago. Required when the package's `requirements.dateOfBirth` is `true`.",
                "pattern": "^\\d{2}/\\d{2}/\\d{4}$"
              },
              "idNumber": {
                "type": "string",
                "description": "The traveller's identification number, 5 to 20 alphanumeric characters. Required when `requirements.idNumber` is `true`.",
                "pattern": "^[A-Za-z0-9]{5,20}$"
              },
              "passportNumber": {
                "type": "string",
                "description": "The traveller's passport number, 5 to 20 alphanumeric characters. Required when `requirements.passportNumber` is `true`.",
                "pattern": "^[A-Za-z0-9]{5,20}$"
              }
            },
            "required": [
              "firstName",
              "lastName",
              "nationality"
            ],
            "description": "The primary insured traveller. A conditional field the package does not ask for is ignored."
          }
        },
        "required": [
          "policyId",
          "startDate",
          "endDate",
          "mobile",
          "email",
          "insurer"
        ]
      },
      "AffiliatePackage": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "price": {
            "type": "number"
          },
          "validity": {
            "type": "number"
          },
          "plan": {
            "type": "string"
          },
          "dataAmount": {
            "type": "number"
          },
          "dataUnit": {
            "type": "string"
          },
          "data": {
            "type": "string"
          },
          "isUnlimited": {
            "type": "boolean"
          },
          "isActivated": {
            "type": "boolean"
          },
          "withKyc": {
            "type": "boolean"
          },
          "withTopUp": {
            "type": "boolean"
          },
          "withSMS": {
            "type": "boolean"
          },
          "withCall": {
            "type": "boolean"
          },
          "withHotspot": {
            "type": "boolean"
          },
          "smsUnit": {
            "type": "string"
          },
          "callUnit": {
            "type": "string"
          },
          "smsLabel": {
            "type": "string"
          },
          "callLabel": {
            "type": "string"
          },
          "smsAmount": {
            "type": "number"
          },
          "callAmount": {
            "type": "number"
          },
          "coverages": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "networks": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "signals": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Signal"
            }
          },
          "link": {
            "type": "string",
            "description": "The referral link for the package, which includes your unique identifier."
          }
        }
      },
      "AffiliateCountry": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "countryName": {
            "type": "string",
            "description": "The name of the country."
          },
          "countryCode": {
            "type": "string"
          },
          "region": {
            "type": "string"
          },
          "packages": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/AffiliatePackage"
            },
            "description": "The packages available for the destination."
          }
        }
      },
      "EsimStatusEvent": {
        "type": "object",
        "properties": {
          "event_category": {
            "type": "string",
            "description": "For esim events, this is `esim`.",
            "enum": [
              "esim"
            ]
          },
          "event_type": {
            "type": "string",
            "description": "For esim status events, this is `status`.",
            "enum": [
              "status"
            ]
          },
          "data": {
            "type": "object",
            "properties": {
              "timestamp": {
                "type": "number",
                "description": "The time when the event was triggered, in unix timestamp format (seconds since epoch)."
              },
              "iccid": {
                "type": "string",
                "description": "The Integrated Circuit Card Identifier of the eSIM."
              },
              "esim_id": {
                "type": "string",
                "description": "The unique identifier of the eSIM."
              },
              "reference_id": {
                "type": "string",
                "description": "A custom referenceId provided by the user when creating the order, if applicable."
              },
              "start": {
                "type": "number",
                "description": "The start time of the usage period, in unix timestamp format (seconds since epoch)."
              },
              "end": {
                "type": "number",
                "description": "The end time of the usage period, in unix timestamp format (seconds since epoch)."
              },
              "status": {
                "type": "string",
                "description": "The status of the eSIM. Possible values include `NEW` (newly generated, not yet installed), `INSTALLED`, `ACTIVATED`, `INACTIVE`, `DELETED`, `REVOKED`, `EXPIRED` and `UNKNOWN`."
              }
            }
          }
        },
        "description": "Sent when an eSIM's status changes."
      },
      "EsimUsageEvent": {
        "type": "object",
        "properties": {
          "event_category": {
            "type": "string",
            "description": "For esim events, this is `esim`.",
            "enum": [
              "esim"
            ]
          },
          "event_type": {
            "type": "string",
            "description": "For esim usage events, this is `usage`.",
            "enum": [
              "usage"
            ]
          },
          "data": {
            "type": "object",
            "properties": {
              "timestamp": {
                "type": "number",
                "description": "The time when the event was triggered, in unix timestamp format (seconds since epoch)."
              },
              "iccid": {
                "type": "string",
                "description": "The Integrated Circuit Card Identifier of the eSIM."
              },
              "esim_id": {
                "type": "string",
                "description": "The unique identifier of the eSIM."
              },
              "reference_id": {
                "type": "string",
                "description": "A custom referenceId provided by the user when creating the order, if applicable."
              },
              "start": {
                "type": "number",
                "description": "The start time of the usage period, in unix timestamp format (seconds since epoch)."
              },
              "end": {
                "type": "number",
                "description": "The end time of the usage period, in unix timestamp format (seconds since epoch)."
              },
              "status": {
                "type": "string",
                "description": "The status of the eSIM. Possible values include `NEW` (newly generated, not yet installed), `INSTALLED`, `ACTIVATED`, `INACTIVE`, `DELETED`, `REVOKED`, `EXPIRED` and `UNKNOWN`."
              },
              "package_id": {
                "type": "string",
                "description": "The unique identifier of the eSIM package."
              },
              "package_name": {
                "type": "string",
                "description": "The name of the eSIM package."
              },
              "data_units": {
                "type": "string",
                "description": "The units used for data allocation, typically `MB`."
              },
              "voice_units": {
                "type": "string",
                "description": "The units used for voice allocation, typically `minutes`."
              },
              "sms_units": {
                "type": "string",
                "description": "The units used for SMS allocation, typically `sms`."
              },
              "usage_data": {
                "type": "object",
                "properties": {
                  "isUnlimited": {
                    "type": "boolean",
                    "description": "Whether the data allocation is unlimited."
                  },
                  "allowed_data": {
                    "type": "number",
                    "description": "The total data allocation in megabytes (MB)."
                  },
                  "remaining_data": {
                    "type": "number",
                    "description": "The remaining data allocation in megabytes (MB)."
                  },
                  "allowed_sms": {
                    "type": "number",
                    "description": "The total SMS allocation."
                  },
                  "remaining_sms": {
                    "type": "number",
                    "description": "The remaining SMS allocation."
                  },
                  "allowed_voice": {
                    "type": "number",
                    "description": "The total voice allocation in minutes."
                  },
                  "remaining_voice": {
                    "type": "number",
                    "description": "The remaining voice allocation in minutes."
                  }
                }
              },
              "usage_list": {
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "date": {
                      "type": "string",
                      "description": "The date of the usage record in ISO 8601 format (YYYY-MM-DD)."
                    },
                    "data_used": {
                      "type": "number",
                      "description": "The amount of data used in megabytes (MB)."
                    },
                    "location": {
                      "type": "string",
                      "description": "The location where the usage occurred."
                    }
                  }
                },
                "description": "Usage records."
              }
            }
          }
        },
        "description": "Sent for every activated eSIM every 4 hours, and when data usage reaches 25%, 50%, 75%, 90% and 100% of the total data allocation."
      },
      "PartnerBalanceEvent": {
        "type": "object",
        "properties": {
          "event_category": {
            "type": "string",
            "description": "For partner events, this is `partner`.",
            "enum": [
              "partner"
            ]
          },
          "event_type": {
            "type": "string",
            "description": "`low_balance`: your balance fell below the configured threshold. `insufficient_balance`: a transaction was attempted that exceeds your current balance. `top_up`: funds were added to your partner account.",
            "enum": [
              "low_balance",
              "insufficient_balance",
              "top_up"
            ]
          },
          "data": {
            "type": "object",
            "properties": {
              "timestamp": {
                "type": "number",
                "description": "The time when the event was triggered, in unix timestamp format (seconds since epoch)."
              },
              "balance": {
                "type": "number",
                "description": "The currency balance amount."
              },
              "threshold": {
                "type": "number",
                "description": "The threshold amount that triggered the event, if applicable."
              },
              "threshold_percentage": {
                "type": "number",
                "description": "The percentage of the threshold relative to the total balance, if applicable."
              },
              "currency": {
                "type": "string",
                "description": "The currency of the balance, in ISO 4217 format (e.g., USD, EUR)."
              }
            }
          }
        },
        "description": "Sent when your partner account balance changes."
      },
      "AffiliateOrderEvent": {
        "type": "object",
        "properties": {
          "event_category": {
            "type": "string",
            "description": "For affiliate events, this is `affiliate`.",
            "enum": [
              "affiliate"
            ]
          },
          "event_type": {
            "type": "string",
            "description": "For affiliate order events, this is `order`.",
            "enum": [
              "order"
            ]
          },
          "data": {
            "type": "object",
            "properties": {
              "timestamp": {
                "type": "number",
                "description": "The time when the event was triggered, in unix timestamp format (seconds since epoch)."
              },
              "partner_name": {
                "type": "string",
                "description": "The name of the affiliate partner."
              },
              "partner_id": {
                "type": "string",
                "description": "The unique identifier of the affiliate account."
              },
              "commission_rate": {
                "type": "number",
                "description": "The commission rate for the order, expressed as a percentage."
              },
              "commission_amount": {
                "type": "number",
                "description": "The total commission amount earned from the order."
              },
              "order_data": {
                "type": "object",
                "properties": {
                  "order_id": {
                    "type": "string",
                    "description": "The unique identifier of the order."
                  },
                  "order_total": {
                    "type": "number",
                    "description": "The total amount of the order."
                  },
                  "order_adjustment": {
                    "type": "number",
                    "description": "The adjusted total amount of the order after any redeemable credits or adjustments."
                  },
                  "order_subtotal": {
                    "type": "number",
                    "description": "The subtotal amount of the order before any discounts."
                  },
                  "order_discount": {
                    "type": "number",
                    "description": "The discount applied to the order, if any."
                  },
                  "order_currency": {
                    "type": "string",
                    "description": "The currency of the order, in ISO 4217 format (e.g., USD, EUR)."
                  },
                  "order_status": {
                    "type": "string",
                    "description": "The status of the order. Possible values include `completed`, `pending`, `failed` and `refunded`."
                  },
                  "order_items": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "item_id": {
                          "type": "string",
                          "description": "The unique identifier of the item."
                        },
                        "item_name": {
                          "type": "string",
                          "description": "The name of the item."
                        },
                        "item_quantity": {
                          "type": "number",
                          "description": "The quantity of the item ordered."
                        },
                        "item_price": {
                          "type": "number",
                          "description": "The price of the item in USD."
                        }
                      }
                    },
                    "description": "Items included in the order."
                  }
                }
              }
            }
          }
        },
        "description": "Sent when an order is placed through your affiliate links."
      },
      "RefundEvent": {
        "type": "object",
        "properties": {
          "event_id": {
            "type": "string",
            "description": "A stable identifier of this event, in the form `rfd_{refund_id}_{event_type}`. It is the same every time the same event is delivered; use it to drop duplicates."
          },
          "event_category": {
            "type": "string",
            "description": "For refund events, this is `refund`.",
            "enum": [
              "refund"
            ]
          },
          "event_type": {
            "type": "string",
            "description": "`refunded`: the request was approved and the refund is complete. `rejected`: the request was rejected.",
            "enum": [
              "refunded",
              "rejected"
            ]
          },
          "data": {
            "type": "object",
            "properties": {
              "timestamp": {
                "type": "number",
                "description": "The time when the event was sent, in unix timestamp format (seconds since epoch)."
              },
              "refund_id": {
                "type": "string",
                "description": "The ID of the refund request."
              },
              "status": {
                "type": "string",
                "description": "The status of the request.",
                "enum": [
                  "REFUNDED",
                  "REJECTED"
                ]
              },
              "product_type": {
                "type": "string",
                "description": "The refunded product. Always `esim` for now."
              },
              "esim_id": {
                "type": "string",
                "description": "The unique identifier of the eSIM."
              },
              "iccid": {
                "type": "string",
                "description": "The ICCID of the eSIM, or an empty string if the eSIM was never redeemed."
              },
              "reference_id": {
                "type": "string",
                "description": "The `referenceId` of the order, or an empty string."
              },
              "order_id": {
                "type": "string",
                "description": "The ID of the order the eSIM belongs to."
              },
              "reason": {
                "$ref": "#/components/schemas/RefundReason"
              },
              "amount": {
                "type": [
                  "number",
                  "null"
                ],
                "description": "The amount refunded, in `currency`. `null` for `rejected`."
              },
              "currency": {
                "type": [
                  "string",
                  "null"
                ],
                "description": "The currency of `amount`. `null` for `rejected`."
              },
              "balance_credit_usd": {
                "type": [
                  "number",
                  "null"
                ],
                "description": "The amount credited to your balance in USD, when the order was paid with your balance. Otherwise `null`."
              },
              "transaction_id": {
                "type": [
                  "string",
                  "null"
                ],
                "description": "The ID of the refund of the payment. `null` for `rejected`."
              },
              "payment_method": {
                "type": [
                  "string",
                  "null"
                ],
                "description": "How the order was paid, in lowercase. `null` for `rejected`."
              },
              "rejection_reason": {
                "type": [
                  "string",
                  "null"
                ],
                "description": "Why support rejected the request, for `rejected` only. Otherwise `null`."
              },
              "rejection_note": {
                "type": [
                  "string",
                  "null"
                ],
                "description": "Support's explanation, for `rejected` only, when given. Otherwise `null`."
              },
              "requested_at": {
                "type": "number",
                "description": "When the request was created, in unix timestamp format."
              },
              "processed_at": {
                "type": [
                  "number",
                  "null"
                ],
                "description": "When the request was decided, in unix timestamp format, or `null`."
              }
            }
          }
        },
        "description": "Sent when Roamify support has decided one of your refund requests. No event is sent when a request is created, approved for processing or cancelled."
      },
      "WebhookAck": {
        "type": "object",
        "properties": {
          "code": {
            "type": "number"
          },
          "status": {
            "type": "string"
          }
        },
        "description": "Acknowledgement your endpoint returns with HTTP 200."
      }
    },
    "responses": {
      "Unauthorized": {
        "description": "Missing token, malformed `Authorization` header, or invalid/rotated token."
      },
      "Forbidden": {
        "description": "Token is valid but does not have permission for the requested action."
      },
      "InternalServerError": {
        "description": "Internal server error. Retry the request with backoff or contact support if the issue persists."
      },
      "BadRequest": {
        "description": "Invalid request payload or missing required fields."
      }
    }
  }
}
