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

# Atualizar webhook de linha

> ⚠️ **Efeito colateral real.** Muda os campos que você enviar e responde `{ "webhook": { … } }`; um campo ausente fica como está. `active: false` **pausa** o webhook (ele não recebe entregas — uma entrega que já está nas retentativas é marcada como falha na próxima tentativa) e `active: true` o retoma; eventos ocorridos enquanto ele estava pausado nunca são enviados.

O webhook resultante é validado como na criação. **Só uma URL que muda é conferida de novo** contra destinos internos, então um webhook sempre pode ser pausado ou ter os eventos editados. Um `name` enviado em branco vira o host da URL (nova ou a guardada). **Editar nunca muda o segredo de assinatura**, e o segredo não é devolvido.

Permissões: com um token OAuth / MCP, o usuário precisa ser **Proprietário ou Administrador** (`phone_lines:webhooks`) — caso contrário, `403 PERMISSION_DENIED`.

Todo endpoint `/v1/phone-lines` aceita só uma chave **com escopo de tenant**: os webhooks das linhas pertencem ao workspace, não a um número de WhatsApp, então uma chave com escopo de número (ou uma concessão OAuth por número) recebe `403 NUMBER_SCOPE_NOT_ALLOWED` antes de qualquer verificação de papel. Um `403 PERMISSION_DENIED` / `WORKSPACE_MEMBERSHIP_REQUIRED` é enviado com `Cache-Control: no-store`.

Estes são os **webhooks das linhas** — um cadastro separado de `/v1/webhooks`: recebem só eventos `phone_line.*`, e um webhook de número nunca recebe um deles.

**Requer uma chave com escopo de tenant.**



## OpenAPI

````yaml openapi.pt.json PATCH /v1/phone-lines/webhooks/{id}
openapi: 3.1.0
info:
  title: API Pilot Status
  version: 1.0.0
  license:
    name: Pilot Status Terms of Service
    url: https://pilotstatus.com.br/terms
  description: >-
    API REST pública do Pilot Status. Autentique com o header `x-api-key:
    ps_...` (ou `x-api-key-id`). Base URL: https://pilotstatus.com.br
servers:
  - url: https://pilotstatus.com.br
security:
  - apiKey: []
  - apiKeyId: []
paths:
  /v1/phone-lines/webhooks/{id}:
    patch:
      tags:
        - Phone Lines
      summary: Editar ou pausar um webhook de linha
      description: >-
        ⚠️ **Efeito colateral real.** Muda os campos que você enviar e responde
        `{ "webhook": { … } }`; um campo ausente fica como está. `active: false`
        **pausa** o webhook (ele não recebe entregas — uma entrega que já está
        nas retentativas é marcada como falha na próxima tentativa) e `active:
        true` o retoma; eventos ocorridos enquanto ele estava pausado nunca são
        enviados.


        O webhook resultante é validado como na criação. **Só uma URL que muda é
        conferida de novo** contra destinos internos, então um webhook sempre
        pode ser pausado ou ter os eventos editados. Um `name` enviado em branco
        vira o host da URL (nova ou a guardada). **Editar nunca muda o segredo
        de assinatura**, e o segredo não é devolvido.


        Permissões: com um token OAuth / MCP, o usuário precisa ser
        **Proprietário ou Administrador** (`phone_lines:webhooks`) — caso
        contrário, `403 PERMISSION_DENIED`.


        Todo endpoint `/v1/phone-lines` aceita só uma chave **com escopo de
        tenant**: os webhooks das linhas pertencem ao workspace, não a um número
        de WhatsApp, então uma chave com escopo de número (ou uma concessão
        OAuth por número) recebe `403 NUMBER_SCOPE_NOT_ALLOWED` antes de
        qualquer verificação de papel. Um `403 PERMISSION_DENIED` /
        `WORKSPACE_MEMBERSHIP_REQUIRED` é enviado com `Cache-Control: no-store`.


        Estes são os **webhooks das linhas** — um cadastro separado de
        `/v1/webhooks`: recebem só eventos `phone_line.*`, e um webhook de
        número nunca recebe um deles.


        **Requer uma chave com escopo de tenant.**
      operationId: patch_phone_lines_webhooks_id
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
          example: cmh1w8b2k0001wh8example3d
          description: >-
            O `id` do webhook (de `GET /v1/phone-lines/webhooks` ou da resposta
            da criação).
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              properties:
                name:
                  type: string
                  maxLength: 100
                  description: >-
                    Opcional, até 100 caracteres (acima disso, `400
                    INVALID_WEBHOOK_NAME`). Em branco ou ausente → o host da
                    URL.
                  example: Linhas — produção
                url:
                  type: string
                  description: >-
                    Precisa ser `https` e apontar para um endereço público. Uma
                    URL que aponte para um endereço interno ou de rede privada —
                    `localhost`, um IP de loopback ou privado, um host sem
                    ponto, ou um nome que resolva para um desses — → `400
                    WEBHOOK_URL_REFUSED`.
                  example: https://hooks.example.com/pilot/phone-lines
                events:
                  type: array
                  minItems: 1
                  items:
                    type: string
                    enum:
                      - phone_line.purchased
                      - phone_line.audio_received
                      - phone_line.code_received
                      - phone_line.code_failed
                      - phone_line.renewed
                      - phone_line.payment_failed
                      - phone_line.suspended
                      - phone_line.returned
                      - phone_line.canceled
                      - phone_line.verification_updated
                      - '*'
                  description: >-
                    Um ou mais eventos de linha, ou `"*"` para todos (neste
                    cadastro, `"*"` significa todos os eventos de linha,
                    inclusive os adicionados depois). Duplicados são removidos.
                    Lista vazia ou evento desconhecido → `400 INVALID_WEBHOOK`.
                  example:
                    - '*'
                active:
                  type: boolean
                  description: '`false` pausa, `true` retoma.'
                  example: false
            example:
              active: false
      responses:
        '200':
          description: O webhook depois da mudança
          content:
            application/json:
              schema:
                type: object
                properties:
                  webhook:
                    type: object
                    properties:
                      id:
                        type: string
                        description: >-
                          O id do webhook. Use-o em todo caminho
                          `/v1/phone-lines/webhooks/{id}`.
                        example: cmh1w8b2k0001wh8example3d
                      name:
                        type: string
                        description: >-
                          Até 100 caracteres. **Nunca vazio:** criado ou editado
                          em branco, é o host da URL (`hooks.example.com`). Não
                          vai nas entregas — o `name` de uma entrega é o da
                          linha.
                        example: hooks.example.com
                      url:
                        type: string
                        description: O destino `https`, normalizado.
                        example: https://hooks.example.com/pilot/phone-lines
                      events:
                        type: array
                        items:
                          type: string
                        description: >-
                          Os eventos assinados, ou `["*"]` — todos os eventos de
                          linha, inclusive os adicionados depois.
                        example:
                          - '*'
                      active:
                        type: boolean
                        description: '`false` = pausado: não recebe entregas.'
                        example: true
                      lastDeliveryAt:
                        type:
                          - string
                          - 'null'
                        format: date-time
                        description: >-
                          ISO 8601 — a última entrega **bem-sucedida**, `null`
                          antes da primeira. Uma tentativa que falha não a muda.
                        example: '2026-10-27T14:11:51.000Z'
                      lastStatusCode:
                        type:
                          - integer
                          - 'null'
                        description: >-
                          O último status HTTP que o seu endpoint respondeu, com
                          sucesso ou não, `null` quando não houve.
                        example: 200
                      createdAt:
                        type: string
                        format: date-time
                        description: ISO 8601 — quando o webhook foi criado.
                        example: '2026-10-27T13:58:02.000Z'
              example:
                webhook:
                  id: cmh1w8b2k0001wh8example3d
                  name: hooks.example.com
                  url: https://hooks.example.com/pilot/phone-lines
                  events:
                    - '*'
                  active: false
                  lastDeliveryAt: '2026-10-27T14:11:51.000Z'
                  lastStatusCode: 200
                  createdAt: '2026-10-27T13:58:02.000Z'
        '400':
          description: >-
            Requisição inválida: corpo que não é um objeto JSON
            (`INVALID_BODY`), campos além de `name`, `url`, `events` e `active`
            (`UNKNOWN_FIELDS`, `details.unknownFields`), um campo com o tipo
            JSON errado (`INVALID_FIELD_TYPE`, `details.field` /
            `details.expected`), URL que não é `https` ou lista de eventos vazia
            / com evento desconhecido (`INVALID_WEBHOOK`), `name` com mais de
            100 caracteres (`INVALID_WEBHOOK_NAME`), ou URL que aponta para um
            endereço interno ou de rede privada (`WEBHOOK_URL_REFUSED`)
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                  code:
                    type: string
                  details:
                    type: object
              examples:
                invalidBody:
                  summary: Corpo não é um objeto JSON
                  value:
                    error: >-
                      Send a JSON object: { "active": false }. | Envie um objeto
                      JSON: { "active": false }.
                    code: INVALID_BODY
                unknownFields:
                  summary: Campo desconhecido
                  value:
                    error: >-
                      Unknown field(s): secret. Accepted: name, url, events,
                      active. | Campo(s) desconhecido(s): secret. Aceitos: name,
                      url, events, active.
                    code: UNKNOWN_FIELDS
                    details:
                      unknownFields:
                        - secret
                invalidFieldType:
                  summary: Campo com o tipo errado
                  value:
                    error: >-
                      "active" must be true or false. | "active" deve ser true
                      ou false.
                    code: INVALID_FIELD_TYPE
                    details:
                      field: active
                      expected: boolean
                invalidWebhook:
                  summary: Não é https, ou eventos vazios / desconhecidos
                  value:
                    error: >-
                      Invalid webhook: use an https URL and known events. |
                      Webhook inválido: use uma URL https e eventos conhecidos.
                    code: INVALID_WEBHOOK
                invalidName:
                  summary: Nome com mais de 100 caracteres
                  value:
                    error: >-
                      Invalid webhook name: use at most 100 characters. | Nome
                      do webhook inválido: use no máximo 100 caracteres.
                    code: INVALID_WEBHOOK_NAME
                urlRefused:
                  summary: Destino interno ou de rede privada
                  value:
                    error: >-
                      Webhook URL refused: it points to an internal or private
                      network address, which we never call. Use a public
                      address. | URL do webhook recusada: ela aponta para um
                      endereço interno ou de rede privada, que nunca chamamos.
                      Use um endereço público.
                    code: WEBHOOK_URL_REFUSED
        '401':
          description: >-
            Credencial ausente ou inválida (`x-api-key`, `x-api-key-id` ou
            `Authorization: Bearer`). O corpo traz só `error`, sem `code`.
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                  code:
                    type: string
              examples:
                missing:
                  summary: Sem credencial
                  value:
                    error: >-
                      Missing x-api-key, x-api-key-id or Authorization Bearer
                      token
                invalid:
                  summary: API key inválida
                  value:
                    error: Invalid API key
        '403':
          description: >-
            Chave com escopo de número (`NUMBER_SCOPE_NOT_ALLOWED`), token
            OAuth/MCP de um usuário que não é Proprietário nem Administrador
            (`PERMISSION_DENIED`) ou que não é mais membro ativo
            (`WORKSPACE_MEMBERSHIP_REQUIRED`), ou workspace arquivado
            (`WORKSPACE_ARCHIVED`). `TENANT_REQUIRED`: credencial sem workspace
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                  code:
                    type: string
              examples:
                numberScope:
                  summary: Chave com escopo de número
                  value:
                    error: This endpoint requires a tenant-scoped API key
                    code: NUMBER_SCOPE_NOT_ALLOWED
                permissionDenied:
                  summary: Usuário OAuth/MCP que não é Proprietário nem Administrador
                  value:
                    error: >-
                      Your workspace role does not allow this action
                      (phone_lines:webhooks).
                    code: PERMISSION_DENIED
                notMember:
                  summary: Usuário OAuth/MCP que não é mais membro
                  value:
                    error: >-
                      The user behind this token is not an active member of this
                      workspace.
                    code: WORKSPACE_MEMBERSHIP_REQUIRED
                archived:
                  summary: Workspace arquivado
                  value:
                    error: >-
                      This workspace has been archived and its API is closed. |
                      Este workspace foi arquivado e sua API está encerrada.
                    code: WORKSPACE_ARCHIVED
                tenantRequired:
                  summary: Credencial sem workspace
                  value:
                    error: This credential is not bound to a workspace.
                    code: TENANT_REQUIRED
        '404':
          description: >-
            Nenhum webhook com esse id no seu workspace (`WEBHOOK_NOT_FOUND`) —
            um webhook de outro workspace responde o mesmo
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                  code:
                    type: string
              example:
                error: Webhook not found. | Webhook não encontrado.
                code: WEBHOOK_NOT_FOUND
        '500':
          description: Falha inesperada (`INTERNAL_ERROR`).
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                  code:
                    type: string
              example:
                error: Unexpected error. | Erro inesperado.
                code: INTERNAL_ERROR
components:
  securitySchemes:
    apiKey:
      type: apiKey
      in: header
      name: x-api-key
      description: Sua chave de API ps_
    apiKeyId:
      type: apiKey
      in: header
      name: x-api-key-id
      description: Id da chave de API (alternativa ao x-api-key)

````

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