Claves de API
Crea, lista, renombra y revoca claves de API.
Gestiona las claves que se usan para autenticarse en la API y en SMTP. El token completo solo aparece una vez, al crearlo: Postal guarda únicamente el hash. Entiende los permisos en Autenticación. Si el plan baja y el equipo queda con más claves que el nuevo límite, las más nuevas quedan en pausa (paused_by_plan: true): siguen en la lista, pero toda solicitud hecha con una clave en pausa responde 403 paused_by_plan (consulta Límites del plan).
#Listar claves
GET/api-keys
Parámetros de consulta
limitintegerDe 1 a 100. Predeterminado: 20.afterstringCursor de la página siguiente.beforestringCursor de la página anterior.searchstringBusca en el nombre o en el inicio del token.permissionstringfull_accessosending_access.
Errores
- 422
validation_errorAlgún campo no es válido. El mensaje indica cuál.
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);
{
"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",
"paused_by_plan": false
}
]
}
#Crear una clave
POST/api-keys
Crea la clave y devuelve el token completo. Guárdalo ahora: no se podrá consultar después. A quien eligió recibir alertas de seguridad se le avisa por correo electrónico de que se creó la clave. El plan define cuántas claves puede tener el equipo y si puede crear claves restringidas (sending_access o limitadas a un dominio).
Cuerpo de la solicitud
namestringobligatorioNombre para identificar la clave, hasta 50 caracteres.permissionstringfull_access(por defecto): toda la API.sending_access: envío (POST /emails,POST /emails/batch,POST /eventsy SMTP), más la lectura deGET /emails/{id}(solo de los correos electrónicos que ella envió) y deGET /usage.domain_idstringRestringe una clavesending_accessa un dominio. No se puede usar confull_access.
Errores
- 422
validation_errorNombre ausente o demasiado largo, permiso no válido, dominio de otro equipo odomain_idconfull_access. - 403
plan_limit_reachedEl plan no permite más claves, o no incluye claves restringidas (sending_accesso condomain_id).
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);
{
"id": "0199f0e2-7b8c-7d9e-8f0a-1b2c3d4e5f6a",
"token": "ps_4Fq9xLmT2vKp8sWd1Yc5Hf3Lz9Ag6Ej0Qm8rBnX"
}
#Obtener una clave
GET/api-keys/{id}
Devuelve la clave con el dominio (cuando es restringida) y quién la creó. El token nunca se devuelve; token_start muestra los primeros caracteres para que la reconozcas.
Parámetros de ruta
idstringobligatorioID de la clave.
Errores
- 404
not_foundEl recurso no existe o es de otro equipo.
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);
{
"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",
"paused_by_plan": false
}
#Renombrar una clave
PATCH/api-keys/{id}
Solo el nombre puede cambiar. Para cambiar el permiso, crea una clave nueva y elimina la antigua.
Parámetros de ruta
idstringobligatorioID de la clave.
Cuerpo de la solicitud
namestringobligatorioNuevo nombre, hasta 50 caracteres.
Errores
- 422
validation_errorAlgún campo no es válido. El mensaje indica cuál. - 403
paused_by_planLa clave está en pausa porque supera el límite de claves del plan. - 404
not_foundEl recurso no existe o es de otro equipo.
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);
{
"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",
"paused_by_plan": false
}
#Eliminar una clave
DELETE/api-keys/{id}
Revoca la clave al instante: las solicitudes y conexiones SMTP con ella pasan a recibir 403 invalid_api_key.
Parámetros de ruta
idstringobligatorioID de la clave.
Errores
- 404
not_foundEl recurso no existe o es de otro equipo.
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);
{
"object": "api_key",
"id": "0199f0e2-7b8c-7d9e-8f0a-1b2c3d4e5f6a",
"deleted": true
}