> ## Documentation Index
> Fetch the complete documentation index at: https://docs.pilotstatus.com.br/llms.txt
> Use this file to discover all available pages before exploring further.

# Link an ad account

> The Meta ad accounts this workspace has connected, so Pilot Status can resolve the ad, ad set and campaign **names** of your Click-to-WhatsApp traffic, plus the accounts you can still connect.

There is no Meta login step: the advertiser adds the Pilot Status business portfolio (`partnerBusinessId`) as a **partner** of the ad account in Meta Business Manager, and Pilot Status reads with its own system user.

**Account-wide credential only** (a number-scoped key is refused with `403 NUMBER_SCOPE_NOT_ALLOWED`): an ad account belongs to the workspace, not to a number. OAuth/MCP tokens need `integrations:manage` (workspace ADMIN or OWNER) on every verb, reads included.

Body: `{ "adAccountId": "act_<digits>" }` and nothing else — any other field is refused with `400 UNKNOWN_FIELDS`. Before anything is written, Pilot Status checks that the account is this workspace's (`409 AD_ACCOUNT_NOT_PROVEN` when no ad from it reached your conversations — contact support) and that the partner grant reached Meta (`409 AD_ACCOUNT_NOT_SHARED`). Linking an account that was unlinked before revives the same link.



## OpenAPI

````yaml openapi.json POST /v1/ads/accounts
openapi: 3.1.0
info:
  title: Pilot Status API
  version: 1.0.0
  license:
    name: Pilot Status Terms of Service
    url: https://pilotstatus.com.br/terms
  description: >-
    Public REST API for Pilot Status. Authenticate with the `x-api-key: ps_...`
    header (or `x-api-key-id`). Base URL: https://pilotstatus.com.br
servers:
  - url: https://pilotstatus.com.br
security:
  - apiKey: []
  - apiKeyId: []
paths:
  /v1/ads/accounts:
    post:
      tags:
        - Ads
      summary: Link an ad account
      description: >-
        The Meta ad accounts this workspace has connected, so Pilot Status can
        resolve the ad, ad set and campaign **names** of your Click-to-WhatsApp
        traffic, plus the accounts you can still connect.


        There is no Meta login step: the advertiser adds the Pilot Status
        business portfolio (`partnerBusinessId`) as a **partner** of the ad
        account in Meta Business Manager, and Pilot Status reads with its own
        system user.


        **Account-wide credential only** (a number-scoped key is refused with
        `403 NUMBER_SCOPE_NOT_ALLOWED`): an ad account belongs to the workspace,
        not to a number. OAuth/MCP tokens need `integrations:manage` (workspace
        ADMIN or OWNER) on every verb, reads included.


        Body: `{ "adAccountId": "act_<digits>" }` and nothing else — any other
        field is refused with `400 UNKNOWN_FIELDS`. Before anything is written,
        Pilot Status checks that the account is this workspace's (`409
        AD_ACCOUNT_NOT_PROVEN` when no ad from it reached your conversations —
        contact support) and that the partner grant reached Meta (`409
        AD_ACCOUNT_NOT_SHARED`). Linking an account that was unlinked before
        revives the same link.
      operationId: post_ads-accounts
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                adAccountId:
                  type: string
                  pattern: ^act_\d+$
                  description: Meta ad account id, `act_` followed by digits.
                  example: act_1234567890
              required:
                - adAccountId
              additionalProperties: false
      responses:
        '201':
          description: Ad account linked
          content:
            application/json:
              example:
                link:
                  adAccountId: act_1234567890
                  adAccountName: MM Design
                  linkedAt: '2026-10-05T14:02:11.000Z'
        '400':
          description: >-
            Body is not a JSON object (`INVALID_BODY`), carries an unknown field
            (`UNKNOWN_FIELDS`, with `unknownFields`), or `adAccountId` is not
            `act_<digits>` (`VALIDATION_FAILED`, with `details`)
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                  code:
                    type: string
              example:
                error: >-
                  Unknown field(s): token. This endpoint accepts only:
                  adAccountId. | Campo(s) desconhecido(s): token. Este endpoint
                  aceita apenas: adAccountId.
                code: UNKNOWN_FIELDS
                unknownFields:
                  - token
        '401':
          description: Missing or invalid `x-api-key` / `x-api-key-id` header
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                  code:
                    type: string
              example:
                error: Unauthorized
        '403':
          description: >-
            Number-scoped key (this endpoint needs an account-wide credential),
            or an OAuth token whose workspace role lacks `integrations:manage`
            (`PERMISSION_DENIED`)
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                  code:
                    type: string
              example:
                error: This endpoint requires a tenant-scoped API key
                code: NUMBER_SCOPE_NOT_ALLOWED
        '409':
          description: >-
            `AD_ACCOUNT_NOT_PROVEN` (no ad from this account reached this
            workspace's conversations) or `AD_ACCOUNT_NOT_SHARED` (the account
            has not shared access with Pilot Status yet)
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                  code:
                    type: string
              example:
                error: >-
                  This ad account has not shared access with Pilot Status yet. |
                  Esta conta de anúncios ainda não compartilhou acesso com a
                  Pilot Status.
                code: AD_ACCOUNT_NOT_SHARED
        '500':
          description: Internal error
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                  code:
                    type: string
              example:
                error: Internal server error | Erro interno do servidor
                code: INTERNAL_ERROR
        '502':
          description: Meta could not be asked about the sharing right now. Retry.
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                  code:
                    type: string
              example:
                error: >-
                  Could not confirm the sharing with Meta right now. Try again.
                  | Não foi possível confirmar o compartilhamento com a Meta
                  agora. Tente novamente.
                code: ADS_LOOKUP_UNAVAILABLE
        '503':
          description: The ads integration is not configured on this installation
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                  code:
                    type: string
              example:
                error: >-
                  The ads integration is not configured on this installation. |
                  Integração de anúncios não configurada nesta instalação.
                code: ADS_NOT_CONFIGURED
components:
  securitySchemes:
    apiKey:
      type: apiKey
      in: header
      name: x-api-key
      description: Your ps_ API key
    apiKeyId:
      type: apiKey
      in: header
      name: x-api-key-id
      description: API key id (alternative to x-api-key)

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.