Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion mcp-server.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -535,7 +535,8 @@ Tool failures come back as MCP tool errors with a short machine-readable prefix:

A completed lookup that returns a normalized empty result such as `found: false` is not a
tool error. It is a successful answer: the lookup ran and the account, post, video, or
page does not exist, was removed or suspended, or the search matched nothing. It is
page does not exist, was removed or suspended, or the search matched nothing, and
`output.reason` says which (`not_found`, or `suspended` for a suspended account). It is
charged only when the source charged AnyAPI for the lookup; a miss the source did not bill
is free. Read `costUsd` for what the call actually cost, which is `0` when nothing was
charged for it.
Expand Down
8 changes: 5 additions & 3 deletions quickstart.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -119,9 +119,11 @@ Prefer to do it yourself? Follow the manual steps below.
```

<Note>
A legitimate "not found" is a success: `output` is `{ "found": false, "data": null }`.
You get it when the account, post, video, or page you named does not exist, has been
removed or suspended, or a search matched nothing. You are charged for it only when the
A legitimate "not found" is a success: `output` is
`{ "found": false, "data": null, "reason": "not_found" }`. You get it when the
account, post, video, or page you named does not exist, has been removed, or a search
matched nothing; a suspended account says `"reason": "suspended"` on an API whose source
can tell. Each API's output schema lists the exact reasons it can answer with. You are charged for it only when the
source charged AnyAPI for the lookup; a miss the source did not bill is free. Failed
calls are never charged, and `costUsd` is always what this call actually cost you -
`0` when nothing was charged for it. See [Not found vs error](/sdks#not-found-vs-error)
Expand Down
16 changes: 13 additions & 3 deletions sdks.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -164,12 +164,16 @@ flag: `output.found` is `false` when the upstream had no matching entity, which
successful answer, not an error. Use `unwrap` to get the data or raise
`ResultNotFoundError` when the result is empty.

Every outcome maps to exactly one shape:
Every outcome maps to exactly one shape, and every `found: false` answer says why in
`output.reason`. Each API's output schema lists the exact words that API can answer with,
so the schema is that API's contract for a miss, it is typed in both SDKs, and it is never
the source's own wording:

| You asked for | You get |
| --- | --- |
| An account, post, video, or channel that does not exist, or a search with no matches | `200` with `output.found: false` and `data: null` |
| An account that is suspended, deleted, or removed by the platform | `200` with `output.found: false` |
| An account, post, video, or channel that does not exist, or a search with no matches | `200` with `output.found: false`, `data: null`, and `reason: "not_found"` |
| An account the platform has suspended | `200` with `output.found: false` and `reason: "suspended"` |
| An account deleted or removed by its owner or the platform | `200` with `output.found: false` and `reason: "not_found"`; the source cannot tell a removed account from one that never existed |
| A target the first source returns nothing for, on an API that has more than one source | Some APIs ask the next source before answering `found: false`; a source that states the target does not exist is taken at its word |
| An API slug that does not exist | `404` `NotFoundError` |
| Input the API cannot accept, such as a malformed URL or a field combination no source serves | `400` `BadRequestError`, never charged |
Expand All @@ -180,6 +184,12 @@ A `found: false` answer is billed only when the source charged AnyAPI for the lo
miss the source refused without billing is free, and `costUsd` / `cost_usd` on the
result is always what the call actually cost you.

`reason` is present only on a miss. In TypeScript it is the `NotFoundReason` union on the
`found: false` branch of `Output<T>`; in Python it is `OutputNotFound.reason`. Every API can
answer `not_found`; an API lists `suspended` only when one of its sources can tell a suspended
account apart. An API can gain a word later, so read the list from its `outputSchema` in
`/v1/apis/{slug}` or the OpenAPI document rather than hardcoding it.

<CodeGroup>
```ts TypeScript
import { unwrap, ResultNotFoundError } from "@getanyapi/sdk";
Expand Down
Loading