Recebidos e inboxes
Inboxes para receber e-mails e os endpoints para ler, encaminhar e organizar as mensagens recebidas.
Receba e-mails na Postal: crie inboxes num domínio seu (com recebimento ativo) ou num endereço gerado em in.postal.so, leia as mensagens pela API e seja avisado na hora pelo webhook email.received. Veja como apontar o MX em Domínios e DNS.
#Listar inboxes
GET/inboxes
Lista as inboxes do time com a contagem de mensagens não lidas. Aceita limit, after e before.
Parâmetros de consulta
limitintegerDe 1 a 100. Padrão: 20.afterstringCursor da próxima página.beforestringCursor da página anterior.
cURL
curl https://api.postal.so/inboxes \
-H "Authorization: Bearer $POSTAL_API_KEY"
Node.js
const response = await fetch('https://api.postal.so/inboxes', {
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/inboxes",
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('inboxes', [
'headers' => ['Authorization' => 'Bearer '.getenv('POSTAL_API_KEY')],
]);
$data = json_decode($response->getBody(), true);
{
"object": "list",
"has_more": false,
"data": [
{
"object": "inbox",
"id": "0199f5c1-0a1b-7c2d-8e3f-4a5b6c7d8e9f",
"name": "Suporte",
"address": "[email protected]",
"domain_id": "0199f0e1-2a3b-7c4d-8e5f-6a7b8c9d0e1f",
"catch_all": false,
"forward_to": ["[email protected]"],
"can_forward": true,
"unread_count": 3,
"last_received_at": "2026-10-24T12:41:09.000000Z",
"created_at": "2026-10-02T18:20:00.000000Z"
}
]
}
#Criar uma inbox
POST/inboxes
Com domain_id, a inbox recebe em local_part@seu-dominio (use * para receber qualquer endereço do domínio, um catch-all). Sem domain_id, a Postal gera um endereço em in.postal.so, como [email protected]. Inboxes no seu domínio estão disponíveis nos planos pagos.
Corpo da requisição
namestringobrigatórioNome da inbox, até 255 caracteres.domain_idstringDomínio seu com recebimento ativo (capabilities.receiving = "enabled").local_partstringParte antes do @, até 64 caracteres: letras, números,.,+,-e_, ou*. Obrigatório comdomain_id.forward_tostring[]Até 5 endereços para onde cada mensagem é encaminhada automaticamente (não vale para catch-all nem parain.postal.so).
Erros
- 422
validation_errorCampo inválido, domínio sem recebimento ativo ou endereço já em uso. - 403
plan_limit_reachedO plano não permite mais inboxes ou inboxes no seu domínio.
cURL
curl -X POST https://api.postal.so/inboxes \
-H "Authorization: Bearer $POSTAL_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "Suporte",
"domain_id": "0199f0e1-2a3b-7c4d-8e5f-6a7b8c9d0e1f",
"local_part": "suporte",
"forward_to": ["[email protected]"]
}'
Node.js
const response = await fetch('https://api.postal.so/inboxes', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.POSTAL_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
name: 'Suporte',
domain_id: '0199f0e1-2a3b-7c4d-8e5f-6a7b8c9d0e1f',
local_part: 'suporte',
forward_to: ['[email protected]'],
}),
});
const data = await response.json();
Python
import os
import requests
response = requests.post(
"https://api.postal.so/inboxes",
headers={"Authorization": f"Bearer {os.environ['POSTAL_API_KEY']}"},
json={
"name": "Suporte",
"domain_id": "0199f0e1-2a3b-7c4d-8e5f-6a7b8c9d0e1f",
"local_part": "suporte",
"forward_to": ["[email protected]"],
},
timeout=10,
)
data = response.json()
PHP
$client = new \GuzzleHttp\Client(['base_uri' => 'https://api.postal.so']);
$response = $client->post('inboxes', [
'headers' => ['Authorization' => 'Bearer '.getenv('POSTAL_API_KEY')],
'json' => [
'name' => 'Suporte',
'domain_id' => '0199f0e1-2a3b-7c4d-8e5f-6a7b8c9d0e1f',
'local_part' => 'suporte',
'forward_to' => ['[email protected]'],
],
]);
$data = json_decode($response->getBody(), true);
{
"object": "inbox",
"id": "0199f5c1-0a1b-7c2d-8e3f-4a5b6c7d8e9f",
"name": "Suporte",
"address": "[email protected]",
"domain_id": "0199f0e1-2a3b-7c4d-8e5f-6a7b8c9d0e1f",
"catch_all": false,
"forward_to": ["[email protected]"],
"can_forward": true,
"unread_count": 0,
"last_received_at": null,
"created_at": "2026-10-02T18:20:00.000000Z"
}
#Obter uma inbox
GET/inboxes/{id}
Parâmetros de caminho
idstringobrigatórioID da inbox.
Erros
- 404
not_foundO recurso não existe ou é de outro time.
cURL
curl https://api.postal.so/inboxes/0199f5c1-0a1b-7c2d-8e3f-4a5b6c7d8e9f \
-H "Authorization: Bearer $POSTAL_API_KEY"
Node.js
const response = await fetch('https://api.postal.so/inboxes/0199f5c1-0a1b-7c2d-8e3f-4a5b6c7d8e9f', {
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/inboxes/0199f5c1-0a1b-7c2d-8e3f-4a5b6c7d8e9f",
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('inboxes/0199f5c1-0a1b-7c2d-8e3f-4a5b6c7d8e9f', [
'headers' => ['Authorization' => 'Bearer '.getenv('POSTAL_API_KEY')],
]);
$data = json_decode($response->getBody(), true);
{
"object": "inbox",
"id": "0199f5c1-0a1b-7c2d-8e3f-4a5b6c7d8e9f",
"name": "Suporte",
"address": "[email protected]",
"domain_id": "0199f0e1-2a3b-7c4d-8e5f-6a7b8c9d0e1f",
"catch_all": false,
"forward_to": ["[email protected]"],
"can_forward": true,
"unread_count": 3,
"last_received_at": "2026-10-24T12:41:09.000000Z",
"created_at": "2026-10-02T18:20:00.000000Z"
}
#Atualizar uma inbox
PATCH/inboxes/{id}
Muda o nome ou os endereços de encaminhamento. O endereço da inbox não muda.
Parâmetros de caminho
idstringobrigatórioID da inbox.
Corpo da requisição
namestringNovo nome.forward_tostring[] | nullAté 5 endereços.nullou[]desliga o encaminhamento.
Erros
- 422
validation_errorAlgum campo é inválido. A mensagem diz qual. - 404
not_foundO recurso não existe ou é de outro time.
cURL
curl -X PATCH https://api.postal.so/inboxes/0199f5c1-0a1b-7c2d-8e3f-4a5b6c7d8e9f \
-H "Authorization: Bearer $POSTAL_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"forward_to": ["[email protected]", "[email protected]"]
}'
Node.js
const response = await fetch('https://api.postal.so/inboxes/0199f5c1-0a1b-7c2d-8e3f-4a5b6c7d8e9f', {
method: 'PATCH',
headers: {
Authorization: `Bearer ${process.env.POSTAL_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
forward_to: ['[email protected]', '[email protected]'],
}),
});
const data = await response.json();
Python
import os
import requests
response = requests.patch(
"https://api.postal.so/inboxes/0199f5c1-0a1b-7c2d-8e3f-4a5b6c7d8e9f",
headers={"Authorization": f"Bearer {os.environ['POSTAL_API_KEY']}"},
json={
"forward_to": ["[email protected]", "[email protected]"],
},
timeout=10,
)
data = response.json()
PHP
$client = new \GuzzleHttp\Client(['base_uri' => 'https://api.postal.so']);
$response = $client->patch('inboxes/0199f5c1-0a1b-7c2d-8e3f-4a5b6c7d8e9f', [
'headers' => ['Authorization' => 'Bearer '.getenv('POSTAL_API_KEY')],
'json' => [
'forward_to' => ['[email protected]', '[email protected]'],
],
]);
$data = json_decode($response->getBody(), true);
{
"object": "inbox",
"id": "0199f5c1-0a1b-7c2d-8e3f-4a5b6c7d8e9f",
"name": "Suporte",
"address": "[email protected]",
"domain_id": "0199f0e1-2a3b-7c4d-8e5f-6a7b8c9d0e1f",
"catch_all": false,
"forward_to": ["[email protected]", "[email protected]"],
"can_forward": true,
"unread_count": 3,
"last_received_at": "2026-10-24T12:41:09.000000Z",
"created_at": "2026-10-02T18:20:00.000000Z"
}
#Excluir uma inbox
DELETE/inboxes/{id}
Exclui a inbox e todas as mensagens recebidas nela.
Parâmetros de caminho
idstringobrigatórioID da inbox.
Erros
- 404
not_foundO recurso não existe ou é de outro time.
cURL
curl -X DELETE https://api.postal.so/inboxes/0199f5c1-0a1b-7c2d-8e3f-4a5b6c7d8e9f \
-H "Authorization: Bearer $POSTAL_API_KEY"
Node.js
const response = await fetch('https://api.postal.so/inboxes/0199f5c1-0a1b-7c2d-8e3f-4a5b6c7d8e9f', {
method: 'DELETE',
headers: {
Authorization: `Bearer ${process.env.POSTAL_API_KEY}`,
},
});
const data = await response.json();
Python
import os
import requests
response = requests.delete(
"https://api.postal.so/inboxes/0199f5c1-0a1b-7c2d-8e3f-4a5b6c7d8e9f",
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->delete('inboxes/0199f5c1-0a1b-7c2d-8e3f-4a5b6c7d8e9f', [
'headers' => ['Authorization' => 'Bearer '.getenv('POSTAL_API_KEY')],
]);
$data = json_decode($response->getBody(), true);
{
"object": "inbox",
"id": "0199f5c1-0a1b-7c2d-8e3f-4a5b6c7d8e9f",
"deleted": true
}
#Listar e-mails recebidos
GET/emails/receiving
Lista as mensagens recebidas, da mais recente para a mais antiga. A lista traz o resumo; o conteúdo vem em GET /emails/receiving/{id}.
Parâmetros de consulta
limitintegerDe 1 a 100. Padrão: 20.afterstringCursor da próxima página.beforestringCursor da página anterior.inbox_idstringSó mensagens de uma inbox.unreadbooleanComtrue, só as não lidas.searchstringBusca em remetente, destinatários e assunto.
Erros
- 422
validation_errorAlgum campo é inválido. A mensagem diz qual.
cURL
curl 'https://api.postal.so/emails/receiving?inbox_id=0199f5c1-0a1b-7c2d-8e3f-4a5b6c7d8e9f&unread=true' \
-H "Authorization: Bearer $POSTAL_API_KEY"
Node.js
const response = await fetch('https://api.postal.so/emails/receiving?inbox_id=0199f5c1-0a1b-7c2d-8e3f-4a5b6c7d8e9f&unread=true', {
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/emails/receiving",
headers={"Authorization": f"Bearer {os.environ['POSTAL_API_KEY']}"},
params={
"inbox_id": "0199f5c1-0a1b-7c2d-8e3f-4a5b6c7d8e9f",
"unread": "true",
},
timeout=10,
)
data = response.json()
PHP
$client = new \GuzzleHttp\Client(['base_uri' => 'https://api.postal.so']);
$response = $client->get('emails/receiving', [
'headers' => ['Authorization' => 'Bearer '.getenv('POSTAL_API_KEY')],
'query' => [
'inbox_id' => '0199f5c1-0a1b-7c2d-8e3f-4a5b6c7d8e9f',
'unread' => 'true',
],
]);
$data = json_decode($response->getBody(), true);
{
"object": "list",
"has_more": false,
"data": [
{
"object": "received_email",
"id": "019a1c00-3e4f-7a5b-9c6d-7e8f9a0b1c2d",
"inbox_id": "0199f5c1-0a1b-7c2d-8e3f-4a5b6c7d8e9f",
"created_at": "2026-10-24T12:41:09.000000Z",
"from": "Carla Souza <[email protected]>",
"to": ["[email protected]"],
"cc": [],
"subject": "Troca de tamanho do pedido #10482",
"message_id": "<[email protected]>",
"read": false,
"size": 18342,
"has_attachments": true
}
]
}
#Obter um e-mail recebido
GET/emails/receiving/{id}
Devolve a mensagem com HTML, texto, cabeçalhos e anexos. Os links de download dos anexos valem por 1 hora.
Parâmetros de caminho
idstringobrigatórioID do e-mail recebido.
Erros
- 404
not_foundO recurso não existe ou é de outro time.
cURL
curl https://api.postal.so/emails/receiving/019a1c00-3e4f-7a5b-9c6d-7e8f9a0b1c2d \
-H "Authorization: Bearer $POSTAL_API_KEY"
Node.js
const response = await fetch('https://api.postal.so/emails/receiving/019a1c00-3e4f-7a5b-9c6d-7e8f9a0b1c2d', {
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/emails/receiving/019a1c00-3e4f-7a5b-9c6d-7e8f9a0b1c2d",
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('emails/receiving/019a1c00-3e4f-7a5b-9c6d-7e8f9a0b1c2d', [
'headers' => ['Authorization' => 'Bearer '.getenv('POSTAL_API_KEY')],
]);
$data = json_decode($response->getBody(), true);
{
"object": "received_email",
"id": "019a1c00-3e4f-7a5b-9c6d-7e8f9a0b1c2d",
"inbox_id": "0199f5c1-0a1b-7c2d-8e3f-4a5b6c7d8e9f",
"created_at": "2026-10-24T12:41:09.000000Z",
"from": "Carla Souza <[email protected]>",
"to": ["[email protected]"],
"cc": [],
"subject": "Troca de tamanho do pedido #10482",
"message_id": "<[email protected]>",
"read": false,
"size": 18342,
"has_attachments": true,
"reply_to": [],
"html": "<p>Oi! Gostaria de trocar a camiseta do pedido #10482 pelo tamanho M.</p>",
"text": "Oi! Gostaria de trocar a camiseta do pedido #10482 pelo tamanho M.",
"headers": {
"date": "Fri, 24 Oct 2026 09:41:07 -0300",
"mime-version": "1.0"
},
"attachments": [
{
"id": "019a1c00-3e50-7b6c-8d7e-9f0a1b2c3d4e",
"filename": "label-photo.jpg",
"content_type": "image/jpeg",
"content_id": null,
"size": 15620,
"download_url": "https://api.postal.so/received-attachments/019a1c00-3e4f-7a5b-9c6d-7e8f9a0b1c2d/019a1c00-3e50-7b6c-8d7e-9f0a1b2c3d4e?expires=1761313269&signature=c0de…"
}
]
}
#Marcar como lido ou não lido
PATCH/emails/receiving/{id}
Parâmetros de caminho
idstringobrigatórioID do e-mail recebido.
Corpo da requisição
readbooleanobrigatóriotruemarca como lido;false, como não lido.
Erros
- 422
validation_errorAlgum campo é inválido. A mensagem diz qual. - 404
not_foundO recurso não existe ou é de outro time.
cURL
curl -X PATCH https://api.postal.so/emails/receiving/019a1c00-3e4f-7a5b-9c6d-7e8f9a0b1c2d \
-H "Authorization: Bearer $POSTAL_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"read": true
}'
Node.js
const response = await fetch('https://api.postal.so/emails/receiving/019a1c00-3e4f-7a5b-9c6d-7e8f9a0b1c2d', {
method: 'PATCH',
headers: {
Authorization: `Bearer ${process.env.POSTAL_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
read: true,
}),
});
const data = await response.json();
Python
import os
import requests
response = requests.patch(
"https://api.postal.so/emails/receiving/019a1c00-3e4f-7a5b-9c6d-7e8f9a0b1c2d",
headers={"Authorization": f"Bearer {os.environ['POSTAL_API_KEY']}"},
json={
"read": True,
},
timeout=10,
)
data = response.json()
PHP
$client = new \GuzzleHttp\Client(['base_uri' => 'https://api.postal.so']);
$response = $client->patch('emails/receiving/019a1c00-3e4f-7a5b-9c6d-7e8f9a0b1c2d', [
'headers' => ['Authorization' => 'Bearer '.getenv('POSTAL_API_KEY')],
'json' => [
'read' => true,
],
]);
$data = json_decode($response->getBody(), true);
{
"object": "received_email",
"id": "019a1c00-3e4f-7a5b-9c6d-7e8f9a0b1c2d",
"inbox_id": "0199f5c1-0a1b-7c2d-8e3f-4a5b6c7d8e9f",
"created_at": "2026-10-24T12:41:09.000000Z",
"from": "Carla Souza <[email protected]>",
"to": ["[email protected]"],
"cc": [],
"subject": "Troca de tamanho do pedido #10482",
"message_id": "<[email protected]>",
"read": true,
"size": 18342,
"has_attachments": true
}
#Excluir um e-mail recebido
DELETE/emails/receiving/{id}
Parâmetros de caminho
idstringobrigatórioID do e-mail recebido.
Erros
- 404
not_foundO recurso não existe ou é de outro time.
cURL
curl -X DELETE https://api.postal.so/emails/receiving/019a1c00-3e4f-7a5b-9c6d-7e8f9a0b1c2d \
-H "Authorization: Bearer $POSTAL_API_KEY"
Node.js
const response = await fetch('https://api.postal.so/emails/receiving/019a1c00-3e4f-7a5b-9c6d-7e8f9a0b1c2d', {
method: 'DELETE',
headers: {
Authorization: `Bearer ${process.env.POSTAL_API_KEY}`,
},
});
const data = await response.json();
Python
import os
import requests
response = requests.delete(
"https://api.postal.so/emails/receiving/019a1c00-3e4f-7a5b-9c6d-7e8f9a0b1c2d",
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->delete('emails/receiving/019a1c00-3e4f-7a5b-9c6d-7e8f9a0b1c2d', [
'headers' => ['Authorization' => 'Bearer '.getenv('POSTAL_API_KEY')],
]);
$data = json_decode($response->getBody(), true);
{
"object": "received_email",
"id": "019a1c00-3e4f-7a5b-9c6d-7e8f9a0b1c2d",
"deleted": true
}
#Mensagem recebida original
GET/emails/receiving/{id}/raw
A mensagem exatamente como chegou ao servidor (RFC 5322, text/plain).
Parâmetros de caminho
idstringobrigatórioID do e-mail recebido.
Erros
- 404
not_foundO recurso não existe ou é de outro time.
cURL
curl https://api.postal.so/emails/receiving/019a1c00-3e4f-7a5b-9c6d-7e8f9a0b1c2d/raw \
-H "Authorization: Bearer $POSTAL_API_KEY"
Node.js
const response = await fetch('https://api.postal.so/emails/receiving/019a1c00-3e4f-7a5b-9c6d-7e8f9a0b1c2d/raw', {
headers: {
Authorization: `Bearer ${process.env.POSTAL_API_KEY}`,
},
});
const message = await response.text();
Python
import os
import requests
response = requests.get(
"https://api.postal.so/emails/receiving/019a1c00-3e4f-7a5b-9c6d-7e8f9a0b1c2d/raw",
headers={"Authorization": f"Bearer {os.environ['POSTAL_API_KEY']}"},
timeout=10,
)
message = response.text
PHP
$client = new \GuzzleHttp\Client(['base_uri' => 'https://api.postal.so']);
$response = $client->get('emails/receiving/019a1c00-3e4f-7a5b-9c6d-7e8f9a0b1c2d/raw', [
'headers' => ['Authorization' => 'Bearer '.getenv('POSTAL_API_KEY')],
]);
$message = (string) $response->getBody();
Received: from mail.cliente.com.br (mail.cliente.com.br [203.0.113.24])
From: Carla Souza <[email protected]>
To: [email protected]
Subject: Troca de tamanho do pedido #10482
Message-ID: <[email protected]>
…
#Encaminhar um e-mail recebido
POST/emails/receiving/{id}/forward
Encaminha a mensagem para até 5 endereços, em segundo plano. Só funciona para inboxes num domínio seu verificado (não catch-all), porque o encaminhamento sai desse domínio.
Parâmetros de caminho
idstringobrigatórioID do e-mail recebido.
Corpo da requisição
tostring[]obrigatórioDe 1 a 5 endereços.
Erros
- 422
validation_errorEndereço inválido, ou a inbox não pode encaminhar. - 404
not_foundO recurso não existe ou é de outro time.
cURL
curl -X POST https://api.postal.so/emails/receiving/019a1c00-3e4f-7a5b-9c6d-7e8f9a0b1c2d/forward \
-H "Authorization: Bearer $POSTAL_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"to": ["[email protected]"]
}'
Node.js
const response = await fetch('https://api.postal.so/emails/receiving/019a1c00-3e4f-7a5b-9c6d-7e8f9a0b1c2d/forward', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.POSTAL_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
to: ['[email protected]'],
}),
});
const data = await response.json();
Python
import os
import requests
response = requests.post(
"https://api.postal.so/emails/receiving/019a1c00-3e4f-7a5b-9c6d-7e8f9a0b1c2d/forward",
headers={"Authorization": f"Bearer {os.environ['POSTAL_API_KEY']}"},
json={
"to": ["[email protected]"],
},
timeout=10,
)
data = response.json()
PHP
$client = new \GuzzleHttp\Client(['base_uri' => 'https://api.postal.so']);
$response = $client->post('emails/receiving/019a1c00-3e4f-7a5b-9c6d-7e8f9a0b1c2d/forward', [
'headers' => ['Authorization' => 'Bearer '.getenv('POSTAL_API_KEY')],
'json' => [
'to' => ['[email protected]'],
],
]);
$data = json_decode($response->getBody(), true);
{
"object": "received_email",
"id": "019a1c00-3e4f-7a5b-9c6d-7e8f9a0b1c2d",
"forwarded": true
}