# Design de API REST de mensagens: recursos, métodos, status codes

> Uma API REST de mensagens modela cada envio como um recurso numa coleção messages. O cliente faz POST de uma mensagem e, como a entrega é assíncrona, o servidor devolve 202 Accepted com um identificador de mensagem e um URL de estado, reportando depois o resultado final por webhook. Métodos HTTP e status codes seguem a semântica da RFC 9110.

- URL canônico: https://www.broadnet.me/pt/reference/rest-messaging-api-design
- Idioma: pt
- Última atualização: 2026-07-19
- Editor: BroadNet (https://www.broadnet.me)

Como se modela uma API REST de mensagens baseada em normas: uma coleção messages, métodos HTTP e semântica de status codes segundo a RFC 9110, envio síncrono vs assíncrono (202 Accepted mais um callback de estado), negociação de conteúdo e versionamento em URL ou header — com uma tabela de trade-offs REST vs SMPP.

## O modelo de recurso messages

Uma API REST de mensagens trata cada mensagem como um recurso dentro de uma coleção — convencionalmente /messages — endereçável por um identificador atribuído pelo servidor. É o verbo, e não um campo do payload, que exprime a intenção: POST /messages cria e enfileira uma nova mensagem de saída; GET /messages/{id} lê o seu estado atual; GET /messages lista e filtra. Esta é a camada REST que assenta sobre as mesmas ligações de operador que o SMPP alcança no fio, pelo que o recurso que o cliente faz POST corresponde, a jusante, a um submit_sm numa sessão SMPP ligada (bound). Como o identificador é gerado pelo servidor e devolvido na resposta (e normalmente ecoado num header Location), o cliente fica com um handle estável para fazer polling ou correlacionar com callbacks de estado posteriores.

*Criar uma mensagem na coleção (padrão REST genérico)*

```http
POST /v1/messages HTTP/1.1
Host: api.example
Content-Type: application/json
Authorization: Bearer <token>
Idempotency-Key: 8f14e45f-ea7b-4c0f-9b2a-1d2c3e4f5a6b

{
  "to": "+15551234567",
  "from": "BRANDNAME",
  "text": "Your one-time code is 401 928",
  "callback_url": "https://app.example/webhooks/dlr"
}
```

## Métodos HTTP e as suas garantias

A RFC 9110 define duas propriedades que governam como um cliente de mensagens e qualquer intermediário podem tratar um pedido. Os métodos seguros (GET, HEAD) não têm efeitos colaterais e são livremente cacheáveis e repetíveis. Os métodos idempotentes (GET, HEAD, PUT, DELETE) podem ser repetidos com o mesmo efeito líquido. POST não é nem seguro nem idempotente, o que é exatamente o problema para a submissão de mensagens: um POST repetido poderia gerar um envio duplicado. A solução padrão não é abusar de PUT, mas manter POST e torná-lo idempotente com um header de pedido Idempotency-Key, para que uma submissão repetida devolva o resultado original em vez de criar uma segunda mensagem.

*Métodos HTTP sobre um recurso messages (RFC 9110)*

| Método | Em /messages | Seguro | Idempotente |
|---|---|---|---|
| POST | Criar e enfileirar uma nova mensagem | No | Não (torne-o idempotente via Idempotency-Key) |
| GET | Leia uma mensagem ou liste a coleção | Sim | Sim |
| HEAD | Verificação de metadados/existência | Sim | Sim |
| PUT | Substituir um recurso mutável (por exemplo, uma configuração de webhook) | No | Sim |
| PATCH | Atualização parcial de um recurso mutável | No | No |
| DELETE | Cancelar uma mensagem ainda na fila | No | Sim |

## Semântica dos status codes no envio

O status code que o servidor devolve codifica se a mensagem foi aceite, concluída ou rejeitada — e o envio de mensagens é quase sempre assíncrono. A RFC 9110 define 202 Accepted precisamente para este caso: o pedido foi aceite para processamento mas o processamento não está concluído, e a resposta deve indicar onde verificar o seu progresso. Uma API de mensagens devolve por isso 202 para um envio enfileirado, reservando 201 Created para um recurso totalmente materializado e 200 OK para uma operação verdadeiramente síncrona. Os erros de cliente (payload malformado, destino inválido, remetente desconhecido) são 4xx e não devem ser repetidos sem alteração; as falhas de servidor e a montante são 5xx e podem ser repetidas com backoff sob o mesmo Idempotency-Key.

*Semântica dos status codes na submissão de mensagens (RFC 9110)*

| Código | Significado | Quando uma API de mensagens a utiliza |
|---|---|---|
| 202 Accepted | Aceito, processamento incompleto | Envio assíncrono enfileirado; o estado final é obtido por meio de um retorno de chamada |
| 201 Created | Recurso criado | Criação síncrona quando o recurso estiver completo |
| 200 OK | Solicitação concluída | Leitura de status síncrona ou operação verdadeiramente imediata |
| 400 / 422 | Erro do cliente / não processável | Corpo malformado ou campo inválido — não tente novamente sem alterações |
| 401 / 403 | Não autenticado / proibido | Credenciais ausentes ou insuficientes |
| 409 Conflict | Conflito de estado | Idempotency-Key reutilizada com um payload diferente |
| 429 Too Many Requests | Limite de taxa excedido | Throttling; respeitar o Retry-After e aplicar backoff |
| 5xx | Falha no servidor/upstream | Transitória — tentar novamente com backoff usando a mesma chave |

## Entrega síncrona vs assíncrona

Existem duas latências distintas numa API de mensagens e é um erro de design confundi-las. A latência da API é o tempo que a chamada HTTP demora a aceitar a mensagem; a latência de entrega é o tempo que a rede do operador demora a entregar a mensagem ao telemóvel e a devolver um recibo. Como a segunda é ilimitada e está fora do controlo do remetente, uma API bem desenhada reconhece de imediato (202) com um estado accepted ou queued e entrega depois o resultado terminal de forma assíncrona — um callback de estado de entrega (o análogo em HTTP de um delivery receipt SMPP). Os clientes que precisam do estado final ou subscrevem o callback (push) ou fazem polling a GET /messages/{id} (pull); o callback é preferível porque evita a carga de polling e reporta mudanças de estado em segundos.

*Resposta 202 Accepted com um handle de estado*

```http
HTTP/1.1 202 Accepted
Location: /v1/messages/01HZY8Q3M6
Content-Type: application/json

{
  "id": "01HZY8Q3M6",
  "status": "accepted",
  "created_at": "2026-07-19T09:15:22Z",
  "status_url": "/v1/messages/01HZY8Q3M6"
}
```

## Negociação de conteúdo e versionamento

Cliente e servidor acordam a representação através dos headers de negociação de conteúdo da RFC 9110: o pedido traz Content-Type para o corpo que envia e Accept para o que pretende receber, e o servidor ecoa o media type escolhido no Content-Type da resposta. A maioria das APIs de mensagens normaliza em application/json e usa application/problem+json para erros. O versionamento de API tem dois padrões principais. O versionamento em URL (/v1/messages) é explícito, favorável a cache e trivial de encaminhar, ao custo de um incremento grosseiro de toda a superfície. O versionamento por header ou media type (Accept: application/vnd.example.v2+json) mantém os URLs estáveis e permite que um recurso evolua de forma independente, ao custo de ser invisível num browser e mais difícil de testar à mão. Seja qual for a escolha, as mudanças aditivas (novos campos opcionais) nunca devem exigir um incremento de versão; só as mudanças que quebram compatibilidade o exigem.

*Abordagens de versionamento de API*

| Abordagem | Exemplo | Trade-off |
|---|---|---|
| Caminho da URL | /v1/messages | Explícito, armazenável em cache, fácil de encaminhar; saltos de versão grosseiros |
| Cabeçalho personalizado | Api-Version: 2026-07-19 | URLs amigáveis, com data fixada; invisíveis para caches e navegadores |
| Tipo multimédia aceito | Accept: application/vnd.example.v2+json | Evolução por recurso; mais difícil de testar manualmente |
| Parâmetro de consulta | /messages?version=2 | Simples; confunde o armazenamento em cache e a identidade do recurso |

## REST vs SMPP: escolher o transporte

A camada HTTP/REST e o SMPP são dois transportes sobre a mesma rede de mensagens, e os remetentes maduros usam ambos. REST é a escolha certa para integração de aplicações: é sem estado, amigável a firewalls sobre HTTPS comum, fácil de proteger com bearer tokens e simples de instrumentar. SMPP é a escolha certa para throughput sustentado muito elevado e o menor overhead por mensagem, porque uma sessão binária de longa duração evita o custo de ligação por mensagem e dá controlo fino da janela. A tabela contrasta os dois para que um integrador possa adequar o transporte à carga de trabalho; para os endpoints REST concretos da BroadNet veja a referência de API para programadores, e para o protocolo de fio veja a visão geral de SMPP.

*REST (HTTP) vs SMPP como transporte de mensagens*

| Propriedade | REST / HTTP | SMPP |
|---|---|---|
| Modelo | Requisição/resposta sem estado via HTTPS | Sessão binária de longa duração com estado (bind) |
| Enquadramento | JSON sobre HTTP/1.1 ou HTTP/2 | PDUs binários (submit_sm, deliver_sm) |
| Comprovativo de entrega | Webhook de status / polling GET | recibo deliver_sm na mesma sessão |
| Throughput | Bom; sobrecarga por solicitação | Maior taxa sustentada; com janela, baixo overhead |
| Auth | Bearer token / chave de API / OAuth 2.0 | system_id + palavra-passe no bind |
| Controlo de fluxo | 429 + Retry-After, cabeçalhos RateLimit | Tamanho da janela + throttling de enquire_link |
| Ideal para | Integração de aplicações, webhooks, volume moderado | Fluxos massivos de A2P de alto volume, padrão carrier |

## Perguntas frequentes

### Porque é que uma API REST de mensagens devolve 202 em vez de 200 ou 201?

Porque a entrega de mensagens é assíncrona. A RFC 9110 define 202 Accepted como 'aceite para processamento, processamento não concluído', o que descreve exatamente um envio enfileirado. A API reconhece de imediato com um id de mensagem e um handle de estado, reportando depois o resultado terminal de entrega por callback. 201 e 200 implicam que a operação já está concluída.

### Como deve ser modelado um recurso messages?

Como uma coleção: POST /messages cria e enfileira uma mensagem, GET /messages/{id} lê o seu estado e GET /messages lista e filtra. O servidor gera o identificador e devolve-o (muitas vezes num header Location) para que o cliente fique com um handle estável para fazer polling ou correlacionar com callbacks de estado.

### POST não é idempotente — como se evitam envios duplicados?

Mantém-se o POST (exprime corretamente 'criar uma nova mensagem') e torna-se idempotente com um header de pedido Idempotency-Key. Uma submissão repetida com a mesma chave devolve o resultado original em vez de criar uma segunda mensagem. Abusar de PUT para forçar idempotência quebra o modelo de recursos REST.

### Qual é a diferença entre latência da API e latência de entrega?

A latência da API é o tempo que a chamada HTTP demora a aceitar a mensagem; a latência de entrega é o tempo que a rede do operador demora a chegar ao telemóvel e a devolver um recibo. A segunda é ilimitada e está fora do controlo do remetente, razão pela qual a API reconhece depressa (202) e reporta a entrega final de forma assíncrona.

### Devo versionar uma API de mensagens no URL ou num header?

O versionamento em URL (/v1/messages) é explícito, favorável a cache e fácil de encaminhar, mas incrementa toda a superfície de uma vez. O versionamento por header ou media type mantém os URLs estáveis e permite que os recursos evoluam de forma independente, mas é invisível para as caches e mais difícil de testar à mão. Em qualquer caso, as mudanças aditivas nunca devem forçar um incremento de versão.

### Quando devo usar REST em vez de SMPP?

Use REST para integração de aplicações: HTTPS sem estado e amigável a firewalls, autenticação por bearer token e instrumentação fácil. Use SMPP para o maior throughput sustentado e o menor overhead por mensagem, onde compensa uma sessão binária de longa duração com janela. Ambos alcançam a mesma rede de mensagens; muitos remetentes usam REST para tráfego de controlo e SMPP para firehoses de alto volume.

## Fontes

- [IETF RFC 9110 — HTTP Semantics](https://datatracker.ietf.org/doc/html/rfc9110)
- [IETF RFC 9111 — HTTP Caching](https://datatracker.ietf.org/doc/html/rfc9111)

## Relacionados

- [Visão geral do protocolo SMPP](https://www.broadnet.me/pt/reference/smpp-protocol-overview)
- [Entrega e fiabilidade de webhooks](https://www.broadnet.me/pt/reference/webhook-delivery-and-reliability)
- [Idempotência e rate limiting](https://www.broadnet.me/pt/reference/idempotency-and-rate-limiting)
- [Erros de API e paginação](https://www.broadnet.me/pt/reference/api-errors-and-pagination)
- [Referência de API da BroadNet](https://www.broadnet.me/pt/developers/api-reference)
