# ABIZ Universal Resolver

Give it a business domain; it returns the domain's published ABIZ record, the conformance checks,
where the evidence came from and an explicit result status, in one request. It does the DNS and
HTTPS work for you. It is free, anonymous, read-only and rate limited.

What it does not do: it does not check company registers, it does not prove who owns a business,
and it cannot make any AI assistant use it. A domain with no ABIZ record, or with an unreachable
record host, is reported as exactly that.

## Resolve a domain

```
GET https://resolve.abizrecord.org/v1/resolve?domain=example.com
GET https://resolve.abizrecord.org/v1/resolve?website=https%3A%2F%2Fexample.com%2Fabout
```

Give exactly one of `domain` (a host name, not a URL) or `website` (a URL; only its host is used).
Names are lower-cased and converted to Punycode. `www.example.com` is looked up as
`_abiz.www.example.com`; it is never silently replaced by `example.com`.

The answer is JSON (`api_version` "1"): `status`, `query`, `resolved_at`, `request_id`,
`discovery` (the TXT value used, its TTL, which DNS-over-HTTPS service answered, the record URL),
`record` (the ABIZ record exactly as published, only when resolved), `checks`, `freshness`,
`warnings`, `sources`, `error` (on failure) and `resolver` (this service's version and the
pinned schema's id and SHA-256).

## Statuses

| HTTP | status | Meaning | Retry |
| --- | --- | --- | --- |
| 200 | resolved | One valid v=abiz1 TXT record, a record at https://h that passes the ABIZ schema, and the DNS, record and queried domain agree | No |
| 400 | invalid_input | The domain or website is not a valid public host | No |
| 404 | not_found | DNS answered and there is no v=abiz1 record at _abiz.domain | Not until DNS changes |
| 409 | conflict | More than one v=abiz1 record | No; the publisher must keep one |
| 422 | invalid_record | A malformed pointer, an unsafe or unreachable record address, or a record that fails the schema or the cross-checks | No; the publisher must fix it |
| 429 | rate_limited | Too many requests from you, or for this domain | After Retry-After |
| 503 | unavailable | DNS or the record host failed or timed out | Yes |

A failure to reach DNS or the record host is never reported as not_found.

Error codes: missing_input, both_inputs, invalid_domain, invalid_website, non_public_domain,
missing_txt, multiple_txt, bad_pointer, duplicate_tag, missing_h, unsafe_host, fetch_failed,
record_too_large, not_json, schema_invalid, identity_host_mismatch, domain_not_claimed,
business_key_mismatch, rate_limited, domain_rate_limited, dns_timeout, dns_failure,
upstream_timeout, origin_unavailable.

## What the checks mean

- checks.schema: the record conforms to the ABIZ JSON Schema (Draft 2020-12, formats asserted), pinned at commit 65071d6 of abiz-org/abiz-agentic-business-record, plus assigned country codes and https URLs.
- checks.dns_assertion: exactly one v=abiz1 TXT record, v first, no repeated h, k or p, no spaces, h a host with an optional path.
- checks.domain_record_link: identity-host equals h exactly (path included), domains includes the queried domain, and k, business-key, country and registration-number agree.
- checks.registration: always not_checked. No company register is queried. A registration number in a record is the publisher's claim.
- checks.mcp_endpoint: advertised_not_invoked when the record lists an mcp-server-url. This service never calls it.

There is no trust score. discovery.dnssec says whether the DNS-over-HTTPS service validated DNSSEC (it set the AD bit); this service does not validate signatures itself.

## MCP

Endpoint: https://resolve.abizrecord.org/mcp (Streamable HTTP, protocol 2026-07-28 and 2025-11-25). No sign-in. One tool:

- resolve_business: Resolve a business domain to its ABIZ record. Arguments: {"domain": "example.com"} or {"website": "https://example.com"}. The result's structuredContent is the same envelope as the HTTP API; isError is true for every status but resolved.

Server card: https://resolve.abizrecord.org/.well-known/mcp.json. MCP Registry entry: https://resolve.abizrecord.org/server.json (org.abizrecord/resolver).

Add it to an MCP host as a remote server with the URL above (for example, a custom connector in Claude or ChatGPT). Whether an assistant calls it is up to that assistant. To make a lookup certain in your own application, call GET /v1/resolve in your code before you call the model, and give the model the whole response, status included.

An agent skill that says when and how to use it: https://resolve.abizrecord.org/skills/abiz-lookup/SKILL.md.

## Caching and limits

- A resolved answer is reused for at most the DNS TTL of the TXT record, and never more than 300 seconds; a not_found, conflict or invalid_record answer for at most 60 seconds; an unavailable answer never. freshness.cache says whether this answer came from the cache, and freshness.expires_at when it stops being reused. Cache-Control matches.
- 60 resolutions a minute per caller, 20 uncached resolutions a minute per domain, 120 MCP requests a minute per caller.
- A record is fetched from https://h only: no redirects, a 5 second limit, 64 KiB, Accept: application/json, and only after every address of the host is checked to be public.

## Privacy

This service logs each lookup with the queried domain, the status, the error code, whether the cache was used and the time taken, to operate it. It does not log record contents, and it uses your IP address only for the rate limit and does not write it to its own log lines. It runs on Cloudflare Workers, whose platform logs for the service may record request details such as the address and time of a request.

## Source

- The ABIZ specification and schema: https://github.com/abiz-org/abiz-agentic-business-record
- The pinned schema: https://resolve.abizrecord.org/schema/abiz-business-record-v1.schema.json (SHA-256 20c5d55b05e809b3f3bb360b1d7e54393eaba66b8a78c91af8ffdaa01c0a7c0c)
- Health: https://resolve.abizrecord.org/health
