Skip to content

Typed absence

Every successful call returns the same envelope, whether or not there was anything to return:

{
"request_id": "req_01K3D5NQ8XJ0R9Y2F4W6T7B8CV",
"status": "not_found",
"data": null,
"claims": [],
"sources": [],
"meta": { "duration_ms": 12 }
}

The HTTP status is 200. The question was answered; the answer is that there is nothing.

status Means
found A subject was resolved and data describes it.
not_found We looked, across the sources listed in meta.coverage, and there is no such subject.
unknown We could not establish an answer. reason says why.
ambiguous The input matched more than one subject and none is authoritative.
partial A batch or multi-source call succeeded for some items and not others.

not_found and unknown are different, and the difference is load-bearing

Section titled “not_found and unknown are different, and the difference is load-bearing”

not_found is a finding. unknown is the absence of a finding. Collapsing them is the error this model exists to prevent: it turns “our source was down” into “this product does not exist”, which is a false statement about the world rather than a description of our own limits.

When status is unknown, reason is always present:

reason Means
NO_SOURCE No source covers this subject.
SOURCE_UNAVAILABLE A source that would cover it did not answer.
OUT_OF_SCOPE The subject is outside what this service resolves.
LICENCE_RESTRICTED Data exists but its licence does not permit this response.
TIMEOUT The lookup exceeded its budget.
AMBIGUOUS_INPUT The input could not be narrowed to one subject.
  • Do not treat a non-found status as a failure. It is a successful call. Retrying a not_found will produce the same not_found and spend quota.
  • unknown is the retryable one, and only for the transient reasons — SOURCE_UNAVAILABLE and TIMEOUT. Retrying NO_SOURCE or OUT_OF_SCOPE cannot change the answer.
  • Dispatch on status, then on reason. Not on the HTTP code, which is 200 for all five.
  • meta.coverage, when present, says what was consulted. It is how you distinguish “this does not exist” from “we do not cover where it would be”.

Real errors — a malformed identifier, a missing key, an exhausted quota — do use HTTP status codes, and arrive as application/problem+json. See Errors.