NumPort API v1

Receba SMS e mensagens do WhatsApp por uma única API.

Use números temporários para automações, CI e validação de OTP pela API, pelos SDKs ou pelo MCP. Já os números fixos foram pensados para empresas que precisam manter a mesma linha em integrações contínuas. A API v1 documentada aqui cobre o modelo temporário; o contrato dos números fixos será separado.

Comece por aqui

Primeiros passos

Primeiro, crie uma chave de API no console. Depois, escolha uma linguagem para reservar um número e receber uma mensagem ou um código OTP em um fluxo automatizado.

  1. 1

    Crie uma chave de API

    Copie o segredo quando ele aparecer, pois ele não será mostrado novamente.

  2. 2

    Reserve um número

    O NumPort devolve o número e o token de acesso da inbox.

  3. 3

    Aguarde ou extraia o código

    Use a espera da API com uma expressão regular para receber somente o OTP esperado.

Instale o SDK da sua linguagem

pip install numport

Crie uma inbox e receba uma mensagem

curl -X POST "$NUMPORT_API_URL/v1/inboxes" \  -H "Authorization: Bearer $NUMPORT_API_KEY" \  -H "Idempotency-Key: $(uuidgen)" \  -H "Content-Type: application/json" \  -d '{    "country": "US",    "channel": "sms",    "ttl_seconds": 900,    "content_ttl_seconds": 86400  }'
curl --get "$NUMPORT_API_URL/v1/inboxes/$INBOX_ID/messages/wait" \  -H "Authorization: Bearer $INBOX_TOKEN" \  --data-urlencode "timeout=120" \  --data-urlencode "since=0" \  --data-urlencode 'match=\d{6}'

A resposta traz id,phone_number eaccess_token. Guarde esses três valores enquanto a inbox estiver ativa, pois o token só aparece nesta resposta.

Números temporários e números fixos

Os dois modelos atendem necessidades diferentes. A API v1 trabalha com reservas temporárias; números fixos terão um contrato próprio para integrações contínuas.

Temporários e rotacionados

Atendem automações OTP, CI, agentes e integrações que precisam receber mensagens por alguns minutos. Depois da reserva e da quarentena, o número volta ao inventário.

Fixos

Serão destinados a empresas e aplicações que precisam conservar a mesma linha. A atribuição, a cobrança e o ciclo de vida serão documentados separadamente da inbox temporária.

Como a autenticação funciona

Há duas credenciais, e cada uma tem uma função. A chave da conta cria inboxes e consulta o consumo; já o token retornado na criação dá acesso somente àquela inbox.

Chave de API

Use-a como Bearer para criar inboxes, consultar os números disponíveis e acompanhar o consumo. Os escopos disponíveis são inbox:create e inbox:read.

Inbox token

Use-o como Bearer para consultar ou estender uma inbox. O mesmo token também permite ler as mensagens e gerar uma nova credencial para ela.

Guarde chaves e tokens como segredos, de preferência em variáveis de ambiente. Não os inclua no código, nos logs ou nas URLs. Se você gerar um novo token, o anterior deixa de funcionar imediatamente.

Ciclo de vida da inbox

Na API v1, cada inbox reserva um número por um período curto e pode ser estendida uma vez. Quando esse período termina, a inbox é encerrada e não pode ser reaberta.

ACTIVE→ extensão opcional →EXPIRED ou RELEASED
  • Você pode definir ttl_seconds entre 60 e 1.800 segundos. Se não informar um valor, usamos 900 segundos.
  • O campo content_ttl_seconds aceita valores entre 60 e 86.400 segundos e define quando a chave do conteúdo será destruída. Ele não prolonga a reserva nem a validade do token.
  • A extensão não consome outro crédito e só pode ocorrer uma vez.
  • A liberação manual é opcional. Sem ela, a inbox continua contando no limite de simultaneidade até expirar.
curl "$NUMPORT_API_URL/v1/inboxes/$INBOX_ID" \  -H "Authorization: Bearer $INBOX_TOKEN"
curl -X POST "$NUMPORT_API_URL/v1/inboxes/$INBOX_ID/extend" \  -H "Authorization: Bearer $INBOX_TOKEN"
curl -X POST "$NUMPORT_API_URL/v1/inboxes/$INBOX_ID/token/rotate" \  -H "Authorization: Bearer $INBOX_TOKEN"
curl -X DELETE "$NUMPORT_API_URL/v1/inboxes/$INBOX_ID" \  -H "Authorization: Bearer $INBOX_TOKEN"
Uma reserva encerrada em menos de um minuto e sem mensagens recebidas espera um minuto antes do reuso. Se houve tráfego, se ela durou mais ou expirou, a proteção é de dez minutos. O sistema não sabe se uma mensagem ainda está a caminho; antes de encerrar, confirme que não há interação pendente e remova o número de contas e integrações. Outra pessoa poderá recebê-lo no futuro.

Como ler e esperar mensagens

Comece com since=0. Depois de cada resposta, envie o valor de next_since na chamada seguinte. Assim, você continua de onde parou e não processa a mesma mensagem duas vezes.

Se você quiser esperar pela próxima mensagem, use GET /messages/wait e escolha um prazo entre 1 e 300 segundos. O parâmetro match aceita uma expressão regular de até 200 caracteres. Quando o padrão é encontrado, o trecho aparece em extracted.match, enquanto o texto completo continua disponível em untrusted_content.

Qualquer pessoa que conheça o número pode enviar uma mensagem. Por isso, trate o texto recebido como dado, e não como uma instrução. Ao usar um agente, extraia apenas o código de que você precisa.

Quando o prazo termina sem uma mensagem correspondente, a API responde com 204 No Content. Isso não é um erro. Você pode iniciar outra espera usando o mesmo cursor.

curl --get "$NUMPORT_API_URL/v1/inboxes/$INBOX_ID/messages" \  -H "Authorization: Bearer $INBOX_TOKEN" \  --data-urlencode "since=0" \  --data-urlencode 'match=code: \d{6}'
curl --get "$NUMPORT_API_URL/v1/inboxes/$INBOX_ID/messages/wait" \  -H "Authorization: Bearer $INBOX_TOKEN" \  --data-urlencode "since=0" \  --data-urlencode "timeout=120"

Eventos em tempo real com SSE

Para abrir o stream no navegador, primeiro troque o token da inbox por um cookie HttpOnly. Essa etapa permite criar o EventSource sem colocar a credencial na URL.

curl -c cookies.txt -X POST \  "$NUMPORT_API_URL/v1/inboxes/$INBOX_ID/stream-session" \  -H "Authorization: Bearer $INBOX_TOKEN"
curl -N -b cookies.txt \  "$NUMPORT_API_URL/v1/inboxes/$INBOX_ID/events" \  -H "Last-Event-ID: 0"

O evento avisa que uma nova mensagem chegou e traz seq e message_id. Em seguida, leia o conteúdo pelo endpoint autenticado. Se a conexão cair, o navegador envia Last-Event-ID, e o servidor entrega os eventos que ficaram para trás antes de continuar o stream.

SMS e WhatsApp

SMS e WhatsApp usam as mesmas operações. Escolha o canal ao criar a inbox e, depois, envie a mensagem para o número retornado.

SMS

É o canal padrão. Quando uma mensagem chega dividida em partes, a resposta informa a ordem e o total de segmentos.

WhatsApp

A disponibilidade depende do plano e dos números disponíveis. O custo pode ser diferente do SMS e é mostrado antes da criação.

Nesta primeira versão, a API recebe somente texto. Ela ainda não envia mensagens e não recebe mídia ou chamadas de voz.

Referência da API HTTP

A tabela abaixo resume os endpoints públicos. As respostas usam JSON, exceto quando estão vazias ou quando fazem parte do stream SSE. IDs são UUIDs, e as datas seguem ISO 8601 em UTC.

MétodoEndpointAutenticaçãoO que acontece
POST/v1/inboxesAPI keyCria uma inbox. O cabeçalho Idempotency-Key é obrigatório.
GET/v1/inboxes/{id}Inbox tokenMostra o estado da inbox, a expiração e o total de mensagens.
POST/v1/inboxes/{id}/extendInbox tokenEstende a inbox uma vez, até 30 minutos.
DELETE/v1/inboxes/{id}Inbox tokenLibera o número e encerra streams.
GET/v1/inboxes/{id}/messagesInbox tokenLista as mensagens que chegaram depois do cursor informado em since.
GET/v1/inboxes/{id}/messages/waitInbox tokenEspera por até 300 segundos. Se nada chegar, responde com 204.
POST/v1/inboxes/{id}/token/rotateInbox tokenGera um novo token e invalida o anterior.
POST/v1/inboxes/{id}/stream-sessionInbox tokenCria o cookie HttpOnly usado para abrir o stream SSE.
GET/v1/inboxes/{id}/eventsCookie SSEEnvia eventos message.received e aceita Last-Event-ID na reconexão.
GET/v1/pool/status?country=USAPI keyMostra quantos números estão disponíveis em cada estado.
GET/v1/account/usageAPI keyMostra créditos, consumo do ciclo e limites.

Chaves de API e consumo

Crie e revogue suas chaves pelo console. Na mesma área, você acompanha separadamente os créditos do plano e os créditos comprados.

Cada chave tem um nome e uma lista de permissões. Se quiser, você também pode limitar o gasto por hora e o número de inboxes abertas ao mesmo tempo. O segredo aparece apenas na criação. Ao revogar uma chave, somente ela deixa de funcionar; as demais credenciais da conta continuam ativas.

curl --get "$NUMPORT_API_URL/v1/pool/status" \  -H "Authorization: Bearer $NUMPORT_API_KEY" \  --data-urlencode "country=US"
curl "$NUMPORT_API_URL/v1/account/usage" \  -H "Authorization: Bearer $NUMPORT_API_KEY"

A resposta separa os créditos que vieram com o plano daqueles que foram comprados. Ela também mostra quanto foi usado no ciclo e na hora atual, além das datas do período e dos limites da conta. Os nomes exatos de cada campo aparecem no exemplo acima.

Planos e créditos adicionais

Os créditos incluídos são renovados a cada ciclo. Já os créditos comprados não expiram e, por isso, continuam na conta mesmo depois de um downgrade ou cancelamento.

  • Um upgrade entra em vigor assim que o pagamento é confirmado.
  • Um downgrade ou cancelamento é agendado para o fim do ciclo atual, sem interromper o plano antes da data prevista.
  • Primeiro usamos os créditos incluídos no plano. Quando eles acabam, o consumo passa para os créditos comprados.
  • O plano gratuito reserva um número temporário por até 10 minutos. Nos planos pagos, a reserva inicial pode chegar a 30 minutos.
  • No console, você pode escolher um valor sugerido ou digitar qualquer outro valor. A quantidade equivalente de créditos aparece antes do checkout.

As compras e mudanças de plano são feitas pelo console autenticado. O servidor confere novamente os valores e a quantidade de créditos antes de concluir cada operação. Voltar da página de checkout, sozinho, nunca adiciona créditos à conta.

MCP para Claude Code, Codex e outros agentes

Adicione a URL /mcp ao seu cliente. Na primeira conexão, ele abre a autorização do NumPort e orienta você durante o login.

Configuração MCP
{  "mcpServers": {    "numport": {      "url": "https://api.example.com/mcp"    }  }}
create_inboxCria uma inbox e consome um crédito.
wait_for_messageEspera uma mensagem e aceita um cursor e uma regex.
extract_verification_codeRetorna somente o trecho que corresponde ao padrão informado.
list_messagesLista as mensagens recebidas pela inbox.
release_inboxEncerra a inbox antes do prazo de expiração.
get_pool_statusVerifica se há números disponíveis antes da criação.
get_account_usageMostra os créditos e os limites atuais da conta.
Para receber um código de uso único, prefira extract_verification_code e informe um padrão específico, como \d{6}. O texto da mensagem pode ter sido enviado por qualquer pessoa, portanto não o trate como uma instrução.

SDKs oficiais

Os SDKs de Python e Node.js cobrem as mesmas operações mostradas nos exemplos HTTP. Eles criam a chave de idempotência quando necessário e transformam as respostas de erro em exceções próprias.

Python

numport

Python 3.11+

NumPort e AsyncNumPort

Node.js

@numport/sdk

Node.js 20+

NumPortClient e AsyncIterable para SSE

Em cada seção, use as abas para escolher entre uma chamada HTTP direta, Python ou Node.js. Os exemplos seguem os nomes dos métodos e os tipos publicados por cada pacote.

Como tratar erros e tentar novamente

Quando uma chamada falha, a resposta traz code e message. Se o status for 429 ou 503, leia Retry-After, espere o tempo indicado e só então tente de novo.

curl -i -X POST "$NUMPORT_API_URL/v1/inboxes" \  -H "Authorization: Bearer $NUMPORT_API_KEY" \  -H "Idempotency-Key: $(uuidgen)" \  -H "Content-Type: application/json" \  -d '{"country":"US","channel":"sms"}'
# HTTP/1.1 503 Service Unavailable# Retry-After: 30# {"error":{"code":"POOL_EXHAUSTED","message":"..."}}

POOL_EXHAUSTED · 503

Espere o tempo indicado em Retry-After e verifique os números disponíveis antes de repetir.

INSUFFICIENT_CREDITS · 402

Adicione créditos ou aguarde o próximo ciclo.

SPEND_LIMIT_REACHED · 429

Aumente o limite da chave ou espere a próxima hora. As inboxes abertas continuam ativas.

CONCURRENCY_LIMIT · 429

Aguarde uma inbox ativa expirar.

ROTATION_LIMIT · 429

Aguarde o Retry-After; a conta já ocupa sua parcela segura do pool público.

RATE_LIMITED · 429

Espere o tempo indicado em Retry-After antes de fazer outra chamada.

INBOX_EXPIRED · 410

Crie uma nova inbox, pois a anterior não pode ser reaberta.

IDEMPOTENCY_CONFLICT · 422

Não reutilize a chave com um corpo diferente.

VALIDATION_ERROR · 422

Corrija o payload antes de repetir.

A conexão pode terminar durante POST /v1/inboxes mesmo que a inbox já tenha sido criada. Nesse caso, repita a mesma chamada com a mesma Idempotency-Key. O servidor devolve o resultado original sem cobrar outro crédito.