Entrar Criar conta
Começando

Autenticação

Toda requisição usa uma chave de API no cabeçalho Authorization. As chaves podem ter acesso total ou só de envio, e ser restritas a um domínio.

#Chave de API

Toda requisição precisa de uma chave de API no cabeçalho Authorization, no formato Bearer:

Cabeçalho
Authorization: Bearer ps_4Fq9xLmT2vKp8sWd1Yc5Hf3Lz9Ag6Ej0Qm8rBnX

As chaves começam com ps_. Crie em Chaves de API no painel, ou pela API com POST /api-keys. O token completo aparece uma única vez, na criação: a Postal guarda só o hash e os primeiros caracteres (token_start), para você reconhecer a chave na lista.

GET /domains

cURL

curl https://api.postal.so/domains \
  -H "Authorization: Bearer $POSTAL_API_KEY"

Node.js

const response = await fetch('https://api.postal.so/domains', {
  headers: {
    Authorization: `Bearer ${process.env.POSTAL_API_KEY}`,
  },
});

const data = await response.json();

Python

import os
import requests

response = requests.get(
    "https://api.postal.so/domains",
    headers={"Authorization": f"Bearer {os.environ['POSTAL_API_KEY']}"},
    timeout=10,
)

data = response.json()

PHP

$client = new \GuzzleHttp\Client(['base_uri' => 'https://api.postal.so']);

$response = $client->get('domains', [
    'headers' => ['Authorization' => 'Bearer '.getenv('POSTAL_API_KEY')],
]);

$data = json_decode($response->getBody(), true);

#Permissões

PermissãoO que pode fazer
full_access
Acesso total
Toda a API: envio, domínios, templates, webhooks, logs, chaves…
sending_access
Só envio
Enviar: POST /emails, POST /emails/batch, POST /events e o SMTP.
Consultar: o status e os eventos dos e-mails que ela mesma enviou, por API ou SMTP (GET /emails/{id}; os e-mails de outras chaves ou do painel respondem 404), e o plano, as cotas e o limite de requisições em GET /usage. Todo o resto pede acesso total.
Pode ser restrita a um domínio (domain_id): aí só envia com remetentes desse domínio.

Criar chaves só de envio ou restritas a um domínio depende do plano (restricted_api_keys); o número de chaves também (api_keys). Veja Limites.

Use chaves só de envio nos sistemas que apenas disparam e-mails ou eventos (o checkout, o WordPress, o ERP) e reserve as de acesso total para automações de infraestrutura. Se uma chave de envio vazar, ela não muda sua configuração nem lê seus contatos, domínios ou os e-mails de outras chaves: só vê o que ela mesma enviou e os limites do plano.

#Erros de autenticação

StatusNomeQuando acontece
401missing_api_keyFaltou o cabeçalho Authorization.
403invalid_api_keyA chave não existe, foi excluída ou não começa com ps_.
401restricted_api_keyUma chave só de envio tentou usar outro endpoint (ela pode enviar, ler os e-mails que enviou com GET /emails/{id} e chamar GET /usage).
403restricted_api_keyUma chave restrita a um domínio tentou enviar de outro domínio.
403paused_by_planA chave passou do limite de chaves do plano atual e foi pausada (paused_by_plan: true em GET /api-keys). Ela não autentica até o plano ou a contagem permitirem de novo; veja Limites.
403team_suspendedA conta foi suspensa pela plataforma que a gerencia.

#Idioma das mensagens e origem das mudanças

Duas escolhas opcionais por requisição:

  • Accept-Language: pt-BR (ou en) escolhe o idioma da message dos erros e dos outros textos que a API escreve para a sua requisição (veja a tabela abaixo). Sem o cabeçalho, vem em inglês. O name é sempre o mesmo.
  • X-Postal-Source: erp dá um rótulo às mudanças que a chave faz nos contatos. O rótulo aparece em source nos webhooks de contato e em last_change_source do contato, e permite que um webhook ignore o que o próprio sistema fez.

O idioma de cada texto que a Postal escreve depende de para quem ele é:

TextoIdioma
Os textos das respostas da APIA message dos erros, os rótulos (como o label de paused em GET /usage), o sending.reason do mesmo endpoint, o diagnostic dos registros DNS do domínio, o sufixo dos nomes de cópias (“(copy)” ou “(cópia)”), o prefixo [Test] ou [Teste] do teste de campanha e do teste de template e o “Other:” ou “Outro:” dos CSV de respostas de formulário. Seguem o Accept-Language da requisição (pt-BR ou en, o primeiro que a Postal conhece). Com chave de API ou sem credenciais, sem o cabeçalho vêm em inglês; GET /plans, que é público, vem em português sem ele.
Texto da IA do diagnósticoPOST /ai/emails/{id}/fix-insights: o parâmetro language (pt-BR, en ou es); sem ele, o idioma da requisição.
Webhooks de pausaO reason sai no idioma do time, o que o dono escolheu no painel; em inglês enquanto ele não escolhe. O reason_code não depende de idioma.
Rodapé de descadastro e página de preferênciasO idioma de cada destinatário: language da campanha, propriedades do contato, idioma do time. Veja Idioma do rodapé e da página.
Formulários públicos e e-mail de confirmaçãosettings.language do formulário, senão o Accept-Language de quem preenche, senão pt-BR. Veja Idioma do formulário.
Em português de propósitoOs modelos padrão dos e-mails de autenticação do Supabase, que você edita na conexão.

#Boas práticas

  • Guarde a chave em variável de ambiente ou num cofre de segredos, nunca no código. Não use a chave no navegador ou em apps: qualquer pessoa poderia copiá-la. Chame a API a partir do seu servidor.
  • Use uma chave por sistema e por ambiente. Assim, dá para revogar uma sem derrubar as outras e ver nos logs quem fez cada requisição.
  • Se uma chave vazar, exclua-a na hora (DELETE /api-keys/{id}) e crie outra.
  • Para dar a um assistente de IA acesso à conta, prefira o OAuth do servidor MCP, que limita o acesso a um time e a escopos e se revoga sem trocar chave.