Skip to main content
Two things you could only do in the dashboard until now are also in the public API and the MCP server:
  • Ad accounts — connect the Meta ad accounts whose ads bring people to your numbers, so Pilot Status can resolve each ad’s name, its ad set and its campaign.
  • Ads summary — Click-to-WhatsApp traffic grouped by ad: conversations, messages, the resolved names and how many Lead Ads leads each ad produced.
The Facebook Pages and Instant Forms of Meta Lead Ads have their own page: Lead Ads Pages and forms.

Endpoints

No Meta login: partner sharing

No endpoint here asks for a Meta token, and none ever will. Access comes from partner sharing: the advertiser adds the Pilot Status business portfolio — the partnerBusinessId returned by GET /v1/ads/accounts — as a partner of the ad account in Meta Business Manager. That is the only manual step, and it happens on Meta’s side. Pilot Status then reads with its own system user.

Credentials and permissions

A classic ps_ key has no role and passes the permission check by its scope. On the summary, a number-scoped key — or an account-wide credential with the x-whatsapp-number-id header — reports that number only; an account-wide credential without the header reports the whole workspace.

GET /v1/ads/accounts

  • sharingActive — true while the partner grant is in place, false when the advertiser revoked it on Meta, and null when Meta could not be asked right now. Never read null as revoked.
  • candidates — accounts shared with Pilot Status that provably belong to your workspace, because an ad from them already reached one of your numbers, and are not linked yet. A new workspace starts with an empty list; link your account by its id.
  • sharingLookup — ok, unavailable (Meta did not answer; linked still comes back) or not_configured.

POST /v1/ads/accounts

The body takes adAccountId (act_ followed by digits) and nothing else: any other field — a token, for example — is refused with 400 UNKNOWN_FIELDS. The answer is 201 { "link": { … } }. Two checks run before anything is written:
  1. The account must be yours. If no ad from it reached your conversations yet, the answer is 409 AD_ACCOUNT_NOT_PROVEN — contact support to link it.
  2. The partner grant must have reached Meta. Otherwise 409 AD_ACCOUNT_NOT_SHARED.
Linking an account you unlinked before revives the same link.

DELETE /v1/ads/accounts/{adAccountId}

Disconnects the account: its ads stop getting new names. The link is kept as history, so names already resolved stay. Answers 200 { "unlinked": true, "adAccountId": "act_…" }, or 404 NOT_FOUND when the account was never linked, was already unlinked, or belongs to another workspace.

GET /v1/ads/summary

string
Restrict to one number inside the credential’s scope. A number outside it answers 403 NUMBER_NOT_IN_GRANT.
string
Start of the range (ISO 8601), over the message time — and the lead’s Meta creation time for leadCount. Must be before or equal to endDate.
string
End of the range (ISO 8601), inclusive.
  • conversations and messages are separate counts: distinct conversations, and messages.
  • leadCount — Lead Ads leads the same ad produced, under the same number scope and date range. An ad that produced leads but never a conversation has no row here: read it from GET /v1/leads.
  • Names: namesResolvedAt set with every name null means Pilot Status asked Meta and got nothing — usually the partner grant is missing. null means it has not asked yet.
  • Privacy: lastHeadline and lastSourceUrl (the ad copy) are null for an ad seen only on a RELAY_ONLY number. The counts do not change. The report never carries conversation content.
  • Cap: at most 200 ads, busiest first. truncated: true says the list was cut — narrow it with startDate/endDate.
GET /v1/referrals/summary is the per-number, chat:read view of the same traffic.

Errors

The refusals of these endpoints carry { "error": "<English> | <Português>", "code": "…" }; the authentication and permission refusals (401, 403 NUMBER_SCOPE_NOT_ALLOWED, 403 PERMISSION_DENIED) keep the body they have on every /v1 endpoint.