{"openapi":"3.1.0","info":{"title":"asiaref — Asian government reference data","version":"1.0.0","description":"Authoritative Asian government reference values as clean JSON: central-bank policy rates, VAT rates, national minimum wages and public holidays for United Arab Emirates (ae), Bangladesh (bd), Bahrain (bh), China (cn), Hong Kong (hk), Indonesia (id), Israel (il), India (in), Iraq (iq), Jordan (jo), Japan (jp), South Korea (kr), Kuwait (kw), Kazakhstan (kz), Sri Lanka (lk), Malaysia (my), Nepal (np), Oman (om), Philippines (ph), Pakistan (pk), Qatar (qa), Saudi Arabia (sa), Singapore (sg), Thailand (th), Türkiye (tr), Taiwan (tw), Uzbekistan (uz), Vietnam (vn). Free tier: public holidays for every country, plus catalog, the change feed (GET /v1/changes), and the re-verification calendar (GET /v1/calendar). Paid access per-call via x402 (USDC) or prepaid card packs from $10 - no signup needed for x402, no subscription ever. Every value carries a citation to its official primary source (government gazette or central-bank statement), an effective date, a last-confirmed date and a staleness flag. Retention: GET /v1/changes (free; past moves and freshness), GET /v1/calendar (free; reverify_by is derived from last_confirmed + update_cycle_days; next_effective_known only when current.effective_to is set; status unknown omits any next date; notes are never parsed; not an MPC, budget, or wage-review date), and POST /alerts (register free) are how a paying agent watches a value after the first paid call. Do not re-buy a series to find out whether it moved. GET /v1/calendar is not a promised future gazette.","x-guidance":"GET /v1/{country}/{series} returns the current value of a reference series — e.g. GET /v1/ae/policy-rate. Countries: ae, bd, bh, cn, hk, id, il, in, iq, jo, jp, kr, kw, kz, lk, my, np, om, ph, pk, qa, sa, sg, th, tr, tw, uz, vn. Series: policy-rate, vat, vat-registration-threshold, minimum-wage, public-holidays, cpi, corporate-tax, withholding-tax, statutory-interest, income-tax, social-contributions, fx-reference. Append /history for past values. GET /v1/all returns every series for every country in one call. GET /catalog (free) lists all available series with freshness metadata, each with the official source it is cited to. If you are an x402/API seller making a cross-border digital sale, POST /v1/vat/determine tells you which jurisdiction's VAT applies, who accounts for it, and the registration trigger — cited to the statute (EU, UK, South Africa), and it handles the wallet-only unidentified-buyer case. Payment is x402 (USDC on Base) per call; no signup or API keys needed. Retention: GET /v1/changes (free; past moves and freshness), GET /v1/calendar (free; reverify_by is derived from last_confirmed + update_cycle_days; next_effective_known only when current.effective_to is set; status unknown omits any next date; notes are never parsed; not an MPC, budget, or wage-review date), and POST /alerts (register free) are how a paying agent watches a value after the first paid call. Do not re-buy a series to find out whether it moved. GET /v1/calendar is not a promised future gazette.","contact":{"name":"afriref API support","email":"api@3l-groupconsulting.co.za","url":"https://asiaref.dev/pricing"},"termsOfService":"https://asiaref.dev/terms"},"servers":[{"url":"https://asiaref.dev"}],"tags":[{"name":"Free","description":"No payment and no key. Public holidays for every country, the catalog, the change/freshness feed, the re-verification calendar (GET /v1/calendar), and the provenance ledger."},{"name":"Reference data","description":"Current and historical values of a government reference series, each cited to the official instrument that set it."},{"name":"Answers","description":"Computed answers over the reference data - VAT breakdowns, wage checks, working days, income tax, statutory interest (Actual/365 simple on the cited statutory-interest series), employment cost (AE only), settlement dates - returned with the workings and the citations behind them. Set receipt:true on a paid answer POST to embed an optional signed answer receipt (kind answer_receipt) in the HTTP 200; no extra charge. That receipt is not a series certified extract."},{"name":"Discovery","description":"Machine-readable descriptions of what is served and what it costs."},{"name":"Alerts","description":"Retention. HMAC-signed webhooks, the free /v1/changes feed (past moves and freshness), and the free /v1/calendar feed (derived reverify window; next_effective_known only from current.effective_to; not a future gazette). Bind after the first paid series or answers call so a gazette change does not silently stale a cached value. Registering an alert is free; deliveries meter after a three-event trial. GET /v1/calendar is unmetered; a 402 on it is a gate bug."},{"name":"x402 sellers","description":"Endpoints aimed at other x402 sellers, notably cross-border VAT determination for digital sales."},{"name":"Certified","description":"Series certified extracts: one value together with its citation, the fingerprint of the archived source document, and how it was verified, at GET /v1/certified/{country}/{series}. Answer receipts (kind answer_receipt) are a different artifact — they ride on paid answer POSTs when receipt:true, share the public key, and are not this extract."}],"security":[{"x402Payment":[]},{"apiKey":[]}],"x-example-urls":["https://asiaref.dev/catalog","https://asiaref.dev/v1/calendar","https://asiaref.dev/public/ae/holidays","https://asiaref.dev/v1/ae/policy-rate","https://asiaref.dev/v1/ae/policy-rate/history","https://asiaref.dev/v1/all"],"paths":{"/catalog":{"get":{"operationId":"getCatalog","summary":"Catalog of all countries and series with freshness metadata (free)","tags":["Free"],"security":[],"parameters":[{"name":"confidence","in":"query","required":false,"schema":{"type":"string"},"example":"primary","description":"Filter to series at the given verification confidence (comma-separated). `primary` = no verification limitation recorded — the absence of a known problem, not a fresh re-verification. `secondary` = corroborated but the primary instrument was not read, usually because the publishing host blocks automated access. `attested` = no primary source is publicly available to anyone. `derived` = computed from another series. Unknown levels return 400 with the valid set."}],"responses":{"200":{"description":"Catalog. Every series carries `confidence`, and `confidence_note` where it is not primary.","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"Unknown confidence level, returned with the valid set and what each means"}}}},"/v1/{country}/public-holidays":{"get":{"operationId":"getPublicHolidaysV1","summary":"Public holiday calendar for a country, with sub-national calendars (free)","description":"The canonical holidays endpoint, and the one the catalog and llms.txt advertise. Returns the NATIONAL days in `value`, and — where a country has regions that set their own days — every region inline under `subdivisions`, keyed by ISO 3166-2 with the scheme named in `subdivisions_standard`. Each region's list contains only that region's ADDITIONAL days, so a full regional calendar is `value` plus that region's entries, not the region's entries alone. This endpoint does NOT take a `subdivision` parameter and ignores one if sent; to have a regional calendar applied for you, POST /v1/answers/working-days with `subdivision`. Some entries carry `date: null` with a `pending_window` where a holiday is statutory but its date is not yet gazetted — we publish the placeholder rather than invent a date — and entries may carry a `note` describing how that day behaves in that specific year, while `name` stays stable across years and is safe to match on.","tags":["Free"],"security":[],"parameters":[{"name":"country","in":"path","required":true,"schema":{"type":"string","enum":["ae","bd","bh","cn","hk","id","il","in","iq","jo","jp","kr","kw","kz","lk","my","np","om","ph","pk","qa","sa","sg","th","tr","tw","uz","vn"],"example":"ae"},"example":"ae"}],"responses":{"200":{"description":"Holiday calendar, plus `subdivisions` where the country has regions","content":{"application/json":{"schema":{"type":"object","properties":{"country":{"type":"string","description":"ISO 3166-1 alpha-2 country code"},"series":{"type":"string"},"value":{"description":"Number for rates/wages; array of {date,name} for holiday calendars"},"unit":{"type":"string"},"effective_from":{"type":["string","null"],"format":"date"},"effective_from_basis":{"type":"string","enum":["restatement"],"description":"Optional. Absent: effective_from is the date the value became the law (a genuine change point). 'restatement': effective_from is the date the value's CURRENT LEGAL BASIS took effect (a new tax code, an annual finance law) while the value itself is older and its true origin is not primary-verifiable — a verified floor, not a change. Do not read a restatement row as the value having changed on that date."},"last_confirmed":{"type":"string","format":"date","description":"When this value was last verified against the official source"},"source":{"type":"object","properties":{"name":{"type":"string"},"url":{"type":"string","format":"uri"}},"required":["name","url"]},"stale":{"type":"boolean","description":"True when past the expected update cycle — treat with caution"},"notes":{"type":"string"},"effective_rate":{"type":"number","description":"Optional. Combined effective rate where statutory levies stack on top of the standard rate (e.g. Ghana VAT 15% + NHIL 2.5% + GETFund 2.5% = 20%). Present only where it differs from value."},"components":{"type":"array","description":"Optional. Breakdown of a composite rate into its named statutory components (present only where applicable, e.g. Ghana VAT).","items":{"type":"object","properties":{"name":{"type":"string"},"rate":{"type":"number"}},"required":["name","rate"]}}},"required":["country","series","value","effective_from","last_confirmed","source","stale"]}}}},"404":{"description":"Unknown country"}}}},"/public/{country}/holidays":{"get":{"operationId":"getPublicHolidays","deprecated":true,"summary":"Public holiday calendar for a country (free) — deprecated legacy alias","description":"Serves the same payload as GET /v1/{country}/public-holidays, which is canonical. Kept working because it is published and in use — no removal is planned — but responses carry a Deprecation header and a Link rel=successor-version pointing at the /v1 form; use that in new clients.","tags":["Free"],"security":[],"parameters":[{"name":"country","in":"path","required":true,"schema":{"type":"string","enum":["ae","bd","bh","cn","hk","id","il","in","iq","jo","jp","kr","kw","kz","lk","my","np","om","ph","pk","qa","sa","sg","th","tr","tw","uz","vn"],"example":"ae"},"example":"ae"}],"responses":{"200":{"description":"Holiday calendar","content":{"application/json":{"schema":{"type":"object","properties":{"country":{"type":"string","description":"ISO 3166-1 alpha-2 country code"},"series":{"type":"string"},"value":{"description":"Number for rates/wages; array of {date,name} for holiday calendars"},"unit":{"type":"string"},"effective_from":{"type":["string","null"],"format":"date"},"effective_from_basis":{"type":"string","enum":["restatement"],"description":"Optional. Absent: effective_from is the date the value became the law (a genuine change point). 'restatement': effective_from is the date the value's CURRENT LEGAL BASIS took effect (a new tax code, an annual finance law) while the value itself is older and its true origin is not primary-verifiable — a verified floor, not a change. Do not read a restatement row as the value having changed on that date."},"last_confirmed":{"type":"string","format":"date","description":"When this value was last verified against the official source"},"source":{"type":"object","properties":{"name":{"type":"string"},"url":{"type":"string","format":"uri"}},"required":["name","url"]},"stale":{"type":"boolean","description":"True when past the expected update cycle — treat with caution"},"notes":{"type":"string"},"effective_rate":{"type":"number","description":"Optional. Combined effective rate where statutory levies stack on top of the standard rate (e.g. Ghana VAT 15% + NHIL 2.5% + GETFund 2.5% = 20%). Present only where it differs from value."},"components":{"type":"array","description":"Optional. Breakdown of a composite rate into its named statutory components (present only where applicable, e.g. Ghana VAT).","items":{"type":"object","properties":{"name":{"type":"string"},"rate":{"type":"number"}},"required":["name","rate"]}}},"required":["country","series","value","effective_from","last_confirmed","source","stale"]}}}},"404":{"description":"Unknown country"}}}},"/provenance":{"get":{"operationId":"getProvenance","summary":"Source-provenance snapshot coverage (free)","description":"Every value cites an official source; this is the evidence behind those citations. Each cited document is fetched, fingerprinted with a sha256 over the exact bytes, and re-checked, so a consumer can see when we verified against it and whether it has changed since. Distinguishes `gone` (404/410) from `blocked_to_automation` (the host refuses bots but a person can still open it) — we do not report a live source as dead. The fingerprint is published, not the mirrored document.","tags":["Free"],"security":[],"responses":{"200":{"description":"Coverage summary and status definitions"},"503":{"description":"Snapshot not yet available"}}}},"/provenance/{country}/{series}":{"get":{"operationId":"getProvenanceForSeries","summary":"Cited sources behind one series, with fingerprints (free)","tags":["Free"],"security":[],"parameters":[{"name":"country","in":"path","required":true,"schema":{"type":"string","enum":["ae","bd","bh","cn","hk","id","il","in","iq","jo","jp","kr","kw","kz","lk","my","np","om","ph","pk","qa","sa","sg","th","tr","tw","uz","vn"],"example":"ae"},"example":"ae"},{"name":"series","in":"path","required":true,"schema":{"type":"string"},"example":"vat"}],"responses":{"200":{"description":"Per-source sha256, size, content type, first-verified, last-changed and current reachability"},"404":{"description":"No cited sources recorded for this country/series"},"503":{"description":"Snapshot not yet available"}}}},"/v1/{country}/{series}":{"get":{"operationId":"getSeries","summary":"Current value of a reference series, with official source citation","description":"Returns the current value. Pass `as_at=YYYY-MM-DD` for the value that was IN FORCE on that date instead — what back-dated payroll and prior-year filings actually need. A point-in-time response carries `as_at`, `point_in_time: true` and `superseded_on` so it cannot be mistaken for the live value, and it REFUSES rather than falling back: a date before the earliest value we hold, or after one lapsed with no successor, returns a free 422 naming the earliest date held. Returning today's rate for a 2023 question would be the wrong number in the right shape.","tags":["Reference data"],"x-payment-info":{"price":{"mode":"fixed","currency":"USD","amount":"0.005000"},"protocols":[{"x402":{}}]},"security":[{"x402Payment":[]},{"apiKey":[]}],"parameters":[{"name":"country","in":"path","required":true,"schema":{"type":"string","enum":["ae","bd","bh","cn","hk","id","il","in","iq","jo","jp","kr","kw","kz","lk","my","np","om","ph","pk","qa","sa","sg","th","tr","tw","uz","vn"],"example":"ae"},"example":"ae","description":"Country code"},{"name":"series","in":"path","required":true,"schema":{"type":"string","enum":["policy-rate","vat","vat-registration-threshold","minimum-wage","public-holidays","cpi","corporate-tax","withholding-tax","statutory-interest","income-tax","social-contributions","fx-reference"],"example":"policy-rate"},"example":"policy-rate","description":"Series id"}],"responses":{"200":{"description":"Current value","content":{"application/json":{"schema":{"type":"object","properties":{"country":{"type":"string","description":"ISO 3166-1 alpha-2 country code"},"series":{"type":"string"},"value":{"description":"Number for rates/wages; array of {date,name} for holiday calendars"},"unit":{"type":"string"},"effective_from":{"type":["string","null"],"format":"date"},"effective_from_basis":{"type":"string","enum":["restatement"],"description":"Optional. Absent: effective_from is the date the value became the law (a genuine change point). 'restatement': effective_from is the date the value's CURRENT LEGAL BASIS took effect (a new tax code, an annual finance law) while the value itself is older and its true origin is not primary-verifiable — a verified floor, not a change. Do not read a restatement row as the value having changed on that date."},"last_confirmed":{"type":"string","format":"date","description":"When this value was last verified against the official source"},"source":{"type":"object","properties":{"name":{"type":"string"},"url":{"type":"string","format":"uri"}},"required":["name","url"]},"stale":{"type":"boolean","description":"True when past the expected update cycle — treat with caution"},"notes":{"type":"string"},"effective_rate":{"type":"number","description":"Optional. Combined effective rate where statutory levies stack on top of the standard rate (e.g. Ghana VAT 15% + NHIL 2.5% + GETFund 2.5% = 20%). Present only where it differs from value."},"components":{"type":"array","description":"Optional. Breakdown of a composite rate into its named statutory components (present only where applicable, e.g. Ghana VAT).","items":{"type":"object","properties":{"name":{"type":"string"},"rate":{"type":"number"}},"required":["name","rate"]}}},"required":["country","series","value","effective_from","last_confirmed","source","stale"]},"example":{"country":"GH","series":"policy-rate","value":14,"unit":"percent","effective_from":"2026-07-24","last_confirmed":"2026-08-05","source":{"name":"Bank of Ghana — Monetary Policy Committee press release, 131st MPC meeting, July 2026","url":"https://www.bog.gov.gh/monetary-policy/mpc-press-releases/"},"notes":"Cut of 100bps at the 131st MPC meeting.","confidence":"primary","stale":false}}}},"402":{"description":"Payment Required — the body quotes the price and payment details; retry with the signed payment in X-PAYMENT, or send a prepaid X-API-Key instead","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaymentRequired"},"example":{"x402Version":2,"error":"Payment required","accepts":[{"scheme":"exact","network":"base","maxAmountRequired":"5000","asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","payTo":"0x…","resource":"/v1/gh/policy-rate","description":"Current value of a reference series"}]}}}},"404":{"description":"Unknown country or series"}}}},"/v1/certified/{country}/{series}":{"get":{"operationId":"getCertifiedExtract","summary":"Certified extract: the value plus its full evidence chain, Ed25519-signed","description":"A signed, dated evidence artifact for one series value - for filing, audit or dispute. Carries the value, its citation, the sha256 fingerprint of the cited source document AS ARCHIVED by this service, how and when the value was last confirmed (byte-identity of the source, mechanical relocation of the value inside it, or an agent reading the source), the located-in-document evidence where held, and the extract's own limitations. Signed with Ed25519 over canonical JSON; verify with the free public key at https://asiaref.dev/certified/public-key. REFUSES (422, uncharged) when the cited source is currently blocked to automation, broken, or not yet fingerprinted: a certificate backed by evidence we do not hold would be worth less than none. What it certifies is that the cited document supported the value on the stated date - NOT that no newer instrument exists elsewhere. This endpoint is the series certified extract only. It is not an answer receipt: kind answer_receipt is embedded in a paid POST /v1/answers/* HTTP 200 when that body sets receipt:true, is included in the answer's existing price, and is a different artifact verified with the same public key.","tags":["Certified"],"x-payment-info":{"price":{"mode":"fixed","currency":"USD","amount":"0.250000"},"protocols":[{"x402":{}}]},"security":[{"x402Payment":[]},{"apiKey":[]}],"parameters":[{"name":"country","in":"path","required":true,"schema":{"type":"string","enum":["ae","bd","bh","cn","hk","id","il","in","iq","jo","jp","kr","kw","kz","lk","my","np","om","ph","pk","qa","sa","sg","th","tr","tw","uz","vn"],"example":"ae"},"example":"ae","description":"Country code"},{"name":"series","in":"path","required":true,"schema":{"type":"string","enum":["policy-rate","vat","vat-registration-threshold","minimum-wage","public-holidays","cpi","corporate-tax","withholding-tax","statutory-interest","income-tax","social-contributions","fx-reference"],"example":"policy-rate"},"example":"policy-rate","description":"Series id"}],"responses":{"200":{"description":"Signed certified extract","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CertifiedExtract"}}}},"402":{"$ref":"#/components/responses/PaymentRequired"},"404":{"description":"Unknown country or series"},"422":{"$ref":"#/components/responses/Refusal"}}}},"/certified/public-key":{"get":{"operationId":"getCertifiedPublicKey","summary":"Public key and canonicalization rule for a certified extract or an answer receipt (free)","description":"Free. No payment. One Ed25519 key verifies both series certified extracts (GET /v1/certified/{country}/{series}) and answer receipts (kind answer_receipt, embedded in a paid POST /v1/answers/* HTTP 200 when the body sets receipt:true). Same key_id and the same canonical JSON rule (keys sorted recursively, no whitespace). An answer receipt is not a series certified extract.","tags":["Free"],"security":[],"responses":{"200":{"description":"Ed25519 public key (PEM), key id, canonicalization rule and verify snippets. Covers certified extracts and answer receipts; no second key."},"503":{"description":"Signing key not provisioned"}}}},"/v1/{country}/{series}/history":{"get":{"operationId":"getSeriesHistory","summary":"Historical values of a series, filterable by date range","tags":["Reference data"],"x-payment-info":{"price":{"mode":"fixed","currency":"USD","amount":"0.005000"},"protocols":[{"x402":{}}]},"security":[{"x402Payment":[]},{"apiKey":[]}],"parameters":[{"name":"country","in":"path","required":true,"schema":{"type":"string","enum":["ae","bd","bh","cn","hk","id","il","in","iq","jo","jp","kr","kw","kz","lk","my","np","om","ph","pk","qa","sa","sg","th","tr","tw","uz","vn"],"example":"ae"},"example":"ae"},{"name":"series","in":"path","required":true,"schema":{"type":"string","enum":["policy-rate","vat","vat-registration-threshold","minimum-wage","public-holidays","cpi","corporate-tax","withholding-tax","statutory-interest","income-tax","social-contributions","fx-reference"],"example":"policy-rate"},"example":"policy-rate"},{"name":"from","in":"query","required":false,"schema":{"type":"string","format":"date"}},{"name":"to","in":"query","required":false,"schema":{"type":"string","format":"date"}}],"responses":{"200":{"description":"Historical entries"},"402":{"description":"Payment Required"},"404":{"description":"Unknown country or series"}}}},"/v1/all":{"get":{"operationId":"getAllSeries","summary":"Snapshot of every series for every country","tags":["Reference data"],"x-payment-info":{"price":{"mode":"fixed","currency":"USD","amount":"0.020000"},"protocols":[{"x402":{}}]},"security":[{"x402Payment":[]},{"apiKey":[]}],"responses":{"200":{"description":"Full snapshot"},"402":{"description":"Payment Required"}}}},"/v1/changes":{"get":{"operationId":"changes","summary":"FREE change + freshness feed — poll this after a paid call instead of re-buying the series","description":"Unmetered and unpriced. Retention surface: after the first paid get_series / answers call, poll this to learn whether the gazette moved, rather than paying $0.005 again to see the same number. Returns every series whose current value took effect on or after `since` (optional; defaults to the last 30 days), newest first, each with the date we last re-confirmed it and whether it is past its verification window. Also returns a freshness summary for the whole served dataset: how many series were re-verified within 1, 7, 30 and 90 days, how many are past their window, and which single series has gone longest without a check. Published free deliberately — freshness is checkable or it is marketing. For push instead of poll, POST /alerts (register free). For a signed freeze of the current value, GET /v1/certified/{country}/{series} ($0.25).","tags":["Discovery","Alerts"],"security":[],"parameters":[{"name":"since","in":"query","required":false,"schema":{"type":"string","format":"date"},"description":"Only return series whose current value took effect on or after this date. Defaults to 30 days ago."}],"responses":{"200":{"description":"Changed series (newest first) plus a dataset-wide freshness summary"},"400":{"description":"since was not a real calendar date"}}}},"/v1/calendar":{"get":{"operationId":"calendar","summary":"FREE re-verification calendar — derived window plus an optional recorded effective_to end","description":"Unmetered and unpriced. security is empty: no x402 challenge and no API key. GET /v1/changes is the past (what moved, plus freshness). GET /v1/calendar is a forward-looking derive from fields already stored on the current value, continent-scoped like /v1/changes. reverify_by is the UTC calendar date of last_confirmed plus update_cycle_days — the same window that sets stale — and it is this service's re-verification cadence, not a government announcement date. next_effective_known is present only when current.effective_to is a non-empty string; next_effective_basis is then \"effective_to\". That date is the recorded end of the currently served value (a coverage or vintage end, such as a public-holidays year window or a CPI month). It is not a promised future gazette and not an MPC, budget, or wage-review date. When effective_to is absent, status is \"unknown\" and next_effective_known and next_effective_basis are omitted; the series is still listed with last_confirmed, stale, update_cycle_days, and reverify_by. Unknown is still free. Notes, determined, and history rows are never parsed for a next date. Sort is country ascending, then series ascending. A 402 on this route is a gate bug — do not pay. For push when a served value actually moves, POST /alerts.","tags":["Discovery","Alerts"],"security":[],"parameters":[{"name":"country","in":"query","required":false,"schema":{"type":"string"},"description":"Optional ISO 3166-1 alpha-2, case-insensitive. Must be in this brand's continent catalog. Not two letters → HTTP 400, free. Not in this brand → HTTP 404, free."},{"name":"series","in":"query","required":false,"schema":{"type":"string"},"description":"Optional series id (for example policy-rate). A valid country (or no country) with no match returns HTTP 200 and an empty entries list. A malformed series query is HTTP 400, free."}],"responses":{"200":{"description":"Free and unmetered. price_note says so. Entries may mix status known and status unknown. Known copies current.effective_to into next_effective_known. Unknown omits next_effective_known and next_effective_basis. No payment headers.","content":{"application/json":{"schema":{"type":"object","required":["as_of","brand","filters","count","entries","note","price_note","disclaimer"],"properties":{"as_of":{"type":"string","format":"date"},"brand":{"type":"string"},"filters":{"type":"object","properties":{"country":{"type":["string","null"]},"series":{"type":["string","null"]}}},"count":{"type":"integer","minimum":0},"entries":{"type":"array","description":"Sorted by country ascending, then series ascending.","items":{"type":"object","required":["country","series","name","last_confirmed","stale","update_cycle_days","reverify_by","status"],"properties":{"country":{"type":"string","description":"ISO 3166-1 alpha-2"},"series":{"type":"string"},"name":{"type":"string"},"last_confirmed":{"type":"string","format":"date"},"stale":{"type":"boolean","description":"Same rule as elsewhere: age in days since last_confirmed is greater than update_cycle_days."},"update_cycle_days":{"type":"integer"},"reverify_by":{"type":"string","format":"date","description":"UTC calendar date of last_confirmed plus update_cycle_days. Service re-verification cadence, not a government announcement date."},"status":{"type":"string","enum":["known","unknown"]},"next_effective_known":{"type":"string","description":"Present only when status is known. Equals current.effective_to. Recorded end of the served value, not an invented MPC, budget, or wage-review date."},"next_effective_basis":{"type":"string","enum":["effective_to"],"description":"Present only when status is known."}}}},"note":{"type":"string","description":"States that reverify_by is derived, that next_effective_known comes only from current.effective_to, and that notes prose is never parsed."},"price_note":{"type":"string","description":"States that this feed is free and unmetered, and points at GET /v1/changes for past moves. Series values remain paid at GET /v1/{country}/{series}."},"disclaimer":{"type":"string"}}}}}},"400":{"description":"Free. Malformed country (not two letters) or malformed series query. No payment."},"404":{"description":"Free. Country is not in this brand's continent catalog. No payment."}}}},"/v1/answers/wage-check":{"post":{"operationId":"answerWageCheck","summary":"Minimum-wage compliance verdict: is this salary at/above the statutory floor?","tags":["Answers"],"x-payment-info":{"price":{"mode":"fixed","currency":"USD","amount":"0.050000"},"protocols":[{"x402":{}}]},"security":[{"x402Payment":[]},{"apiKey":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"country":{"type":"string","enum":["ae","bd","bh","cn","hk","id","il","in","iq","jo","jp","kr","kw","kz","lk","my","np","om","ph","pk","qa","sa","sg","th","tr","tw","uz","vn"]},"amount":{"type":"number","description":"Wage in the country's own currency"},"period":{"type":"string","enum":["month","day","hour","week"],"description":"Must match the statutory floor's period — cross-period conversion is never guessed"},"receipt":{"type":"boolean","default":false,"description":"Optional. Default false. When true, a paid HTTP 200 embeds an Ed25519-signed receipt (kind answer_receipt) the caller can file and later verify at /certified/public-key. Included in this answer's existing price — no extra charge. The field is omitted on unpaid 402 and on free 4xx refusals. This is not a series certified extract: GET /v1/certified/{country}/{series} is a different artifact, with its own price."}},"required":["country","amount","period"]}}}},"responses":{"200":{"description":"Verdict (above/at/below), margin, statutory floor, instrument citation. Honest statuses for countries with no enforceable floor or period mismatch. Optional property receipt (schema AnswerReceipt, kind answer_receipt) is present only when the request set receipt:true and this response is a paid HTTP 200. Unpaid 402 and free 4xx refusals do not include receipt. Not a series certified extract (GET /v1/certified/{country}/{series}).","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"description":"Route-specific answer fields (verdict, workings, citations). receipt is optional and does not replace them.","properties":{"receipt":{"$ref":"#/components/schemas/AnswerReceipt"}}}}}},"400":{"description":"Invalid body (free — validated before payment). No receipt."},"402":{"description":"Payment Required. No receipt object is returned on 402."},"404":{"description":"Unknown country. No receipt."}}}},"/v1/answers/vat":{"post":{"operationId":"answerVat","summary":"VAT breakdown: net/tax/gross for an amount, incl. statutory levy components","tags":["Answers"],"x-payment-info":{"price":{"mode":"fixed","currency":"USD","amount":"0.020000"},"protocols":[{"x402":{}}]},"security":[{"x402Payment":[]},{"apiKey":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"country":{"type":"string","enum":["ae","bd","bh","cn","hk","id","il","in","iq","jo","jp","kr","kw","kz","lk","my","np","om","ph","pk","qa","sa","sg","th","tr","tw","uz","vn"]},"amount":{"type":"number"},"mode":{"type":"string","enum":["add","extract"],"description":"add = amount is net; extract = amount is gross (default add)"},"receipt":{"type":"boolean","default":false,"description":"Optional. Default false. When true, a paid HTTP 200 embeds an Ed25519-signed receipt (kind answer_receipt) the caller can file and later verify at /certified/public-key. Included in this answer's existing price — no extra charge. The field is omitted on unpaid 402 and on free 4xx refusals. This is not a series certified extract: GET /v1/certified/{country}/{series} is a different artifact, with its own price."}},"required":["country","amount"]}}}},"responses":{"200":{"description":"Breakdown with rate applied, components where composite (e.g. Ghana), and instrument citation. Optional property receipt (schema AnswerReceipt, kind answer_receipt) is present only when the request set receipt:true and this response is a paid HTTP 200. Unpaid 402 and free 4xx refusals do not include receipt. Not a series certified extract (GET /v1/certified/{country}/{series}).","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"description":"Route-specific answer fields (verdict, workings, citations). receipt is optional and does not replace them.","properties":{"receipt":{"$ref":"#/components/schemas/AnswerReceipt"}}}}}},"400":{"description":"Invalid body (free). No receipt."},"402":{"description":"Payment Required. No receipt object is returned on 402."},"404":{"description":"Unknown country. No receipt."},"422":{"description":"No single statutory VAT rate exists (e.g. Brazil transition) — free, with explanation. No receipt."}}}},"/v1/answers/working-days":{"post":{"operationId":"answerWorkingDays","summary":"Working days in a date range: weekends and public holidays applied, next working day","tags":["Answers"],"x-payment-info":{"price":{"mode":"fixed","currency":"USD","amount":"0.020000"},"protocols":[{"x402":{}}]},"security":[{"x402Payment":[]},{"apiKey":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"country":{"type":"string","enum":["ae","bd","bh","cn","hk","id","il","in","iq","jo","jp","kr","kw","kz","lk","my","np","om","ph","pk","qa","sa","sg","th","tr","tw","uz","vn"]},"from":{"type":"string","format":"date"},"to":{"type":"string","format":"date","description":"Max 366 days after from"},"subdivision":{"type":"string","description":"Optional ISO 3166-2 code (e.g. 'DE-BY'). Computes the count on that region's statutory calendar — (national minus the region's exclusions) plus the region's own days — instead of national-only. Omit for national. Which countries offer regions, and the valid codes, are on GET /v1/{country}/public-holidays under `subdivisions`. An unrecognised code is refused FREE (422) with `available_subdivisions` listed; we never fall back to national, because that would silently return the wrong count.","example":"DE-BY"},"receipt":{"type":"boolean","default":false,"description":"Optional. Default false. When true, a paid HTTP 200 embeds an Ed25519-signed receipt (kind answer_receipt) the caller can file and later verify at /certified/public-key. Included in this answer's existing price — no extra charge. The field is omitted on unpaid 402 and on free 4xx refusals. This is not a series certified extract: GET /v1/certified/{country}/{series} is a different artifact, with its own price."}},"required":["country","from","to"]}}}},"responses":{"200":{"description":"Counts, holidays hit, next working day, country weekend convention (Egypt Fri–Sat). Optional property receipt (schema AnswerReceipt, kind answer_receipt) is present only when the request set receipt:true and this response is a paid HTTP 200. Unpaid 402 and free 4xx refusals do not include receipt. Not a series certified extract (GET /v1/certified/{country}/{series}).","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"description":"Route-specific answer fields (verdict, workings, citations). receipt is optional and does not replace them.","properties":{"receipt":{"$ref":"#/components/schemas/AnswerReceipt"}}}}}},"400":{"description":"Invalid body (free). No receipt."},"402":{"description":"Payment Required. No receipt object is returned on 402."},"404":{"description":"Unknown country. No receipt."},"422":{"description":"Refused FREE, never charged. Three cases: `calendar_coverage_exhausted` — the range falls outside the years we hold, returned with the exact covered period, because extrapolating would silently count that year's public holidays as working days; `calendar_not_publishable_in_advance` (with `permanent: true`) — the horizon is structural rather than a backlog, for calendars whose dates depend on moon-sighting confirmation or an annual religious-calendar gazette, returned naming the specific blocking holidays, so do not queue a retry expecting the year to appear; and unknown `subdivision`, returned with `available_subdivisions`. No receipt."}}}},"/v1/answers/settlement-date":{"post":{"operationId":"answerSettlementDate","summary":"Settlement/value date: T+n business days across intersected national statutory calendars, with the cited market cycle","description":"Computes the date n business days after a trade date on the INTERSECTION of the calendars supplied, returning a per-day trail (every skipped day with the reason on each calendar), the convention applied and whether it was cited or caller-asserted, and each calendar's basis, weekend rule, coverage and official source. Calendars are NATIONAL STATUTORY holiday calendars, not CSD or trading-venue calendars — the response states each calendar's basis and any known divergence. Anything we cannot compute from a cited calendar under a stated convention is refused free before the payment gate: coverage exhaustion, an instrument class with no primary-sourced cycle, a trade date on which no cited cycle was in force, T+0 on a non-business day, and FX spot value dates. See GET /settlement-conventions (free) for every cycle we hold and what we deliberately refuse to cite.","tags":["Answers"],"x-payment-info":{"price":{"mode":"fixed","currency":"USD","amount":"0.050000"},"protocols":[{"x402":{}}]},"security":[{"x402Payment":[]},{"apiKey":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"trade_date":{"type":"string","format":"date","description":"Trade/reference date. Day 0: never counted toward n, never rolled forward."},"calendars":{"type":"array","items":{"type":"string"},"minItems":1,"maxItems":4,"description":"Calendar ids to intersect: ISO 3166-1 alpha-2 country codes plus 'eu.t2' for the euro cash leg (TARGET2). The settlement date must be a business day on every calendar named. Bare 'eu' is refused as ambiguous."},"business_days":{"type":"integer","minimum":0,"maximum":30,"description":"The offset you are trading under. Supply this, or market + instrument_class to have a cited cycle applied. If both are given and they differ, yours is used and the cited cycle is shown beside it."},"market":{"type":"string","description":"ISO 3166-1 alpha-2 country of the market whose settlement cycle applies (with instrument_class)"},"instrument_class":{"type":"string","enum":["cash_equity","etf","corporate_bond","government_bond","tbill","repo","primary_issuance","other"],"description":"Instrument class. A government bond never inherits an equity cycle."},"receipt":{"type":"boolean","default":false,"description":"Optional. Default false. When true, a paid HTTP 200 embeds an Ed25519-signed receipt (kind answer_receipt) the caller can file and later verify at /certified/public-key. Included in this answer's existing price — no extra charge. The field is omitted on unpaid 402 and on free 4xx refusals. This is not a series certified extract: GET /v1/certified/{country}/{series} is a different artifact, with its own price."}},"required":["trade_date","calendars"]},"example":{"trade_date":"2026-08-06","calendars":["za","eu.t2"],"market":"za","instrument_class":"equity"}}}},"responses":{"200":{"description":"Settlement date, per-day trail, convention applied with citations, each calendar's basis/coverage/source, caveats. Optional property receipt (schema AnswerReceipt, kind answer_receipt) is present only when the request set receipt:true and this response is a paid HTTP 200. Unpaid 402 and free 4xx refusals do not include receipt. Not a series certified extract (GET /v1/certified/{country}/{series}).","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/SettlementDateAnswer"},{"type":"object","properties":{"receipt":{"$ref":"#/components/schemas/AnswerReceipt"}}}]}}}},"400":{"description":"Invalid body, or no convention supplied (free). No receipt."},"402":{"description":"Payment Required. No receipt object is returned on 402."},"404":{"description":"Unknown calendar (free). No receipt."},"422":{"description":"Refused free: calendar coverage exhausted, no cited cycle for this market+instrument, cycle not in force on the trade date, T+0 on a non-business day, or ambiguous calendar. No receipt."},"501":{"description":"FX spot value dates are not computed — the USD-holiday test admits more than one documented reading (free)"}}}},"/settlement-conventions":{"get":{"operationId":"settlementConventions","summary":"Free: every settlement cycle we hold, with its primary-source citation — and what we deliberately refuse to cite","tags":["Discovery"],"security":[],"responses":{"200":{"description":"Cited cycles per market and instrument class, each with authority tier, in-force dates and citations, plus an explicit deliberately-absent list"}}}},"/v1/answers/income-tax":{"post":{"operationId":"answerIncomeTax","summary":"Statutory income tax on a taxable-income figure, with per-bracket workings","tags":["Answers"],"x-payment-info":{"price":{"mode":"fixed","currency":"USD","amount":"0.050000"},"protocols":[{"x402":{}}]},"security":[{"x402Payment":[]},{"apiKey":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"country":{"type":"string","enum":["ae","bd","bh","cn","hk","id","il","in","iq","jo","jp","kr","kw","kz","lk","my","np","om","ph","pk","qa","sa","sg","th","tr","tw","uz","vn"]},"taxable_income":{"type":"number","description":"Taxable income in local currency, in the schedule's own period basis. NOT gross pay — reliefs are applied first, and are not modelled here."},"receipt":{"type":"boolean","default":false,"description":"Optional. Default false. When true, a paid HTTP 200 embeds an Ed25519-signed receipt (kind answer_receipt) the caller can file and later verify at /certified/public-key. Included in this answer's existing price — no extra charge. The field is omitted on unpaid 402 and on free 4xx refusals. This is not a series certified extract: GET /v1/certified/{country}/{series} is a different artifact, with its own price."}},"required":["country","taxable_income"]}}}},"responses":{"200":{"description":"Tax, effective + marginal rate, per-bracket breakdown, tax-unit scaling (UVT/UTA/UIT/BPC), instrument citation, and a scope_note that this is not net take-home pay. Optional property receipt (schema AnswerReceipt, kind answer_receipt) is present only when the request set receipt:true and this response is a paid HTTP 200. Unpaid 402 and free 4xx refusals do not include receipt. Not a series certified extract (GET /v1/certified/{country}/{series}).","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"description":"Route-specific answer fields (verdict, workings, citations). receipt is optional and does not replace them.","properties":{"receipt":{"$ref":"#/components/schemas/AnswerReceipt"}}}}}},"400":{"description":"Invalid body (free — validated before payment). No receipt."},"402":{"description":"Payment Required. No receipt object is returned on 402."},"404":{"description":"Unknown country. No receipt."},"422":{"description":"Country's income-tax schedule is not in computable bracket form (free). No receipt."}}}},"/v1/answers/statutory-interest":{"post":{"operationId":"answerStatutoryInterest","summary":"Simple statutory interest on a principal at the cited statutory-interest series rate (Actual/365)","description":"Computes simple interest for a principal and a day count at the numeric rate of the cited statutory-interest series, after the same derived materialization GET /v1/{country}/statutory-interest uses. Formula: interest = principal × (rate_percent / 100) × (days / 365). Day-count basis is Actual/365 simple: `from` is inclusive, `to` is exclusive, and the day count is the UTC calendar difference. Interest is rounded to 2 decimal places and the workings show that rounding. Not legal advice. Jurisdiction-specific compounding, mora-versus-judgment splits, and leap-year statutes are not applied. When the series publishes current.rates[], the headline current.value is used; there is no rate_key input. Supply `days`, or `from` and `to`. If both are supplied and the day counts disagree, the call is refused free (400) before payment. A series that is present but has no numeric rate after materialization (value null or not a number — mechanism-only) is refused free (422) with the series notes; a non-answer is never sold. Unknown country or a missing series is 404 free. Optional receipt:true embeds an answer_receipt on a paid HTTP 200 only, included in this answer's existing price. That receipt is not a series certified extract (GET /v1/certified/{country}/{series}).","tags":["Answers"],"x-payment-info":{"price":{"mode":"fixed","currency":"USD","amount":"0.050000"},"protocols":[{"x402":{}}]},"security":[{"x402Payment":[]},{"apiKey":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"country":{"type":"string","enum":["ae","bd","bh","cn","hk","id","il","in","iq","jo","jp","kr","kw","kz","lk","my","np","om","ph","pk","qa","sa","sg","th","tr","tw","uz","vn"],"description":"ISO 3166-1 alpha-2 in this brand's catalog that holds a statutory-interest series."},"principal":{"type":"number","exclusiveMinimum":0,"description":"Principal in the country's currency. Must be a finite number greater than 0."},"days":{"type":"number","exclusiveMinimum":0,"description":"Positive day-count days. Supply this, or from and to. If both are sent and disagree, the call is 400 free."},"from":{"type":"string","format":"date","description":"Start date YYYY-MM-DD, inclusive. Required together with to when days is omitted."},"to":{"type":"string","format":"date","description":"End date YYYY-MM-DD, exclusive. Day count is the UTC calendar difference to − from."},"receipt":{"type":"boolean","default":false,"description":"Optional. Default false. When true, a paid HTTP 200 embeds an Ed25519-signed receipt (kind answer_receipt) the caller can file and later verify at /certified/public-key. Included in this answer's existing price — no extra charge. The field is omitted on unpaid 402 and on free 4xx refusals. This is not a series certified extract: GET /v1/certified/{country}/{series} is a different artifact, with its own price."}},"required":["country","principal"]},"example":{"country":"ae","principal":1000,"days":30}}}},"responses":{"200":{"description":"Interest, the cited rate, Actual/365 workings, disclaimer and limitations. Optional property receipt (schema AnswerReceipt, kind answer_receipt) is present only when the request set receipt:true and this response is a paid HTTP 200. Unpaid 402 and free 4xx refusals do not include receipt. Not a series certified extract (GET /v1/certified/{country}/{series}).","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/StatutoryInterestAnswer"},{"type":"object","properties":{"receipt":{"$ref":"#/components/schemas/AnswerReceipt"}}}]}}}},"400":{"description":"Invalid body, free, before payment. No receipt. Includes a non-finite or non-positive principal, a bad date, days together with from/to that disagree, or receipt that is not a boolean."},"402":{"description":"Payment Required. No receipt object is returned on 402, including when the body set receipt:true."},"404":{"description":"Unknown country for this brand, or no statutory-interest series for that country. Free. No receipt."},"422":{"description":"Free, before payment. No receipt. The statutory-interest series is present but has no numeric rate after derived materialization (current value null or not a number). Typical of a mechanism-only series, for example a treasury-bill reference that does not publish a prescribed percent. The body includes the series notes or explanation. A non-answer is never sold."}}}},"/v1/answers/employment-cost":{"post":{"operationId":"answerEmploymentCost","summary":"Cost to employ: statutory contributions priced line by line (employee + employer), with refused schemes named","description":"Prices a gross salary against the country's statutory contribution schedule. Returns every employee-side and employer-side line that can be priced, the employer cost (gross + employer contributions), and an explicit refused list for every scheme that could not be priced — unknown, not zero. Does not compute income tax (that is /v1/answers/payroll, Nigeria and Kenya only). This operation is published only on a brand whose catalog intersects the costed set. On this brand the supported countries are: AE. Any other country, and any unknown subdivision, is refused FREE (422) before payment, with no receipt. Optional receipt:true on a paid HTTP 200 embeds an answer_receipt (kind answer_receipt), included in this answer's existing price. That receipt is not a series certified extract (GET /v1/certified/{country}/{series}).","tags":["Answers"],"x-payment-info":{"price":{"mode":"fixed","currency":"USD","amount":"0.100000"},"protocols":[{"x402":{}}]},"security":[{"x402Payment":[]},{"apiKey":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"country":{"type":"string","enum":["ae"],"description":"ISO 3166-1 alpha-2 limited to this brand's overlap with the costed contribution set (AE). Any other country is refused FREE (422)."},"gross":{"type":"number","description":"Gross pay in local currency"},"period":{"type":"string","enum":["month","year"],"description":"Period the gross covers (default month)"},"subdivision":{"type":"string","description":"Optional ISO 3166-2 code where a region runs its own schedule (e.g. CA-QC, DE-SN, AU-NF). Unknown codes refused FREE with the available list."},"nationality":{"type":"string","enum":["national","gcc","expat"],"description":"Required in the Gulf: pension reach depends on nationality"},"contract":{"type":"string","enum":["indefinite","fixed_term"],"description":"Selects unemployment / fixed-term surcharge rates where they differ"},"workplace_pension":{"type":"boolean","description":"Auto-enrolment (GB) / PPK (PL); both opt-out, default true"},"childless_over_23":{"type":"boolean","description":"Germany: employee long-term-care surcharge"},"children_under_25":{"type":"number","description":"Germany: per-child care-rate reduction"},"zusatzbeitrag_rate":{"type":"number","description":"Germany: sickness-fund supplement rate (no national figure)"},"receipt":{"type":"boolean","default":false,"description":"Optional. Default false. When true, a paid HTTP 200 embeds an Ed25519-signed receipt (kind answer_receipt) the caller can file and later verify at /certified/public-key. Included in this answer's existing price — no extra charge. The field is omitted on unpaid 402 and on free 4xx refusals. This is not a series certified extract: GET /v1/certified/{country}/{series} is a different artifact, with its own price."}},"required":["country","gross"]},"example":{"country":"ae","gross":5000,"period":"month","receipt":true}}}},"responses":{"200":{"description":"Employee and employer contribution lines, employer_cost, refused schemes with reasons, citations. Optional property receipt (schema AnswerReceipt, kind answer_receipt) is present only when the request set receipt:true and this response is a paid HTTP 200. Unpaid 402 and free 4xx refusals do not include receipt. Not a series certified extract (GET /v1/certified/{country}/{series}).","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"description":"Route-specific answer fields (verdict, workings, citations). receipt is optional and does not replace them.","properties":{"receipt":{"$ref":"#/components/schemas/AnswerReceipt"}}}}}},"400":{"description":"Invalid body (free). No receipt."},"402":{"description":"Payment Required. No receipt object is returned on 402."},"404":{"description":"social-contributions series not available. No receipt."},"422":{"description":"Country is outside this brand's costed overlap, or the subdivision is unknown — refused free with the available list. No receipt."}}}},"/v1/vat/determine":{"post":{"operationId":"determineCrossBorderVat","summary":"Cross-border VAT treatment of a digital-services sale (EU, UK, South Africa) — the applied rule, cited to the statute","description":"Regulatory information with citations, for x402/API sellers: place of supply, who accounts for the VAT, rate basis, registration/threshold trigger and reporting mechanism for a seller-country → buyer-country digital-services sale. Unknown buyers (wallet-address only) are resolved under B2C-default rules and explicitly flagged; combinations outside the verified ruleset are refused FREE (422) before payment — never guessed, never charged.","tags":["x402 sellers"],"x-payment-info":{"price":{"mode":"fixed","currency":"USD","amount":"0.100000"},"protocols":[{"x402":{}}]},"security":[{"x402Payment":[]},{"apiKey":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"seller_country":{"type":"string","description":"ISO 3166-1 alpha-2 (EL accepted for Greece, UK for United Kingdom)"},"buyer_country":{"type":"string","description":"ISO 3166-1 alpha-2"},"buyer_type":{"type":"string","enum":["B2B","B2C","unknown"],"description":"Default unknown — treated as B2C and flagged in the response"}},"required":["seller_country","buyer_country"]}}}},"responses":{"200":{"description":"The applied rule (place of supply, who accounts, rate basis, registration trigger, reporting) with statutory citation, classification workings, destination-liability companion where applicable, e-services definition, ViDA forward-flag and disclaimer"},"400":{"description":"Invalid body (free — validated before payment)"},"402":{"description":"Payment Required"},"405":{"description":"Wrong method (free) — use POST"},"422":{"description":"Combination outside the verified ruleset (free, labeled — never guessed, never charged)"}}}},"/alerts":{"post":{"operationId":"registerAlert","summary":"FREE to register — HMAC webhook on series.changed and/or source.changed (retention bind)","description":"After a first paid call, this is how a long-running agent subscribes to the next gazette instead of caching a $0.005 value as eternal. Watch VALUES (series patterns → series.changed when a served value or its effective date moves) and/or DOCUMENTS (exact official-source URLs from the provenance ledger → source.changed when the document's bytes change, with old/new sha256 and the series that cite it). A source event asserts only that the DOCUMENT changed — republications and layout edits also change bytes; value changes are decided by re-verification and arrive as series.changed. Source watches are limited to URLs this service already fingerprints daily (every series response carries its source.url); anything else is refused free and logged as a request (error source_not_fingerprinted). Register: $0 · Delivery after trial: $0.10 (refunded when a webhook fails to send). The first 3 deliveries are free. The HMAC secret is shown once on 201. Prefer GET /v1/changes if you would rather poll. Does not create a new payment endpoint.","tags":["Alerts"],"x-payment-info":{"register":{"mode":"fixed","currency":"USD","amount":"0.000000"},"delivery_after_trial":{"mode":"fixed","currency":"USD","amount":"0.100000"},"note":"Register: $0 · Delivery after trial: $0.10","protocols":[{"x402":{}}]},"security":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"url":{"type":"string","format":"uri","description":"Webhook endpoint to receive events"},"series":{"type":"array","items":{"type":"string"},"description":"Value watches. Patterns like \"ng/policy-rate\", \"ke/*\", or \"*\"","maxItems":20},"sources":{"type":"array","items":{"type":"string","format":"uri"},"description":"Document watches. Exact official-source URLs from the provenance ledger (see each series' source.url). Unknown URLs are refused free with error source_not_fingerprinted.","maxItems":20},"api_key":{"type":"string","description":"Optional prepaid key to fund deliveries after the free trial"}},"required":["url"]},"example":{"url":"https://your-app.example/hooks/refdata","series":["za/vat-registration-threshold"],"sources":["https://www.sars.gov.za/types-of-tax/value-added-tax/register-for-vat/"]}}}},"responses":{"201":{"description":"Subscription created; response includes the HMAC secret (shown once)"},"400":{"description":"Invalid body"},"422":{"$ref":"#/components/responses/Refusal"}}}}},"components":{"securitySchemes":{"x402Payment":{"type":"apiKey","in":"header","name":"X-PAYMENT","description":"x402 (USDC on Base). Call without this header, receive HTTP 402 carrying the price and payment details, then retry with the signed payment payload in X-PAYMENT. No signup, no account, no key. Per-operation prices are in the x-payment-info extension and at https://asiaref.dev/pricing."},"apiKey":{"type":"apiKey","in":"header","name":"X-API-Key","description":"Prepaid credit bought by card (from $10) at https://asiaref.dev/pricing. Send the key on every call. How the two payment rails charge: by card, every successful paid call uses one prepaid credit ($0.005 each on the $10, $25 and $100 packs), whichever endpoint it is; over x402, every call pays the price quoted in its own 402 challenge, $0.005 to $0.25 depending on the endpoint (listed at https://asiaref.dev/pricing). Failed or refused calls are not charged on either rail. Use this instead of x402 if you want an invoice."}},"schemas":{"SeriesValue":{"type":"object","properties":{"country":{"type":"string","description":"ISO 3166-1 alpha-2 country code"},"series":{"type":"string"},"value":{"description":"Number for rates/wages; array of {date,name} for holiday calendars"},"unit":{"type":"string"},"effective_from":{"type":["string","null"],"format":"date"},"effective_from_basis":{"type":"string","enum":["restatement"],"description":"Optional. Absent: effective_from is the date the value became the law (a genuine change point). 'restatement': effective_from is the date the value's CURRENT LEGAL BASIS took effect (a new tax code, an annual finance law) while the value itself is older and its true origin is not primary-verifiable — a verified floor, not a change. Do not read a restatement row as the value having changed on that date."},"last_confirmed":{"type":"string","format":"date","description":"When this value was last verified against the official source"},"source":{"type":"object","properties":{"name":{"type":"string"},"url":{"type":"string","format":"uri"}},"required":["name","url"]},"stale":{"type":"boolean","description":"True when past the expected update cycle — treat with caution"},"notes":{"type":"string"},"effective_rate":{"type":"number","description":"Optional. Combined effective rate where statutory levies stack on top of the standard rate (e.g. Ghana VAT 15% + NHIL 2.5% + GETFund 2.5% = 20%). Present only where it differs from value."},"components":{"type":"array","description":"Optional. Breakdown of a composite rate into its named statutory components (present only where applicable, e.g. Ghana VAT).","items":{"type":"object","properties":{"name":{"type":"string"},"rate":{"type":"number"}},"required":["name","rate"]}}},"required":["country","series","value","effective_from","last_confirmed","source","stale"]},"Error":{"type":"object","description":"Every refusal carries a machine-readable reason. This service refuses rather than guesses, so a 4xx here often means 'we will not assert something we cannot evidence' - not that the request was malformed. Beyond the base fields, each refusal type attaches the structured data an agent needs to RECOVER: a coverage refusal names the covered period, an unknown-subdivision refusal lists the valid codes, a permanent-horizon refusal says not to retry. Fields absent from a given refusal simply do not apply to it.","properties":{"error":{"type":"string","description":"Short machine-readable reason, e.g. 'calendar_coverage_exhausted', 'unknown_calendar', 'no_verified_convention', 'commencement_date_unknown', 'absence_not_dated'"},"explanation":{"type":"string","description":"What specifically was wrong or unprovable, in plain language"},"no_charge":{"type":"boolean","description":"true when the refusal was validated BEFORE the payment gate and nothing was billed"},"coverage":{"type":"array","description":"On coverage refusals: the period each named calendar actually covers, so the caller can re-send a range inside it","items":{"type":"object","properties":{"calendar":{"type":"string"},"from":{"type":"string","format":"date"},"to":{"type":"string","format":"date"}}}},"reached":{"type":"string","format":"date","description":"On coverage refusals during counting: the last date that COULD be evaluated before coverage ran out"},"available_subdivisions":{"type":"array","items":{"type":"string"},"description":"On unknown-subdivision refusals: every ISO 3166-2 code this country serves - re-send with one of these"},"permanent":{"type":"boolean","description":"true when the refusal is structural, not a backlog: the blocking facts (e.g. moon-sighting holiday dates) cannot exist yet. Do not queue a retry."},"pending_window":{"type":"object","description":"On not-yet-gazetted holiday placeholders: the window in which the official date will fall"},"countries":{"type":"array","items":{"type":"string"},"description":"On unknown-country refusals: the country codes this brand serves"},"detail":{"type":"string","description":"Additional machine-oriented detail where the error code alone is ambiguous"}},"required":["error"],"example":{"error":"calendar_coverage_exhausted","explanation":"The requested range 2028-01-01 to 2028-03-31 falls outside the period our KE holiday calendar covers (2024-01-01 to 2027-12-31). We do not extrapolate holiday calendars by rule. No charge has been made.","coverage":[{"calendar":"ke","from":"2024-01-01","to":"2027-12-31"}],"no_charge":true}},"StatutoryInterestAnswer":{"type":"object","description":"Simple statutory interest on the cited statutory-interest series. The rate is that series' numeric value after derived materialization, not a rate invented for this call. Interest is rounded to 2 decimal places. Not legal advice.","properties":{"status":{"type":"string","enum":["ok"]},"country":{"type":"string","description":"ISO 3166-1 alpha-2"},"principal":{"type":"number"},"days":{"type":"number","description":"Day-count days used. From the request, or the UTC calendar difference to − from."},"rate":{"type":"number","description":"Cited series rate in percent, after the same materialization as GET /v1/{country}/statutory-interest."},"rate_unit":{"type":"string","enum":["percent"]},"day_count_basis":{"type":"string","enum":["actual/365_simple"]},"interest":{"type":"number","description":"principal × (rate / 100) × (days / 365), rounded to 2 decimal places."},"workings":{"type":"string","description":"The arithmetic, including the 2-decimal rounding."},"disclaimer":{"type":"string","description":"COMPUTED_DISCLAIMER. This is a computation, not a cited value and not advice."},"limitations":{"type":"array","items":{"type":"string"},"description":"Always populated. Not legal advice; the computation is over the cited series as of last_confirmed; Actual/365 simple only."},"provenance":{"type":"object","properties":{"effective_from":{"type":["string","null"],"format":"date"},"last_confirmed":{"type":["string","null"],"format":"date"},"source":{"type":"object","properties":{"name":{"type":"string"},"url":{"type":"string"}}}}}},"required":["status","country","principal","days","rate","rate_unit","day_count_basis","interest","workings","disclaimer","limitations","provenance"]},"SettlementDateAnswer":{"type":"object","description":"The settlement-date computation with its full evidence trail. Nothing here is asserted without a stated basis: the convention says whether it was cited from an instrument or supplied by the caller, and every skipped day names the calendar and reason that skipped it.","properties":{"status":{"type":"string","enum":["ok"]},"settlement_date":{"type":"string","format":"date"},"settlement_weekday":{"type":"string"},"question":{"type":"object","description":"The question as understood: trade date and weekday, business-day count applied, calendars intersected, market/instrument when supplied"},"convention_applied":{"type":"object","description":"The T+n actually used and where it came from: 'cited_convention' (with the instrument, authority and whether it is compelled by law) or 'caller_supplied'. When both were given and differ, the cited cycle is shown beside the caller's."},"trail":{"type":"array","description":"Per-day walk from trade date to settlement: each candidate day, whether it counted, and - when skipped - which calendar blocked it and why (weekend rule or a named public holiday)","items":{"type":"object"}},"calendars":{"type":"array","description":"Each calendar's basis (national statutory - NOT a CSD or venue calendar), weekend rule, covered period and official source, plus any known divergence worth flagging","items":{"type":"object"}},"caveats":{"type":"array","items":{"type":"string"},"description":"Always worth reading: the specific limits of this answer"}},"required":["status","settlement_date","question","convention_applied"]},"PaymentRequired":{"type":"object","description":"HTTP 402 body: the price and how to pay it. Retry the same request with the signed payment in X-PAYMENT.","properties":{"x402Version":{"type":"integer"},"error":{"type":"string"},"accepts":{"type":"array","description":"Payment options; each carries the amount, asset, network and pay-to address.","items":{"type":"object"}}}},"AnswerReceipt":{"type":"object","description":"Signed record of one paid answer computation. Present only on HTTP 200 when the request body set receipt:true. kind is answer_receipt. This object is not a series certified extract: GET /v1/certified/{country}/{series} returns a different artifact (value, citation, archived-source fingerprint, verification chain) at its own price. An answer receipt is included in the answer's existing price — no extra charge. It is not legal advice. It only covers the computation over the cited series as of each series' last_confirmed. Signing: build the object without signature, set receipt_id from the sha256 of that canonical JSON (first 24 hex chars, same pattern as extract_id), re-canonicalize including receipt_id, then sign. Verify with the free key at /certified/public-key — the same key and the same canonicalization rule as series certified extracts, not a second key.","properties":{"kind":{"type":"string","const":"answer_receipt"},"receipt_id":{"type":"string","pattern":"^[0-9a-f]{24}$","description":"First 24 hex characters of sha256 over the canonical JSON of this object before signature is attached. Same pattern as certified extract_id. The signature covers the object including receipt_id."},"answer":{"type":"string","description":"Route or tool name of the paid answer, e.g. vat, wage-check, working-days, settlement-date, income-tax, statutory-interest, payroll, employment-cost.","examples":["vat","wage-check","statutory-interest"]},"request":{"type":"object","additionalProperties":true,"description":"Sanitized inputs echoed from the request. Properties are route-specific."},"result":{"type":"object","additionalProperties":true,"description":"Compact summary of the answer status and workings already returned on this 200. Properties are route-specific."},"cited_series":{"type":"array","description":"Series the computation cited. Empty only when the answer cited none.","items":{"type":"object","properties":{"country":{"type":"string","examples":["za"]},"series_id":{"type":"string","examples":["vat"]},"value":{"type":["number","string","null"],"description":"Cited series value as held. Number, string, or null."},"last_confirmed":{"type":["string","null"],"format":"date","description":"ISO date the cited series was last confirmed, or null."},"source_url":{"type":["string","null"]},"source_sha256":{"type":["string","null"],"description":"Hex fingerprint from provenance when available, otherwise null."}},"required":["country","series_id","value","last_confirmed","source_url","source_sha256"]}},"issued_at":{"type":"string","format":"date-time","description":"ISO8601 timestamp when the receipt was issued."},"limitations":{"type":"array","items":{"type":"string"},"description":"Always populated. States that this receipt is not a series certified extract and is not legal advice, and that it only covers the computation over the cited series as of each series' last_confirmed.","examples":[["This receipt is not a series certified extract (GET /v1/certified/{country}/{series}).","This receipt is not legal advice. It only covers the computation over the cited series as of each series' last_confirmed."]]},"signature":{"type":"object","description":"Ed25519 signature over the canonical JSON of this receipt with the signature field omitted. Same key_id and same canonicalization rule as series certified extracts, published at /certified/public-key. Not a second production key.","properties":{"alg":{"type":"string","const":"Ed25519"},"key_id":{"type":"string","description":"Same key_id as GET /certified/public-key and as series certified extracts."},"public_key":{"type":"string","description":"Absolute URL of GET /certified/public-key."},"signed_payload":{"type":"string","description":"canonical JSON of answer_receipt: keys sorted recursively, no whitespace (see /certified/public-key)"},"value":{"type":"string","description":"Base64 Ed25519 signature."}},"required":["alg","key_id","public_key","signed_payload","value"]}},"required":["kind","receipt_id","answer","request","result","cited_series","issued_at","limitations","signature"],"example":{"kind":"answer_receipt","receipt_id":"0123456789abcdef01234567","answer":"vat","request":{"country":"za","amount":100,"mode":"add","receipt":true},"result":{"status":"ok"},"cited_series":[{"country":"za","series_id":"vat","value":null,"last_confirmed":"2026-04-01","source_url":null,"source_sha256":null}],"issued_at":"2026-09-25T15:45:00.000Z","limitations":["This receipt is not a series certified extract (GET /v1/certified/{country}/{series}).","This receipt is not legal advice. It only covers the computation over the cited series as of each series' last_confirmed."],"signature":{"alg":"Ed25519","key_id":"<same key_id as /certified/public-key>","public_key":"https://example.invalid/certified/public-key","signed_payload":"canonical JSON of answer_receipt: keys sorted recursively, no whitespace (see /certified/public-key)","value":"<base64>"}}},"CertifiedExtract":{"type":"object","description":"A signed series certified extract. Not an answer receipt (kind answer_receipt lives on paid answer responses). The signature covers the canonical JSON of certified_extract exactly as received.","properties":{"certified_extract":{"type":"object","properties":{"format":{"type":"string","const":"afriref-certified-extract/1"},"issued_at":{"type":"string","format":"date-time"},"extract_id":{"type":"string","description":"Stable id derived from the extract's own content"},"issuer":{"type":"object"},"subject":{"type":"object","properties":{"country":{"type":"string"},"series":{"type":"string"}}},"value":{"type":"object","description":"Value, unit, effective dates, confidence and staleness"},"citation":{"type":"object","description":"Official source name and URL; includes the rule-vs-instances split for dated series"},"source_document":{"type":"object","description":"The cited document as archived: sha256 over the retrieved bytes, size, content type, first and latest fingerprint dates, and whether a copy is held."},"verification":{"type":"object","description":"How and when the value was last confirmed, and - where the mechanical pass holds it - the value located in the archived document with surrounding context."},"limitations":{"type":"array","items":{"type":"string"},"description":"What this extract does NOT certify. Always populated."}}},"signature":{"type":"object","properties":{"alg":{"type":"string","const":"Ed25519"},"key_id":{"type":"string"},"public_key":{"type":"string","format":"uri"},"signed_payload":{"type":"string","description":"How to reconstruct the signed bytes"},"value":{"type":"string","description":"Base64 Ed25519 signature"}}}}}},"responses":{"PaymentRequired":{"description":"Payment required - retry with X-PAYMENT, or send X-API-Key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaymentRequired"}}}},"Refusal":{"description":"Refused, with the reason. Validation refusals happen BEFORE payment and are never charged.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}