Autenticación
La API de Zelta Pay utiliza claves API (API keys) para autenticar todas las solicitudes. Cada solicitud debe incluir tu clave en el header X-API-Key.
Autenticación con API Key
Cómo funciona
Todas las solicitudes a la API deben incluir el header X-API-Key con tu clave:
X-API-Key: tu-api-key-aquiLa API valida la clave en cada solicitud. Si la clave es inválida o no se incluye, la solicitud será rechazada con un error de autenticación.
Obtener tu API Key
- Inicia sesión en tu
- Navega a API Keys
- Ingresa un alias descriptivo y haz clic en + Crear
- Copia la clave generada y guárdala de forma segura
La API key solo se muestra una vez
La API key solo se muestra una vez al momento de generarla. Si la pierdes, deberás revocarla y crear una nueva.
Rate Limiting
La API aplica un límite de 60 solicitudes por minuto por API key, usando una ventana deslizante de 1 minuto.
Headers de rate limit
Cada respuesta incluye headers con información del estado de tu límite:
| Header | Descripción |
|---|---|
RateLimit-Limit | Número máximo de solicitudes permitidas por ventana (60) |
RateLimit-Remaining | Solicitudes restantes en la ventana actual |
RateLimit-Reset | Segundos hasta que se reinicie la ventana |
Manejo de rate limits
Cuando superas el límite, la API responde con estado 429 Too Many Requests:
{
"success": false,
"error": {
"code": "ERR_RATE_LIMIT_EXCEEDED",
"message": "Rate limit exceeded"
},
"timestamp": "2026-03-13T10:30:00.000Z"
}Implementa reintentos con backoff exponencial
Implementa backoff exponencial cuando recibas un 429. Usa el header RateLimit-Reset para saber cuánto tiempo esperar antes de reintentar.
Manejo de errores
Errores comunes de autenticación
| Código de error | HTTP Status | Descripción |
|---|---|---|
ERR_MISSING_API_KEY | 401 | No se incluyó el header X-API-Key en la solicitud |
ERR_API_KEY_NOT_FOUND | 404 | La API key proporcionada no existe o fue revocada |
ERR_ACCOUNT_SUSPENDED | 403 | La cuenta asociada a la API key está suspendida |
ERR_RATE_LIMIT_EXCEEDED | 429 | Se superó el límite de solicitudes por minuto |
Formato de respuesta de error
{
"success": false,
"error": {
"code": "ERR_MISSING_API_KEY",
"message": "API key is required"
},
"timestamp": "2026-03-13T10:30:00.000Z"
}Ejemplos de implementación
:: tab Node.js
const response = await fetch('https://api-pay.zelta.dev/v1/payment-links', {
method: 'GET',
headers: {
'X-API-Key': process.env.ZELTA_API_KEY,
'Content-Type': 'application/json'
}
});
const data = await response.json();
if (!data.success) {
console.error('Error:', data.error.code, data.error.message);
}::
:: tab Cloudflare Workers
export default {
async fetch(request, env, ctx) {
const response = await fetch('https://api-pay.zelta.dev/v1/payment-links', {
method: 'GET',
headers: {
'X-API-Key': env.ZELTA_API_KEY,
'Content-Type': 'application/json'
}
});
const data = await response.json();
return new Response(JSON.stringify(data), {
headers: { 'Content-Type': 'application/json' }
});
}
};::
:: tab Hono
import { Hono } from 'hono';
type Bindings = {
ZELTA_API_KEY: string;
};
const app = new Hono<{ Bindings: Bindings }>();
app.get('/payment-links', async (c) => {
const response = await fetch('https://api-pay.zelta.dev/v1/payment-links', {
method: 'GET',
headers: {
'X-API-Key': c.env.ZELTA_API_KEY,
'Content-Type': 'application/json'
}
});
const data = await response.json();
return c.json(data);
});
export default app;::
:: tab Python
import os
import requests
api_key = os.environ.get('ZELTA_API_KEY')
response = requests.get(
'https://api-pay.zelta.dev/v1/payment-links',
headers={
'X-API-Key': api_key,
'Content-Type': 'application/json'
}
)
data = response.json()
if not data.get('success'):
print(f"Error: {data['error']['code']} - {data['error']['message']}")::
:: tab PHP
<?php
$apiKey = getenv('ZELTA_API_KEY');
$ch = curl_init('https://api-pay.zelta.dev/v1/payment-links');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'X-API-Key: ' . $apiKey,
'Content-Type: application/json'
]
]);
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
$data = json_decode($response, true);
if (!$data['success']) {
echo "Error: {$data['error']['code']} - {$data['error']['message']}";
}::
Buenas prácticas de seguridad
Variables de entorno
Nunca incluyas API keys directamente en tu código fuente. Usa variables de entorno:
# .env (nunca subir al control de versiones)
ZELTA_API_KEY=tu-api-key-aquiNo subas API keys al control de versiones
Nunca guardes API keys en el control de versiones. Agrega .env a tu archivo .gitignore.
Rotación de claves
- Rota tus API keys periódicamente
- Revoca inmediatamente cualquier clave comprometida desde el
- Usa nombres descriptivos para identificar fácilmente qué clave usa cada servicio
Control de acceso
- Genera claves diferentes para cada servicio o aplicación
- Limita el acceso a las API keys solo al personal necesario
- Almacena las claves en un gestor de secretos en producción
Manejo de errores
- Nunca expongas tu API key en mensajes de error del lado del cliente
- Registra los errores de autenticación para detectar intentos de acceso no autorizado
- Implementa alertas para errores
403recurrentes
Probar la autenticación
Verifica que tu API key funcione correctamente con esta solicitud:
curl -X GET "https://api-pay.zelta.dev/v1/payment-links?lim=1" \
-H "X-API-Key: tu-api-key-aqui" \
-H "Content-Type: application/json"Una respuesta exitosa confirma que tu clave es válida:
{
"success": true,
"data": {
"paymentLinks": [],
"total": 0
},
"message": "Payment links retrieved successfully",
"timestamp": "2026-03-13T10:30:00.000Z"
}Solución de problemas
Error 401 — API key faltante o inválida
- Verifica que estés usando el header
X-API-Key(noAuthorization) - Confirma que la clave no tenga espacios en blanco adicionales
- Asegúrate de que la clave esté activa en tu
Error 403 — Cuenta suspendida
- Tu cuenta puede estar suspendida por actividad inusual
- Contacta a soporte para resolver el problema
Error 429 — Rate limit excedido
- Estás enviando más de 60 solicitudes por minuto
- Implementa backoff exponencial en tus reintentos
- Revisa el header
RateLimit-Resetpara saber cuándo puedes reintentar - Si necesitas mayor capacidad, contacta a soporte
Siguientes pasos
- — Documentación completa de endpoints y formatos
- — Crea tu primer link de pago
- — Guía paso a paso para empezar