1. Descripción general
La API REST de Eyivo permite administrar sitios web estructurados mediante programación. Usa HTTPS y JSON, está versionada en /api/v1 y aplica las mismas reglas de propiedad, límites del plan, validación y auditoría que el panel.
JSON y multipart
Accept: application/json. Content-Type: application/json; file: multipart/form-data.
Acceso del propietario
Cada operación del sitio está restringida a sitios propiedad del usuario autenticado.
Primero en borrador
Guarda un borrador, comprueba si está listo y publica ese elemento e idioma cuando el usuario quiera hacerlo visible. Los demás borradores no se publican.
Versionado: Los cambios que rompen el contrato requieren una nueva versión base. Pueden añadirse campos a los objetos JSON existentes; los clientes deben ignorar los que no reconocen.
2. Inicio rápido
- 1Crea un token.
Inicia sesión en la aplicación, abre Tokens de API, elige los ámbitos mínimos necesarios y copia el
ey_secreto cuando aparezca. - 2Lista tus sitios.
Confirma la autenticación y obtén el ID numérico del sitio que usan los endpoints dependientes.
- 3Envía solicitudes de escritura idempotentes.
Asigna a cada solicitud POST, PATCH y DELETE una clave
Idempotency-Key.
curl --request GET \
--url https://app.eyivo.com/api/v1/sites \
--header 'Accept: application/json' \
--header 'Authorization: Bearer ey_your_token'
Una respuesta correcta a una consulta de colección agrupa los registros en data:
{
"data": [
{
"id": 42,
"platform_subdomain_key": "7kr9mp2x",
"template_key": "corporate-01",
"status": "active",
"native_locale": "en",
"english_enabled": false,
"content_version": 1,
"search_visibility": "platform_noindex"
}
]
}
3. Autenticación
Todas las solicitudes a /api/v1 requieren un token de acceso:
Authorization: Bearer <token>
Tokens personales de API
Indicados para scripts, integraciones de servidor y automatizaciones de la cuenta. Los tokens empiezan por ey_, se almacenan como hashes y solo se muestran una vez.
- Crea y revoca los tokens en https://app.eyivo.com/tokens.
- Elige uno o varios ámbitos.
- Puedes limitar un token a uno de tus sitios.
- Los tokens no vencidos siguen siendo válidos hasta que sean revocados.
OAuth 2.0 + PKCE
Indicado para aplicaciones que actúan en nombre de usuarios de Eyivo. Usa el flujo de código de autorización con PKCE; no uses los flujos de contraseña ni implícito.
- Autorización:
https://app.eyivo.com/oauth/authorize - Token y actualización:
https://app.eyivo.com/oauth/token - Los tokens de acceso caducan después de 2 horas.
- Los tokens de actualización caducan después de 1 año.
Flujo de autorización PKCE
- Crea un
code_verifierde alta entropía y sucode_challengeSHA-256. - Redirige al usuario a
/oauth/authorizeconresponse_type=code, elclient_idpúblico, elredirect_uriregistrado exacto, los ámbitos solicitados enscopeseparados por espacios,state,code_challengeycode_challenge_method=S256. - Comprueba
statetras la redirección y canjea el código de autorización en/oauth/tokenusando elcode_verifieroriginal. - Guarda de forma segura los tokens de acceso y renovación. Renuévalos antes de que caduquen y sustituye de forma atómica las credenciales rotadas.
4. Ámbitos
Cada solicitud necesita el ámbito indicado a continuación. Un token personal con * supera todas las comprobaciones de ámbito, pero las aplicaciones deben solicitar solo los permisos necesarios.
| Ámbito | Función REST |
|---|---|
sites:read | Listar los sitios propios y consultar uno de ellos. |
sites:write | Crear sitios con un token válido para toda la cuenta. |
content:read | Leer contenido, esquemas, menús, formularios y ajustes. |
content:write | Crear, editar, eliminar y publicar contenido explícitamente; ejecutar acciones declaradas del panel. |
media:read | GET /sites/{site}/media, GET /sites/{site}/media/stock-photos |
media:write | POST /sites/{site}/media, DELETE /sites/{site}/media/{media} |
domains:read | Listar los dominios del sitio. |
domains:write | Solicitar, activar y seleccionar dominios personalizados. |
REST requiere el permiso del endpoint, no mcp:use. Los endpoints multimedia usan media:read o media:write.
5. Escrituras idempotentes
Envía Idempotency-Key en las modificaciones JSON para repetir la misma solicitud de forma segura. Las cargas multipart y la emisión de tickets quedan excluidas; verifica el resultado antes de reintentar.
Idempotency-Key: site-42-page-create-01J7M6Y8RRF3ZE6WB4Z0Y9XJXC
| Situación | Resultado |
|---|---|
| Primera solicitud | La operación se ejecuta y se almacenan su código de estado y el cuerpo JSON. |
| Misma clave, método, ruta, parámetros de consulta y cuerpo | Se devuelve la respuesta guardada sin repetir la operación. |
| Misma clave con una solicitud diferente | 422 — se rechaza la reutilización de la clave con un cuerpo distinto. |
| Misma clave mientras se ejecuta la primera solicitud | 409 — la solicitud ya está en curso. |
| Sin clave | La solicitud se ejecuta, pero no puede repetirse de forma segura. |
Para comparar solicitudes se tienen en cuenta el método HTTP, la ruta y el cuerpo bruto exacto. Al reintentarlo, utiliza el mismo JSON serializado.
6. Respuestas y estructura de los recursos
Las operaciones de contenido devuelven un envoltorio data. MCP devuelve structuredContent y una copia JSON en texto; REST devuelve JSON. Consulta los esquemas para IDs, preparación y paginación. Blogs, archivos y envíos incluyen información de páginas.
Recurso individual
{ "data": { "id": 42, "status": "active" } }Colección
{ "data": [{ "id": 42 }, { "id": 43 }] }Las colecciones tienen formatos distintos. Sigue los metadatos de paginación de cada endpoint; no supongas que todas son listas simples o sin paginar.
7. Sitios
/sitesListar sitios propios · sites:read
/sitesCrear un sitio · sites:write
/sites/{site}Recuperar un sitio propio · sites:read
Crear un sitio
curl --request POST \
--url https://app.eyivo.com/api/v1/sites \
--header 'Accept: application/json' \
--header 'Authorization: Bearer ey_your_token' \
--header 'Content-Type: application/json' \
--header 'Idempotency-Key: site-create-01J7M6Y8' \
--data '{
"display_name": "Northstar Studio",
"template_key": "corporate-01",
"native_locale": "en"
}'
| Campo | Reglas |
|---|---|
display_name | Cadena requerida, máximo 200 caracteres. |
template_key | Clave de plantilla integrada obligatoria. La lista completa de valores actuales está en OpenAPI. |
native_locale | Código de idioma compatible obligatorio. |
Respuesta: 201 Created con un recurso de sitio. Durante la asignación inicial, el estado puede no ser todavía activo. Si se supera un límite de sitios o del plan, se devuelve 422.
Campos del recurso de sitio: id, platform_subdomain_key, template_key, status, native_locale, english_enabled, content_version, search_visibility, runtime opcional y marcas de tiempo.
8. Páginas
/sites/{site}/pagesListar páginas · content:read
/sites/{site}/pagesCrear un borrador · content:write
/sites/{site}/pages/{page}Recuperar una página · content:read
/sites/{site}/pages/{page}Actualizar un borrador · content:write
/sites/{site}/pages/{page}Eliminar una página · content:write
/sites/{site}/pages/{page}/publicationcontent:write · locale
Crear una página
{
"type": "page",
"sort_order": 300,
"locale": "en",
"slug": "our-story",
"title": "Our story",
"body": "<p>How the company began.</p>",
"meta_title": "Our story | Northstar Studio",
"meta_description": "Learn about Northstar Studio."
}
| Campo | Reglas de creación y actualización |
|---|---|
type | Usa page para contenido general. Los tipos admitidos y esquemas de componentes están en las capacidades del sitio. |
sort_order | Entero opcional y anulable de 0 a 9999; el valor predeterminado al crear es 0. |
locale | Obligatorio al crear. Al actualizar, se requiere si cambian title, slug o body. |
slug | Obligatorio al crear. Letras ASCII, dígitos, guiones y guiones bajos; máximo 160 caracteres. |
title | Cadena obligatoria al crear; 200 caracteres como máximo. |
body | Cadena o valor nulo; 50.000 caracteres como máximo. |
meta_title | Cadena o valor nulo; 200 caracteres como máximo. |
meta_description | Cadena o valor nulo; 500 caracteres como máximo. |
Respuesta al crear: 201. Respuesta al actualizar: 200. Respuesta al eliminar: 204, sin cuerpo.
Guarda un borrador, comprueba si está listo y publica ese elemento e idioma cuando el usuario quiera hacerlo visible. Los demás borradores no se publican.
9. Elementos del catálogo
/sites/{site}/catalog-itemsListar elementos · content:read
/sites/{site}/catalog-itemsCrear un elemento como borrador · content:write
/sites/{site}/catalog-items/{catalogItem}Consultar un elemento · content:read
/sites/{site}/catalog-items/{catalogItem}Eliminar un elemento · content:write
/sites/{site}/catalog-items/{catalogItem}content:write · locale, slug, title
/sites/{site}/catalog-items/{catalogItem}/publicationcontent:write · locale
Crear un elemento del catálogo
{
"sort_order": 100,
"locale": "en",
"slug": "strategy-advisory",
"title": "Strategy advisory",
"summary": "Focused advice for consequential decisions.",
"body": "Talk to our senior advisory team."
}
| Campo | Reglas |
|---|---|
sort_order | Entero opcional de 0 a 9999, o valor nulo; 0 por defecto. |
locale | Código de idioma compatible obligatorio. |
slug | Se requiere slug ASCII; máximo 160. |
title | Cadena requerida; máximo 200. |
summary | Cadena o valor nulo; 1.000 caracteres como máximo. |
body | Cadena o valor nulo; 50.000 caracteres como máximo. |
Guarda un borrador, comprueba si está listo y publica ese elemento e idioma cuando el usuario quiera hacerlo visible. Los demás borradores no se publican.
Estos son ejemplos por área de contenido. Descubre todos los esquemas y permisos en tools/list o en OpenAPI. Las rutas REST son relativas a /api/v1/sites/{site}.
Descubrir sitios y capacidades
GET /capabilities · GET /readiness
Páginas, componentes y enlaces internos
/pages · /pages/{page_id}/components · POST /pages/{page_id}/publication
Productos, galerías y vídeos
/catalog-items · /galleries · /videos · POST /{collection}/{id}/publication
Borradores de blog, categorías y programación
/blog/posts · /blog/categories · /blog/links · /blog/posts/{post_id}/publication · /blog/posts/{post_id}/schedule
Navegación principal y menús adicionales
/menus · /menus/destinations · /menu-assignments/{type}/{target_id} · /menus/{menu_key}/publication
Biblioteca multimedia y fotos de stock
/media · /media/transfers · /media/stock-photos
Formularios, envíos y paneles de plugins
/forms · /submissions · /plugins · /plugins/panel · /plugins/panel/actions
Empresa, tema, idiomas e integraciones
/company · /theme · /theme/settings · /locales · /integrations · /demo · /demo/drafts · /cache/reset
Capacidades y contrato de edición
Selecciona un sitio y consulta sus capacidades: idiomas activos, campos del tema, esquemas de componentes, menús y paneles de plugins. Lee el recurso content-workflow antes de escribir. Los clientes sin recursos pueden usar get-site-capabilities-tool. Sigue nextCursor de tools/list hasta completar el catálogo.
GET /api/v1/sites/{site}/capabilities
GET /api/v1/sites/{site}/pages/{page_id}/components/schema?locale=en
Usa el idioma solicitado y la version o revision actual. Guardar un blog reemplaza el documento completo y cancela su programación. Los menús usan revision numérica; las asignaciones usan un hash menu_revision independiente. Conserva los elementos de las listas reemplazadas. Ante un conflicto, vuelve a leer y combina los cambios.
La navegación principal sigue siendo automática. Los menús adicionales tienen sus propios borradores y publicación. Guardar contenido prepara sus asignaciones; publicar el elemento las aplica sin publicar otros menús. Publicar un menú nunca publica su contenido enlazado. source_hash rechaza traducciones basadas en texto de origen obsoleto.
El cuerpo de las páginas y los campos richtext aceptan HTML saneado. Usa list-page-links-tool para enlaces estables /__eyivo/pages/{id}, resueltos en el idioma del visitante cuando estén publicados. Los blogs usan document JSON estructurado con media_id del mismo sitio y destinos de página/entrada, no body_html.
{
"type": "doc",
"content": [{
"type": "paragraph",
"content": [{ "type": "text", "text": "Our story" }]
}]
}
Cargar imágenes y vídeos
upload-media-tool abre un selector de archivos en clientes MCP Apps como Claude. ChatGPT también puede proporcionar su referencia de adjunto; un adjunto de Claude no es una referencia de archivo OpenAI. No inventes URLs de descarga ni envíes archivos base64 como argumentos.
Codex y Claude Code pueden llamar a prepare-media-upload-tool y enviar el archivo multipart a upload_url con su upload_token de un solo uso en cinco minutos. Mantén el token en secreto. Los clientes REST pueden usar su bearer media:write. Solo una carga completada devuelve el ID del archivo; emitir un ticket no carga nada.
POST /api/v1/sites/{site}/media
Authorization: Bearer <media:write token>
Content-Type: multipart/form-data; boundary=<generated by HTTP client>
file: <original file bytes>
10. Dominios personalizados
/sites/{site}/domainsListar dominios · domains:read
/sites/{site}/domainsSolicitar un dominio · domains:write
/sites/{site}/domains/{domain}/activateActivar después de la verificación · domains:write
/sites/{site}/domains/{domain}/primarySeleccionar el nombre de host principal · domains:write
Solicitar un dominio
curl --request POST \
--url https://app.eyivo.com/api/v1/sites/42/domains \
--header 'Accept: application/json' \
--header 'Authorization: Bearer ey_your_token' \
--header 'Content-Type: application/json' \
--header 'Idempotency-Key: domain-request-example-com' \
--data '{"domain":"www.example.com"}'
Un dominio pendiente incluye verification_token. Añade el registro DNS requerido para demostrar la propiedad, espera su propagación y llama al endpoint de activación. Una vez activo, llama al endpoint principal si debe convertirse en el nombre de host público canónico.
Campos del recurso de dominio: id, domain, site_id, is_primary, status, verification_token cuando corresponda y marcas de tiempo. Los límites del plan y los errores de validación de dominio devuelven 422.
11. Errores
| Estado | Significado | Acción típica |
|---|---|---|
401 | Falta el token de acceso, no es válido, ha caducado o se ha revocado. | Sustituye o renueva las credenciales. |
403 | Falta un permiso, hay una restricción de sitio o alguien que no es propietario intenta modificar el sitio. | Usa un ámbito o sitio autorizado; no repitas la solicitud sin modificarla. |
404 | Falta el recurso o no es propiedad del usuario. | Comprueba los ID y la propiedad. |
409 | Un conflicto de versión requiere volver a leer y combinar los cambios. No reintentes el mismo contenido obsoleto. | Lee el borrador del idioma elegido y su revisión actual antes de editar. |
422 | Error de validación, límite del plan, regla de dominio o solicitud distinta con la misma clave de idempotencia. | Lee errors o message, corrige la solicitud y usa otra clave si cambia el cuerpo. |
5xx | Error inesperado de la plataforma o de un servicio externo. | Reintenta las lecturas seguras; para reintentar escrituras, usa la misma clave de idempotencia. |
Respuesta de validación
{
"message": "The title field is required.",
"errors": {
"title": ["The title field is required."]
}
}
Respuesta de autenticación o autorización
{
"message": "Missing required scope [content:write]."
}
12. Límites actuales y lista de verificación de integración
REST v1 expone deliberadamente un conjunto limitado de funciones de Eyivo. Que no exista un endpoint no autoriza a llamar a las API internas.
Disponible
- Listar, consultar y crear sitios
- Páginas, componentes y enlaces internos
- Gestiona páginas, componentes, blogs, productos, galerías, vídeos, menús, archivos, formularios y ajustes del sitio mediante herramientas y endpoints REST con permisos definidos.
- Listar, solicitar y activar dominios, y elegir el principal
No disponible en REST v1
- Cambios de facturación y suscripciones
- Contraseñas y gestión de tokens
- Acceso directo al almacenamiento y APIs internas
- Instalar o ejecutar código arbitrario del tema
Antes de pasar a producción
- Usa HTTPS y comprueba que el host esperado sea
app.eyivo.com. - Mantén los tokens de acceso en el servidor y oculta los encabezados de autorización en los registros.
- Solicita solo los ámbitos necesarios y prefiere tokens personales limitados a un sitio cuando sea posible.
- Utiliza una clave de idempotencia única para cada operación de escritura y consérvala en todos los reintentos.
- Considera
401,403,404y422errores no transitorios, salvo que cambien la solicitud o las credenciales. - Usa reintentos con espera exponencial y variación aleatoria ante errores transitorios, y respeta cualquier futuro encabezado
Retry-After. - Las colecciones tienen formatos distintos. Sigue los metadatos de paginación de cada endpoint; no supongas que todas son listas simples o sin paginar.