{
  "openapi": "3.0.3",
  "info": {
    "title": "Yadozei API",
    "version": "1.0.0",
    "description": "Japan accommodation-tax (宿泊税) calculation, area rules, address-to-area resolution and a change feed. Data version 2026.10. Docs: https://yadozei.jp/en/docs (English), https://yadozei.jp/docs (日本語). CORS preflight answers 204; unsupported methods answer 405 with an empty body.",
    "contact": {
      "name": "Yadozei",
      "url": "https://yadozei.jp/en/contact"
    }
  },
  "servers": [
    {
      "url": "https://yadozei.jp"
    }
  ],
  "paths": {
    "/v1/calculate": {
      "post": {
        "operationId": "calculateTax",
        "summary": "Calculate the accommodation tax for one stay. Each night is taxed under the rules in force on its own date; you get per-night results, the stay total and a breakdown by taxing authority.",
        "security": [
          {},
          {
            "ApiKey": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CalculateRequest"
              },
              "example": {
                "areaId": "tokyo",
                "ratePerNight": 15000,
                "date": "2026-12-01",
                "nights": 2,
                "guests": 2
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "headers": {
              "X-Data-Version": {
                "$ref": "#/components/headers/XDataVersion"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CalculateResponse"
                },
                "example": {
                  "areaId": "tokyo",
                  "areaName": {
                    "en": "Tokyo",
                    "ja": "東京都"
                  },
                  "currency": "JPY",
                  "dateUsed": "2026-12-01",
                  "basis": "per_person",
                  "perNightTax": 200,
                  "breakdown": [
                    {
                      "authority": {
                        "en": "Tokyo Metropolitan Government",
                        "ja": "東京都"
                      },
                      "amount": 200,
                      "type": "fixed"
                    }
                  ],
                  "nights": 2,
                  "guests": 2,
                  "nightly": [
                    {
                      "date": "2026-12-01",
                      "ratePerNight": 15000,
                      "perNightTax": 200,
                      "breakdown": [
                        {
                          "authority": {
                            "en": "Tokyo Metropolitan Government",
                            "ja": "東京都"
                          },
                          "amount": 200,
                          "type": "fixed"
                        }
                      ]
                    },
                    {
                      "date": "2026-12-02",
                      "ratePerNight": 15000,
                      "perNightTax": 200,
                      "breakdown": [
                        {
                          "authority": {
                            "en": "Tokyo Metropolitan Government",
                            "ja": "東京都"
                          },
                          "amount": 200,
                          "type": "fixed"
                        }
                      ]
                    }
                  ],
                  "stayTotal": {
                    "perPerson": 400,
                    "total": 800,
                    "breakdown": [
                      {
                        "authority": {
                          "en": "Tokyo Metropolitan Government",
                          "ja": "東京都"
                        },
                        "amount": 800,
                        "type": "fixed"
                      }
                    ]
                  }
                }
              }
            }
          },
          "400": {
            "description": "invalid_json: The body is not valid JSON; validation_error: The body or query failed validation; message names the first problem",
            "headers": {
              "X-Data-Version": {
                "$ref": "#/components/headers/XDataVersion"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "invalid_json": {
                    "value": {
                      "error": {
                        "code": "invalid_json",
                        "message": "The body is not valid JSON"
                      }
                    }
                  },
                  "validation_error": {
                    "value": {
                      "error": {
                        "code": "validation_error",
                        "message": "The body or query failed validation; message names the first problem"
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "unauthorized: The X-API-Key is unknown or revoked",
            "headers": {
              "X-Data-Version": {
                "$ref": "#/components/headers/XDataVersion"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "unauthorized": {
                    "value": {
                      "error": {
                        "code": "unauthorized",
                        "message": "The X-API-Key is unknown or revoked"
                      }
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "unknown_area: The area id does not exist",
            "headers": {
              "X-Data-Version": {
                "$ref": "#/components/headers/XDataVersion"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "unknown_area": {
                    "value": {
                      "error": {
                        "code": "unknown_area",
                        "message": "The area id does not exist",
                        "suggestions": [
                          "kyoto"
                        ]
                      }
                    }
                  }
                }
              }
            }
          },
          "413": {
            "description": "payload_too_large: The body is over its limit: 4 KB for /v1/calculate, 128 KB for /v1/resolve",
            "headers": {
              "X-Data-Version": {
                "$ref": "#/components/headers/XDataVersion"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "payload_too_large": {
                    "value": {
                      "error": {
                        "code": "payload_too_large",
                        "message": "The body is over its limit: 4 KB for /v1/calculate, 128 KB for /v1/resolve"
                      }
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "rate_limited: A per-minute limit or the daily/monthly quota was exceeded",
            "headers": {
              "X-Data-Version": {
                "$ref": "#/components/headers/XDataVersion"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfter"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "rate_limited": {
                    "value": {
                      "error": {
                        "code": "rate_limited",
                        "message": "A per-minute limit or the daily/monthly quota was exceeded",
                        "retryAfter": 42
                      }
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Unexpected error. The body may not be JSON; retry with backoff."
          }
        }
      }
    },
    "/v1/areas": {
      "get": {
        "operationId": "listAreas",
        "summary": "List every covered area: id, names, prefecture, administrative level and tax base.",
        "security": [
          {},
          {
            "ApiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "headers": {
              "X-Data-Version": {
                "$ref": "#/components/headers/XDataVersion"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AreaList"
                },
                "example": {
                  "areas": [
                    {
                      "id": "tokyo",
                      "name": {
                        "en": "Tokyo",
                        "ja": "東京都"
                      },
                      "prefecture": {
                        "en": "Tokyo",
                        "ja": "東京都"
                      },
                      "level": "prefecture",
                      "taxBase": "per_person"
                    },
                    {
                      "id": "osaka",
                      "name": {
                        "en": "Osaka",
                        "ja": "大阪府"
                      },
                      "prefecture": {
                        "en": "Osaka",
                        "ja": "大阪府"
                      },
                      "level": "prefecture",
                      "taxBase": "per_person"
                    },
                    {
                      "id": "kyoto",
                      "name": {
                        "en": "Kyoto",
                        "ja": "京都市"
                      },
                      "prefecture": {
                        "en": "Kyoto",
                        "ja": "京都府"
                      },
                      "level": "city",
                      "taxBase": "per_person"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "unauthorized: The X-API-Key is unknown or revoked",
            "headers": {
              "X-Data-Version": {
                "$ref": "#/components/headers/XDataVersion"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "unauthorized": {
                    "value": {
                      "error": {
                        "code": "unauthorized",
                        "message": "The X-API-Key is unknown or revoked"
                      }
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "rate_limited: A per-minute limit or the daily/monthly quota was exceeded",
            "headers": {
              "X-Data-Version": {
                "$ref": "#/components/headers/XDataVersion"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfter"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "rate_limited": {
                    "value": {
                      "error": {
                        "code": "rate_limited",
                        "message": "A per-minute limit or the daily/monthly quota was exceeded",
                        "retryAfter": 42
                      }
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Unexpected error. The body may not be JSON; retry with backoff."
          }
        }
      }
    },
    "/v1/areas/{id}": {
      "get": {
        "operationId": "getArea",
        "summary": "Get one area's full rules — effective dates, tiers or rate, cap, threshold — plus exemption categories and the official source.",
        "security": [
          {},
          {
            "ApiKey": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Area id.",
            "schema": {
              "type": "string",
              "minLength": 1
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "headers": {
              "X-Data-Version": {
                "$ref": "#/components/headers/XDataVersion"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Area"
                },
                "example": {
                  "id": "tokyo",
                  "name": {
                    "en": "Tokyo",
                    "ja": "東京都"
                  },
                  "prefecture": {
                    "en": "Tokyo",
                    "ja": "東京都"
                  },
                  "level": "prefecture",
                  "taxBase": "per_person",
                  "rules": [
                    {
                      "authority": {
                        "en": "Tokyo Metropolitan Government",
                        "ja": "東京都"
                      },
                      "effectiveFrom": "2002-10-01",
                      "effectiveUntil": "2027-03-31",
                      "type": "fixed",
                      "tiers": [
                        {
                          "min": 0,
                          "max": 9999,
                          "amount": 0
                        },
                        {
                          "min": 10000,
                          "max": 14999,
                          "amount": 100
                        },
                        {
                          "min": 15000,
                          "max": null,
                          "amount": 200
                        }
                      ]
                    },
                    {
                      "authority": {
                        "en": "Tokyo Metropolitan Government",
                        "ja": "東京都"
                      },
                      "effectiveFrom": "2027-04-01",
                      "effectiveUntil": null,
                      "type": "percentage",
                      "rate": 0.03,
                      "cap": null,
                      "threshold": 13000
                    }
                  ],
                  "exemptions": [
                    "school_trips"
                  ],
                  "notes": "Revision consented by the Minister of Internal Affairs 2026-06-30, in effect from 2027-04-01: flat 3% of the nightly charge (no cap), exempt threshold raised to stays under 13,000 yen per person per night, and hostels (kan'i-shukusho) / minpaku added to the scope (their operators register as collection agents from 2026-07-01).",
                  "source": "https://www.tax.metro.tokyo.lg.jp/kazei/leisure/shuk"
                }
              }
            }
          },
          "401": {
            "description": "unauthorized: The X-API-Key is unknown or revoked",
            "headers": {
              "X-Data-Version": {
                "$ref": "#/components/headers/XDataVersion"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "unauthorized": {
                    "value": {
                      "error": {
                        "code": "unauthorized",
                        "message": "The X-API-Key is unknown or revoked"
                      }
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "unknown_area: The area id does not exist",
            "headers": {
              "X-Data-Version": {
                "$ref": "#/components/headers/XDataVersion"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "unknown_area": {
                    "value": {
                      "error": {
                        "code": "unknown_area",
                        "message": "The area id does not exist",
                        "suggestions": [
                          "kyoto"
                        ]
                      }
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "rate_limited: A per-minute limit or the daily/monthly quota was exceeded",
            "headers": {
              "X-Data-Version": {
                "$ref": "#/components/headers/XDataVersion"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfter"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "rate_limited": {
                    "value": {
                      "error": {
                        "code": "rate_limited",
                        "message": "A per-minute limit or the daily/monthly quota was exceeded",
                        "retryAfter": 42
                      }
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Unexpected error. The body may not be JSON; retry with backoff."
          }
        }
      }
    },
    "/v1/resolve": {
      "get": {
        "operationId": "resolveAddress",
        "summary": "Find a property's tax area (areaId) from its address: its municipality's own tax, the prefecture-wide tax, or no accommodation tax at all — decided from the prefecture and the municipality.",
        "security": [
          {},
          {
            "ApiKey": []
          }
        ],
        "parameters": [
          {
            "name": "address",
            "in": "query",
            "required": false,
            "description": "The address, starting with the prefecture (e.g. 沖縄県国頭郡恩納村…). A postal code, a leading 日本, full-width characters and spaces are fine.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 200
            }
          },
          {
            "name": "prefecture",
            "in": "query",
            "required": false,
            "description": "Instead of address: the prefecture's full name (e.g. 沖縄県), sent with municipality.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 200
            }
          },
          {
            "name": "municipality",
            "in": "query",
            "required": false,
            "description": "Instead of address: the municipality (e.g. 国頭郡恩納村 or 那覇市).",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 200
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "headers": {
              "X-Data-Version": {
                "$ref": "#/components/headers/XDataVersion"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ResolveResult"
                },
                "example": {
                  "input": "沖縄県国頭郡恩納村字恩納2451",
                  "areaId": "onna",
                  "match": "municipal",
                  "areaName": {
                    "ja": "恩納村",
                    "en": "Onna"
                  },
                  "prefecture": "沖縄県",
                  "municipality": "恩納村"
                }
              }
            }
          },
          "400": {
            "description": "validation_error: The body or query failed validation; message names the first problem",
            "headers": {
              "X-Data-Version": {
                "$ref": "#/components/headers/XDataVersion"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "validation_error": {
                    "value": {
                      "error": {
                        "code": "validation_error",
                        "message": "The body or query failed validation; message names the first problem"
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "unauthorized: The X-API-Key is unknown or revoked",
            "headers": {
              "X-Data-Version": {
                "$ref": "#/components/headers/XDataVersion"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "unauthorized": {
                    "value": {
                      "error": {
                        "code": "unauthorized",
                        "message": "The X-API-Key is unknown or revoked"
                      }
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "rate_limited: A per-minute limit or the daily/monthly quota was exceeded",
            "headers": {
              "X-Data-Version": {
                "$ref": "#/components/headers/XDataVersion"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfter"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "rate_limited": {
                    "value": {
                      "error": {
                        "code": "rate_limited",
                        "message": "A per-minute limit or the daily/monthly quota was exceeded",
                        "retryAfter": 42
                      }
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Unexpected error. The body may not be JSON; retry with backoff."
          }
        }
      },
      "post": {
        "operationId": "resolveAddresses",
        "summary": "Resolve up to 100 addresses in one call, with results in the order sent. One call counts as one request, however many addresses it carries. Paid plans only.",
        "security": [
          {
            "ApiKey": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ResolveBatchRequest"
              },
              "example": {
                "addresses": [
                  "沖縄県国頭郡恩納村字恩納2451",
                  "沖縄県那覇市泉崎1-2-2",
                  "京都府宇治市宇治琵琶33",
                  "那覇市泉崎1-2-2"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "headers": {
              "X-Data-Version": {
                "$ref": "#/components/headers/XDataVersion"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ResolveBatch"
                },
                "example": {
                  "results": [
                    {
                      "input": "沖縄県国頭郡恩納村字恩納2451",
                      "areaId": "onna",
                      "match": "municipal",
                      "areaName": {
                        "ja": "恩納村",
                        "en": "Onna"
                      },
                      "prefecture": "沖縄県",
                      "municipality": "恩納村"
                    },
                    {
                      "input": "沖縄県那覇市泉崎1-2-2",
                      "areaId": "okinawa_other",
                      "match": "prefecture",
                      "areaName": {
                        "ja": "沖縄県（その他地域）",
                        "en": "Okinawa Prefecture (other areas)"
                      },
                      "prefecture": "沖縄県",
                      "municipality": null
                    },
                    {
                      "input": "京都府宇治市宇治琵琶33",
                      "areaId": null,
                      "match": "no_tax",
                      "prefecture": "京都府",
                      "municipality": null
                    },
                    {
                      "input": "那覇市泉崎1-2-2",
                      "areaId": null,
                      "match": "unresolved",
                      "message": "Could not identify the prefecture: start the address with it (e.g. 沖縄県那覇市…)."
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "description": "invalid_json: The body is not valid JSON; validation_error: The body or query failed validation; message names the first problem",
            "headers": {
              "X-Data-Version": {
                "$ref": "#/components/headers/XDataVersion"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "invalid_json": {
                    "value": {
                      "error": {
                        "code": "invalid_json",
                        "message": "The body is not valid JSON"
                      }
                    }
                  },
                  "validation_error": {
                    "value": {
                      "error": {
                        "code": "validation_error",
                        "message": "The body or query failed validation; message names the first problem"
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "unauthorized: The X-API-Key is unknown or revoked",
            "headers": {
              "X-Data-Version": {
                "$ref": "#/components/headers/XDataVersion"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "unauthorized": {
                    "value": {
                      "error": {
                        "code": "unauthorized",
                        "message": "The X-API-Key is unknown or revoked"
                      }
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "forbidden: The endpoint needs a paid-plan key",
            "headers": {
              "X-Data-Version": {
                "$ref": "#/components/headers/XDataVersion"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "forbidden": {
                    "value": {
                      "error": {
                        "code": "forbidden",
                        "message": "The endpoint needs a paid-plan key"
                      }
                    }
                  }
                }
              }
            }
          },
          "413": {
            "description": "payload_too_large: The body is over its limit: 4 KB for /v1/calculate, 128 KB for /v1/resolve",
            "headers": {
              "X-Data-Version": {
                "$ref": "#/components/headers/XDataVersion"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "payload_too_large": {
                    "value": {
                      "error": {
                        "code": "payload_too_large",
                        "message": "The body is over its limit: 4 KB for /v1/calculate, 128 KB for /v1/resolve"
                      }
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "rate_limited: A per-minute limit or the daily/monthly quota was exceeded",
            "headers": {
              "X-Data-Version": {
                "$ref": "#/components/headers/XDataVersion"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfter"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "rate_limited": {
                    "value": {
                      "error": {
                        "code": "rate_limited",
                        "message": "A per-minute limit or the daily/monthly quota was exceeded",
                        "retryAfter": 42
                      }
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Unexpected error. The body may not be JSON; retry with backoff."
          }
        }
      }
    },
    "/v1/changes": {
      "get": {
        "operationId": "listChanges",
        "summary": "List dataset changes after since_seq, oldest first. Syncing needs an API key — anonymous callers see only the newest 5.",
        "security": [
          {},
          {
            "ApiKey": []
          }
        ],
        "parameters": [
          {
            "name": "since_seq",
            "in": "query",
            "required": false,
            "description": "Returns entries with a seq greater than this. Store the highest seq you have processed and pass it back.",
            "schema": {
              "type": "integer",
              "minimum": 0,
              "default": 0
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "headers": {
              "X-Data-Version": {
                "$ref": "#/components/headers/XDataVersion"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ChangeList"
                },
                "example": {
                  "changes": [
                    {
                      "seq": 6,
                      "releasedAt": "2026-09-20",
                      "dataVersion": "2026.09",
                      "areaIds": [
                        "kutchan",
                        "niseko"
                      ],
                      "type": "corrected",
                      "summary": {
                        "en": "Notes clarified, no rate or date change: in Kutchan, and in Niseko from 2026-11-01, the Hokkaido prefectural tiers legally still apply but the town tax is 3% minus the prefectural amount, collected as one 3% charge by the town. The dataset keeps a single 3% town rule, so the breakdown does not split out the prefectural share.",
                        "ja": "注記の明確化（税率・施行日に変更なし）：倶知安町、および2026年11月1日以降のニセコ町では道税の定額区分が法的に存続するが、町税＝3％－道税額として町が3％を一括徴収する。データは単一の3％町ルールを維持し、内訳は道税分を分離しない。"
                      },
                      "effectiveFrom": null,
                      "sources": [
                        "https://www.town.kutchan.hokkaido.jp/town_administration/AccommodationTax/3108/",
                        "https://www.pref.hokkaido.lg.jp/kz/kkd/191976.html"
                      ]
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "description": "validation_error: The body or query failed validation; message names the first problem",
            "headers": {
              "X-Data-Version": {
                "$ref": "#/components/headers/XDataVersion"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "validation_error": {
                    "value": {
                      "error": {
                        "code": "validation_error",
                        "message": "The body or query failed validation; message names the first problem"
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "unauthorized: The X-API-Key is unknown or revoked",
            "headers": {
              "X-Data-Version": {
                "$ref": "#/components/headers/XDataVersion"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "unauthorized": {
                    "value": {
                      "error": {
                        "code": "unauthorized",
                        "message": "The X-API-Key is unknown or revoked"
                      }
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "rate_limited: A per-minute limit or the daily/monthly quota was exceeded",
            "headers": {
              "X-Data-Version": {
                "$ref": "#/components/headers/XDataVersion"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfter"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "rate_limited": {
                    "value": {
                      "error": {
                        "code": "rate_limited",
                        "message": "A per-minute limit or the daily/monthly quota was exceeded",
                        "retryAfter": 42
                      }
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Unexpected error. The body may not be JSON; retry with backoff."
          }
        }
      }
    },
    "/v1/data": {
      "get": {
        "operationId": "getDataset",
        "summary": "Get the full dataset — every area with all its rules — and the data version in one call. Paid plans only.",
        "security": [
          {
            "ApiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "headers": {
              "X-Data-Version": {
                "$ref": "#/components/headers/XDataVersion"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Dataset"
                },
                "example": {
                  "dataVersion": "2026.10",
                  "areas": [
                    {
                      "id": "tokyo",
                      "name": {
                        "en": "Tokyo",
                        "ja": "東京都"
                      },
                      "prefecture": {
                        "en": "Tokyo",
                        "ja": "東京都"
                      },
                      "level": "prefecture",
                      "taxBase": "per_person",
                      "rules": [
                        {
                          "authority": {
                            "en": "Tokyo Metropolitan Government",
                            "ja": "東京都"
                          },
                          "effectiveFrom": "2002-10-01",
                          "effectiveUntil": "2027-03-31",
                          "type": "fixed",
                          "tiers": [
                            {
                              "min": 0,
                              "max": 9999,
                              "amount": 0
                            },
                            {
                              "min": 10000,
                              "max": 14999,
                              "amount": 100
                            },
                            {
                              "min": 15000,
                              "max": null,
                              "amount": 200
                            }
                          ]
                        },
                        {
                          "authority": {
                            "en": "Tokyo Metropolitan Government",
                            "ja": "東京都"
                          },
                          "effectiveFrom": "2027-04-01",
                          "effectiveUntil": null,
                          "type": "percentage",
                          "rate": 0.03,
                          "cap": null,
                          "threshold": 13000
                        }
                      ],
                      "exemptions": [
                        "school_trips"
                      ],
                      "notes": "Revision consented by the Minister of Internal Affairs 2026-06-30, in effect from 2027-04-01: flat 3% of the nightly charge (no cap), exempt threshold raised to stays under 13,000 yen per person per night, and hostels (kan'i-shukusho) / minpaku added to the scope (their operators register as collection agents from 2026-07-01).",
                      "source": "https://www.tax.metro.tokyo.lg.jp/kazei/leisure/shuk"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "unauthorized: The X-API-Key is unknown or revoked",
            "headers": {
              "X-Data-Version": {
                "$ref": "#/components/headers/XDataVersion"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "unauthorized": {
                    "value": {
                      "error": {
                        "code": "unauthorized",
                        "message": "The X-API-Key is unknown or revoked"
                      }
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "forbidden: The endpoint needs a paid-plan key",
            "headers": {
              "X-Data-Version": {
                "$ref": "#/components/headers/XDataVersion"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "forbidden": {
                    "value": {
                      "error": {
                        "code": "forbidden",
                        "message": "The endpoint needs a paid-plan key"
                      }
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "rate_limited: A per-minute limit or the daily/monthly quota was exceeded",
            "headers": {
              "X-Data-Version": {
                "$ref": "#/components/headers/XDataVersion"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfter"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "rate_limited": {
                    "value": {
                      "error": {
                        "code": "rate_limited",
                        "message": "A per-minute limit or the daily/monthly quota was exceeded",
                        "retryAfter": 42
                      }
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Unexpected error. The body may not be JSON; retry with backoff."
          }
        }
      }
    },
    "/healthz": {
      "get": {
        "operationId": "getHealth",
        "summary": "Service health and the data version. Not rate-limited, so use it for monitoring.",
        "security": [],
        "responses": {
          "200": {
            "description": "OK",
            "headers": {
              "X-Data-Version": {
                "$ref": "#/components/headers/XDataVersion"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Health"
                },
                "example": {
                  "status": "ok",
                  "dataVersion": "2026.10",
                  "db": "ok"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected error. The body may not be JSON; retry with backoff."
          },
          "503": {
            "description": "unhealthy: /healthz only: the database is not writable",
            "headers": {
              "X-Data-Version": {
                "$ref": "#/components/headers/XDataVersion"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "unhealthy": {
                    "value": {
                      "error": {
                        "code": "unhealthy",
                        "message": "/healthz only: the database is not writable",
                        "dataVersion": "2026.10"
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "ApiKey": {
        "type": "apiKey",
        "in": "header",
        "name": "X-API-Key"
      }
    },
    "headers": {
      "XDataVersion": {
        "description": "Dataset version used for this response, e.g. 2026.09.",
        "schema": {
          "type": "string"
        }
      },
      "RetryAfter": {
        "description": "Seconds until the limit that was hit resets.",
        "schema": {
          "type": "integer"
        }
      },
      "XRateLimitLimit": {
        "description": "The quota: requests per day without a key, per month with one.",
        "schema": {
          "type": "integer"
        }
      },
      "XRateLimitRemaining": {
        "description": "Requests left in the window, this one counted.",
        "schema": {
          "type": "integer"
        }
      },
      "XRateLimitReset": {
        "description": "Seconds until the window resets: JST midnight, or the 1st of the month for keys.",
        "schema": {
          "type": "integer"
        }
      }
    },
    "schemas": {
      "LocalizedName": {
        "type": "object",
        "required": [
          "en",
          "ja"
        ],
        "properties": {
          "en": {
            "type": "string"
          },
          "ja": {
            "type": "string"
          }
        }
      },
      "AreaSummary": {
        "type": "object",
        "required": [
          "id",
          "name",
          "prefecture",
          "level",
          "taxBase"
        ],
        "properties": {
          "id": {
            "type": "string",
            "example": "tokyo"
          },
          "name": {
            "$ref": "#/components/schemas/LocalizedName"
          },
          "prefecture": {
            "$ref": "#/components/schemas/LocalizedName"
          },
          "level": {
            "type": "string",
            "enum": [
              "prefecture",
              "city",
              "town",
              "village",
              "ward"
            ]
          },
          "taxBase": {
            "type": "string",
            "enum": [
              "per_person",
              "per_unit",
              "variable"
            ]
          }
        }
      },
      "AreaList": {
        "type": "object",
        "required": [
          "areas"
        ],
        "properties": {
          "areas": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/AreaSummary"
            }
          }
        }
      },
      "TaxTier": {
        "type": "object",
        "required": [
          "min",
          "max",
          "amount"
        ],
        "properties": {
          "min": {
            "type": "integer"
          },
          "max": {
            "type": "integer",
            "nullable": true
          },
          "amount": {
            "type": "integer"
          }
        }
      },
      "TaxRule": {
        "type": "object",
        "required": [
          "authority",
          "effectiveFrom",
          "effectiveUntil",
          "type"
        ],
        "properties": {
          "authority": {
            "$ref": "#/components/schemas/LocalizedName"
          },
          "effectiveFrom": {
            "type": "string",
            "format": "date",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
          },
          "effectiveUntil": {
            "type": "string",
            "format": "date",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
            "nullable": true
          },
          "type": {
            "type": "string",
            "enum": [
              "fixed",
              "percentage"
            ]
          },
          "tiers": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TaxTier"
            }
          },
          "rate": {
            "type": "number"
          },
          "cap": {
            "type": "integer",
            "nullable": true
          },
          "threshold": {
            "type": "integer"
          },
          "baseRoundDownTo": {
            "type": "integer"
          }
        }
      },
      "Area": {
        "type": "object",
        "required": [
          "id",
          "name",
          "prefecture",
          "level",
          "taxBase",
          "rules",
          "exemptions",
          "notes",
          "source"
        ],
        "properties": {
          "id": {
            "type": "string",
            "example": "tokyo"
          },
          "name": {
            "$ref": "#/components/schemas/LocalizedName"
          },
          "prefecture": {
            "$ref": "#/components/schemas/LocalizedName"
          },
          "level": {
            "type": "string",
            "enum": [
              "prefecture",
              "city",
              "town",
              "village",
              "ward"
            ]
          },
          "taxBase": {
            "type": "string",
            "enum": [
              "per_person",
              "per_unit",
              "variable"
            ]
          },
          "rules": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TaxRule"
            }
          },
          "exemptions": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "notes": {
            "type": "string",
            "nullable": true
          },
          "source": {
            "type": "string",
            "format": "uri"
          }
        }
      },
      "Dataset": {
        "type": "object",
        "required": [
          "dataVersion",
          "areas"
        ],
        "properties": {
          "dataVersion": {
            "type": "string"
          },
          "areas": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Area"
            }
          }
        }
      },
      "BreakdownItem": {
        "type": "object",
        "required": [
          "authority",
          "amount",
          "type"
        ],
        "properties": {
          "authority": {
            "$ref": "#/components/schemas/LocalizedName"
          },
          "amount": {
            "type": "integer"
          },
          "type": {
            "type": "string",
            "enum": [
              "fixed",
              "percentage"
            ],
            "description": "In stayTotal.breakdown: the last contributing night's rule type."
          }
        }
      },
      "StayNight": {
        "type": "object",
        "required": [
          "date",
          "ratePerNight",
          "perNightTax",
          "breakdown"
        ],
        "properties": {
          "date": {
            "type": "string",
            "format": "date",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
          },
          "ratePerNight": {
            "type": "integer"
          },
          "perNightTax": {
            "type": "integer"
          },
          "breakdown": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BreakdownItem"
            }
          }
        }
      },
      "CalculateRequest": {
        "type": "object",
        "description": "Send exactly one of ratePerNight or nightlyRates. Omit optional fields to take their defaults; null is rejected, and so are unknown keys.",
        "additionalProperties": false,
        "required": [
          "areaId"
        ],
        "properties": {
          "areaId": {
            "type": "string",
            "minLength": 1,
            "description": "Area id from GET /v1/areas (e.g. tokyo, kyoto, onna). An unknown id returns 404 unknown_area with suggestions."
          },
          "ratePerNight": {
            "type": "integer",
            "minimum": 0,
            "maximum": 10000000,
            "description": "Taxable charge for one night in JPY, excluding consumption tax: per person — or per room/unit when the applied basis is per_unit — room only, service charge included. Applied to every night. Never send a tax-inclusive price."
          },
          "nightlyRates": {
            "type": "array",
            "minItems": 1,
            "maxItems": 365,
            "items": {
              "type": "integer",
              "minimum": 0,
              "maximum": 10000000
            },
            "description": "One rate per night in JPY, excluding consumption tax, in the same unit as ratePerNight: nightlyRates[0] is the night of the check-in date, nightlyRates[i] the night of date + i days; the number of nights is the array's length. Each night is taxed on its own, so send the real rates, not an average."
          },
          "date": {
            "type": "string",
            "format": "date",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
            "description": "Check-in date (the first night), YYYY-MM-DD. Accepted: 2020-01-01 to 2030-12-31. Default: today in Japan (JST)."
          },
          "nights": {
            "type": "integer",
            "minimum": 1,
            "maximum": 365,
            "description": "Number of nights. If you also send nightlyRates, it must equal the array's length. Default: 1, or the length of nightlyRates."
          },
          "guests": {
            "type": "integer",
            "minimum": 1,
            "maximum": 100,
            "default": 1,
            "description": "Number of guests. Multiplies the total when the applied basis is per_person."
          },
          "basis": {
            "type": "string",
            "enum": [
              "per_person",
              "per_unit"
            ],
            "description": "Pricing basis. Only read for variable areas (see Pricing basis); ignored everywhere else. Default: per_unit."
          }
        },
        "oneOf": [
          {
            "required": [
              "ratePerNight"
            ]
          },
          {
            "required": [
              "nightlyRates"
            ]
          }
        ]
      },
      "CalculateResponse": {
        "type": "object",
        "required": [
          "areaId",
          "areaName",
          "currency",
          "dateUsed",
          "basis",
          "perNightTax",
          "breakdown",
          "nights",
          "guests",
          "nightly",
          "stayTotal"
        ],
        "properties": {
          "areaId": {
            "type": "string"
          },
          "areaName": {
            "$ref": "#/components/schemas/LocalizedName"
          },
          "currency": {
            "type": "string",
            "enum": [
              "JPY"
            ]
          },
          "dateUsed": {
            "type": "string",
            "format": "date",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
          },
          "basis": {
            "type": "string",
            "enum": [
              "per_person",
              "per_unit"
            ]
          },
          "perNightTax": {
            "type": "integer"
          },
          "breakdown": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BreakdownItem"
            }
          },
          "nights": {
            "type": "integer"
          },
          "guests": {
            "type": "integer"
          },
          "nightly": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/StayNight"
            }
          },
          "stayTotal": {
            "type": "object",
            "required": [
              "perPerson",
              "total",
              "breakdown"
            ],
            "properties": {
              "perPerson": {
                "type": "integer"
              },
              "total": {
                "type": "integer"
              },
              "breakdown": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/BreakdownItem"
                }
              }
            }
          }
        }
      },
      "ResolveBatchRequest": {
        "type": "object",
        "description": "Up to 100 addresses, each starting with the prefecture. Unknown keys are rejected; the body may be up to 128 KB.",
        "additionalProperties": false,
        "required": [
          "addresses"
        ],
        "properties": {
          "addresses": {
            "type": "array",
            "minItems": 1,
            "maxItems": 100,
            "items": {
              "type": "string",
              "minLength": 1,
              "maxLength": 200
            },
            "description": "The addresses, each written as for GET's address."
          }
        }
      },
      "ResolveResult": {
        "type": "object",
        "required": [
          "input",
          "areaId",
          "match"
        ],
        "properties": {
          "input": {
            "type": "string"
          },
          "areaId": {
            "type": "string",
            "nullable": true,
            "description": "The area id to send to /v1/calculate; null for no_tax and unresolved."
          },
          "match": {
            "type": "string",
            "enum": [
              "municipal",
              "prefecture",
              "no_tax",
              "unresolved"
            ]
          },
          "areaName": {
            "$ref": "#/components/schemas/LocalizedName"
          },
          "prefecture": {
            "type": "string",
            "description": "The prefecture found, in Japanese. Absent when none was."
          },
          "municipality": {
            "type": "string",
            "nullable": true,
            "description": "The matched municipal area's name; null when no municipal area matched."
          },
          "message": {
            "type": "string",
            "description": "unresolved only: what the address is missing."
          }
        }
      },
      "ResolveBatch": {
        "type": "object",
        "required": [
          "results"
        ],
        "properties": {
          "results": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ResolveResult"
            }
          }
        }
      },
      "ChangelogEntry": {
        "type": "object",
        "required": [
          "seq",
          "releasedAt",
          "dataVersion",
          "areaIds",
          "type",
          "summary",
          "effectiveFrom",
          "sources"
        ],
        "properties": {
          "seq": {
            "type": "integer"
          },
          "releasedAt": {
            "type": "string",
            "format": "date",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
          },
          "dataVersion": {
            "type": "string"
          },
          "areaIds": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "type": {
            "type": "string",
            "enum": [
              "added",
              "revised",
              "corrected"
            ]
          },
          "supersedes": {
            "type": "integer"
          },
          "summary": {
            "$ref": "#/components/schemas/LocalizedName"
          },
          "effectiveFrom": {
            "type": "string",
            "format": "date",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
            "nullable": true
          },
          "sources": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        }
      },
      "ChangeList": {
        "type": "object",
        "required": [
          "changes"
        ],
        "properties": {
          "changes": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ChangelogEntry"
            }
          }
        }
      },
      "Health": {
        "type": "object",
        "required": [
          "status",
          "dataVersion",
          "db"
        ],
        "properties": {
          "status": {
            "type": "string",
            "enum": [
              "ok"
            ]
          },
          "dataVersion": {
            "type": "string"
          },
          "db": {
            "type": "string",
            "enum": [
              "ok"
            ]
          }
        }
      },
      "Error": {
        "type": "object",
        "required": [
          "error"
        ],
        "properties": {
          "error": {
            "type": "object",
            "required": [
              "code",
              "message"
            ],
            "properties": {
              "code": {
                "type": "string",
                "description": "Machine-readable error code — branch on it. New codes may be added. Current codes: invalid_json, validation_error, unauthorized, forbidden, unknown_area, payload_too_large, rate_limited, unhealthy."
              },
              "message": {
                "type": "string"
              },
              "suggestions": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              },
              "retryAfter": {
                "type": "integer"
              },
              "dataVersion": {
                "type": "string"
              }
            }
          }
        }
      }
    }
  }
}