{
  "openapi": "3.1.0",
  "info": {
    "title": "tabiji.ai API",
    "version": "1.5.0",
    "description": "Free REST API for AI-curated travel data — 6905 destinations, 1,616 curated picks guides (15,227 place records), 398 day-by-day itineraries, 1,218 destination comparisons, and unified search. No API key required.",
    "contact": {
      "name": "tabiji.ai",
      "url": "https://tabiji.ai",
      "email": "hello@tabiji.ai"
    },
    "license": {
      "name": "Free for non-commercial use",
      "url": "https://tabiji.ai/api/"
    }
  },
  "servers": [
    {
      "url": "https://tabiji.ai/api/v1",
      "description": "Production (Cloudflare Pages CDN)"
    }
  ],
  "paths": {
    "/index.json": {
      "get": {
        "operationId": "getApiIndex",
        "summary": "API metadata and endpoint list",
        "description": "Returns API metadata including version, stats, and a list of all available endpoints.",
        "tags": [
          "Meta"
        ],
        "responses": {
          "200": {
            "description": "API index",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiIndex"
                }
              }
            }
          }
        }
      }
    },
    "/destinations.json": {
      "get": {
        "operationId": "listDestinations",
        "summary": "List all destinations",
        "description": "Returns all 942 destinations with budget level, best season, vibes, travel styles, and a one-line pitch.",
        "tags": [
          "Destinations"
        ],
        "responses": {
          "200": {
            "description": "List of destinations",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DestinationList"
                }
              }
            }
          }
        }
      }
    },
    "/destinations/{slug}.json": {
      "get": {
        "operationId": "getDestination",
        "summary": "Get a single destination",
        "description": "Returns full details for a destination. Slug is the city name lowercased with spaces replaced by hyphens.",
        "tags": [
          "Destinations"
        ],
        "parameters": [
          {
            "name": "slug",
            "in": "path",
            "required": true,
            "description": "Destination slug (e.g., 'tokyo', 'new-york', 'buenos-aires')",
            "schema": {
              "type": "string"
            },
            "example": "tokyo"
          }
        ],
        "responses": {
          "200": {
            "description": "Destination detail",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DestinationDetail"
                }
              }
            }
          },
          "404": {
            "description": "Destination not found"
          }
        }
      }
    },
    "/picks.json": {
      "get": {
        "operationId": "listPicks",
        "summary": "List all picks guides",
        "description": "Returns all 389 curated 'best of' guides — restaurants, cafes, bars, attractions — with summary metadata.",
        "tags": [
          "Picks"
        ],
        "responses": {
          "200": {
            "description": "List of picks guides",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PicksList"
                }
              }
            }
          }
        }
      }
    },
    "/picks/{slug}.json": {
      "get": {
        "operationId": "getPicksGuide",
        "summary": "Get a full picks guide",
        "description": "Returns a complete picks guide with all places, Google ratings, opening hours, maps links, 'what to order' tips, Reddit quotes, and insider tips.",
        "tags": [
          "Picks"
        ],
        "parameters": [
          {
            "name": "slug",
            "in": "path",
            "required": true,
            "description": "Picks guide slug (e.g., 'amsterdam-brunch', 'tokyo-ramen', 'paris-wine-bars')",
            "schema": {
              "type": "string"
            },
            "example": "amsterdam-brunch"
          }
        ],
        "responses": {
          "200": {
            "description": "Full picks guide with places",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PicksDetail"
                }
              }
            }
          },
          "404": {
            "description": "Guide not found"
          }
        }
      }
    },
    "/itineraries.json": {
      "get": {
        "operationId": "listItineraries",
        "summary": "List all itineraries",
        "description": "Returns all 344 day-by-day travel itineraries with summary metadata.",
        "tags": [
          "Itineraries"
        ],
        "responses": {
          "200": {
            "description": "List of itineraries",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ItineraryList"
                }
              }
            }
          }
        }
      }
    },
    "/itineraries/{slug}.json": {
      "get": {
        "operationId": "getItinerary",
        "summary": "Get a full itinerary",
        "description": "Returns a complete day-by-day itinerary with activities, times, descriptions, tips, and logistics.",
        "tags": [
          "Itineraries"
        ],
        "parameters": [
          {
            "name": "slug",
            "in": "path",
            "required": true,
            "description": "Itinerary slug (e.g., 'itineraries-5-day-tokyo-food-nightlife', 'bach-wave')",
            "schema": {
              "type": "string"
            },
            "example": "itineraries-5-day-tokyo-food-nightlife"
          }
        ],
        "responses": {
          "200": {
            "description": "Full itinerary with day-by-day details",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ItineraryDetail"
                }
              }
            }
          },
          "404": {
            "description": "Itinerary not found"
          }
        }
      }
    },
    "/compare.json": {
      "get": {
        "operationId": "listComparisons",
        "summary": "List all destination comparisons",
        "description": "Returns all 40 head-to-head destination comparisons with summary metadata.",
        "tags": [
          "Comparisons"
        ],
        "responses": {
          "200": {
            "description": "List of comparisons",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ComparisonList"
                }
              }
            }
          }
        }
      }
    },
    "/compare/{slug}.json": {
      "get": {
        "operationId": "getComparison",
        "summary": "Get a full comparison",
        "description": "Returns a complete head-to-head comparison with all categories, Reddit quotes, verdict, and FAQs.",
        "tags": [
          "Comparisons"
        ],
        "parameters": [
          {
            "name": "slug",
            "in": "path",
            "required": true,
            "description": "Comparison slug (e.g., 'tokyo-vs-kyoto', 'mexico-city-vs-oaxaca')",
            "schema": {
              "type": "string"
            },
            "example": "tokyo-vs-kyoto"
          }
        ],
        "responses": {
          "200": {
            "description": "Full comparison",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ComparisonDetail"
                }
              }
            }
          },
          "404": {
            "description": "Comparison not found"
          }
        }
      }
    },
    "/search.json": {
      "get": {
        "operationId": "searchCollections",
        "summary": "Search across all collections",
        "description": "Search destinations, picks, itineraries, and comparisons from one endpoint. Supports q, optional type filter, and optional limit.",
        "tags": [
          "Search"
        ],
        "parameters": [
          {
            "name": "q",
            "in": "query",
            "required": true,
            "description": "Free-text search query",
            "schema": {
              "type": "string"
            },
            "example": "tokyo"
          },
          {
            "name": "type",
            "in": "query",
            "required": false,
            "description": "Filter to destination, pick, itinerary, or comparison",
            "schema": {
              "type": "string",
              "enum": [
                "destination",
                "pick",
                "itinerary",
                "compare"
              ]
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Maximum results to return (1-100)",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 20
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Search results",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SearchResults"
                }
              }
            }
          }
        }
      }
    },
    "/countries.json": {
      "get": {
        "operationId": "listCountries",
        "summary": "List all countries with facts",
        "description": "Returns 250 countries and territories with capitals, population, area, currencies, languages, borders, driving side, dial codes, timezones, flags, and maps links. Sourced from restcountries.com.",
        "tags": [
          "Countries"
        ],
        "responses": {
          "200": {
            "description": "Country catalog",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CountriesList"
                }
              }
            }
          }
        }
      }
    },
    "/countries/{iso2}.json": {
      "get": {
        "operationId": "getCountry",
        "summary": "Get country facts by ISO code",
        "description": "Returns full facts for a single country. Use the lowercase 2-letter ISO 3166-1 alpha-2 code (e.g. jp, fr, us, sg).",
        "tags": [
          "Countries"
        ],
        "parameters": [
          {
            "name": "iso2",
            "in": "path",
            "required": true,
            "description": "Lowercase ISO 3166-1 alpha-2 code (e.g. jp, fr, us)",
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{2}$"
            },
            "example": "jp"
          }
        ],
        "responses": {
          "200": {
            "description": "Country facts",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CountryFacts"
                }
              }
            }
          }
        }
      }
    },
    "/cards.json": {
      "get": {
        "operationId": "listCreditCards",
        "summary": "List all credit cards with travel benefits",
        "description": "Returns all 48 travel credit cards with issuer, network, annual fee, and best-for tags.",
        "tags": [
          "Credit Cards"
        ],
        "responses": {
          "200": {
            "description": "List of credit cards",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "count": {
                      "type": "integer"
                    },
                    "cards": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "slug": {
                            "type": "string"
                          },
                          "name": {
                            "type": "string"
                          },
                          "issuer": {
                            "type": "string"
                          },
                          "network": {
                            "type": "string"
                          },
                          "annualFee": {
                            "type": "string"
                          },
                          "bestFor": {
                            "type": "array",
                            "items": {
                              "type": "string"
                            }
                          },
                          "url": {
                            "type": "string"
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/cards/{slug}.json": {
      "get": {
        "operationId": "getCreditCard",
        "summary": "Get a single credit card's travel benefits",
        "description": "Returns full travel benefit details for a credit card including trip delay/cancellation insurance, baggage coverage, rental car CDW, lounge access, and rewards structure.",
        "tags": [
          "Credit Cards"
        ],
        "parameters": [
          {
            "name": "slug",
            "in": "path",
            "required": true,
            "description": "Card slug (e.g., 'chase-sapphire-reserve', 'amex-platinum')",
            "schema": {
              "type": "string"
            },
            "example": "chase-sapphire-reserve"
          }
        ],
        "responses": {
          "200": {
            "description": "Credit card detail",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "slug": {
                      "type": "string"
                    },
                    "name": {
                      "type": "string"
                    },
                    "issuer": {
                      "type": "string"
                    },
                    "network": {
                      "type": "string"
                    },
                    "annualFee": {
                      "type": "string"
                    },
                    "travelBenefits": {
                      "type": "object"
                    },
                    "rewards": {
                      "type": "object"
                    },
                    "travelPerks": {
                      "type": "array"
                    },
                    "bestFor": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Card not found"
          }
        }
      }
    },
    "/safety.json": {
      "get": {
        "operationId": "listSafetyProfiles",
        "summary": "List all country safety profiles",
        "description": "Returns an index of all 40 country safety profiles with advisory levels, last updated timestamps, and links to individual profiles.",
        "tags": [
          "Safety"
        ],
        "responses": {
          "200": {
            "description": "Safety profile index",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SafetyIndex"
                }
              }
            }
          }
        }
      }
    },
    "/safety/{iso2}.json": {
      "get": {
        "operationId": "getSafetyProfile",
        "summary": "Get a single country safety profile",
        "description": "Returns the full safety profile for a country. Use lowercase ISO 3166-1 alpha-2 codes (e.g., 'jp', 'fr', 'us').",
        "tags": [
          "Safety"
        ],
        "parameters": [
          {
            "name": "iso2",
            "in": "path",
            "required": true,
            "description": "Lowercase ISO 3166-1 alpha-2 country code (e.g., 'jp', 'fr', 'us')",
            "schema": {
              "type": "string"
            },
            "example": "jp"
          }
        ],
        "responses": {
          "200": {
            "description": "Country safety profile",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SafetyProfile"
                }
              }
            }
          },
          "404": {
            "description": "Safety profile not found"
          }
        }
      }
    },
    "/catalog.json": {
      "get": {
        "summary": "Normalized entity catalog spanning destinations, picks, places, itineraries, and comparisons",
        "responses": {
          "200": {
            "description": "Catalog response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CatalogResponse"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "ApiIndex": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string"
          },
          "version": {
            "type": "string"
          },
          "description": {
            "type": "string"
          },
          "baseUrl": {
            "type": "string",
            "format": "uri"
          },
          "documentation": {
            "type": "string",
            "format": "uri"
          },
          "lastUpdated": {
            "type": "string",
            "format": "date-time"
          },
          "stats": {
            "type": "object",
            "properties": {
              "destinations": {
                "type": "integer"
              },
              "picksGuides": {
                "type": "integer"
              },
              "totalPlaces": {
                "type": "integer"
              },
              "itineraries": {
                "type": "integer"
              },
              "comparisons": {
                "type": "integer"
              }
            }
          },
          "endpoints": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "path": {
                  "type": "string"
                },
                "description": {
                  "type": "string"
                },
                "method": {
                  "type": "string"
                }
              }
            }
          }
        }
      },
      "DestinationSummary": {
        "type": "object",
        "properties": {
          "slug": {
            "type": "string",
            "example": "tokyo"
          },
          "name": {
            "type": "string",
            "example": "Tokyo"
          },
          "region": {
            "type": "string",
            "example": "Japan"
          },
          "continent": {
            "type": "string",
            "example": "Asia"
          },
          "budget": {
            "type": "string",
            "example": "$$$"
          },
          "season": {
            "type": "string",
            "example": "Mar–May, Oct–Nov"
          },
          "vibes": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "example": [
              "City",
              "Cultural",
              "Nightlife"
            ]
          },
          "photo": {
            "type": "string",
            "example": "https://img.tabiji.ai/find/img/tokyo.webp"
          },
          "pitch": {
            "type": "string",
            "example": "Controlled chaos that somehow works perfectly."
          },
          "id": {
            "type": "string",
            "example": "destination:tokyo"
          },
          "type": {
            "type": "string",
            "enum": [
              "destination"
            ]
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          },
          "sourceUrl": {
            "type": "string",
            "format": "uri"
          },
          "tags": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "sourceMeta": {
            "$ref": "#/components/schemas/RecordSourceMeta"
          },
          "editorialSummary": {
            "type": "string"
          },
          "bestFor": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "relatedPicks": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/RelatedRecordSummary"
            }
          },
          "relatedItineraries": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/RelatedRecordSummary"
            }
          },
          "relatedComparisons": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/RelatedRecordSummary"
            }
          },
          "relatedDestinations": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/RelatedRecordSummary"
            }
          }
        }
      },
      "DestinationList": {
        "type": "object",
        "properties": {
          "count": {
            "type": "integer",
            "example": 942
          },
          "destinations": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/DestinationSummary"
            }
          }
        }
      },
      "DestinationDetail": {
        "allOf": [
          {
            "$ref": "#/components/schemas/DestinationSummary"
          },
          {
            "type": "object",
            "properties": {
              "travelStyles": {
                "type": "array",
                "items": {
                  "type": "string"
                },
                "example": [
                  "solo",
                  "photography"
                ]
              },
              "url": {
                "type": "string",
                "format": "uri"
              }
            }
          }
        ]
      },
      "PicksSummary": {
        "type": "object",
        "properties": {
          "slug": {
            "type": "string",
            "example": "amsterdam-brunch"
          },
          "title": {
            "type": "string",
            "example": "12 Best Brunch Spots in Amsterdam 2026"
          },
          "city": {
            "type": "string",
            "example": "Amsterdam"
          },
          "category": {
            "type": "string",
            "example": "Brunch Spots"
          },
          "placeCount": {
            "type": "integer",
            "example": 12
          },
          "url": {
            "type": "string",
            "format": "uri"
          },
          "description": {
            "type": "string"
          },
          "destinationSlug": {
            "type": "string"
          },
          "destinationName": {
            "type": "string"
          },
          "relatedPicks": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/RelatedRecordSummary"
            }
          }
        }
      },
      "PicksList": {
        "type": "object",
        "properties": {
          "count": {
            "type": "integer"
          },
          "totalPlaces": {
            "type": "integer"
          },
          "picks": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PicksSummary"
            }
          }
        }
      },
      "Place": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "example": "Little Collins"
          },
          "position": {
            "type": "integer",
            "example": 1
          },
          "cuisineTags": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "example": [
              "Antipodean Brunch"
            ]
          },
          "googleRating": {
            "type": "number",
            "example": 4.5
          },
          "reviewCount": {
            "type": "integer",
            "example": 1859
          },
          "priceRange": {
            "type": "string",
            "example": "€15–€25/person"
          },
          "address": {
            "type": "string",
            "example": "De Pijp"
          },
          "googleMapsUrl": {
            "type": "string",
            "format": "uri"
          },
          "openingHours": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            },
            "example": {
              "Mon": "9:00 AM – 4:00 PM",
              "Tue": "9:00 AM – 4:00 PM"
            }
          },
          "phone": {
            "type": "string"
          },
          "website": {
            "type": "string",
            "format": "uri"
          },
          "photo": {
            "type": "string",
            "format": "uri"
          },
          "whatToOrder": {
            "type": "string",
            "example": "The cilbir (Turkish-style poached eggs)..."
          },
          "redditQuotes": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "text": {
                  "type": "string"
                },
                "source": {
                  "type": "string"
                }
              }
            }
          },
          "insiderTip": {
            "type": "string"
          },
          "area": {
            "type": "string",
            "example": "De Pijp"
          },
          "verdict": {
            "type": "string"
          },
          "editorialSummary": {
            "type": "string"
          },
          "bestFor": {
            "type": "string"
          },
          "comparison": {
            "type": "object",
            "additionalProperties": true
          },
          "mapsLinks": {
            "type": "object",
            "properties": {
              "google": {
                "type": "string",
                "format": "uri"
              }
            }
          },
          "sourceMeta": {
            "$ref": "#/components/schemas/PlaceSourceMeta"
          }
        }
      },
      "PicksDetail": {
        "type": "object",
        "properties": {
          "slug": {
            "type": "string"
          },
          "title": {
            "type": "string"
          },
          "description": {
            "type": "string"
          },
          "city": {
            "type": "string"
          },
          "category": {
            "type": "string"
          },
          "heroImage": {
            "type": "string",
            "format": "uri"
          },
          "placeCount": {
            "type": "integer"
          },
          "url": {
            "type": "string",
            "format": "uri"
          },
          "places": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Place"
            }
          },
          "id": {
            "type": "string",
            "example": "pick:tokyo-ramen"
          },
          "type": {
            "type": "string",
            "enum": [
              "pick"
            ]
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          },
          "sourceUrl": {
            "type": "string",
            "format": "uri"
          },
          "tags": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "sourceMeta": {
            "$ref": "#/components/schemas/RecordSourceMeta"
          },
          "destinationSlug": {
            "type": "string"
          },
          "destinationName": {
            "type": "string"
          },
          "editorialSummary": {
            "type": "string"
          },
          "bestFor": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "relatedPicks": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/RelatedRecordSummary"
            }
          },
          "relatedItineraries": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/RelatedRecordSummary"
            }
          },
          "relatedComparisons": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/RelatedRecordSummary"
            }
          }
        }
      },
      "ItinerarySummary": {
        "type": "object",
        "properties": {
          "slug": {
            "type": "string"
          },
          "title": {
            "type": "string"
          },
          "destination": {
            "type": "string"
          },
          "duration": {
            "type": "string"
          },
          "tripType": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "url": {
            "type": "string",
            "format": "uri"
          },
          "dayCount": {
            "type": "integer"
          },
          "destinationSlug": {
            "type": "string"
          }
        }
      },
      "ItineraryList": {
        "type": "object",
        "properties": {
          "count": {
            "type": "integer"
          },
          "itineraries": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ItinerarySummary"
            }
          }
        }
      },
      "Activity": {
        "type": "object",
        "properties": {
          "time": {
            "type": "string",
            "example": "☀️ Morning"
          },
          "name": {
            "type": "string",
            "example": "Tsukiji Outer Market"
          },
          "description": {
            "type": "string"
          },
          "details": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "tips": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        }
      },
      "ItineraryDay": {
        "type": "object",
        "properties": {
          "dayLabel": {
            "type": "string",
            "example": "Day 1 · Mar 5 (Wed)"
          },
          "neighborhoods": {
            "type": "string",
            "example": "Tsukiji · Ginza"
          },
          "title": {
            "type": "string",
            "example": "Market Morning & Ginza Glamour"
          },
          "description": {
            "type": "string"
          },
          "activities": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Activity"
            }
          }
        }
      },
      "ItineraryDetail": {
        "type": "object",
        "properties": {
          "slug": {
            "type": "string"
          },
          "title": {
            "type": "string"
          },
          "description": {
            "type": "string"
          },
          "destination": {
            "type": "string"
          },
          "duration": {
            "type": "string"
          },
          "tripType": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "heroImage": {
            "type": "string",
            "format": "uri"
          },
          "url": {
            "type": "string",
            "format": "uri"
          },
          "dayCount": {
            "type": "integer"
          },
          "days": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ItineraryDay"
            }
          },
          "id": {
            "type": "string",
            "example": "itinerary:tokyo-4-days"
          },
          "type": {
            "type": "string",
            "enum": [
              "itinerary"
            ]
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          },
          "sourceUrl": {
            "type": "string",
            "format": "uri"
          },
          "tags": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "sourceMeta": {
            "$ref": "#/components/schemas/RecordSourceMeta"
          },
          "destinationSlug": {
            "type": "string"
          },
          "editorialSummary": {
            "type": "string"
          },
          "relatedPicks": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/RelatedRecordSummary"
            }
          },
          "relatedComparisons": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/RelatedRecordSummary"
            }
          }
        }
      },
      "ComparisonSummary": {
        "type": "object",
        "properties": {
          "slug": {
            "type": "string",
            "example": "tokyo-vs-kyoto"
          },
          "title": {
            "type": "string",
            "example": "Tokyo vs Kyoto: Which Should You Visit?"
          },
          "destination1": {
            "type": "string",
            "example": "Tokyo"
          },
          "destination2": {
            "type": "string",
            "example": "Kyoto"
          },
          "categoryCount": {
            "type": "integer",
            "example": 10
          },
          "url": {
            "type": "string",
            "format": "uri"
          },
          "destination1Slug": {
            "type": "string"
          },
          "destination2Slug": {
            "type": "string"
          },
          "destinationSlugs": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        }
      },
      "ComparisonList": {
        "type": "object",
        "properties": {
          "count": {
            "type": "integer"
          },
          "comparisons": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ComparisonSummary"
            }
          }
        }
      },
      "ComparisonCategory": {
        "type": "object",
        "properties": {
          "title": {
            "type": "string"
          },
          "summary": {
            "type": "string"
          },
          "highlights": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "redditQuotes": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ComparisonQuote"
            }
          },
          "winnerSummary": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            }
          }
        }
      },
      "FAQ": {
        "type": "object",
        "properties": {
          "question": {
            "type": "string"
          },
          "answer": {
            "type": "string"
          }
        }
      },
      "ComparisonDetail": {
        "type": "object",
        "properties": {
          "slug": {
            "type": "string"
          },
          "title": {
            "type": "string"
          },
          "description": {
            "type": "string"
          },
          "destination1": {
            "type": "string"
          },
          "destination2": {
            "type": "string"
          },
          "heroImage": {
            "type": "string",
            "format": "uri"
          },
          "url": {
            "type": "string",
            "format": "uri"
          },
          "categoryCount": {
            "type": "integer"
          },
          "categories": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ComparisonCategory"
            }
          },
          "verdict": {
            "$ref": "#/components/schemas/ComparisonVerdict"
          },
          "faqs": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/FAQ"
            }
          },
          "id": {
            "type": "string",
            "example": "compare:kyoto-vs-osaka"
          },
          "type": {
            "type": "string",
            "enum": [
              "compare"
            ]
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          },
          "sourceUrl": {
            "type": "string",
            "format": "uri"
          },
          "tags": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "sourceMeta": {
            "$ref": "#/components/schemas/RecordSourceMeta"
          },
          "destination1Slug": {
            "type": "string"
          },
          "destination2Slug": {
            "type": "string"
          },
          "destinationSlugs": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "editorialSummary": {
            "type": "string"
          },
          "relatedDestinations": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/RelatedRecordSummary"
            }
          },
          "relatedItineraries": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/RelatedRecordSummary"
            }
          },
          "relatedPicks": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/RelatedRecordSummary"
            }
          }
        }
      },
      "ComparisonQuote": {
        "type": "object",
        "properties": {
          "text": {
            "type": "string"
          },
          "source": {
            "type": "string"
          },
          "sourceUrl": {
            "type": "string",
            "format": "uri"
          }
        }
      },
      "ComparisonVerdict": {
        "type": "object",
        "properties": {
          "summary": {
            "type": "string"
          },
          "takeaways": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "cards": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "title": {
                  "type": "string"
                },
                "text": {
                  "type": "string"
                }
              }
            }
          }
        }
      },
      "SearchItem": {
        "type": "object",
        "properties": {
          "type": {
            "type": "string"
          },
          "slug": {
            "type": "string"
          },
          "title": {
            "type": "string"
          },
          "subtitle": {
            "type": "string"
          },
          "url": {
            "type": "string",
            "format": "uri"
          },
          "siteUrl": {
            "type": "string",
            "format": "uri"
          }
        }
      },
      "SearchResults": {
        "type": "object",
        "properties": {
          "query": {
            "type": "string"
          },
          "type": {
            "type": [
              "string",
              "null"
            ]
          },
          "count": {
            "type": "integer"
          },
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SearchItem"
            }
          }
        }
      },
      "RelatedRecordSummary": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "example": "pick:tokyo-ramen"
          },
          "type": {
            "type": "string",
            "enum": [
              "destination",
              "pick",
              "itinerary",
              "compare"
            ]
          },
          "slug": {
            "type": "string",
            "example": "tokyo-ramen"
          },
          "title": {
            "type": "string",
            "example": "12 Best Ramen in Tokyo"
          },
          "url": {
            "type": "string",
            "format": "uri"
          }
        },
        "additionalProperties": true
      },
      "RecordSourceMeta": {
        "type": "object",
        "properties": {
          "sourceType": {
            "type": "string",
            "example": "tabiji-static-page"
          },
          "sourcePath": {
            "type": "string",
            "example": "popular-picks/tokyo-ramen/index.html"
          },
          "sourceUrl": {
            "type": "string",
            "format": "uri"
          },
          "lastVerified": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "PlaceSourceMeta": {
        "type": "object",
        "properties": {
          "guideSlug": {
            "type": "string"
          },
          "guideTitle": {
            "type": "string"
          },
          "guideUrl": {
            "type": "string",
            "format": "uri"
          },
          "collectionCity": {
            "type": "string"
          },
          "collectionCategory": {
            "type": "string"
          },
          "fieldSources": {
            "type": "object",
            "additionalProperties": {
              "type": "array",
              "items": {
                "type": "string"
              }
            }
          }
        }
      },
      "CountryFacts": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "example": "country:jp"
          },
          "name": {
            "type": "string",
            "example": "Japan"
          },
          "officialName": {
            "type": "string",
            "example": "Japan"
          },
          "iso2": {
            "type": "string",
            "example": "JP"
          },
          "iso3": {
            "type": "string",
            "example": "JPN"
          },
          "capital": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "example": [
              "Tokyo"
            ]
          },
          "population": {
            "type": "integer",
            "example": 123210000
          },
          "area": {
            "type": "number",
            "example": 377930.0,
            "description": "Total area in km²"
          },
          "region": {
            "type": "string",
            "example": "Asia"
          },
          "subregion": {
            "type": "string",
            "example": "Eastern Asia"
          },
          "borders": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "ISO3 codes of neighboring countries",
            "example": []
          },
          "landlocked": {
            "type": "boolean",
            "example": false
          },
          "demonyms": {
            "type": "object",
            "properties": {
              "male": {
                "type": "string",
                "example": "Japanese"
              },
              "female": {
                "type": "string",
                "example": "Japanese"
              }
            }
          },
          "startOfWeek": {
            "type": "string",
            "example": "monday"
          },
          "maps": {
            "type": "object",
            "properties": {
              "googleMaps": {
                "type": "string",
                "format": "uri"
              },
              "openStreetMaps": {
                "type": "string",
                "format": "uri"
              }
            }
          },
          "currencies": {
            "type": "object",
            "additionalProperties": {
              "type": "object",
              "properties": {
                "name": {
                  "type": "string"
                },
                "symbol": {
                  "type": "string"
                }
              }
            },
            "example": {
              "JPY": {
                "name": "Japanese yen",
                "symbol": "¥"
              }
            }
          },
          "languages": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            },
            "example": {
              "jpn": "Japanese"
            }
          },
          "timezones": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "example": [
              "UTC+09:00"
            ]
          },
          "flag": {
            "type": "string",
            "description": "Emoji flag",
            "example": "🇯🇵"
          },
          "flagSvg": {
            "type": "string",
            "format": "uri"
          },
          "flagPng": {
            "type": "string",
            "format": "uri"
          },
          "drivingSide": {
            "type": "string",
            "enum": [
              "left",
              "right"
            ],
            "example": "left"
          },
          "dialCode": {
            "type": "string",
            "example": "+81"
          },
          "tld": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "example": [
              ".jp"
            ]
          },
          "type": {
            "type": "string",
            "const": "country"
          }
        }
      },
      "CountriesList": {
        "type": "object",
        "properties": {
          "count": {
            "type": "integer",
            "example": 250
          },
          "countries": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CountryFacts"
            }
          }
        }
      },
      "FreshnessMeta": {
        "type": "object",
        "properties": {
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          },
          "lastVerifiedAt": {
            "type": "string",
            "format": "date-time"
          },
          "confidence": {
            "type": "string"
          },
          "confidenceScore": {
            "type": "number"
          },
          "operationalFieldsMayChange": {
            "type": "boolean"
          }
        }
      },
      "ProvenanceMeta": {
        "type": "object",
        "properties": {
          "sources": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "sourcePath": {
            "type": "string"
          },
          "sourceUrl": {
            "type": "string",
            "format": "uri"
          },
          "lastVerifiedAt": {
            "type": "string",
            "format": "date-time"
          },
          "parentId": {
            "type": "string"
          }
        },
        "additionalProperties": true
      },
      "CatalogEntity": {
        "type": "object",
        "required": [
          "id",
          "entityType",
          "schemaVersion",
          "source",
          "slug",
          "tags",
          "freshness",
          "provenance"
        ],
        "properties": {
          "id": {
            "type": "string"
          },
          "entityType": {
            "type": "string",
            "enum": [
              "destination",
              "pick",
              "place",
              "itinerary",
              "compare"
            ]
          },
          "schemaVersion": {
            "type": "string"
          },
          "source": {
            "type": "string"
          },
          "slug": {
            "type": "string"
          },
          "title": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "description": {
            "type": "string"
          },
          "tags": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "freshness": {
            "$ref": "#/components/schemas/FreshnessMeta"
          },
          "provenance": {
            "$ref": "#/components/schemas/ProvenanceMeta"
          }
        },
        "additionalProperties": true
      },
      "SafetyIndex": {
        "type": "object",
        "properties": {
          "count": {
            "type": "integer"
          },
          "lastUpdated": {
            "type": "string",
            "format": "date-time"
          },
          "profiles": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SafetyIndexEntry"
            }
          }
        },
        "required": [
          "count",
          "lastUpdated",
          "profiles"
        ]
      },
      "SafetyIndexEntry": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "example": "safety:jp"
          },
          "iso2": {
            "type": "string",
            "example": "JP"
          },
          "name": {
            "type": "string",
            "example": "Japan"
          },
          "lastUpdated": {
            "type": "string",
            "format": "date-time"
          },
          "advisoryLevel": {
            "type": "integer",
            "description": "US State Department advisory level (1-4)"
          },
          "advisoryLevelText": {
            "type": "string",
            "example": "Exercise Normal Precautions"
          },
          "url": {
            "type": "string",
            "example": "/api/v1/safety/jp.json"
          }
        },
        "required": [
          "id",
          "iso2",
          "name",
          "advisoryLevel",
          "advisoryLevelText",
          "url"
        ]
      },
      "SafetyProfile": {
        "type": "object",
        "properties": {
          "iso2": {
            "type": "string",
            "example": "JP"
          },
          "name": {
            "type": "string",
            "example": "Japan"
          },
          "emergency": {
            "type": "object",
            "properties": {
              "police": {
                "type": "string"
              },
              "ambulance": {
                "type": "string"
              },
              "fire": {
                "type": "string"
              }
            }
          },
          "embassies": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "country": {
                  "type": "string"
                },
                "address": {
                  "type": "string"
                },
                "lat": {
                  "type": "number"
                },
                "lng": {
                  "type": "number"
                },
                "phone": {
                  "type": "string"
                }
              }
            }
          },
          "travelAdvisory": {
            "type": "object",
            "properties": {
              "level": {
                "type": "integer"
              },
              "levelText": {
                "type": "string"
              },
              "summary": {
                "type": "string"
              },
              "source": {
                "type": "string"
              }
            }
          },
          "travelAdvisoryUK": {
            "type": "object",
            "properties": {
              "level": {
                "type": "string"
              },
              "summary": {
                "type": "string"
              },
              "source": {
                "type": "string"
              }
            }
          },
          "healthcare": {
            "type": "object",
            "properties": {
              "quality": {
                "type": "string"
              },
              "notes": {
                "type": "string"
              },
              "vaccinations": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              }
            }
          },
          "medications": {
            "type": "object",
            "properties": {
              "banned": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              },
              "restricted": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              },
              "notes": {
                "type": "string"
              }
            }
          },
          "scams": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "name": {
                  "type": "string"
                },
                "description": {
                  "type": "string"
                },
                "avoidance": {
                  "type": "string"
                }
              }
            }
          },
          "connectivity": {
            "type": "object",
            "properties": {
              "simCards": {
                "type": "string"
              },
              "esim": {
                "type": "boolean"
              },
              "averageSpeedMbps": {
                "type": "number"
              }
            }
          },
          "cultural": {
            "type": "object",
            "properties": {
              "tipping": {
                "type": "string"
              },
              "dresscode": {
                "type": "string"
              },
              "taboos": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              }
            }
          },
          "phrases": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "phrase": {
                  "type": "string"
                },
                "meaning": {
                  "type": "string"
                },
                "pronunciation": {
                  "type": "string"
                }
              }
            }
          },
          "safety": {
            "type": "object",
            "properties": {
              "overallRating": {
                "type": "number"
              },
              "soloFemaleRating": {
                "type": "number"
              },
              "nightSafetyRating": {
                "type": "number"
              }
            }
          },
          "practical": {
            "type": "object",
            "properties": {
              "currency": {
                "type": "string"
              },
              "voltage": {
                "type": "string"
              },
              "plug": {
                "type": "string"
              },
              "drivingSide": {
                "type": "string"
              }
            }
          }
        },
        "required": [
          "iso2",
          "name",
          "emergency"
        ]
      },
      "CatalogResponse": {
        "type": "object",
        "properties": {
          "version": {
            "type": "string"
          },
          "schemaVersion": {
            "type": "string"
          },
          "generatedAt": {
            "type": "string",
            "format": "date-time"
          },
          "itemCount": {
            "type": "integer"
          },
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CatalogEntity"
            }
          }
        },
        "required": [
          "version",
          "schemaVersion",
          "generatedAt",
          "itemCount",
          "items"
        ]
      }
    }
  },
  "tags": [
    {
      "name": "Meta",
      "description": "API metadata and status"
    },
    {
      "name": "Destinations",
      "description": "942 travel destinations worldwide"
    },
    {
      "name": "Picks",
      "description": "Curated 'best of' guides — restaurants, cafes, bars, attractions"
    },
    {
      "name": "Itineraries",
      "description": "Day-by-day travel itineraries"
    },
    {
      "name": "Comparisons",
      "description": "Head-to-head destination comparisons"
    },
    {
      "name": "Countries",
      "description": "250 countries and territories with essential travel facts"
    },
    {
      "name": "Safety",
      "description": "40 country safety profiles with emergency numbers, embassies, advisories, healthcare, and cultural norms"
    }
  ]
}