{
  "openapi": "3.1.0",
  "info": {
    "title": "SafarieSIM Partner Catalog API",
    "version": "2026-09-24",
    "description": "Read-only, authenticated catalog of SafarieSIM eSIM plans for comparison and affiliate platforms. Prices are computed at request time with the same resolver the checkout uses. Wholesale cost and supplier configuration are never exposed.",
    "contact": {
      "name": "SafarieSIM",
      "url": "https://safariesim.com/api",
      "email": "info@safariesim.com"
    }
  },
  "servers": [
    {
      "url": "https://api.safariesim.com/functions/v1",
      "description": "Production"
    }
  ],
  "security": [
    {
      "ApiKeyAuth": []
    },
    {
      "BearerAuth": []
    }
  ],
  "paths": {
    "/partner-catalog": {
      "get": {
        "summary": "List eSIM plans",
        "operationId": "getPartnerCatalog",
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "default": 1
            }
          },
          {
            "name": "per_page",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 250,
              "default": 100
            }
          },
          {
            "name": "country",
            "in": "query",
            "description": "ISO-3166 alpha-2; returns every plan whose coverage includes it (local and regional), e.g. KE",
            "schema": {
              "type": "string",
              "minLength": 2,
              "maxLength": 2
            }
          },
          {
            "name": "destination",
            "in": "query",
            "description": "Destination slug filter, e.g. kenya",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "currency",
            "in": "query",
            "schema": {
              "type": "string",
              "default": "USD",
              "enum": [
                "USD",
                "EUR",
                "GBP",
                "PLN",
                "AED",
                "SAR",
                "BRL",
                "IDR",
                "KES",
                "MUR",
                "TWD",
                "SGD",
                "NZD",
                "AUD",
                "NGN"
              ]
            }
          },
          {
            "name": "format",
            "in": "query",
            "schema": {
              "type": "string",
              "default": "catalog",
              "enum": [
                "catalog",
                "esims-io",
                "esimdb"
              ]
            }
          },
          {
            "name": "days",
            "in": "query",
            "description": "Durations to price for day-based destinations: single (10), list (1,5,10), range (1-30) or all.",
            "schema": {
              "type": "string",
              "default": "1,3,7,15,30"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Catalog page",
            "headers": {
              "X-Api-Version": {
                "schema": {
                  "type": "string"
                }
              },
              "Cache-Control": {
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CatalogResponse"
                }
              }
            }
          },
          "400": {
            "description": "Bad query parameter (unsupported_currency, unsupported_format, invalid_days)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Missing, unknown, or revoked key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "405": {
            "description": "Only GET is supported",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Hourly rate limit exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "500": {
            "description": "Temporary failure; retry with backoff",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "ApiKeyAuth": {
        "type": "apiKey",
        "in": "header",
        "name": "x-api-key"
      },
      "BearerAuth": {
        "type": "http",
        "scheme": "bearer"
      }
    },
    "schemas": {
      "CatalogResponse": {
        "type": "object",
        "required": [
          "api_version",
          "generated_at",
          "currency",
          "pagination",
          "data"
        ],
        "properties": {
          "api_version": {
            "type": "string",
            "example": "2026-09-24"
          },
          "generated_at": {
            "type": "string",
            "format": "date-time"
          },
          "currency": {
            "type": "string",
            "example": "USD"
          },
          "pricing_source": {
            "type": "string",
            "enum": [
              "auto",
              "daily_rate",
              "variant_srp"
            ]
          },
          "days": {
            "type": "array",
            "items": {
              "type": "integer"
            }
          },
          "pagination": {
            "$ref": "#/components/schemas/Pagination"
          },
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Plan"
            }
          }
        }
      },
      "Pagination": {
        "type": "object",
        "properties": {
          "page": {
            "type": "integer"
          },
          "per_page": {
            "type": "integer"
          },
          "total": {
            "type": "integer"
          },
          "total_pages": {
            "type": "integer"
          }
        }
      },
      "Plan": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "Stable. Day-based: <slug>-<days>d. Fixed catalog: variant UUID.",
            "example": "kenya-7d"
          },
          "name": {
            "type": "string",
            "example": "Kenya eSIM — 7 days"
          },
          "destination_slug": {
            "type": "string",
            "example": "kenya"
          },
          "destination_name": {
            "type": "string",
            "example": "Kenya"
          },
          "country_iso2": {
            "type": [
              "string",
              "null"
            ],
            "example": "KE"
          },
          "countries": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "region": {
            "type": [
              "string",
              "null"
            ],
            "example": "Africa"
          },
          "coverage_type": {
            "type": [
              "string",
              "null"
            ],
            "example": "Nationwide"
          },
          "data_amount_mb": {
            "type": [
              "number",
              "null"
            ]
          },
          "is_unlimited": {
            "type": "boolean"
          },
          "validity_days": {
            "type": "integer"
          },
          "price": {
            "type": "number",
            "description": "Retail price for one traveller, in `currency`, with charm rounding."
          },
          "price_usd": {
            "type": "number"
          },
          "currency": {
            "type": "string"
          },
          "operators": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "name": {
                  "type": "string"
                },
                "network_types": {
                  "type": "array",
                  "items": {
                    "type": "string"
                  }
                }
              }
            }
          },
          "network_types": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "plan_type": {
            "type": "string",
            "example": "unlimited"
          },
          "topup_available": {
            "type": "boolean"
          },
          "status": {
            "type": "string",
            "example": "available"
          },
          "product_url": {
            "type": "string",
            "format": "uri"
          },
          "checkout_url": {
            "type": "string",
            "format": "uri"
          },
          "last_updated": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "ErrorResponse": {
        "type": "object",
        "properties": {
          "error": {
            "type": "object",
            "properties": {
              "code": {
                "type": "string",
                "example": "unauthorized"
              },
              "message": {
                "type": "string"
              }
            }
          },
          "api_version": {
            "type": "string"
          }
        }
      }
    }
  }
}