request_crawl

Subscribe your organization to a Crawl Target so the AdCrunch Library starts pulling that brand or keyword.

Tells AdCrunch to start crawling a specific brand or keyword into the shared Library corpus on behalf of your organization. On first track, the subscription is recorded and a fetch is enqueued immediately — the appropriate per-provider workflow runs within minutes.

Use this when an agent searches with search_ads and finds that a brand you care about isn’t in the corpus yet — request_crawl is how you seed it.

Input

FieldTypeRequiredDescription
provider'meta' | 'tiktok'yesAd library to crawl. Only meta and tiktok are wired for now.
type'brand' | 'keyword'yesbrand tracks a single Page / advertiser by id. keyword issues a free-text search against the provider library.
valuestring (1–200 chars)yesNumeric Page ID (Meta) or business_id (TikTok) when type=brand; search terms when type=keyword.

Brand values must be numeric (e.g. "123456789012345"). The tool returns an error if you pass a non-numeric brand value.

Output

FieldTypeDescription
status'created' | 'already_tracked'created on first subscription; already_tracked if your org already tracks this target.
targetId`tgt_${string}`Deterministic id, stable across re-tracks and across orgs.

No synchronous crawl

request_crawl does not wait for the crawl to run. On first track it records the subscription, pushes a message onto the library-crawl-request queue, and returns. A consumer in worker-library picks the message up and dispatches the per-provider fetch workflow — fresh data shows up in search_ads / get_ad results within minutes (subject to provider rate limits), not on the daily cron tick. There is no “wait until crawled” path.

Re-tracks don't re-crawl

When status === "already_tracked", no fetch is enqueued. The corpus is shared across orgs, so once any org has triggered a crawl for this (provider, type, value), the ads are visible to everyone. To force a refresh of a stale brand, wait for the daily cron orchestrator to pick it up.

Shared corpus, private subscriptions

The crawl target itself is global: if two orgs both track Nike, the crawler still fetches Nike’s ads once and stores them in the shared corpus. Your subscription (tracked_targets) is private to your org and is what keeps the target alive in the crawl rotation.

Examples

Track a brand by Page ID

“Add Nike on Meta to our tracking list.”

request_crawl({
  provider: 'meta',
  type: 'brand',
  value: '15087023444', // Nike's Meta Page ID
});

Returns:

{ "status": "created", "targetId": "tgt_abc123..." }

Track a TikTok advertiser

“Start crawling TikTok ads from Duolingo.”

request_crawl({
  provider: 'tiktok',
  type: 'brand',
  value: '7012345678901234567', // Duolingo's TikTok business_id
});

Track a keyword

“Crawl any Meta ad that mentions ‘AI coding assistant’.”

request_crawl({
  provider: 'meta',
  type: 'keyword',
  value: 'AI coding assistant',
});

Idempotent re-track

If you call request_crawl again with the exact same (provider, type, value), the existing subscription is returned untouched — same targetId, but status: "already_tracked":

request_crawl({
  provider: 'meta',
  type: 'brand',
  value: '15087023444',
});
// → { "status": "already_tracked", "targetId": "tgt_abc123..." }

Agents can call this safely without checking first — the deterministic tgt_<hash> id means re-tracking is a no-op write.

Agent-driven seeding loop

A common pattern: an agent searches, finds the corpus is thin for a brand, seeds it, and tells the user when to check back.

“Compare Adidas and Nike’s current Meta ads.”

// 1. Try searching first.
search_ads({ brandId: 'brn_nike_meta', limit: 20 });
// → empty / few results

// 2. Seed the missing brand.
request_crawl({
  provider: 'meta',
  type: 'brand',
  value: '15087023444', // Nike
});
// → { status: "created", targetId: "tgt_..." }

request_crawl({
  provider: 'meta',
  type: 'brand',
  value: '20796650100', // Adidas
});
// → { status: "created", targetId: "tgt_..." }

// 3. Tell the user fresh data lands on the next crawl tick.

Errors

  • Invalid brand value — returns an error result when type=brand but value is not a numeric provider id (Meta Page ID or TikTok business_id).
  • 401 Unauthorized — the OAuth token has expired. Re-authorize from your AI client’s settings.