{
  "openapi": "3.1.0",
  "info": {
    "title": "Faxvio public data API",
    "version": "1.0.0",
    "summary": "Fax destinations, carrier country routing, page pricing and the transmission-time model, as JSON.",
    "description": "A read-only, keyless, CORS-open API over the four datasets this site publishes: the destinations the Faxvio app will dial (37), the carrier country table with the routing rules that resolve a typed number to a territory (250), the page packs and their prices, and the ITU-T-derived model behind fax transmission time. The same numbers the human-readable pages render. Reuse is licensed CC BY 4.0 with a link back.",
    "contact": {
      "name": "Faxvio support",
      "email": "support@faxvio.com",
      "url": "https://faxvio.com/contact/"
    },
    "license": {
      "name": "CC BY 4.0",
      "url": "https://creativecommons.org/licenses/by/4.0/"
    },
    "termsOfService": "https://faxvio.com/terms/"
  },
  "servers": [
    {
      "url": "https://faxvio.com/api/v1",
      "description": "Static origin behind Cloudflare"
    }
  ],
  "paths": {
    "/destinations.json": {
      "get": {
        "operationId": "getDestinations",
        "summary": "The countries the app will send a fax to",
        "description": "The app's server-side allow-list. A number outside it is refused before a page is charged.",
        "responses": {
          "200": {
            "description": "The destination list",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DestinationList"
                }
              }
            }
          }
        }
      }
    },
    "/countries.json": {
      "get": {
        "operationId": "getCountries",
        "summary": "Carrier country table and number-routing rules",
        "description": "Every territory the carrier knows, plus the trunk-prefix, shared-dial-code and NANP area-code rules needed to decide which territory a typed number belongs to.",
        "responses": {
          "200": {
            "description": "The country table",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CountryList"
                }
              }
            }
          }
        }
      }
    },
    "/pricing.json": {
      "get": {
        "operationId": "getPricing",
        "summary": "Page packs, prices and billing terms",
        "responses": {
          "200": {
            "description": "Pricing",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Pricing"
                }
              }
            }
          }
        }
      }
    },
    "/transmission-time.json": {
      "get": {
        "operationId": "getTransmissionTimeModel",
        "summary": "Constants and formula for estimating fax duration",
        "responses": {
          "200": {
            "description": "The model",
            "content": {
              "application/json": {}
            }
          }
        }
      }
    },
    "/status.json": {
      "get": {
        "operationId": "getStatus",
        "summary": "Freshness of the published datasets",
        "responses": {
          "200": {
            "description": "Status",
            "content": {
              "application/json": {}
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "DestinationList": {
        "type": "object",
        "required": [
          "count",
          "destinations"
        ],
        "properties": {
          "count": {
            "type": "integer",
            "examples": [
              37
            ]
          },
          "updated": {
            "type": "string",
            "format": "date"
          },
          "limits": {
            "$ref": "#/components/schemas/Limits"
          },
          "destinations": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Destination"
            }
          }
        }
      },
      "Destination": {
        "type": "object",
        "required": [
          "country",
          "iso2",
          "dial_code",
          "sendable"
        ],
        "properties": {
          "country": {
            "type": "string",
            "examples": [
              "Germany"
            ]
          },
          "iso2": {
            "type": "string",
            "examples": [
              "DE"
            ]
          },
          "dial_code": {
            "type": "string",
            "examples": [
              "+49"
            ]
          },
          "region": {
            "type": "string",
            "examples": [
              "Europe"
            ]
          },
          "sendable": {
            "type": "boolean",
            "const": true
          },
          "special_prefix_rule": {
            "type": [
              "string",
              "null"
            ],
            "description": "Human-readable rule for the prefixes inside this country that cost two pages per page."
          },
          "special_prefixes": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "National-number prefixes, trunk prefix already removed, that are billed at two pages per page.",
            "examples": [
              [
                "900",
                "180",
                "137",
                "800"
              ]
            ]
          }
        }
      },
      "CountryList": {
        "type": "object",
        "required": [
          "count",
          "countries",
          "routing"
        ],
        "properties": {
          "count": {
            "type": "integer",
            "examples": [
              250
            ]
          },
          "sendable_count": {
            "type": "integer",
            "examples": [
              37
            ]
          },
          "routing": {
            "$ref": "#/components/schemas/Routing"
          },
          "countries": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Country"
            }
          }
        }
      },
      "Country": {
        "type": "object",
        "required": [
          "country",
          "iso2",
          "dial_code",
          "carrier_support",
          "sendable"
        ],
        "properties": {
          "country": {
            "type": "string"
          },
          "iso2": {
            "type": "string",
            "examples": [
              "IT"
            ]
          },
          "dial_code": {
            "type": "string",
            "examples": [
              "+39"
            ]
          },
          "carrier_support": {
            "type": "string",
            "enum": [
              "full",
              "beta",
              "none"
            ],
            "description": "The carrier's own tier for the territory."
          },
          "sendable": {
            "type": "boolean",
            "description": "Whether the Faxvio app will dial it. Decided by the app's allow-list, NOT by carrier_support — a territory with full carrier support can still be unsendable."
          }
        }
      },
      "Routing": {
        "type": "object",
        "description": "Everything needed to turn a number as printed into the territory it belongs to.",
        "properties": {
          "trunk_zero_dial_codes": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Dial codes whose national numbers carry a leading 0 that the international form drops. Italy (+39) is deliberately absent: an Italian landline keeps its 0."
          },
          "special_prefixes": {
            "type": "object",
            "description": "Dial code to the national prefixes billed at two pages per page.",
            "additionalProperties": {
              "type": "array",
              "items": {
                "type": "string"
              }
            }
          },
          "nanp_area_code_exceptions": {
            "type": "object",
            "description": "Area codes inside +1 that belong to a territory other than the US or Canada.",
            "additionalProperties": {
              "type": "string"
            }
          },
          "shared_dial_codes": {
            "type": "object",
            "description": "National-number prefixes that move a number to another territory under the same dial code. Longest prefix wins."
          }
        }
      },
      "Limits": {
        "type": "object",
        "properties": {
          "max_pages_per_fax": {
            "type": "integer",
            "examples": [
              50
            ]
          },
          "max_upload_bytes": {
            "type": "integer"
          },
          "faxes_per_hour": {
            "type": "integer"
          },
          "faxes_per_day": {
            "type": "integer"
          }
        }
      },
      "Pricing": {
        "type": "object",
        "properties": {
          "currency": {
            "type": "string",
            "const": "USD"
          },
          "storefront": {
            "type": "string",
            "const": "United States"
          },
          "packs": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Pack"
            }
          },
          "billing": {
            "type": "object"
          }
        }
      },
      "Pack": {
        "type": "object",
        "required": [
          "product_id",
          "pages",
          "price_usd"
        ],
        "properties": {
          "product_id": {
            "type": "string",
            "description": "The App Store Connect product id. Immutable."
          },
          "pages": {
            "type": "integer",
            "examples": [
              23
            ]
          },
          "price_usd": {
            "type": "number",
            "examples": [
              4.99
            ]
          },
          "price_per_page_usd": {
            "type": "number",
            "examples": [
              0.217
            ]
          }
        }
      }
    }
  },
  "externalDocs": {
    "description": "Human-readable API documentation",
    "url": "https://faxvio.com/api/"
  },
  "x-endpoints": {
    "destinations": "https://faxvio.com/api/v1/destinations.json",
    "countries": "https://faxvio.com/api/v1/countries.json",
    "pricing": "https://faxvio.com/api/v1/pricing.json",
    "transmission_time": "https://faxvio.com/api/v1/transmission-time.json",
    "status": "https://faxvio.com/api/v1/status.json",
    "openapi": "https://faxvio.com/api/v1/openapi.json",
    "catalog": "https://faxvio.com/api/v1/index.json"
  }
}
