Skip to main content
GET /v1/items/lookup answers with the item itself, not a job to poll. It is the light path next to import: metadata and captions only, no media bytes, no reference created in your library.
URL-encode the url value, as --data-urlencode does. An unencoded & in the link ends the value there, and the rest, such as &t=10s, arrives as a parameter of its own. Parameter names are case-sensitive. An unknown one, such as t or maxage, is refused with invalid_input, details.field naming it and details.reason set to unknown_parameter. A lookup takes 1–6 seconds live, under 0.2 seconds from the store, and never more than 20 seconds. YouTube is read from its watch page in about a second; on the rare page that cannot be read, a slower engine answers instead (about 12 seconds). include=transcript on an item with captions usually refetches them live even within maxAge (see Transcripts), so it takes live time and can come close to the 20-second limit. Call GET /v1/resolve first if you want to know for free whether a link is supported.

The item

Two discriminators tell you what to read:
  • platform names the one platform block that is filled. For a tiktok item, tiktok is an object and instagram and youtube are null. For meta_ad_library all three are null.
  • ad is filled if and only if kind is ad.
kind is video, short, image, carousel, or ad.

Core and blocks

A field is in the common core only when at least two platforms publish it with the same meaning. Everything else lives in the platform block, so nothing is squeezed into a field it does not fit. An Ad Library ad reports publishedAt: null and every stats value null: the library publishes a run window, not a publication date or engagement. The run start is ad.startedAt, and ad.deeplinkId is the id carried by the URL you sent, so you can join the link you had to the item you got.

Unknown values

An unknown value is null, never 0 and never invented. unavailableFields lists, in a fixed order, every core field whose value in this response is unknown:
stats.comments is 0 because the source reported zero comments, so it is not listed. transcript is listed only when you asked for one and there is none.

Freshness and maxAge

Refmatter keeps a canonical record of every item it has seen, shared by everyone who asks for it. When it already holds an observation of the item confirmed no longer ago than maxAge, the lookup answers from that record without touching the platform, and observedAt is the time the observation was last confirmed. An import writes the same observation a lookup does, so a URL your workspace imported five minutes ago is served from the store. A live fetch that finds the item unchanged renews the confirmation time without rewriting history; observations are immutable, and a changed count records a new one. Thumbnail URLs on TikTok, Instagram, and Meta are signed and expire, so they are never stored. A store hit for those platforms returns thumbnails: [] and lists thumbnails in unavailableFields. YouTube thumbnail URLs are stable and are kept. When you need a thumbnail you can rely on, ask with maxAge=0.

Credits

One credit buys one item for your workspace for the length of your maxAge. usage.lines lists only charged parts, and usage.creditsCharged is their sum. At a zero balance a lookup that would charge answers 402 insufficient_credits before the platform is contacted; a repeat within your maxAge is free and keeps answering from the store. Consequences worth knowing:
  • The window is yours. Once your workspace paid for an item, nothing another workspace or an import does to it costs you again within your maxAge: if someone refreshed the item, you are served the newer counts free.
  • The window is measured from your last charge for the item, with the maxAge of the request you are making. A request with a shorter maxAge than the time since that charge pays again.
  • Five concurrent repeats of the same stored item charge at most once.
  • A lookup does not store transcripts, so include=transcript on an item with captions reads the platform again each time. When that read is free for you, it runs at most once a minute per item: a sooner repeat answers 429 rate_limited with retryAfterSeconds. A read you pay for is never refused this way.

Transcripts

include=transcript returns timed text built from the platform’s own captions. There is no speech recognition, and a transcript is never charged on its own: one that turns out to be empty adds nothing to the price of the item.
source is captions for a human-authored track or automatic_captions for the platform’s speech recognition. Instagram and Meta Ad Library publish no captions, so they always answer transcript: null. When the stored facts say the item has no caption track, the store answers null without a fetch. When the item has captions and none is stored, the lookup refetches them live, free for a workspace that already paid for that observation. A lookup does not keep the transcript. Use import when you want a transcript stored with a reference.

Headers

Server-Timing omits a phase that did not run, so a store hit carries total alone. A fetch whose result could not be written carries persist;dur=…;desc="failed", and the item comes back with creditsCharged: 0.

Rate limits

Every platform request waits for source capacity first. A lookup waits up to 1.5 seconds for it; if none frees up it answers 429 rate_limited without contacting the platform, free, with an honest wait:
Retry-After carries the same number. Wait it out rather than retrying at once: it is computed from real slot, pace, and cooldown state, so after a platform challenge it can be minutes or hours rather than seconds.

Errors

Every one of these is free and carries Refmatter-Credits-Charged: 0. unsupported_object names what you sent and what to do instead:
The full vocabulary is in Errors.

From an agent

The MCP server exposes the same two operations. lookup_item states its price and latency in its own description, and resolve_url is free, so an agent can check a link before spending anything.
See MCP server for setup.

Not in this endpoint

  • Media bytes. A lookup never downloads video or audio; use import for that, and for a reference you can annotate and keep.
  • Short share links (vm.tiktok.com, vt.tiktok.com, tiktok.com/t/…, instagram.com/share/…). Open them once and pass the URL they land on.
  • TikTok photo posts. The TikTok route serves videos; images and carousels are served through Instagram.
  • Accounts, lists, and search. Lookup answers one item at a time.