GET /v1/search returns one page of search results inside the request. platform says where to search, and type chooses item rows or account rows.
type itself: search.items asks for item rows and search.accounts for account rows.
platform is always required, on a first page and on a cursor page alike. q is required when cursor is absent. A cursor excludes q, type, and every filter; pass it with platform and nothing else, optionally with maxAge. A cursor that continues another platform’s search is refused with 400 invalid_input and details.reason: "platform_mismatch".
What each platform offers
Instagram and TikTok answer
422 unsupported_object: neither publishes a search to a visitor who is not signed in. The Ad Library answers about advertisers only, so type=items on it is refused, and uploadDate, duration, and sort are refused there as well. country on YouTube is refused the same way. Every one of those refusals is 400 invalid_input with details.reason: "not_available_for_platform", details.platform, and a plain details.hint such as sort=popular is not available for meta_ad_library. — never a silently ignored parameter.
Item results
Whentype=items, the response is an ItemSummaryList.
Account results
Whentype=accounts, the response is an AccountList. A YouTube search answers with channels.
meta_ad_library block.
id straight to List an account’s items as account.
What you get and what you do not
totalApproximate sits next to total and says what the number is. A YouTube search reports true, because YouTube states an estimate that can change between pages. An Ad Library search reports false: the total is the number of rows in the answer. totalApproximate is null whenever total is null.
Item search rows include viewsApproximate. The example reports false, so that value is typically exact for that result. The contract still allows true or null, so read the flag instead of assuming precision. Search rows provide relative publishedText; publishedAt is null in the normal search projection.
YouTube account rows include id, platform, handle, name, url, description, avatar, verified, and stats.followers. They do not include stats.following or the full account response fields such as banners, links, country, or joined date, and their meta_ad_library is null.
An Ad Library row names one advertiser page: its id, the page alias as handle, its name, its Ad Library link, its picture, and its like count as stats.followers. The meta_ad_library block adds the page category, the same like count, the Instagram profile Meta shows beside the page, and pageDeleted for a page that no longer exists but whose ads are still archived. description is null: the suggestion list carries no page description. handle is null for a page that has set no alias. A picture the Ad Library serves from an address we do not read costs that row its avatar, never the page.
Paging
Passpage.nextCursor back as cursor, with the same platform and nothing else, optionally with maxAge. Cursors expire after 24 hours. A cursor is not tied to your workspace, but each workspace pays for the pages it is served.
The Ad Library has no cursor. Its own search box offers a short list of suggestions — up to fifteen — and no way to ask for more, so page.nextCursor is always null and page.hasMore is always false. Narrow q, or set country, to see different advertisers.
Freshness
maxAge defaults to 15m and accepts up to 1d. A stored search page confirmed within the window can be served without contacting the platform. Observations are immutable.
Credits
usage.creditsCharged is the number charged in this response. Errors are always free.
At a zero balance a live page answers 402 insufficient_credits before the platform is contacted; a repeat within your maxAge and an empty page are free and keep answering.
Headers
Rate limits
If no platform request can start, the endpoint returns429 rate_limited with details.retryAfterSeconds. Wait that many seconds before trying again. Errors are free.
Errors
A phrase that matches nothing is an empty page, not an error, and costs nothing.
From an agent
Usesearch_items for item rows and search_accounts for account rows; both take platform and q. Pass page.nextCursor as cursor with the same platform. Then pass an advertiser row’s id to list_items as account. All of them return one page synchronously.