Referência da API

Exportações

Arquivos CSV com e-mails, domínios, logs, chaves e supressões.

Gere arquivos CSV com e-mails, domínios, logs, chaves de API, supressões ou contatos (as propriedades vão numa coluna em JSON). A exportação roda em segundo plano: crie, consulte até status ser completed e baixe pelo download_url. Os arquivos ficam disponíveis por 7 dias e o link de download vale por 1 hora (consulte de novo para gerar outro).

#Listar exportações

GET/exports

Chave de acesso total

Aceita limit, after e before.

GET /exports

cURL

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

Node.js

const response = await fetch('https://api.postal.so/exports', {
  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/exports",
    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('exports', [
    'headers' => ['Authorization' => 'Bearer '.getenv('POSTAL_API_KEY')],
]);

$data = json_decode($response->getBody(), true);
200Resposta
{
  "object": "list",
  "has_more": false,
  "data": [
    {
      "object": "export",
      "id": "019a1c10-7e8f-7a90-8b1c-2d3e4f5a6b7c",
      "type": "emails",
      "filters": {
        "status": "bounced"
      },
      "status": "completed",
      "rows": 312,
      "total_rows": 312,
      "error": null,
      "created_at": "2026-10-24T13:20:00.000000Z",
      "completed_at": "2026-10-24T13:20:04.000000Z",
      "expires_at": "2026-10-31T13:20:00.000000Z",
      "filename": "postal-emails-2026-10-24-132000.csv",
      "download_url": "https://api.postal.so/exports/019a1c10-7e8f-7a90-8b1c-2d3e4f5a6b7c/download?expires=1761315600&signature=7b1d…"
    }
  ]
}

#Criar uma exportação

POST/exports

Chave de acesso total

Os filtros são os mesmos da lista correspondente: e-mails, domínios, logs e chaves e contatos (supressões não têm filtros). Se uma exportação igual ainda estiver rodando, ela é devolvida (status 200) em vez de criar outra. Cada time pode ter até 3 exportações em andamento.

Corpo da requisição

  • typestringobrigatório
    emails, domains, logs, api_keys, suppressions ou contacts.
  • filtersobject
    Filtros da lista, como {"status": "bounced", "start_date": "2026-10-01"}.

Erros

  • 422validation_error
    Tipo ou filtro inválido.
  • 429rate_limit_exceeded
    Já há 3 exportações em andamento.
POST /exports

cURL

curl -X POST https://api.postal.so/exports \
  -H "Authorization: Bearer $POSTAL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "emails",
    "filters": {
      "status": "bounced"
    }
  }'

Node.js

const response = await fetch('https://api.postal.so/exports', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.POSTAL_API_KEY}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    type: 'emails',
    filters: {
      status: 'bounced',
    },
  }),
});

const data = await response.json();

Python

import os
import requests

response = requests.post(
    "https://api.postal.so/exports",
    headers={"Authorization": f"Bearer {os.environ['POSTAL_API_KEY']}"},
    json={
        "type": "emails",
        "filters": {
            "status": "bounced",
        },
    },
    timeout=10,
)

data = response.json()

PHP

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

$response = $client->post('exports', [
    'headers' => ['Authorization' => 'Bearer '.getenv('POSTAL_API_KEY')],
    'json' => [
        'type' => 'emails',
        'filters' => [
            'status' => 'bounced',
        ],
    ],
]);

$data = json_decode($response->getBody(), true);
201Resposta
{
  "object": "export",
  "id": "019a1c10-7e8f-7a90-8b1c-2d3e4f5a6b7c",
  "type": "emails",
  "filters": {
    "status": "bounced"
  },
  "status": "pending",
  "rows": 0,
  "total_rows": null,
  "error": null,
  "created_at": "2026-10-24T13:20:00.000000Z",
  "completed_at": null,
  "expires_at": "2026-10-31T13:20:00.000000Z",
  "filename": "postal-emails-2026-10-24-132000.csv",
  "download_url": null
}

#Obter uma exportação

GET/exports/{id}

Chave de acesso total

Mostra o progresso (rows de total_rows) e, quando pronta, o link de download. status: pending, processing, completed ou failed (com error).

Parâmetros de caminho

  • idstringobrigatório
    ID da exportação.

Erros

  • 404not_found
    O recurso não existe ou é de outro time.
GET /exports/{id}

cURL

curl https://api.postal.so/exports/019a1c10-7e8f-7a90-8b1c-2d3e4f5a6b7c \
  -H "Authorization: Bearer $POSTAL_API_KEY"

Node.js

const response = await fetch('https://api.postal.so/exports/019a1c10-7e8f-7a90-8b1c-2d3e4f5a6b7c', {
  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/exports/019a1c10-7e8f-7a90-8b1c-2d3e4f5a6b7c",
    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('exports/019a1c10-7e8f-7a90-8b1c-2d3e4f5a6b7c', [
    'headers' => ['Authorization' => 'Bearer '.getenv('POSTAL_API_KEY')],
]);

$data = json_decode($response->getBody(), true);
200Resposta
{
  "object": "export",
  "id": "019a1c10-7e8f-7a90-8b1c-2d3e4f5a6b7c",
  "type": "emails",
  "filters": {
    "status": "bounced"
  },
  "status": "completed",
  "rows": 312,
  "total_rows": 312,
  "error": null,
  "created_at": "2026-10-24T13:20:00.000000Z",
  "completed_at": "2026-10-24T13:20:04.000000Z",
  "expires_at": "2026-10-31T13:20:00.000000Z",
  "filename": "postal-emails-2026-10-24-132000.csv",
  "download_url": "https://api.postal.so/exports/019a1c10-7e8f-7a90-8b1c-2d3e4f5a6b7c/download?expires=1761315600&signature=7b1d…"
}