Un solo contrato para tus casas
El contrato OpenAPI y las pocas reglas que sigue todo cliente: claves de idempotencia, ETags, trabajos y detalles de problema.
El contrato legible por máquinas
GET /api/v1/openapi.json devuelve un documento OpenAPI 3.1 con exactamente lo que implementa este despliegue: cada ruta, esquema, permiso requerido y respuesta, además de los eventos de webhook. Se genera a partir del catálogo de operaciones en ejecución, el mismo que produce las herramientas MCP, así que REST y MCP nunca se separan.
curl -s "https://<tu host>/api/v1/openapi.json"La superficie cubre casas y borradores, revisiones y publicaciones, entradas, el catálogo de plantillas, importaciones, carteras y ejecuciones masivas, dominios y planes DNS, reenvío de correo, ajustes de suscripción y contacto, fuentes sociales, analítica, promociones, facturación, miembros del equipo y webhooks. GET /workspaces/{id}/capabilities te dice cuáles están activas, simuladas o pendientes de credenciales en tu espacio.
Los reintentos son deliberados
- Toda mutación necesita una cabecera
Idempotency-Keyde 16 a 128 caracteres. Repetir una solicitud con la misma clave y el mismo cuerpo devuelve el resultado original conIdempotent-Replayed: true. La misma clave con otro cuerpo da409 idempotency_key_reused. - Las ediciones de una casa necesitan
If-Matchcon elETagde tu última lectura. Un valor desactualizado da412 revision_conflicty no cambia nada. - Publicar requiere el
revision_idy elexpected_digestexactos que leíste, así publicas lo que revisaste.
El trabajo largo es un trabajo
Publicar, las ejecuciones masivas y otras operaciones lentas responden 202 con un trabajo. Consulta GET /workspaces/{id}/jobs/{job_id} no más a menudo que next_poll_after_seconds, o suscríbete a los webhooks job.updated. Aceptado no es terminado: lee el state, los contadores y el error del trabajo antes de dar algo por hecho.
Los errores son detalles de problema
Los errores usan application/problem+json con un code estable, un title traducido, el request_id y retryable. Decide según code, nunca según el texto del título.
{
"type": "https://<tu host>/problems/insufficient_scope",
"title": "Este token no incluye el permiso que necesita esta acción.",
"status": 403,
"code": "insufficient_scope",
"request_id": "01M5...",
"retryable": false,
"context": { "required_scope": "account:read" }
}Listas y límites
- Los listados aceptan
limit(hasta 100) y uncursorde la página anterior. - Cada token de espacio puede hacer 120 lecturas y 30 escrituras por minuto. Por encima del límite recibes
429con una cabeceraRetry-After. - Conserva los campos desconocidos de las respuestas: pueden aparecer campos nuevos sin cambio de versión.