Iniciar sesión Crear cuenta
Para empezar

Autenticación

Toda solicitud usa una clave de API en el encabezado Authorization. Las claves pueden tener acceso total o solo de envío, y restringirse a un dominio.

#Clave de API

Toda solicitud necesita una clave de API en el encabezado Authorization, con el formato Bearer:

Encabezado
Authorization: Bearer ps_4Fq9xLmT2vKp8sWd1Yc5Hf3Lz9Ag6Ej0Qm8rBnX

Las claves empiezan por ps_. Créalas en Claves de API en el panel, o por la API con POST /api-keys. El token completo aparece una sola vez, al crearla: Postal guarda solo el hash y los primeros caracteres (token_start), para que reconozcas la clave en la 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);

#Permisos

PermisoQué puede hacer
full_access
Acceso total
Toda la API: envío, dominios, plantillas, webhooks, registros, claves…
sending_access
Solo envío
Enviar: POST /emails, POST /emails/batch, POST /events y el SMTP.
Consultar: el estado y los eventos de los correos electrónicos que ella misma envió, por API o SMTP (GET /emails/{id}; los correos de otras claves o del panel responden 404), y el plan, las cuotas y el límite de solicitudes en GET /usage. Todo lo demás requiere acceso total.
Puede restringirse a un dominio (domain_id): entonces solo envía con remitentes de ese dominio.

Crear claves solo de envío o restringidas a un dominio depende del plan (restricted_api_keys); el número de claves también (api_keys). Consulta Límites.

Usa claves solo de envío en los sistemas que únicamente disparan correos electrónicos o eventos (el checkout, WordPress, el ERP) y reserva las de acceso total para automatizaciones de infraestructura. Si una clave de envío se filtra, no cambia tu configuración ni lee tus contactos, dominios o los correos de otras claves: solo ve lo que ella misma envió y los límites del plan.

#Errores de autenticación

EstadoNombreCuándo ocurre
401missing_api_keyFalta el encabezado Authorization.
403invalid_api_keyLa clave no existe, fue eliminada o no empieza con ps_.
401restricted_api_keyUna clave solo de envío intentó usar otro endpoint (puede enviar, leer los correos que envió con GET /emails/{id} y llamar a GET /usage).
403restricted_api_keyUna clave restringida a un dominio intentó enviar desde otro dominio.
403paused_by_planLa clave superó el límite de claves del plan actual y fue pausada (paused_by_plan: true en GET /api-keys). No se autentica hasta que el plan o el conteo lo permitan de nuevo; consulta Límites.
403team_suspendedLa cuenta fue suspendida por la plataforma que la gestiona.

#Idioma de los mensajes y origen de los cambios

Dos opciones por solicitud:

  • Accept-Language: pt-BR (o en) elige el idioma del message de los errores y de los demás textos que la API escribe para tu solicitud (consulta la tabla de abajo). Sin el encabezado, viene en inglés. El name es siempre el mismo.
  • X-Postal-Source: erp pone una etiqueta a los cambios que la clave hace en los contactos. La etiqueta aparece en source en los webhooks de contacto y en last_change_source del contacto, y permite que un webhook ignore lo que hizo el propio sistema.

El idioma de cada texto que escribe Postal depende de a quién va dirigido:

TextoIdioma
Los textos de las respuestas de la APIEl message de los errores, las etiquetas (como el label de paused en GET /usage), el sending.reason del mismo endpoint, el diagnostic de los registros DNS del dominio, el sufijo de los nombres de copias (“(copy)” o “(cópia)”), el prefijo [Test] o [Teste] de la prueba de campaña y de la prueba de plantilla y el “Other:” u “Outro:” de los CSV de respuestas de formulario. Siguen el Accept-Language de la solicitud (pt-BR o en, el primero que Postal conoce). Con clave de API o sin credenciales, sin el encabezado vienen en inglés; GET /plans, que es público, viene en portugués sin él.
Texto de la IA del diagnósticoPOST /ai/emails/{id}/fix-insights: el parámetro language (pt-BR, en o es); sin él, el idioma de la solicitud.
Webhooks de pausaEl reason sale en el idioma del equipo, el que eligió el propietario en el panel; en inglés mientras no elija. El reason_code no depende del idioma.
Pie de cancelación de suscripción y página de preferenciasEl idioma de cada destinatario: language de la campaña, propiedades del contacto, idioma del equipo. Consulta Idioma del pie y de la página.
Formularios públicos y correo electrónico de confirmaciónsettings.language del formulario; si no, el Accept-Language de quien lo rellena; si no, pt-BR. Consulta Idioma del formulario.
En portugués a propósitoLas plantillas predeterminadas de los correos electrónicos de autenticación de Supabase, que editas en la conexión.

#Buenas prácticas

  • Guarda la clave en una variable de entorno o en un gestor de secretos, nunca en el código. No uses la clave en el navegador ni en apps: cualquier persona podría copiarla. Llama a la API desde tu servidor.
  • Usa una clave por sistema y por entorno. Así puedes revocar una sin tumbar las demás y ver en los registros quién hizo cada solicitud.
  • Si una clave se filtra, elimínala de inmediato (DELETE /api-keys/{id}) y crea otra.
  • Para dar a un asistente de IA acceso a la cuenta, prefiere el OAuth del servidor MCP, que limita el acceso a un equipo y a ámbitos, y se revoca sin cambiar de clave.