openapi: 3.1.0
info:
  title: MigrationFit Static Data API
  version: "A02"
  description: Static JSON, CSV, Markdown, and bulk data endpoints for MigrationFit. No authentication required.
  contact:
    name: MigrationFit
    url: "https://migrationfit.com/contact/"
  license:
    name: CC BY 4.0
    url: "https://creativecommons.org/licenses/by/4.0/"
servers:
  - url: "https://migrationfit.com"
paths:
  /data/catalog.json:
    get:
      summary: Data catalog
      operationId: getCatalog
      responses:
        "200":
          description: Catalog of countries, cities, selections, and export routes.
          content:
            application/json:
              schema:
                $ref: "./data/schema.json#/$defs/catalog_export"
  /data/schema.json:
    get:
      summary: JSON Schema
      operationId: getSchema
      responses:
        "200":
          description: Published JSON Schema for MigrationFit exports.
          content:
            application/schema+json:
              schema:
                type: object
  /data/countries/{cc}.json:
    get:
      summary: Country export by ISO alpha-2 code
      operationId: getCountryByCode
      parameters:
        - $ref: "#/components/parameters/CountryCode"
      responses:
        "200":
          description: Country-level export envelope.
          content:
            application/json:
              schema:
                $ref: "./data/schema.json#/$defs/country_export"
        "404":
          $ref: "#/components/responses/NotFound"
  /data/legal/catalog.json:
    get:
      summary: Legal passport catalog
      operationId: getLegalCatalog
      responses:
        "200":
          description: Catalog of passport legal pages and per-passport exports.
          content:
            application/json:
              schema:
                $ref: "./data/schema.json#/$defs/legal_catalog_export"
  /data/legal/passport/{cc}.json:
    get:
      summary: Legal passport export
      operationId: getLegalPassport
      parameters:
        - $ref: "#/components/parameters/CountryCode"
      responses:
        "200":
          description: Passport-by-destination legal rules export.
          content:
            application/json:
              schema:
                $ref: "./data/schema.json#/$defs/legal_passport_export"
        "404":
          $ref: "#/components/responses/NotFound"
  /data/reports/catalog.json:
    get:
      summary: Question-driven reports catalog
      operationId: getReportsCatalog
      responses:
        "200":
          description: Catalog of public question-driven report pages and exports.
          content:
            application/json:
              schema:
                $ref: "./data/schema.json#/$defs/question_driven_report_catalog_export"
  /data/reports/{slug}.json:
    get:
      summary: Question-driven report export
      operationId: getReport
      parameters:
        - $ref: "#/components/parameters/Slug"
      responses:
        "200":
          description: Machine-readable public report export.
          content:
            application/json:
              schema:
                $ref: "./data/schema.json#/$defs/question_driven_report_export"
        "404":
          $ref: "#/components/responses/NotFound"
  /data/profiles/{profile}/{cc}.json:
    get:
      summary: Country profile ranking export
      operationId: getProfileRanking
      parameters:
        - name: profile
          in: path
          required: true
          schema:
            type: string
          example: remote-worker
        - $ref: "#/components/parameters/CountryCode"
      responses:
        "200":
          description: Published country-profile ranking with weights, coverage gate, relevant routes, and ranked rows.
          content:
            application/json:
              schema:
                $ref: "./data/schema.json#/$defs/profile_ranking_export"
        "404":
          $ref: "#/components/responses/NotFound"
  /data/routes/{origin}-{destination}.json:
    get:
      summary: Origin-to-destination corridor export
      operationId: getCorridor
      parameters:
        - name: origin
          in: path
          required: true
          schema:
            type: string
          example: india
        - name: destination
          in: path
          required: true
          schema:
            type: string
          example: de
      responses:
        "200":
          description: Published migration corridor with entry access, official routes, PR timeline, best cities, and source links.
          content:
            application/json:
              schema:
                $ref: "./data/schema.json#/$defs/corridor_export"
        "404":
          $ref: "#/components/responses/NotFound"
  /data/tax-rules/{ruleId}.json:
    get:
      summary: Versioned net-salary rule export
      operationId: getTaxRule
      parameters:
        - name: ruleId
          in: path
          required: true
          schema:
            type: string
          example: de-2026
      responses:
        "200":
          description: Versioned country-year tax-rule export with thresholds, sources, assumptions, and default modeled result.
          content:
            application/json:
              schema:
                $ref: "./data/schema.json#/$defs/tax_rule_export"
        "404":
          $ref: "#/components/responses/NotFound"
  /data/move-cost-rules/{cc}.json:
    get:
      summary: Country move-cost rule export
      operationId: getMoveCostRule
      parameters:
        - $ref: "#/components/parameters/CountryCode"
      responses:
        "200":
          description: Country-level first-month move-cost rules with deposit norm, reusable line items, route metadata, and checklist templates.
          content:
            application/json:
              schema:
                $ref: "./data/schema.json#/$defs/move_cost_rule_export"
        "404":
          $ref: "#/components/responses/NotFound"
  /data/countries/{cc}/{topic}.json:
    get:
      summary: Country topic export
      operationId: getCountryTopic
      parameters:
        - $ref: "#/components/parameters/CountryCode"
        - name: topic
          in: path
          required: true
          schema:
            type: string
          example: visas
      responses:
        "200":
          description: Country topic export.
          content:
            application/json:
              schema:
                type: object
        "404":
          $ref: "#/components/responses/NotFound"
  /data/cities/{cc}/{slug}.json:
    get:
      summary: City export
      operationId: getCity
      parameters:
        - $ref: "#/components/parameters/CountryCode"
        - $ref: "#/components/parameters/Slug"
      responses:
        "200":
          description: City-level export envelope.
          content:
            application/json:
              schema:
                $ref: "./data/schema.json#/$defs/city_export"
        "404":
          $ref: "#/components/responses/NotFound"
  /data/timeseries/{metric_id}/{entity_id}.json:
    get:
      summary: Metric timeseries export
      operationId: getMetricTimeseries
      parameters:
        - name: metric_id
          in: path
          required: true
          schema:
            type: string
          example: rent_avg_nettokalt_eur_per_m2_month
        - name: entity_id
          in: path
          required: true
          schema:
            type: string
          example: de.berlin
      responses:
        "200":
          description: Historical observations plus the current significant trend for one metric/entity pair.
          content:
            application/json:
              schema:
                $ref: "./data/schema.json#/$defs/metric_timeseries_export"
        "404":
          $ref: "#/components/responses/NotFound"
  /data/regions/{cc}/{slug}.json:
    get:
      summary: Region export
      operationId: getRegion
      parameters:
        - $ref: "#/components/parameters/CountryCode"
        - $ref: "#/components/parameters/Slug"
      responses:
        "200":
          description: Region-level export envelope.
          content:
            application/json:
              schema:
                $ref: "./data/schema.json#/$defs/region_export"
        "404":
          $ref: "#/components/responses/NotFound"
  /data/compare/{pair}.json:
    get:
      summary: City comparison export
      operationId: getCompare
      parameters:
        - name: pair
          in: path
          required: true
          schema:
            type: string
          example: berlin-vs-hamburg
      responses:
        "200":
          description: City comparison export.
          content:
            application/json:
              schema:
                $ref: "./data/schema.json#/$defs/compare_export"
        "404":
          $ref: "#/components/responses/NotFound"
  /data/metrics/{id}.json:
    get:
      summary: Metric definition and coverage
      operationId: getMetric
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
          example: population_total
      responses:
        "200":
          description: Metric definition export.
          content:
            application/json:
              schema:
                type: object
        "404":
          $ref: "#/components/responses/NotFound"
  /data/bulk/{cc}.json.gz:
    get:
      summary: Per-country bulk dump
      operationId: getCountryBulkDump
      parameters:
        - $ref: "#/components/parameters/CountryCode"
      responses:
        "200":
          description: Gzipped country bundle with country, city, region, compare, and selection exports available in the current build.
          content:
            application/gzip:
              schema:
                type: string
                format: binary
        "404":
          $ref: "#/components/responses/NotFound"
  /data/bulk/manifest.json:
    get:
      summary: Bulk dump manifest
      operationId: getBulkManifest
      responses:
        "200":
          description: Checksums, sizes, and data versions for bulk dumps.
          content:
            application/json:
              schema:
                type: object
  /data/csv/cities.csv:
    get:
      summary: City CSV export
      operationId: getCitiesCsv
      responses:
        "200":
          description: Flat city CSV export.
          content:
            text/csv:
              schema:
                type: string
components:
  parameters:
    CountryCode:
      name: cc
      in: path
      required: true
      schema:
        type: string
        pattern: "^[a-z]{2}$"
      example: de
    Slug:
      name: slug
      in: path
      required: true
      schema:
        type: string
      example: berlin
  responses:
    NotFound:
      description: Static error envelope for missing data exports.
      content:
        application/json:
          schema:
            $ref: "./data/schema.json#/$defs/error_body"
