Referência da API

Chaves de API

Crie, liste, renomeie e revogue chaves de API.

Gerencie as chaves usadas para autenticar na API e no SMTP. O token completo só aparece uma vez, na criação: a Postal guarda apenas o hash. Entenda as permissões em Autenticação.

#Listar chaves

GET/api-keys

Chave de acesso total

Parâmetros de consulta

  • limitinteger
    De 1 a 100. Padrão: 20.
  • afterstring
    Cursor da próxima página.
  • beforestring
    Cursor da página anterior.
  • searchstring
    Busca no nome ou no início do token.
  • permissionstring
    full_access ou sending_access.

Erros

  • 422validation_error
    Algum campo é inválido. A mensagem diz qual.
GET /api-keys

cURL

curl 'https://api.postal.so/api-keys?permission=sending_access' \
  -H "Authorization: Bearer $POSTAL_API_KEY"

Node.js

const response = await fetch('https://api.postal.so/api-keys?permission=sending_access', {
  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/api-keys",
    headers={"Authorization": f"Bearer {os.environ['POSTAL_API_KEY']}"},
    params={
        "permission": "sending_access",
    },
    timeout=10,
)

data = response.json()

PHP

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

$response = $client->get('api-keys', [
    'headers' => ['Authorization' => 'Bearer '.getenv('POSTAL_API_KEY')],
    'query' => [
        'permission' => 'sending_access',
    ],
]);

$data = json_decode($response->getBody(), true);
200Resposta
{
  "object": "list",
  "has_more": false,
  "data": [
    {
      "id": "0199f0e2-7b8c-7d9e-8f0a-1b2c3d4e5f6a",
      "name": "Produção - checkout",
      "permission": "sending_access",
      "domain_id": "0199f0e1-2a3b-7c4d-8e5f-6a7b8c9d0e1f",
      "token_start": "ps_4Fq9xLm",
      "uses_count": 1284,
      "created_at": "2026-10-02T18:40:00.000000Z",
      "last_used_at": "2026-10-24T13:02:11.000000Z"
    }
  ]
}

#Criar uma chave

POST/api-keys

Chave de acesso total

Cria a chave e devolve o token completo. Guarde-o agora: ele não pode ser consultado depois.

Corpo da requisição

  • namestringobrigatório
    Nome para identificar a chave, até 50 caracteres.
  • permissionstring
    full_access (padrão): toda a API. sending_access: só envio (POST /emails, POST /emails/batch e SMTP).
  • domain_idstring
    Restringe uma chave sending_access a um domínio. Não pode ser usado com full_access.

Erros

  • 422validation_error
    Nome ausente ou longo demais, permissão inválida, domínio de outro time ou domain_id com full_access.
POST /api-keys

cURL

curl -X POST https://api.postal.so/api-keys \
  -H "Authorization: Bearer $POSTAL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Produção - checkout",
    "permission": "sending_access",
    "domain_id": "0199f0e1-2a3b-7c4d-8e5f-6a7b8c9d0e1f"
  }'

Node.js

const response = await fetch('https://api.postal.so/api-keys', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.POSTAL_API_KEY}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    name: 'Produção - checkout',
    permission: 'sending_access',
    domain_id: '0199f0e1-2a3b-7c4d-8e5f-6a7b8c9d0e1f',
  }),
});

const data = await response.json();

Python

import os
import requests

response = requests.post(
    "https://api.postal.so/api-keys",
    headers={"Authorization": f"Bearer {os.environ['POSTAL_API_KEY']}"},
    json={
        "name": "Produção - checkout",
        "permission": "sending_access",
        "domain_id": "0199f0e1-2a3b-7c4d-8e5f-6a7b8c9d0e1f",
    },
    timeout=10,
)

data = response.json()

PHP

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

$response = $client->post('api-keys', [
    'headers' => ['Authorization' => 'Bearer '.getenv('POSTAL_API_KEY')],
    'json' => [
        'name' => 'Produção - checkout',
        'permission' => 'sending_access',
        'domain_id' => '0199f0e1-2a3b-7c4d-8e5f-6a7b8c9d0e1f',
    ],
]);

$data = json_decode($response->getBody(), true);
201Resposta
{
  "id": "0199f0e2-7b8c-7d9e-8f0a-1b2c3d4e5f6a",
  "token": "ps_4Fq9xLmT2vKp8sWd1Yc5Hf3Lz9Ag6Ej0Qm8rBnX"
}

#Obter uma chave

GET/api-keys/{id}

Chave de acesso total

Devolve a chave com o domínio (quando restrita) e quem a criou. O token nunca é devolvido; token_start mostra os primeiros caracteres para você reconhecê-la.

Parâmetros de caminho

  • idstringobrigatório
    ID da chave.

Erros

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

cURL

curl https://api.postal.so/api-keys/0199f0e2-7b8c-7d9e-8f0a-1b2c3d4e5f6a \
  -H "Authorization: Bearer $POSTAL_API_KEY"

Node.js

const response = await fetch('https://api.postal.so/api-keys/0199f0e2-7b8c-7d9e-8f0a-1b2c3d4e5f6a', {
  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/api-keys/0199f0e2-7b8c-7d9e-8f0a-1b2c3d4e5f6a",
    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('api-keys/0199f0e2-7b8c-7d9e-8f0a-1b2c3d4e5f6a', [
    'headers' => ['Authorization' => 'Bearer '.getenv('POSTAL_API_KEY')],
]);

$data = json_decode($response->getBody(), true);
200Resposta
{
  "id": "0199f0e2-7b8c-7d9e-8f0a-1b2c3d4e5f6a",
  "name": "Produção - checkout",
  "permission": "sending_access",
  "domain_id": "0199f0e1-2a3b-7c4d-8e5f-6a7b8c9d0e1f",
  "token_start": "ps_4Fq9xLm",
  "uses_count": 1284,
  "domain": {
    "id": "0199f0e1-2a3b-7c4d-8e5f-6a7b8c9d0e1f",
    "name": "lojaexemplo.com.br"
  },
  "created_by": {
    "name": "Rafaela Lima",
    "email": "[email protected]"
  },
  "created_at": "2026-10-02T18:40:00.000000Z",
  "last_used_at": "2026-10-24T13:02:11.000000Z"
}

#Renomear uma chave

PATCH/api-keys/{id}

Chave de acesso total

Só o nome pode mudar. Para mudar a permissão, crie uma chave nova e exclua a antiga.

Parâmetros de caminho

  • idstringobrigatório
    ID da chave.

Corpo da requisição

  • namestringobrigatório
    Novo nome, até 50 caracteres.

Erros

  • 422validation_error
    Algum campo é inválido. A mensagem diz qual.
  • 404not_found
    O recurso não existe ou é de outro time.
PATCH /api-keys/{id}

cURL

curl -X PATCH https://api.postal.so/api-keys/0199f0e2-7b8c-7d9e-8f0a-1b2c3d4e5f6a \
  -H "Authorization: Bearer $POSTAL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Produção - checkout v2"
  }'

Node.js

const response = await fetch('https://api.postal.so/api-keys/0199f0e2-7b8c-7d9e-8f0a-1b2c3d4e5f6a', {
  method: 'PATCH',
  headers: {
    Authorization: `Bearer ${process.env.POSTAL_API_KEY}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    name: 'Produção - checkout v2',
  }),
});

const data = await response.json();

Python

import os
import requests

response = requests.patch(
    "https://api.postal.so/api-keys/0199f0e2-7b8c-7d9e-8f0a-1b2c3d4e5f6a",
    headers={"Authorization": f"Bearer {os.environ['POSTAL_API_KEY']}"},
    json={
        "name": "Produção - checkout v2",
    },
    timeout=10,
)

data = response.json()

PHP

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

$response = $client->patch('api-keys/0199f0e2-7b8c-7d9e-8f0a-1b2c3d4e5f6a', [
    'headers' => ['Authorization' => 'Bearer '.getenv('POSTAL_API_KEY')],
    'json' => [
        'name' => 'Produção - checkout v2',
    ],
]);

$data = json_decode($response->getBody(), true);
200Resposta
{
  "id": "0199f0e2-7b8c-7d9e-8f0a-1b2c3d4e5f6a",
  "name": "Produção - checkout v2",
  "permission": "sending_access",
  "domain_id": "0199f0e1-2a3b-7c4d-8e5f-6a7b8c9d0e1f",
  "token_start": "ps_4Fq9xLm",
  "uses_count": 1284,
  "created_at": "2026-10-02T18:40:00.000000Z",
  "last_used_at": "2026-10-24T13:02:11.000000Z"
}

#Excluir uma chave

DELETE/api-keys/{id}

Chave de acesso total

Revoga a chave na hora: requisições e conexões SMTP com ela passam a receber 403 invalid_api_key.

Parâmetros de caminho

  • idstringobrigatório
    ID da chave.

Erros

  • 404not_found
    O recurso não existe ou é de outro time.
DELETE /api-keys/{id}

cURL

curl -X DELETE https://api.postal.so/api-keys/0199f0e2-7b8c-7d9e-8f0a-1b2c3d4e5f6a \
  -H "Authorization: Bearer $POSTAL_API_KEY"

Node.js

const response = await fetch('https://api.postal.so/api-keys/0199f0e2-7b8c-7d9e-8f0a-1b2c3d4e5f6a', {
  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/api-keys/0199f0e2-7b8c-7d9e-8f0a-1b2c3d4e5f6a",
    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('api-keys/0199f0e2-7b8c-7d9e-8f0a-1b2c3d4e5f6a', [
    'headers' => ['Authorization' => 'Bearer '.getenv('POSTAL_API_KEY')],
]);

$data = json_decode($response->getBody(), true);
200Resposta
{
  "object": "api_key",
  "id": "0199f0e2-7b8c-7d9e-8f0a-1b2c3d4e5f6a",
  "deleted": true
}