# Enviar mensagem

`POST /api/v1/conversations/messages`

Envia uma mensagem de WhatsApp pelo workspace da chave, com autoria do membro que a criou, e retorna a mensagem salva. `type` assume `text` por padrão. Informe `channelId` ou `senderPhoneNumberId` para escolher o canal; sem eles, usa o canal padrão do workspace.
O caminho legado `POST /api/v1/messages` mantém o mesmo contrato e os mesmos requisitos. Novas integrações devem usar `/api/v1/conversations/messages`.

## Autenticação

Envie a chave em `Authorization: Bearer pf_live_…`.

## Corpo da requisição

Content-Type: `application/json`

```json
{
  "to": "5511999999999",
  "type": "text",
  "text": "Olá, Ana. Podemos conversar sobre a proposta?",
  "channelId": "ID_DO_CANAL"
}
```

### Campos

| Campo | Tipo | Obrigatório no objeto | Descrição |
| --- | --- | --- | --- |
| `to` | `string` | Sim | Telefone do destinatário em E.164 ou no formato normalizado do workspace. |
| `type` | `string` | Não | text, image, audio, video, document, template, … Aceita null. |
| `text` | `string` | Não | Aceita null. |
| `senderPhoneNumberId` | `string` | Não | Identificador do número de telefone do canal no provedor. Aceita null. |
| `channelId` | `string` | Não | Identificador do canal de envio; tem prioridade sobre senderPhoneNumberId. Aceita null. |
| `mediaAssetId` | `string` | Não | Identificador de mídia já armazenada no workspace. Aceita null. |
| `mediaLink` | `string` | Não | URL pública usada pelo provedor para baixar a mídia. Aceita null. |
| `caption` | `string` | Não | Aceita null. |
| `filename` | `string` | Não | Aceita null. |
| `mimeType` | `string` | Não | Aceita null. |
| `templateName` | `string` | Não | Aceita null. |
| `templateLanguageCode` | `string` | Não | Aceita null. |
| `templateComponents` | `array` | Não | Aceita null. |
| `quotedMessageId` | `string` | Não | Mensagem à qual se está respondendo. Aceita null. |
| `voice` | `boolean` | Não | Somente áudio. Padrão: true, para entregar como mensagem de voz (ícone de microfone e forma de onda). Envie false para entregar como arquivo de áudio. Aceita null. |

## Respostas

### 201

Criado

| Campo | Tipo | Obrigatório no objeto | Descrição |
| --- | --- | --- | --- |
| `data` | `SendMessageResponse` | Não |  |
| `data.id` | `string` | Não |  |
| `data.conversationId` | `string` | Não |  |
| `data.channelId` | `string` | Não |  |
| `data.externalId` | `string` | Não | Identificador da mensagem no provedor; nulo até a aceitação pelo provedor. Aceita null. |
| `data.direction` | `string` | Não | Valores: inbound, outbound. |
| `data.type` | `string` | Não |  |
| `data.status` | `string` | Não |  |
| `data.body` | `string` | Não |  |
| `data.errorMessage` | `string` | Não | Aceita null. |
| `data.timestamp` | `string` | Não | Formato: date-time. |
| `message` | `string` | Não |  |

```json
{
  "type": "object",
  "properties": {
    "data": {
      "$ref": "#/components/schemas/SendMessageResponse"
    },
    "message": {
      "type": "string"
    }
  }
}
```

### 400

Falha de validação dos campos; `fieldErrors` contém os erros.

| Campo | Tipo | Obrigatório no objeto | Descrição |
| --- | --- | --- | --- |
| `error` | `string` | Sim |  |
| `code` | `string` | Sim | Valores: BAD_REQUEST, VALIDATION_ERROR, UNAUTHORIZED, FORBIDDEN, FEATURE_DISABLED, NOT_FOUND, CONFLICT, QUOTA_EXCEEDED, UNPROCESSABLE_ENTITY, INTERNAL_ERROR, SERVICE_UNAVAILABLE. |
| `requestId` | `string` | Sim |  |
| `details` | `string` | Não | Aceita null. |
| `fieldErrors` | `array` | Não | Aceita null. |
| `fieldErrors[].field` | `string` | Não |  |
| `fieldErrors[].message` | `string` | Não |  |

```json
{
  "type": "object",
  "description": "Formato padrão de erro. `details` e `fieldErrors` são omitidos quando ausentes.",
  "properties": {
    "error": {
      "type": "string"
    },
    "code": {
      "type": "string",
      "enum": [
        "BAD_REQUEST",
        "VALIDATION_ERROR",
        "UNAUTHORIZED",
        "FORBIDDEN",
        "FEATURE_DISABLED",
        "NOT_FOUND",
        "CONFLICT",
        "QUOTA_EXCEEDED",
        "UNPROCESSABLE_ENTITY",
        "INTERNAL_ERROR",
        "SERVICE_UNAVAILABLE"
      ]
    },
    "requestId": {
      "type": "string"
    },
    "details": {
      "type": "string",
      "nullable": true
    },
    "fieldErrors": {
      "type": "array",
      "nullable": true,
      "items": {
        "type": "object",
        "properties": {
          "field": {
            "type": "string"
          },
          "message": {
            "type": "string"
          }
        }
      }
    }
  },
  "required": [
    "error",
    "code",
    "requestId"
  ]
}
```

### 401

Chave ausente, malformada, desconhecida, revogada ou expirada, ou membro emissor inativo.

| Campo | Tipo | Obrigatório no objeto | Descrição |
| --- | --- | --- | --- |
| `error` | `string` | Sim |  |
| `code` | `string` | Sim | Valores: BAD_REQUEST, VALIDATION_ERROR, UNAUTHORIZED, FORBIDDEN, FEATURE_DISABLED, NOT_FOUND, CONFLICT, QUOTA_EXCEEDED, UNPROCESSABLE_ENTITY, INTERNAL_ERROR, SERVICE_UNAVAILABLE. |
| `requestId` | `string` | Sim |  |
| `details` | `string` | Não | Aceita null. |
| `fieldErrors` | `array` | Não | Aceita null. |
| `fieldErrors[].field` | `string` | Não |  |
| `fieldErrors[].message` | `string` | Não |  |

```json
{
  "type": "object",
  "description": "Formato padrão de erro. `details` e `fieldErrors` são omitidos quando ausentes.",
  "properties": {
    "error": {
      "type": "string"
    },
    "code": {
      "type": "string",
      "enum": [
        "BAD_REQUEST",
        "VALIDATION_ERROR",
        "UNAUTHORIZED",
        "FORBIDDEN",
        "FEATURE_DISABLED",
        "NOT_FOUND",
        "CONFLICT",
        "QUOTA_EXCEEDED",
        "UNPROCESSABLE_ENTITY",
        "INTERNAL_ERROR",
        "SERVICE_UNAVAILABLE"
      ]
    },
    "requestId": {
      "type": "string"
    },
    "details": {
      "type": "string",
      "nullable": true
    },
    "fieldErrors": {
      "type": "array",
      "nullable": true,
      "items": {
        "type": "object",
        "properties": {
          "field": {
            "type": "string"
          },
          "message": {
            "type": "string"
          }
        }
      }
    }
  },
  "required": [
    "error",
    "code",
    "requestId"
  ]
}
```

### 403

Autenticado, mas sem acesso: falta de permissão (`FORBIDDEN`), recurso desligado no workspace (`FEATURE_DISABLED`) ou tentativa de acessar uma agenda não permitida.

| Campo | Tipo | Obrigatório no objeto | Descrição |
| --- | --- | --- | --- |
| `error` | `string` | Sim |  |
| `code` | `string` | Sim | Valores: BAD_REQUEST, VALIDATION_ERROR, UNAUTHORIZED, FORBIDDEN, FEATURE_DISABLED, NOT_FOUND, CONFLICT, QUOTA_EXCEEDED, UNPROCESSABLE_ENTITY, INTERNAL_ERROR, SERVICE_UNAVAILABLE. |
| `requestId` | `string` | Sim |  |
| `details` | `string` | Não | Aceita null. |
| `fieldErrors` | `array` | Não | Aceita null. |
| `fieldErrors[].field` | `string` | Não |  |
| `fieldErrors[].message` | `string` | Não |  |

```json
{
  "type": "object",
  "description": "Formato padrão de erro. `details` e `fieldErrors` são omitidos quando ausentes.",
  "properties": {
    "error": {
      "type": "string"
    },
    "code": {
      "type": "string",
      "enum": [
        "BAD_REQUEST",
        "VALIDATION_ERROR",
        "UNAUTHORIZED",
        "FORBIDDEN",
        "FEATURE_DISABLED",
        "NOT_FOUND",
        "CONFLICT",
        "QUOTA_EXCEEDED",
        "UNPROCESSABLE_ENTITY",
        "INTERNAL_ERROR",
        "SERVICE_UNAVAILABLE"
      ]
    },
    "requestId": {
      "type": "string"
    },
    "details": {
      "type": "string",
      "nullable": true
    },
    "fieldErrors": {
      "type": "array",
      "nullable": true,
      "items": {
        "type": "object",
        "properties": {
          "field": {
            "type": "string"
          },
          "message": {
            "type": "string"
          }
        }
      }
    }
  },
  "required": [
    "error",
    "code",
    "requestId"
  ]
}
```

### 404

Recurso não encontrado ou fora da visibilidade do membro.

| Campo | Tipo | Obrigatório no objeto | Descrição |
| --- | --- | --- | --- |
| `error` | `string` | Sim |  |
| `code` | `string` | Sim | Valores: BAD_REQUEST, VALIDATION_ERROR, UNAUTHORIZED, FORBIDDEN, FEATURE_DISABLED, NOT_FOUND, CONFLICT, QUOTA_EXCEEDED, UNPROCESSABLE_ENTITY, INTERNAL_ERROR, SERVICE_UNAVAILABLE. |
| `requestId` | `string` | Sim |  |
| `details` | `string` | Não | Aceita null. |
| `fieldErrors` | `array` | Não | Aceita null. |
| `fieldErrors[].field` | `string` | Não |  |
| `fieldErrors[].message` | `string` | Não |  |

```json
{
  "type": "object",
  "description": "Formato padrão de erro. `details` e `fieldErrors` são omitidos quando ausentes.",
  "properties": {
    "error": {
      "type": "string"
    },
    "code": {
      "type": "string",
      "enum": [
        "BAD_REQUEST",
        "VALIDATION_ERROR",
        "UNAUTHORIZED",
        "FORBIDDEN",
        "FEATURE_DISABLED",
        "NOT_FOUND",
        "CONFLICT",
        "QUOTA_EXCEEDED",
        "UNPROCESSABLE_ENTITY",
        "INTERNAL_ERROR",
        "SERVICE_UNAVAILABLE"
      ]
    },
    "requestId": {
      "type": "string"
    },
    "details": {
      "type": "string",
      "nullable": true
    },
    "fieldErrors": {
      "type": "array",
      "nullable": true,
      "items": {
        "type": "object",
        "properties": {
          "field": {
            "type": "string"
          },
          "message": {
            "type": "string"
          }
        }
      }
    }
  },
  "required": [
    "error",
    "code",
    "requestId"
  ]
}
```

### 429

Limite de requisições excedido por workspace ou IP.

| Campo | Tipo | Obrigatório no objeto | Descrição |
| --- | --- | --- | --- |
| `error` | `string` | Sim |  |
| `code` | `string` | Sim | Valores: BAD_REQUEST, VALIDATION_ERROR, UNAUTHORIZED, FORBIDDEN, FEATURE_DISABLED, NOT_FOUND, CONFLICT, QUOTA_EXCEEDED, UNPROCESSABLE_ENTITY, INTERNAL_ERROR, SERVICE_UNAVAILABLE. |
| `requestId` | `string` | Sim |  |
| `details` | `string` | Não | Aceita null. |
| `fieldErrors` | `array` | Não | Aceita null. |
| `fieldErrors[].field` | `string` | Não |  |
| `fieldErrors[].message` | `string` | Não |  |

```json
{
  "type": "object",
  "description": "Formato padrão de erro. `details` e `fieldErrors` são omitidos quando ausentes.",
  "properties": {
    "error": {
      "type": "string"
    },
    "code": {
      "type": "string",
      "enum": [
        "BAD_REQUEST",
        "VALIDATION_ERROR",
        "UNAUTHORIZED",
        "FORBIDDEN",
        "FEATURE_DISABLED",
        "NOT_FOUND",
        "CONFLICT",
        "QUOTA_EXCEEDED",
        "UNPROCESSABLE_ENTITY",
        "INTERNAL_ERROR",
        "SERVICE_UNAVAILABLE"
      ]
    },
    "requestId": {
      "type": "string"
    },
    "details": {
      "type": "string",
      "nullable": true
    },
    "fieldErrors": {
      "type": "array",
      "nullable": true,
      "items": {
        "type": "object",
        "properties": {
          "field": {
            "type": "string"
          },
          "message": {
            "type": "string"
          }
        }
      }
    }
  },
  "required": [
    "error",
    "code",
    "requestId"
  ]
}
```
