{"openapi":"3.1.0","info":{"title":"torii — x402 Japan Data Factory","version":"1.0.0","description":"Pay-per-call HTTP APIs for Japanese public data, metered with x402 (HTTP 402 + PAYMENT-SIGNATURE). Send a plain GET to receive 402 with the price and payment requirements, then resend the request with a signed payment. Only 2xx responses are charged; 4xx and 5xx are free. Per-operation payment metadata is published under the `x-payment-info` extension."},"servers":[{"url":"https://torii-gateway-staging.ichis-lab.workers.dev"}],"paths":{"/v1/jp-biz-calendar/holidays":{"get":{"operationId":"jp-biz-calendar_holidays","summary":"List Japanese national holidays for a year","tags":["practical"],"parameters":[{"name":"year","in":"query","required":true,"description":"Calendar year (Gregorian). Accepted range is 1955-2100, but only years covered by the upstream Cabinet Office CSV can be answered; years outside the covered range return 404 and are not charged.","example":2026,"schema":{"type":"integer","minimum":1955,"maximum":2100}}],"responses":{"200":{"description":"Successful, paid (or free-tier) response.","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"A query parameter is missing, or its value does not satisfy the constraints declared above. Nothing is charged.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":"invalid_param","request_id":"8f1c2d3e4a5b6c7d-NRT"}}}},"402":{"description":"Payment required. Resend the same request with a PAYMENT-SIGNATURE header built from the PAYMENT-REQUIRED header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaymentRequired"},"example":{"error":"payment_required","docs":"https://torii-gateway-staging.ichis-lab.workers.dev/docs/jp-biz-calendar","price_usd":0.01,"free_tier":{"per_day":10,"unit":"ip_hash"}}}}},"404":{"description":"The request falls outside the range this dataset covers — for example a date or year the published data does not include. Nothing is charged.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":"out_of_range","request_id":"8f1c2d3e4a5b6c7d-NRT"}}}},"405":{"description":"Paid endpoints accept GET only; HEAD and OPTIONS are rejected as well. Nothing is charged.","headers":{"Allow":{"description":"Methods this endpoint accepts. Always `GET`.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":"method_not_allowed","request_id":"8f1c2d3e4a5b6c7d-NRT"}}}},"410":{"description":"This source has been retired and no longer answers. The body names the source, why it was retired, when, and its successor when one exists. Retired sources are dropped from the catalogue, this document included, but may still appear in cached copies for a few minutes. Nothing is charged.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GoneResponse"},"example":{"error":"gone","request_id":"8f1c2d3e4a5b6c7d-NRT","source_id":"example-dataset","reason":"consecutive_failures","retired_at":"2026-08-20T00:00:00.000Z","successor":null}}}},"429":{"description":"Too many requests from this client for this source within the last minute. The per-minute allowance of each source is published in the catalogue. Slow down and retry; nothing is charged.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":"rate_limited","request_id":"8f1c2d3e4a5b6c7d-NRT"}}}},"502":{"description":"The payment service could not be reached, so the payment could not be verified or settled. Nothing is charged; retry in a few moments.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SettlementError"},"example":{"error":"facilitator_unavailable"}}}},"503":{"description":"Temporarily unable to answer. `unavailable` means either the data for this source has not been fetched yet, or the source is paused by health monitoring (`reason` says why); both carry `Retry-After`. `payment_unavailable` means payment set-up failed and carries no `Retry-After`. Nothing is charged in any case.","headers":{"Retry-After":{"description":"Seconds to wait before retrying. Present on every `error: unavailable` response; absent for `error: payment_unavailable`.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":"unavailable","request_id":"8f1c2d3e4a5b6c7d-NRT"}}}}},"x-payment-info":{"price_usd":0.01,"price_display":"$0.01","scheme":"exact","network":"eip155:84532","pay_to":"0x1C4f8d631e25061EBD6a5079a8C32Ed3568cDf76","max_timeout_seconds":300,"free_tier":{"per_day":10,"unit":"ip_hash"}}}},"/v1/jp-biz-calendar/is-business-day":{"get":{"operationId":"jp-biz-calendar_is-business-day","summary":"Tell whether a given date is a Japanese business day","tags":["practical"],"parameters":[{"name":"date","in":"query","required":true,"description":"Date to check, in YYYY-MM-DD (ISO 8601 calendar date, interpreted in UTC). Dates outside the years covered by the upstream CSV return 404 and are not charged.","example":"2026-01-05","schema":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$"}}],"responses":{"200":{"description":"Successful, paid (or free-tier) response.","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"A query parameter is missing, or its value does not satisfy the constraints declared above. Nothing is charged.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":"invalid_param","request_id":"8f1c2d3e4a5b6c7d-NRT"}}}},"402":{"description":"Payment required. Resend the same request with a PAYMENT-SIGNATURE header built from the PAYMENT-REQUIRED header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaymentRequired"},"example":{"error":"payment_required","docs":"https://torii-gateway-staging.ichis-lab.workers.dev/docs/jp-biz-calendar","price_usd":0.01,"free_tier":{"per_day":10,"unit":"ip_hash"}}}}},"404":{"description":"The request falls outside the range this dataset covers — for example a date or year the published data does not include. Nothing is charged.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":"out_of_range","request_id":"8f1c2d3e4a5b6c7d-NRT"}}}},"405":{"description":"Paid endpoints accept GET only; HEAD and OPTIONS are rejected as well. Nothing is charged.","headers":{"Allow":{"description":"Methods this endpoint accepts. Always `GET`.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":"method_not_allowed","request_id":"8f1c2d3e4a5b6c7d-NRT"}}}},"410":{"description":"This source has been retired and no longer answers. The body names the source, why it was retired, when, and its successor when one exists. Retired sources are dropped from the catalogue, this document included, but may still appear in cached copies for a few minutes. Nothing is charged.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GoneResponse"},"example":{"error":"gone","request_id":"8f1c2d3e4a5b6c7d-NRT","source_id":"example-dataset","reason":"consecutive_failures","retired_at":"2026-08-20T00:00:00.000Z","successor":null}}}},"429":{"description":"Too many requests from this client for this source within the last minute. The per-minute allowance of each source is published in the catalogue. Slow down and retry; nothing is charged.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":"rate_limited","request_id":"8f1c2d3e4a5b6c7d-NRT"}}}},"502":{"description":"The payment service could not be reached, so the payment could not be verified or settled. Nothing is charged; retry in a few moments.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SettlementError"},"example":{"error":"facilitator_unavailable"}}}},"503":{"description":"Temporarily unable to answer. `unavailable` means either the data for this source has not been fetched yet, or the source is paused by health monitoring (`reason` says why); both carry `Retry-After`. `payment_unavailable` means payment set-up failed and carries no `Retry-After`. Nothing is charged in any case.","headers":{"Retry-After":{"description":"Seconds to wait before retrying. Present on every `error: unavailable` response; absent for `error: payment_unavailable`.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":"unavailable","request_id":"8f1c2d3e4a5b6c7d-NRT"}}}}},"x-payment-info":{"price_usd":0.01,"price_display":"$0.01","scheme":"exact","network":"eip155:84532","pay_to":"0x1C4f8d631e25061EBD6a5079a8C32Ed3568cDf76","max_timeout_seconds":300,"free_tier":{"per_day":10,"unit":"ip_hash"}}}},"/v1/jp-biz-calendar/add-business-days":{"get":{"operationId":"jp-biz-calendar_add-business-days","summary":"Add or subtract business days from a given date","tags":["practical"],"parameters":[{"name":"date","in":"query","required":true,"description":"Base date, in YYYY-MM-DD (ISO 8601 calendar date, interpreted in UTC). Results outside the years covered by the upstream CSV return 404 and are not charged.","example":"2026-01-05","schema":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$"}},{"name":"n","in":"query","required":true,"description":"Business days to add; negative goes backwards. 0 returns the base date if it is a business day, else the next one (never the previous). From a non-business base date, n=1 lands on the same day as n=0.","example":5,"schema":{"type":"integer","minimum":-3650,"maximum":3650}}],"responses":{"200":{"description":"Successful, paid (or free-tier) response.","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"A query parameter is missing, or its value does not satisfy the constraints declared above. Nothing is charged.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":"invalid_param","request_id":"8f1c2d3e4a5b6c7d-NRT"}}}},"402":{"description":"Payment required. Resend the same request with a PAYMENT-SIGNATURE header built from the PAYMENT-REQUIRED header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaymentRequired"},"example":{"error":"payment_required","docs":"https://torii-gateway-staging.ichis-lab.workers.dev/docs/jp-biz-calendar","price_usd":0.01,"free_tier":{"per_day":10,"unit":"ip_hash"}}}}},"404":{"description":"The request falls outside the range this dataset covers — for example a date or year the published data does not include. Nothing is charged.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":"out_of_range","request_id":"8f1c2d3e4a5b6c7d-NRT"}}}},"405":{"description":"Paid endpoints accept GET only; HEAD and OPTIONS are rejected as well. Nothing is charged.","headers":{"Allow":{"description":"Methods this endpoint accepts. Always `GET`.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":"method_not_allowed","request_id":"8f1c2d3e4a5b6c7d-NRT"}}}},"410":{"description":"This source has been retired and no longer answers. The body names the source, why it was retired, when, and its successor when one exists. Retired sources are dropped from the catalogue, this document included, but may still appear in cached copies for a few minutes. Nothing is charged.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GoneResponse"},"example":{"error":"gone","request_id":"8f1c2d3e4a5b6c7d-NRT","source_id":"example-dataset","reason":"consecutive_failures","retired_at":"2026-08-20T00:00:00.000Z","successor":null}}}},"429":{"description":"Too many requests from this client for this source within the last minute. The per-minute allowance of each source is published in the catalogue. Slow down and retry; nothing is charged.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":"rate_limited","request_id":"8f1c2d3e4a5b6c7d-NRT"}}}},"502":{"description":"The payment service could not be reached, so the payment could not be verified or settled. Nothing is charged; retry in a few moments.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SettlementError"},"example":{"error":"facilitator_unavailable"}}}},"503":{"description":"Temporarily unable to answer. `unavailable` means either the data for this source has not been fetched yet, or the source is paused by health monitoring (`reason` says why); both carry `Retry-After`. `payment_unavailable` means payment set-up failed and carries no `Retry-After`. Nothing is charged in any case.","headers":{"Retry-After":{"description":"Seconds to wait before retrying. Present on every `error: unavailable` response; absent for `error: payment_unavailable`.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":"unavailable","request_id":"8f1c2d3e4a5b6c7d-NRT"}}}}},"x-payment-info":{"price_usd":0.01,"price_display":"$0.01","scheme":"exact","network":"eip155:84532","pay_to":"0x1C4f8d631e25061EBD6a5079a8C32Ed3568cDf76","max_timeout_seconds":300,"free_tier":{"per_day":10,"unit":"ip_hash"}}}},"/v1/jp-biz-calendar/wareki":{"get":{"operationId":"jp-biz-calendar_wareki","summary":"Convert a Gregorian date to the Japanese imperial era (wareki)","tags":["practical"],"parameters":[{"name":"date","in":"query","required":true,"description":"Date to convert, in YYYY-MM-DD (UTC). Must be between 1873-01-01 (when Japan adopted the Gregorian calendar) and 2100-12-31; dates outside that range return 400, uncharged.","example":"2026-01-05","schema":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$"}}],"responses":{"200":{"description":"Successful, paid (or free-tier) response.","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"A query parameter is missing, or its value does not satisfy the constraints declared above. Nothing is charged.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":"invalid_param","request_id":"8f1c2d3e4a5b6c7d-NRT"}}}},"402":{"description":"Payment required. Resend the same request with a PAYMENT-SIGNATURE header built from the PAYMENT-REQUIRED header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaymentRequired"},"example":{"error":"payment_required","docs":"https://torii-gateway-staging.ichis-lab.workers.dev/docs/jp-biz-calendar","price_usd":0.01,"free_tier":{"per_day":10,"unit":"ip_hash"}}}}},"404":{"description":"The request falls outside the range this dataset covers — for example a date or year the published data does not include. Nothing is charged.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":"out_of_range","request_id":"8f1c2d3e4a5b6c7d-NRT"}}}},"405":{"description":"Paid endpoints accept GET only; HEAD and OPTIONS are rejected as well. Nothing is charged.","headers":{"Allow":{"description":"Methods this endpoint accepts. Always `GET`.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":"method_not_allowed","request_id":"8f1c2d3e4a5b6c7d-NRT"}}}},"410":{"description":"This source has been retired and no longer answers. The body names the source, why it was retired, when, and its successor when one exists. Retired sources are dropped from the catalogue, this document included, but may still appear in cached copies for a few minutes. Nothing is charged.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GoneResponse"},"example":{"error":"gone","request_id":"8f1c2d3e4a5b6c7d-NRT","source_id":"example-dataset","reason":"consecutive_failures","retired_at":"2026-08-20T00:00:00.000Z","successor":null}}}},"429":{"description":"Too many requests from this client for this source within the last minute. The per-minute allowance of each source is published in the catalogue. Slow down and retry; nothing is charged.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":"rate_limited","request_id":"8f1c2d3e4a5b6c7d-NRT"}}}},"502":{"description":"The payment service could not be reached, so the payment could not be verified or settled. Nothing is charged; retry in a few moments.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SettlementError"},"example":{"error":"facilitator_unavailable"}}}},"503":{"description":"Temporarily unable to answer. `unavailable` means either the data for this source has not been fetched yet, or the source is paused by health monitoring (`reason` says why); both carry `Retry-After`. `payment_unavailable` means payment set-up failed and carries no `Retry-After`. Nothing is charged in any case.","headers":{"Retry-After":{"description":"Seconds to wait before retrying. Present on every `error: unavailable` response; absent for `error: payment_unavailable`.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":"unavailable","request_id":"8f1c2d3e4a5b6c7d-NRT"}}}}},"x-payment-info":{"price_usd":0.01,"price_display":"$0.01","scheme":"exact","network":"eip155:84532","pay_to":"0x1C4f8d631e25061EBD6a5079a8C32Ed3568cDf76","max_timeout_seconds":300,"free_tier":{"per_day":10,"unit":"ip_hash"}}}}},"components":{"schemas":{"ErrorResponse":{"type":"object","description":"Error envelope returned by every 4xx / 5xx response.","properties":{"error":{"type":"string","description":"Machine-readable error code."},"request_id":{"type":"string","description":"Correlation id echoed in the server logs (Cloudflare Ray ID when available)."},"reason":{"type":["string","null"],"description":"Why the source is unavailable (present on 503 from source health monitoring; null when the source is paused manually)."}},"required":["error","request_id"],"additionalProperties":false},"FreeTier":{"type":["object","null"],"description":"Free calls granted per day, or null when the source has no free tier.","properties":{"per_day":{"type":"integer"},"unit":{"type":"string","description":"Counting unit of the free tier (e.g. ip_hash)."}},"required":["per_day","unit"],"additionalProperties":false},"Successor":{"type":["object","null"],"description":"The source that replaces a retired one, or null when there is none.","properties":{"id":{"type":"string","description":"Id of the successor source."},"url":{"type":"string","format":"uri","description":"Human-readable page of the successor."}},"required":["id","url"],"additionalProperties":false},"GoneResponse":{"type":"object","description":"Body returned when a source has been retired.","properties":{"error":{"type":"string","const":"gone"},"request_id":{"type":"string","description":"Correlation id echoed in the server logs (Cloudflare Ray ID when available)."},"source_id":{"type":"string","description":"Id of the retired source."},"reason":{"type":["string","null"],"description":"Why the source was retired (null when it was retired manually rather than by health monitoring)."},"retired_at":{"type":["string","null"],"format":"date-time","description":"When the source was retired (null when it was retired manually)."},"successor":{"$ref":"#/components/schemas/Successor"}},"required":["error","request_id","source_id","reason","retired_at","successor"],"additionalProperties":false},"SettlementError":{"type":"object","description":"Body returned when the payment could not be verified or settled.","properties":{"error":{"type":"string","const":"facilitator_unavailable"}},"required":["error"],"additionalProperties":false},"PaymentRequired":{"type":"object","description":"Body returned together with the PAYMENT-REQUIRED header on 402.","properties":{"error":{"type":"string","const":"payment_required"},"docs":{"type":"string","format":"uri"},"price_usd":{"type":"number","description":"Effective price of one successful call, in USD."},"free_tier":{"$ref":"#/components/schemas/FreeTier"}},"required":["error","docs","price_usd","free_tier"],"additionalProperties":false}}}}