PUT /api/listings crea o actualiza un listado completo en una sola llamada atómica: la API, sus endpoints, el secreto de origen, los planes, las FAQs y las APIs vinculadas. O se guarda todo, o no se guarda nada. Es lo que usan internamente las herramientas MCP provider_*, y puedes llamarla directamente desde scripts o CI.

Acceso

  • Cualquier cuenta con correo verificado. Las cuentas no verificadas o bloqueadas reciben 403.
  • Autentícate con tu clave de API: Authorization: Bearer YOUR_API_KEY.
  • Límites de velocidad por cuenta: 30 upserts y 120 lecturas por minuto.
  • Los listados nuevos cuentan contra la cuota de APIs nuevas. Las actualizaciones nunca cuentan.

Endpoints

Método Ruta Propósito
PUT /api/listings Crea o actualiza un listado (o lo elimina con "delete": true)
GET /api/listings Tus listados (status, page, per_page)
GET /api/listings/{product_key} Definición completa de un listado (nunca el secreto de origen)
GET /api/listings/me Tu cuenta, límites, nombres de plan válidos y tipos de parámetro
GET /api/listings/categories Ids de categoría

Ejemplo

curl -X PUT https://zylalabs.com/api/listings \
  -H "Authorization: Bearer $ZYLA_API_KEY" \
  -H "Content-Type: application/json" \
  -d @listing.json

listing.json:

{
  "product_key": "trustpilot-api",
  "publish": true,
  "api": {
    "name": "Trustpilot Reviews API",
    "short_description": "Retrieve Trustpilot company reviews, ratings and reviewer details in JSON.",
    "trial": false
  },
  "access": { "in": "header", "key": "X-Origin-Key", "value": "your-origin-secret" },
  "endpoints": [{
    "name": "Get Company Reviews",
    "description": "Returns the latest public reviews for a company domain with pagination.",
    "method": "GET",
    "base_url": "https://origin.example.com/v1/items/||domain||",
    "path_params": { "domain": "example.com" },
    "parameters": [
      { "key": "page", "type": "number", "description": "Page number, starting at 1.", "value": "1", "required": false }
    ],
    "headers": [{ "key": "Accept", "value": "application/json" }],
    "example_response": { "reviews": [{ "rating": 5 }] }
  }],
  "plans": [
    { "name": "Basic", "interval": "Monthly", "price": 24.99, "max_requests": 1000 },
    { "name": "Pro", "interval": "Monthly", "price": 49.99, "max_requests": 5000 },
    { "name": "ProPlus", "interval": "Monthly", "price": 99.99, "max_requests": 15000, "rate_limit": 120 }
  ],
  "faqs": [{ "question": "What data does it return?", "answer": "Public reviews with rating and text." }],
  "slaves": [{ "name": "Company Reviews Lookup API" }]
}

Reglas

Identidad. product_key es tu propio id estable para el listado. Una clave nueva crea el listado; una clave que ya usaste lo actualiza. Una clave pertenece a la cuenta que la creó (403 para cualquier otra). Los listados eliminados no aceptan ediciones (409).

Publicación. El listado se publica cuando pasa las reglas de calidad y tiene al menos un endpoint con una respuesta de ejemplo y planes activos. Sin eso, "publish": true devuelve 422. Omite publish para publicarlo en cuanto esté listo, o envía "publish": false para mantenerlo como borrador. false nunca despublica un listado que ya está en vivo.

Campos de la API. name sigue las reglas de nombre: hasta 50 caracteres, incluye la palabra "API", único en el hub. short_description de al menos 50 caracteres. Zyla completa el resto de la página del listado por ti: la descripción larga se genera a partir de tu descripción corta, y la categoría y las etiquetas se eligen con IA. Si envías long_description, category_id, tags o website_url, se ignoran y se listan en warnings.

Endpoints. Cuando endpoints está presente, es la lista completa: los endpoints se emparejan por método + base_url (sin el query string), se crean los nuevos y se eliminan los que falten en la lista. Omite endpoints para dejarlos sin cambios.

  • Descripción de al menos 40 caracteres. Método GET, POST, PUT, DELETE o PATCH.
  • base_url debe ser una URL válida. Los parámetros de ruta van entre ||, como en /items/||domain||, con un valor de ejemplo en path_params.
  • Los parámetros necesitan key, type (string, number, email, url, domain, date, datetime) y una descripción de al menos 10 caracteres.
  • example_response es obligatorio, de hasta 10,000 caracteres.

Secreto de origen (access). Un header o parámetro de consulta que Zyla agrega a cada llamada hacia tu origen, para que tu servidor solo acepte tráfico del hub. Se guarda oculto y nunca se devuelve ni se registra. Omítelo para mantener el actual; envía null para eliminarlo.

Planes. Nombres exactos: Free, Basic, Pro, ProPlus, Premium, Elite, Ultimate, Pay as you go. price en USD; los planes anuales llevan su precio anual final. max_requests por ciclo; un plan más barato debe incluir menos solicitudes que uno más caro en el mismo intervalo. rate_limit de 60 a 240 por minuto. Deben mantenerse activos al menos tres planes mensuales pagos. Si no envías planes en un listado nuevo, se crea un conjunto por defecto.

FAQs. Lista completa cuando está presente, hasta 10. Pregunta de 5 a 100 caracteres, respuesta de 3 a 700.

APIs vinculadas (slaves). Variantes de tu API con su propio nombre y página que reutilizan sus endpoints. Se emparejan por nombre y siguen los cambios en los endpoints de la principal. La principal necesita endpoints, y una API vinculada no puede tener APIs vinculadas propias.

Eliminar. {"product_key": "...", "delete": true} elimina el listado. Se rechaza con 409 mientras tenga suscripciones pagas. Las APIs vinculadas se eliminan solo si las nombras en slaves.

No soportado. Transformaciones de respuesta, cuerpos de solicitud y subida de archivos (422 not_supported). Usa el asistente web para eso.

Respuestas

Éxito: {"success": true, "listing": {...}, "warnings": []}, con 201 al crear y 200 al actualizar. listing.url se establece en cuanto el listado está en vivo.

Estado code Significado
401 unauthenticated Clave ausente o inválida
403 forbidden Cuenta no verificada o bloqueada, o el product_key pertenece a otra cuenta
404 not_found product_key desconocido
409 name_taken, active_subscriptions, endpoints_required, listing_deleted, slave_of_slave, product_key_conflict Conflicto; no se cambió nada
422 validation_failed, ai_validation_failed, not_supported errors indexado por campo, por ejemplo endpoints.2.parameters.0.description
429 creation_limit_reached Se agotó la cuota de APIs nuevas; retry_after en segundos y un header Retry-After
503 ai_unavailable La verificación de contenido no respondió; no se guardó nada; vuelve a intentarlo
500 server_error Falla inesperada; no se guardó nada