Quickstart
Middle Eastern government reference data as cited JSON. No account, no API key, no signup required — though you can have a key if you would rather pay by card. Every paid call costs $0.001 for a single value.
1. Free, right now
Nothing below needs a key, a wallet or a header. Start here to see what exists:
# Every country and series this service holds
curl https://mearef.dev/catalog
# A full public-holiday calendar, cited to its official source
curl https://mearef.dev/public/ae/holidays
# What changed recently, and how recently each value was re-verified
curl https://mearef.dev/v1/changes
Public holidays are free for every country, permanently. So are /catalog, /v1/changes, /settlement-conventions, /openapi.json and /llms.txt.
2. A paid call, and what it costs
Paid endpoints answer 402 Payment Required until they are paid. The 402 is not an error — it is the price quote, and it is machine-readable:
curl -i https://mearef.dev/v1/ae/policy-rate
HTTP/1.1 402 Payment Required
payment-required: eyJ4NDAyVmVyc2lvbiI6MiwiZXJyb3IiOiJQYXltZW50...
That header is base64-encoded JSON. Decode it to see the price, the asset, the chain and the address to pay:
curl -sD- -o /dev/null https://mearef.dev/v1/ae/policy-rate \
| grep -i '^payment-required:' | cut -d' ' -f2- | base64 -d | jq .
The challenge is also mirrored into the response body, so a client that cannot read headers is not locked out. Amounts are in the asset's base units — USDC has 6 decimals, so 1000 means $0.001.
3. Two ways to pay
Option A — x402, for agents with a wallet
Pay per call in USDC on Base. No account exists to create. A client library does the 402 → sign → retry loop for you:
npm install @x402/fetch
import { wrapFetchWithPayment } from "@x402/fetch";
import { createWalletClient, http } from "viem";
import { privateKeyToAccount } from "viem/accounts";
import { base } from "viem/chains";
const account = privateKeyToAccount(process.env.PRIVATE_KEY);
const wallet = createWalletClient({ account, chain: base, transport: http() });
const fetchWithPay = wrapFetchWithPayment(fetch, wallet);
const res = await fetchWithPay("https://mearef.dev/v1/ae/policy-rate");
const data = await res.json();
console.log(data.value, data.source.url); // the number, and where it came from
On success the settlement receipt comes back in the PAYMENT-RESPONSE header. You sign a payment authorisation, not a blank cheque: the amount is fixed by the challenge.
Option B — an API key, for people and businesses
Buy prepaid credit by card on the pricing page and send the key as a header. No wallet, no crypto, and you get an invoice:
curl -H 'X-API-Key: YOUR_KEY' https://mearef.dev/v1/ae/policy-rate
import requests
r = requests.get(
"https://mearef.dev/v1/ae/policy-rate",
headers={"X-API-Key": "YOUR_KEY"},
timeout=15,
)
r.raise_for_status()
d = r.json()
print(d["value"], d["unit"], "as at", d["effective_from"])
print("source:", d["source"]["url"])
Credit does not expire and there is no subscription. Calls that fail because of our error are not deducted.
4. What comes back
Every paid value carries the evidence with it. The citation is the product — a number without one is what we are trying to replace:
{
"country": "AE",
"series": "policy-rate",
"value": 15.75,
"unit": "percent",
"effective_from": "2026-07-14", // when this value took legal effect
"last_confirmed": "2026-07-24", // when we last re-read the official source
"source": {
"name": "...", // the instrument, named
"url": "https://..." // the document itself
},
"confidence": "primary", // how the value was obtained
"stale": false // past its expected update cycle?
}
| Field | Why it is there |
|---|---|
effective_from | The date the value took effect, which is rarely the date we published it. Use it, not the fetch date, for anything point-in-time. |
last_confirmed | When a human or job last re-read the official source. An old date here is a disclosure, not a bug. |
source.url | The governing document. Follow it and check us. |
confidence | primary means read from the authority's own publication. Filter the catalog with /catalog?confidence=primary. |
stale | True when past the expected update cycle. We serve it flagged rather than withholding it or aging it quietly. |
5. Point-in-time reads
Add ?as_at=YYYY-MM-DD to get the value that was in force on a date, rather than today's:
curl 'https://mearef.dev/v1/ae/policy-rate?as_at=2025-06-30'
If we hold no value in force on that date, you get a free 422 explaining what we do hold — not the nearest value, and not a guess.
6. Refusals — read this before treating one as a bug
The service refuses questions it cannot answer honestly, and refusals are always free: they are validated before the payment gate, so you are never charged for a question we know we cannot answer well.
| Status | Meaning |
|---|---|
400 | Malformed input. Free. |
402 | The price quote. Pay and retry. |
404 | Unknown country or series for this brand. Each regional service serves only its own countries — check /catalog. |
422 | A refusal with a reason. Free. See the codes below. |
429 | Rate limited on a free discovery route. Retry after the header says. |
The 422 reasons you are most likely to meet:
| Code | What it means |
|---|---|
calendar_coverage_exhausted | Your date range runs past the years we hold for that country. The response names the covered period. We do not extrapolate calendars. |
calendar_not_publishable_in_advance | Permanent, flagged permanent: true. Islamic dates are confirmed by moon sighting and some calendars are gazetted annually — the year will not appear later, so do not queue a retry. |
no_value_in_force_on_that_date | An as_at date earlier than our earliest recorded value. |
no_verified_convention | A settlement question for a market whose cycle we have not verified. We will not guess a cycle. |
A refusal names the specific blocking reason and tells you what you can do instead. Treat it as data, not as failure.
7. Rate limits
Free, unauthenticated discovery routes are throttled per IP; paid data routes are not throttled at all. Current limits and what they cover are published on /status.
8. If you are an agent, not a person
| /llms.txt | The whole service in one plain-text file, written to be read by a model. |
| /openapi.json | OpenAPI, with x-payment-info on every paid operation. |
/.well-known/x402 | x402 v2 resource manifest — every priced resource, machine-readable. |
/mcp | MCP server over streamable HTTP. Free tools: list_series, get_public_holidays. Paid: get_series, get_series_history, get_snapshot. |
Something wrong?
If a value disagrees with its official source, send us the instrument — corrections with a primary source are acted on and credited on the accuracy record. api@3l-groupconsulting.co.za