# Reading a response

Every call answers with the same envelope. Learn it once and every platform reads alike: what came back, what did not and why, when it was measured, how sure to be, and what it cost.

## The envelope

`data` is per op — the profiles, posts, products or rows asked for. The other fields are identical on every platform. The values in this example are illustrative; the **shape** is the contract.

```json
{
  "data": {
    "profiles": [
      { "username": "example", "followers": 48210, "…": "…" }
    ]
  },
  "coverage": [
    {
      "platform": "instagram",
      "requested": 2,
      "returned": 1,
      "omitted": [ { "subject": "gone_account", "reason": "not_found", "note": null } ]
    }
  ],
  "provenance": [
    {
      "platform": "instagram",
      "subject": "example",
      "measuredAt": "2026-09-06T08:12:41+00:00",
      "source": "capture",
      "cacheAgeSeconds": null
    }
  ],
  "confidence": { "followers": "measured", "engagementRate": "derived" },
  "cost": { "creditsCharged": 3, "creditsRemaining": 997, "chargedFor": ["instagram:profiles:example"] },
  "notes": [],
  "contextVersion": "3",
  "engineVersion": "1.14.28"
}
```

-   `coverage` — per platform, how many subjects were asked for, how many came back, and each one that did not with a typed reason. `requested` always equals `returned` plus the omissions.
-   `provenance` — per subject, when it was measured and whether this answer was a fresh `capture` or served from what was already held (`cache`, with its age in seconds).
-   `confidence` — per field: `measured` (the platform reported it), `derived` (computed from measured inputs, such as an engagement rate) or `unavailable` (cannot be known — an explicit value, never a missing key).
-   `cost` — what the ledger actually charged for this call, the balance after it, and which items were charged for. Read from the ledger, never recomputed from a price list.
-   `notes` — anything a reader should know that has no field of its own.

## Partial success is success

A subject that could not be served does not fail the call. It arrives as an entry in `coverage.omitted` with one of the reasons below, and the rest of the answer is whole. Each reason maps to a different next step, which is why it is a code and not a sentence.

<table class="w-full min-w-[520px] border-collapse text-left text-sm"><tbody><tr class="border-b border-border align-top last:border-b-0"><td class="px-4 py-2.5 whitespace-nowrap"><code class="font-mono text-[12.5px] text-foreground">not_found</code></td><td class="px-4 py-2.5 text-muted-foreground">The handle or id did not resolve. A finding about the subject as typed — check it, never conclude the thing does not exist.</td></tr><tr class="border-b border-border align-top last:border-b-0"><td class="px-4 py-2.5 whitespace-nowrap"><code class="font-mono text-[12.5px] text-foreground">private_account</code></td><td class="px-4 py-2.5 text-muted-foreground">It exists and hides its data. Terminal: nothing more will arrive by asking again.</td></tr><tr class="border-b border-border align-top last:border-b-0"><td class="px-4 py-2.5 whitespace-nowrap"><code class="font-mono text-[12.5px] text-foreground">vendor_unavailable</code></td><td class="px-4 py-2.5 text-muted-foreground">The source could not answer right now. Reasonable to retry later. Nothing was charged for it.</td></tr><tr class="border-b border-border align-top last:border-b-0"><td class="px-4 py-2.5 whitespace-nowrap"><code class="font-mono text-[12.5px] text-foreground">budget_exhausted</code></td><td class="px-4 py-2.5 text-muted-foreground">maxCredits could not cover it. Raise the budget or ask for less.</td></tr><tr class="border-b border-border align-top last:border-b-0"><td class="px-4 py-2.5 whitespace-nowrap"><code class="font-mono text-[12.5px] text-foreground">field_unavailable</code></td><td class="px-4 py-2.5 text-muted-foreground">The platform does not publish this for this subject.</td></tr><tr class="border-b border-border align-top last:border-b-0"><td class="px-4 py-2.5 whitespace-nowrap"><code class="font-mono text-[12.5px] text-foreground">structurally_impossible</code></td><td class="px-4 py-2.5 text-muted-foreground">The ask contradicts itself for this platform (a filter it cannot honour). The note says which.</td></tr><tr class="border-b border-border align-top last:border-b-0"><td class="px-4 py-2.5 whitespace-nowrap"><code class="font-mono text-[12.5px] text-foreground">platform_unsupported</code></td><td class="px-4 py-2.5 text-muted-foreground">Not served. The miss is recorded as demand.</td></tr></tbody></table>

## Measured, not estimated

Nothing in `data` is a guess. A number is what the platform showed at `measuredAt`; if it was measured three weeks ago, the provenance says so, and the honest sentence is "had 48k followers as of that date". A value that could not be measured is absent from `data` and named in `confidence` as `unavailable`.

Read `coverage` and `notes` before concluding anything from an empty list. A named omission is an answer; an empty list with no omission is a measured nothing.

---

Source: https://zomler.com/docs/api/responses
