API
Todo lo que hace el panel está disponible a través de dos APIs distintas. Ambas usan la misma cuenta, el mismo saldo y el mismo catálogo; se diferencian en el formato y en las capacidades.
Todo lo que hace el panel está disponible a través de dos APIs distintas. Ambas usan la misma cuenta, el mismo saldo y el mismo catálogo; se diferencian en el formato y en las capacidades.
¿Por qué hay dos APIs?
La API clásica de revendedor (v2) que usa todo el sector envía un formulario a un único endpoint y siempre responde HTTP 200. Ese es exactamente el formato que espera el software de panel prefabricado, así que se mantiene tal cual. Quienes escriben su propio sistema chocaban una y otra vez con sus límites: los errores no se podían distinguir, el catálogo llegaba en una sola pieza y había que consultar el estado del pedido sin descanso. v3 se escribió para ellos.
Comparativa
| Característica | Legacy (v2) | Nueva (v3) |
|---|---|---|
| Formato | Un solo endpoint, envío de formulario, parámetro action | REST orientado a recursos, cuerpo JSON |
| Código HTTP | Siempre 200, incluso al fallar | Códigos reales (400, 401, 402, 404, 409, 429, 502) |
| Errores | Texto libre | type + code estable + mensaje localizado + param + doc_url |
| Estado del pedido | Solo texto localizado | Valor de máquina estable más una etiqueta de presentación aparte |
| Descripción del servicio | No existe | Descripción en 10 idiomas, tiempo medio, plataforma, categoría |
| Campos del pedido | Se deducen del nombre del tipo | Cada servicio publica su propio esquema de campos |
| Unidad de precio | No se indica (fuente de errores de 1000x en los paquetes) | Se indica explícitamente como per_1000 o per_order |
| Catálogo | Todos los servicios en una sola respuesta | Filtros más paginación por cursor |
| Protección contra duplicados | No existe | Idempotency-Key |
| Aviso de estado | Consulta continua | Webhooks firmados o flujo de eventos |
| Esquema | No existe | OpenAPI 3.1 |
| Idiomas | Inglés y turco (direcciones separadas) | 10 idiomas (por cabecera o por parámetro) |
¿Cuál me conviene?
Elige la API legacy si usas software de panel prefabricado, un bot o un panel de revendedor. La mayoría solo te pide cambiar la dirección de la API y la clave, y funciona en cuestión de minutos.
Elige v3 si estás escribiendo tu propia aplicación, tienda o automatización. La gestión de errores, la protección contra duplicados y las notificaciones vienen ya incluidas, y puedes generar el formulario de pedido directamente desde el esquema del servicio.
Primeros pasos
- 1Crea una clave de API en la pestaña Claves.
- 2Descarga la lista de servicios y consulta el id y el esquema de campos del servicio que vas a usar.
- 3Valida el pedido primero con preview y créalo después.
- 4Registra un webhook, o lee el flujo de eventos, para seguir los cambios de estado.
Una API REST diseñada para desarrolladores que construyen su propio sistema: rutas orientadas a recursos, códigos de estado HTTP reales, errores legibles por máquina y notificaciones firmadas.
Dirección base
Todas las rutas se añaden a esta dirección. La versión vive en la ruta: si alguna vez hace falta un cambio incompatible, se publica una ruta nueva (v4) y esta sigue funcionando intacta. La fecha de publicación del contrato se devuelve en la cabecera X-Api-Version en cada respuesta.
https://panelfollows.com/api/v3Autenticación
Envía tu clave de API como token Bearer en la cabecera Authorization. Como alternativa también se acepta la cabecera X-Api-Key.
GET https://panelfollows.com/api/v3/account
Authorization: Bearer pf_live_...Tu clave legacy actual también funciona en v3, así que puedes probarla de inmediato. En producción usa una clave v3: se puede etiquetar, revocar una por una y nunca se guarda en texto plano.
Inicio rápido
curl https://panelfollows.com/api/v3/services?limit=5 \
-H "Authorization: Bearer YOUR_API_KEY"Idioma
El idioma de la respuesta se elige con la cabecera Accept-Language o con el parámetro ?lang=; el parámetro tiene prioridad. Los nombres de servicio, las descripciones de servicio, los nombres de categoría, las etiquetas de estado del pedido, las etiquetas de los campos del pedido y los mensajes de error llegan todos en ese idioma.
Los valores de máquina no cambian nunca con el idioma: error.code, order.status, service.type y currency son siempre los mismos. Condiciona tu código sobre ellos y muestra el texto a tus usuarios.
Accept-Language: tr
# veya
GET https://panelfollows.com/api/v3/services?lang=trFormato de solicitud y respuesta
El cuerpo de la solicitud es JSON (application/json); para pruebas rápidas también se acepta form-urlencoded. Las respuestas son JSON: un recurso individual es un objeto plano y las listas llegan en un sobre con data, has_more y next_cursor. Cada objeto lleva un campo object que indica su tipo.
Los importes se devuelven como CADENAS decimales ("1.2340"), no como números en coma flotante. Conviértelos a un tipo decimal en tu lado para no perder fracciones. La moneda es USD.
Las marcas de tiempo siguen el formato RFC 3339 (2026-08-21T00:24:45.255Z).
Errores
Los fallos devuelven un código de estado HTTP real y un cuerpo con un único objeto error. Tu código debe ramificar sobre error.code: ese valor es estable y no cambia nunca con el idioma.
HTTP/1.1 400 Bad Request
Content-Type: application/json
X-Request-Id: req_0c858d8af7f65eca001b2f5a
{
"object": "error",
"error": {
"type": "invalid_request_error",
"code": "quantity_out_of_range",
"message": "Miktar, bu servisin izin verdiği aralığın dışında.",
"param": "quantity",
"doc_url": "https://panelfollows.com/api-docs#error-quantity_out_of_range",
"request_id": "req_0c858d8af7f65eca001b2f5a"
}
}| type | Clase general: si se puede reintentar o si es un fallo tuyo. |
| code | Valor de máquina estable. Condiciona tu código sobre este. |
| message | Texto legible por personas en el idioma que hayas elegido. |
| param | Nombre del campo que provocó el error, si lo hay. |
| doc_url | Enlace a la sección exacta de esta documentación. |
| request_id | La única referencia que debes citar al contactar con soporte. |
Límite de solicitudes
600 solicitudes por minuto y clave, más 900 por minuto e IP. Cada respuesta lleva RateLimit-Limit, RateLimit-Remaining y RateLimit-Reset, así que puedes frenar antes de chocar contra el límite. Superarlo devuelve 429 con una cabecera Retry-After.
Paginación
Las listas se paginan por cursor. Envía limit para el tamaño de página (500 como máximo) y starting_after con el id del último elemento de la página anterior. Continúa hasta que has_more sea false; next_cursor te da el cursor listo para la siguiente llamada. Un limit fuera de rango no se recorta en silencio, devuelve error: el recorte silencioso hace creer al cliente que lo ha descargado todo.
Protección contra duplicados (Idempotency-Key)
Añade una cabecera Idempotency-Key aleatoria al crear un pedido. Si se corta la conexión y reintentas con la misma clave, no se crea un segundo pedido: se devuelve de nuevo la respuesta de la primera solicitud, con la cabecera Idempotent-Replay: true. Los registros se conservan 24 horas.
Enviar la misma clave con un cuerpo DISTINTO devuelve 409 idempotency_key_reuse. Eso casi siempre significa que la generación de claves está rota en el lado del cliente. Una solicitud fallida no quema la clave: corrige el problema y reintenta con la misma.
Crear un pedido
curl -X POST https://panelfollows.com/api/v3/orders \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: 8f14e45f-ea3a-4b1c-9c1e-2b0d5c6a7e91" \
-d '{
"service": 1234,
"link": "https://instagram.com/username",
"quantity": 1000
}'Esquema de campos del servicio
Cada servicio publica en un array fields los campos que necesita: nombre, tipo, si es obligatorio, sus límites y una etiqueta con su descripción en tu idioma. Cuando un campo tiene determines_quantity a true, la cantidad se calcula a partir del número de líneas que contiene.
// Servisin kendi alan şemasından formu OTOMATİK üretmek:
// hiçbir servis tipini koda gömmeniz gerekmez.
const res = await fetch("https://panelfollows.com/api/v3/services/1234", {
headers: { Authorization: "Bearer YOUR_API_KEY", "Accept-Language": "tr" },
});
const service = await res.json();
for (const field of service.fields) {
renderInput({
name: field.name,
label: field.label, // kullanıcının dilinde
hint: field.description, // kullanıcının dilinde
required: field.required,
type: field.type, // url | integer | string | text_lines
min: field.min,
max: field.max,
// true ise miktarı bu alanın satır sayısı belirler
countsLines: field.determines_quantity === true,
});
}El objeto servicio
{
"object": "service",
"id": 1234,
"name": "Instagram Takipçi | Türk | 30 gün telafi",
"description": "Gerçek hesaplardan Türk takipçi. Başlangıç 0-1 saat.",
"type": "default",
"platform": "instagram",
"category": { "slug": "instagram-takipci", "name": "Instagram Takipçi" },
"pricing": {
"rate": "1.2340",
"currency": "USD",
"unit": "per_1000",
"unit_note": "Fiyat 1000 adet içindir."
},
"limits": { "min": 100, "max": 100000 },
"features": { "refill": true, "cancel": false, "dripfeed": true },
"average_time_seconds": 4320,
"fields": [
{
"name": "link",
"type": "url",
"required": true,
"label": "Bağlantı",
"description": "Gönderimin yapılacağı profilin herkese açık adresi."
},
{
"name": "quantity",
"type": "integer",
"required": true,
"label": "Miktar",
"description": "Kaç adet gönderileceği.",
"min": 100,
"max": 100000
}
],
"is_active": true,
"updated_at": "2026-08-20T09:15:00.000Z"
}Vista previa del pedido (ejecución en seco)
POST /orders/preview valida un pedido y calcula su coste SIN crearlo. Puedes mostrar el precio a tu cliente y comprobar de antemano si tu saldo lo cubre. No se descuenta nada del saldo ni se contacta con el proveedor.
Pedidos por lotes
POST /orders/batch acepta hasta 50 pedidos en una sola llamada. Los elementos se procesan en orden y cada uno informa de su propio resultado: si uno falla, los demás se crean igualmente y ves exactamente cuál falló y por qué.
Incrustar objetos relacionados
Si envías include=service en los endpoints de pedidos, el objeto del servicio se incrusta en la respuesta y te ahorras una segunda solicitud.
Referencia de endpoints
| Método | Endpoint | Descripción |
|---|---|---|
| GET | /api/v3 | Discovery document: version, endpoints, limits and event types. |
| GET | /api/v3/openapi.json | OpenAPI 3.1 schema for this API. |
| GET | /api/v3/account | Account balance, currency and current rate-limit window. |
| PATCH | /api/v3/account | Set the low balance alert threshold that triggers account.low_balance. |
| GET | /api/v3/services | List services with filters and cursor pagination. |
| GET | /api/v3/services/{id} | Retrieve one service, including its order field schema. |
| GET | /api/v3/categories | List categories with their active service counts. |
| GET | /api/v3/platforms | List platform keys usable as the ?platform= filter, with counts. |
| POST | /api/v3/orders | Create an order. Supports the Idempotency-Key header. |
| POST | /api/v3/orders/preview | Validate an order and compute its charge without creating it. |
| POST | /api/v3/orders/batch | Create up to 50 orders in one call; each item reports its own result. |
| GET | /api/v3/orders | List your orders, newest first. |
| GET | /api/v3/orders/{id} | Retrieve one order. |
| POST | /api/v3/orders/{id}/cancel | Request cancellation. Only for services whose features.cancel is true. |
| POST | /api/v3/orders/{id}/refill | Request a refill for a completed order. |
| GET | /api/v3/refills | List your refill requests, newest first. |
| GET | /api/v3/refills/{id} | Retrieve one refill; refreshes its status from the provider. |
| GET | /api/v3/events | Read your event stream oldest-first; the polling alternative to webhooks. |
| GET | /api/v3/webhooks | List your webhook endpoints. |
| POST | /api/v3/webhooks | Register a webhook endpoint. The signing secret is returned once. |
| GET | /api/v3/webhooks/{id} | Retrieve one webhook endpoint. |
| PATCH | /api/v3/webhooks/{id} | Update a webhook endpoint's url, events, description or active state. |
| DELETE | /api/v3/webhooks/{id} | Delete a webhook endpoint and its delivery log. |
| POST | /api/v3/webhooks/{id}/test | Send a test event to this endpoint, ignoring its event filter. |
| POST | /api/v3/webhooks/{id}/rotate_secret | Generate a new signing secret. The old one stops working immediately. |
| GET | /api/v3/webhooks/{id}/deliveries | Delivery log for one endpoint: attempts, response codes and errors. |
Esquema OpenAPI
Una definición legible por máquina de cada endpoint. Pasa este archivo a un generador de clientes (openapi-generator, Kiota) o a Postman y obtendrás un cliente listo en tu propio lenguaje.
https://panelfollows.com/api/v3/openapi.jsonPreguntas frecuentes
¿Funciona mi clave legacy en v3?
Sí. No necesitas generar una clave nueva para probarlo. Aun así, pasa a una clave v3 en producción: se puede revocar y no se guarda en texto plano.
¿Por qué los precios son cadenas?
Los números en coma flotante pierden fracciones en importes decimales. Devolver cadenas y convertirlas a un tipo decimal en tu lado elimina por completo esa clase de diferencias de redondeo.
¿Por qué importa el campo unit?
La mayoría de los servicios se cobran por cada 1000 unidades (per_1000), pero los servicios de paquete se venden como un solo artículo (per_order) y la tarifa cubre el paquete entero. Las integraciones que ignoran esta distinción calculaban el precio de los paquetes con un factor de 1000 de error.
Mi pedido se creó pero se quedó en pending. ¿Qué ha pasado?
La entrega al proveedor puede haberse retrasado. Tu saldo está retenido y el pedido no se pierde; nuestro equipo lo reenvía automáticamente. El campo processing_delayed marca ese estado.
¿Todos los servicios admiten cancelación y reposición?
No. Consulta features.cancel y features.refill en el objeto del servicio. Llamar al endpoint en un servicio que no lo admite devuelve 400.
¿Puedo usar las dos APIs a la vez?
Sí. Misma cuenta, mismo saldo, mismos pedidos. Un pedido creado desde v2 se puede consultar desde v3.
La API clásica de revendedor, estándar en todo el sector. Este es el formato que espera el software de panel prefabricado.
Endpoint
POST https://panelfollows.com/api/v2
POST https://panelfollows.com/api/v2/trAutenticación
Cada solicitud lleva un parámetro key. Mantén tu clave en secreto y regenérala de inmediato si se filtra.
Formato de solicitud y respuesta
Las solicitudes se envían por POST como formulario (application/x-www-form-urlencoded) y las respuestas son JSON. Los fallos también devuelven HTTP 200, con { "error": "..." } en el cuerpo.
También se admite, aunque hasta ahora no estaba documentado: puedes llamarla con GET y puedes enviar el cuerpo como application/json.
Límite de solicitudes
240 solicitudes por minuto y clave, más 300 por minuto e IP. Las solicitudes que excedan el límite se rechazan con 429.
Acciones y parámetros
| action | Parámetro | Descripción |
|---|---|---|
| services | key, action | Lista todos los servicios activos (id, nombre, categoría, tarifa, mín./máx., reposición, cancelación, entrega gradual). |
| add | key, action, service, link, quantity[, runs, interval, comments, username, posts, min, max] | Crea un pedido. service es el id del servicio en el catálogo. Añade runs e interval para la entrega gradual, y los campos correspondientes para los tipos especiales. |
| status | key, action, order | orders | Estado del pedido. Usa order para uno solo, o una lista orders separada por comas para varios. |
| balance | key, action | Saldo de la cuenta y moneda. |
| refill | key, action, order | orders | Crea una solicitud de reposición, que se envía directamente al proveedor. |
| refill_status | key, action, refill | refills | Consulta el estado de la reposición. |
| cancel | key, action, orders | Cancela pedidos. Solo funciona en servicios cuyo proveedor admite la cancelación. |
Ejemplo
curl -X POST https://panelfollows.com/api/v2 \
-d "key=YOUR_API_KEY" \
-d "action=add" \
-d "service=1234" \
-d "link=https://instagram.com/username" \
-d "quantity=1000"
# Yanıt: { "order": 23501 }Respuestas en turco
Añade /tr al final de la dirección para recibir los nombres de servicio, las categorías, los estados de pedido y los mensajes de error en turco. Los parámetros, las acciones y la estructura de la respuesta son idénticos, y tu clave funciona en las dos direcciones. Los campos técnicos (type, refill_status, currency) se mantienen en inglés por compatibilidad con el estándar.
Migrar a v3
La migración no es obligatoria. Si decides migrar, la mayor parte de tu lógica de negocio se conserva porque los nombres de los parámetros no cambian; lo que cambia es el transporte y la forma de leer los errores.
- 1Mueve la clave del campo key del cuerpo a la cabecera Authorization: Bearer.
- 2Llama a la ruta del recurso en lugar de action=... (POST /orders en vez de add).
- 3Comprueba los fallos con el código de estado HTTP y error.code en lugar de preguntar "¿hay un campo error?".
- 4Compara el estado del pedido con el valor de máquina, no con el texto de presentación.
- 5Añade una Idempotency-Key al crear pedidos.
- 6Sustituye la consulta continua de estado por webhooks.
Una clave da acceso completo a tu cuenta. No la compartas, no la incrustes en código del lado del cliente y no la subas nunca a un repositorio público.
Claves v3
Puedes crear tantas claves como necesites, etiquetar cada una y revocarlas de una en una. En nuestro lado solo se guarda un resumen criptográfico de la clave.
Crear una cuenta gratisClave legacy
La única clave que usa la API clásica de revendedor (v2). También funciona en v3. Al regenerarla, el valor anterior queda invalidado al instante.
Seguridad
- Guarda la clave en una variable de entorno, nunca en el código fuente.
- No pongas una clave en código que se ejecute en el navegador; pasa las llamadas por tu propio servidor.
- Crea una clave distinta para cada sistema, así revocar una no afecta a las demás.
- Si sospechas de una filtración, pon primero la clave nueva en marcha y revoca después la antigua.
Cuando un pedido cambia de estado enviamos una notificación firmada a tu servidor, así no tienes que consultar el estado sin parar.
¿Por qué webhooks?
La consulta continua es lenta y derrochadora a la vez: preguntar por miles de pedidos cada minuto se come tu límite de solicitudes y aun así te enteras del cambio minutos más tarde. Con un webhook el cambio te llega en el momento en que ocurre.
Configuración
- 1Prepara una dirección https pública (no se aceptan direcciones locales ni de red interna).
- 2Añade la dirección abajo y guarda la clave de firma que se muestra una sola vez.
- 3Verifica la firma en tu lado y responde 2xx.
- 4Usa el botón de prueba para confirmar el recorrido completo de extremo a extremo.
Lo que enviamos
POST /hooks/pf HTTP/1.1
Content-Type: application/json
Webhook-Id: evt_7f910fba7cd042ef9d9069ba5c074fa0
Webhook-Timestamp: 1787261223
Webhook-Signature: t=1787261223,v1=9c1e2b0d5c6a7e91...
{
"object": "event",
"id": "evt_7f910fba7cd042ef9d9069ba5c074fa0",
"type": "order.completed",
"created_at": "2026-08-21T00:27:03.531Z",
"data": {
"previous_status": "in_progress",
"order": {
"object": "order",
"id": 23501,
"status": "completed",
"status_label": "Tamamlandı",
"service": 1234,
"quantity": 1000,
"start_count": 4210,
"remains": 0,
"charge": "1.2340",
"currency": "USD"
}
}
}Verificación de la firma
Cada solicitud lleva una cabecera Webhook-Signature: t es la marca de tiempo y v1 es la firma. La firma es el HMAC-SHA256 de la cadena "<marca de tiempo>.<cuerpo en bruto>" calculado con tu clave secreta.
- 1Extrae los valores t y v1 de la cabecera.
- 2Comprueba que t no tenga más de 5 minutos, para bloquear ataques de repetición.
- 3Calcula el HMAC-SHA256 de "<t>.<cuerpo en bruto>" con tu clave secreta.
- 4Compáralo con v1 en tiempo constante y rechaza la solicitud si no coincide.
Ejemplo de verificación
import crypto from "node:crypto";
import express from "express";
const app = express();
// ÖNEMLİ: imza HAM gövde üzerinden hesaplanır. JSON'a çevirip yeniden
// dizeye dönüştürürseniz boşluklar değişir ve imza tutmaz.
app.post("/hooks/pf", express.raw({ type: "application/json" }), (req, res) => {
const raw = req.body.toString("utf8");
const header = req.get("Webhook-Signature") ?? "";
const m = /t=(\d+),v1=([0-9a-f]+)/.exec(header);
if (!m) return res.sendStatus(400);
const [, timestamp, signature] = m;
// Tekrar saldırısına karşı: 5 dakikadan eski damgayı reddet.
if (Math.abs(Date.now() / 1000 - Number(timestamp)) > 300) return res.sendStatus(400);
const expected = crypto
.createHmac("sha256", process.env.WEBHOOK_SECRET)
.update(`${timestamp}.${raw}`, "utf8")
.digest("hex");
const ok =
expected.length === signature.length &&
crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(signature));
if (!ok) return res.sendStatus(401);
const event = JSON.parse(raw);
// 2xx dönmezseniz gönderim artan aralıklarla tekrar denenir.
res.sendStatus(200);
if (event.type === "order.completed") {
// ... siparişi kendi sisteminizde tamamlandı olarak işaretleyin
}
});Reintentos
El primer intento se hace en el momento del evento. Si la respuesta no es 2xx, o si no se puede establecer la conexión, el envío se reintenta al cabo de 1 minuto, 5 minutos, 30 minutos, 2 horas y 6 horas. Tras 6 intentos en total el envío se marca como fallido y aparece en el registro de entregas.
Tipos de evento
Puedes suscribirte a los tipos que te interesen o recibirlos todos. Un cambio de estado genera exactamente un evento, con el tipo que mejor encaja con el nuevo estado.
| order.created | Se ha creado un pedido. |
| order.processing | El proveedor ha empezado a trabajar en el pedido. |
| order.completed | El pedido está completo. |
| order.partial | El pedido se entregó parcialmente y el resto se reembolsó. |
| order.canceled | El pedido se canceló o se reembolsó. |
| order.updated | El estado cambió de alguna otra forma. |
| refill.created | Se ha solicitado una reposición. |
| refill.updated | Una reposición ha cambiado de estado. |
| account.low_balance | Tu saldo bajó del umbral que fijaste con PATCH /account. Se emite en el cruce, no en cada pedido, y se rearma cuando el saldo vuelve a superarlo. |
Si no puedes alojar un webhook
Los mismos eventos se pueden leer con un cursor desde GET /api/v3/events. Usa esta vía mientras desarrollas en local, cuando no tengas IP fija o cuando estés detrás de un cortafuegos.
// Webhook kuramıyorsanız (yerelde geliştirme, sabit IP yok) aynı bilgiyi
// imleçle çekebilirsiniz. İmleci kendi tarafınızda saklayın.
let cursor = loadCursor(); // en son işlediğiniz olayın "cursor" değeri
const url = new URL("https://panelfollows.com/api/v3/events");
url.searchParams.set("limit", "100");
if (cursor) url.searchParams.set("starting_after", String(cursor));
const res = await fetch(url, { headers: { Authorization: "Bearer YOUR_API_KEY" } });
const { data, has_more } = await res.json();
for (const event of data) {
handle(event); // sizin işleyiciniz
cursor = event.cursor; // imleci ilerlet
}
saveCursor(cursor);Errores (48)
| Código | Estado | Descripción |
|---|---|---|
| missing_api_key | 401 | No se envió ninguna clave de API. Envíela en 'Authorization: Bearer <key>'. |
| invalid_api_key | 401 | La clave de API que proporcionó no es válida. |
| revoked_api_key | 401 | Esta clave de API fue revocada y ya no puede utilizarse. |
| account_banned | 403 | Esta cuenta está bloqueada. |
| account_suspended | 403 | Esta cuenta está suspendida. |
| insufficient_scope | 403 | Esta clave de API no tiene permiso para este endpoint. |
| invalid_json | 400 | El cuerpo de la solicitud no es JSON válido. |
| unsupported_content_type | 415 | Content-Type no admitido. Use application/json o application/x-www-form-urlencoded. |
| method_not_allowed | 405 | Este método HTTP no está permitido en este endpoint. |
| payload_too_large | 413 | El cuerpo de la solicitud es demasiado grande. |
| missing_parameter | 400 | Falta un parámetro obligatorio. |
| invalid_parameter | 400 | Un parámetro tiene un valor no válido. |
| invalid_link | 400 | El enlace falta o no es una URL http(s) válida. |
| invalid_quantity | 400 | La cantidad no es un número entero positivo válido. |
| quantity_out_of_range | 400 | La cantidad está fuera del rango permitido por este servicio. |
| invalid_comments | 400 | El campo de comentarios está vacío o tiene demasiadas líneas. |
| invalid_username | 400 | El nombre de usuario no es válido para este servicio. |
| invalid_subscription | 400 | Los parámetros de la suscripción no son válidos. |
| invalid_runs | 400 | El valor de 'runs' no es válido para la entrega gradual. |
| invalid_interval | 400 | El valor de 'interval' no es válido para la entrega gradual. |
| dripfeed_not_supported | 400 | Este servicio no admite la entrega gradual. |
| missing_required_field | 400 | Falta un campo requerido por este tipo de servicio o su valor no es válido. |
| service_inactive | 400 | Este servicio no está disponible para pedidos en este momento. |
| invalid_cursor | 400 | El cursor de paginación no es válido. |
| invalid_limit | 400 | El parámetro 'limit' está fuera del rango permitido. |
| invalid_webhook_url | 400 | La URL del webhook debe ser una dirección https:// pública. |
| invalid_events | 400 | Uno o más de los tipos de evento solicitados son desconocidos. |
| batch_too_large | 400 | Demasiados elementos en una sola solicitud por lotes. |
| cancel_not_supported | 400 | Este servicio no admite la cancelación. |
| refill_not_supported | 400 | Este servicio no ofrece reposición. |
| unknown_endpoint | 404 | Endpoint desconocido. Las rutas disponibles están en la referencia de la API. |
| service_not_found | 404 | No existe ningún servicio con este id. |
| order_not_found | 404 | No existe ningún pedido con este id en su cuenta. |
| refill_not_found | 404 | No existe ninguna reposición con este id en su cuenta. |
| webhook_not_found | 404 | No existe ningún endpoint de webhook con este id en su cuenta. |
| order_not_cancelable | 409 | Este pedido ya no se puede cancelar debido a su estado actual. |
| cancel_rejected | 409 | El proveedor rechazó la solicitud de cancelación. |
| order_not_completed | 409 | La reposición solo se puede solicitar para un pedido completado. |
| duplicate_link | 409 | Ya existe un pedido activo para este enlace. Espere a que se complete. |
| idempotency_key_reuse | 409 | Esta Idempotency-Key ya se utilizó con un cuerpo de solicitud diferente. |
| idempotency_in_progress | 409 | Una solicitud con esta Idempotency-Key sigue en proceso. Reinténtelo en breve. |
| webhook_limit_reached | 409 | Alcanzó el número máximo de endpoints de webhook. |
| insufficient_balance | 402 | Su saldo no es suficiente para este pedido. |
| rate_limit_exceeded | 429 | Límite de solicitudes superado. Consulte la cabecera de respuesta Retry-After. |
| provider_error | 502 | El proveedor devolvió un error. Inténtelo de nuevo. |
| refill_failed | 502 | El proveedor rechazó la solicitud de reposición. |
| service_temporarily_unavailable | 503 | Este servicio no está disponible temporalmente. Inténtelo más tarde. |
| internal_error | 500 | Se produjo un error inesperado de nuestro lado. |