> ## 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.

# Get Flow endpoint key state

> The `data_exchange` endpoint keypair of ONE number: whether one exists (`configured`), its public half (`publicKey`), when Meta accepted it (`uploadedAt`), the base URL to register on a Flow (`endpointUrl`), and — the part that has no other symptom — what META says it holds (`metaStatus`).

⛔ `metaStatus` has FOUR values and `UNKNOWN` is not `NOT_SET`. `VALID` is Meta holding the key we hold; `MISMATCH` is Meta holding a DIFFERENT one, which silently breaks every `data_exchange` Flow on the number and raises no error on our side; `NOT_SET` is Meta answering that it holds no key; `UNKNOWN` is us failing to ask. Collapsing the last two makes an operator rotate over a transient Graph 500 — and rotating replaces the key Meta holds.

`uploadedAt: null` means a pair was generated here but Meta never accepted it. That is not the same as no key at all, and it is the state a repeat `POST` RESUMES rather than replaces.

The PRIVATE half is never in this payload. `endpointUrl` is a credential — it embeds the number's endpoint path token — which is why the permission is `flows:manage` and deliberately not `flows:read`. Append the Flow id as a final segment to get the `endpoint_uri` of one Flow.

⚠️ The `{id}` in the path is CHECKED against the credential's own number, never used to look one up. A path id that does not match answers 404 `FLOW_NUMBER_NOT_FOUND` — never 403, and the same body whether the id belongs to another tenant or to another of your own numbers, so a wrong guess learns nothing.

**Requires a number-scoped key.** A tenant-scoped key must name the number with the `x-whatsapp-number-id` header, or it gets 403 `TENANT_SCOPE_NOT_ALLOWED`.



## OpenAPI

````yaml openapi.json GET /v1/numbers/{id}/flow-endpoint-key
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/numbers/{id}/flow-endpoint-key:
    get:
      tags:
        - Numbers
      summary: Get Flow endpoint key state
      description: >-
        The `data_exchange` endpoint keypair of ONE number: whether one exists
        (`configured`), its public half (`publicKey`), when Meta accepted it
        (`uploadedAt`), the base URL to register on a Flow (`endpointUrl`), and
        — the part that has no other symptom — what META says it holds
        (`metaStatus`).


        ⛔ `metaStatus` has FOUR values and `UNKNOWN` is not `NOT_SET`. `VALID`
        is Meta holding the key we hold; `MISMATCH` is Meta holding a DIFFERENT
        one, which silently breaks every `data_exchange` Flow on the number and
        raises no error on our side; `NOT_SET` is Meta answering that it holds
        no key; `UNKNOWN` is us failing to ask. Collapsing the last two makes an
        operator rotate over a transient Graph 500 — and rotating replaces the
        key Meta holds.


        `uploadedAt: null` means a pair was generated here but Meta never
        accepted it. That is not the same as no key at all, and it is the state
        a repeat `POST` RESUMES rather than replaces.


        The PRIVATE half is never in this payload. `endpointUrl` is a credential
        — it embeds the number's endpoint path token — which is why the
        permission is `flows:manage` and deliberately not `flows:read`. Append
        the Flow id as a final segment to get the `endpoint_uri` of one Flow.


        ⚠️ The `{id}` in the path is CHECKED against the credential's own
        number, never used to look one up. A path id that does not match answers
        404 `FLOW_NUMBER_NOT_FOUND` — never 403, and the same body whether the
        id belongs to another tenant or to another of your own numbers, so a
        wrong guess learns nothing.


        **Requires a number-scoped key.** A tenant-scoped key must name the
        number with the `x-whatsapp-number-id` header, or it gets 403
        `TENANT_SCOPE_NOT_ALLOWED`.
      operationId: get_numbers_id_flow_endpoint_key
      parameters:
        - name: id
          in: path
          required: true
          description: >-
            The id of the number the key is bound to — the `id` (or instance id)
            `GET /v1/numbers` returns. It is CHECKED against the credential's
            own number, never used to look one up.
          schema:
            type: string
          example: num_01HZX...
      responses:
        '200':
          description: >-
            The number's `data_exchange` endpoint keypair as it stands here and
            at Meta. The private half is never in the payload
          content:
            application/json:
              example:
                configured: true
                publicKey: |
                  -----BEGIN PUBLIC KEY-----
                  MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA...
                  -----END PUBLIC KEY-----
                uploadedAt: '2026-09-02T10:00:00.000Z'
                endpointUrl: https://pilotstatus.com.br/api/flows/endpoint/AbC123...
                metaStatus: VALID
        '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: >-
            Tenant-scoped key used on a number-scoped endpoint, or the key's
            role lacks `flows:manage`
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                  code:
                    type: string
              example:
                error: >-
                  This endpoint acts on a single WhatsApp number: send the
                  x-whatsapp-number-id header naming the number to act on (its
                  id or instance id from GET /v1/numbers) | Este endpoint atua
                  sobre um único número de WhatsApp: envie o header
                  x-whatsapp-number-id indicando o número desejado (o id dele ou
                  o id da instância, obtidos em GET /v1/numbers)
                code: TENANT_SCOPE_NOT_ALLOWED
        '404':
          description: >-
            The path `{id}` is not the number this credential is bound to. Never
            403: another tenant's number and another of your own numbers answer
            the same body, byte for byte, so a guessed id is never confirmed
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    description: Portuguese half
                  errorEN:
                    type: string
                    description: English half
                  code:
                    type: string
              example:
                error: >-
                  Número não encontrado para esta chave. Esta rota atua sobre o
                  número ao qual a chave está vinculada — use a chave do número
                  em questão, ou o header x-whatsapp-number-id se a chave for de
                  conta.
                errorEN: >-
                  Number not found for this key. This route acts on the number
                  the key is bound to — use that number's key, or the
                  x-whatsapp-number-id header if the key is an account-wide one.
                code: FLOW_NUMBER_NOT_FOUND
        '422':
          description: >-
            The key's number is not a Meta (Cloud API) number, or has no WABA
            behind it
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    description: Portuguese half
                  errorEN:
                    type: string
                    description: English half
                  code:
                    type: string
              example:
                error: >-
                  Flows existem apenas em números Meta (API Oficial). O número
                  desta chave não é Meta ou não tem uma WABA associada — use uma
                  chave de um número Meta.
                errorEN: >-
                  Flows only exist on Meta (Cloud API) numbers. This key's
                  number is not a Meta number, or has no WABA behind it — use a
                  key bound to a Meta number.
                code: FLOW_REQUIRES_META_NUMBER
        '429':
          description: Rate limit exceeded
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                  code:
                    type: string
              example:
                error: Too many requests
        '500':
          description: >-
            Internal error. Never carries the internal message — that belongs in
            the log
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    description: Portuguese half
                  errorEN:
                    type: string
                    description: English half
                  code:
                    type: string
              example:
                error: Erro interno do servidor.
                errorEN: Internal server error.
                code: INTERNAL_ERROR
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)

````