Page Lemon

Referencia de la API REST

La API REST de Page Lemon está en https://api.pagelemon.com/v1. Los agentes de código con terminal la usan para publicar una carpeta con un solo comando; los agentes de IA deben empezar por la guía de publicación para IA (Markdown).

Última actualización: · Ver en Markdown

En esta página

Inicio rápido

Publica una carpeta sin cuenta (queda en línea 72 horas si no la conservas):

bash
tar -czf - -C dist . | curl -sS --data-binary @- https://api.pagelemon.com/v1/deploy

Con un token de API, el sitio va directo a tu cuenta:

bash
tar -czf - -C dist . | curl -sS -H "Authorization: Bearer $PAGELEMON_TOKEN" --data-binary @- https://api.pagelemon.com/v1/deploy

Hosts

HostSirve
https://pagelemon.comEste sitio, /agents, /llms.txt, /docs/*
https://api.pagelemon.comAPI REST bajo /v1
https://mcp.pagelemon.comServidor MCP remoto (HTTP transmitible) en / (alias /mcp)
https://app.pagelemon.comTu cuenta: sitios, personas, tokens, facturación
https://<name>.pagelemon.devTus sitios

Autenticación

Envía las credenciales como Authorization: Bearer <token>.

CredencialAspectoDe dónde saleQué puede hacer
Token del sitiost_…Se devuelve una sola vez en un despliegue anónimoActualizar, leer, revertir y ver ese único sitio, hasta que se reclame. Después de la reclamación solo informa de ella (GET /v1/sites/:name)
Enlace de reclamaciónhttps://app.pagelemon.com/claim/ct_…Se devuelve una sola vez en un despliegue anónimoUna persona con sesión iniciada reclama el sitio
Token de APIpl_…app.pagelemon.com/account/tokens (Ajustes de la cuenta → Tokens de API; consulta Tokens de API)Todo lo que puedes hacer en tu cuenta, por REST y MCP
Token de acceso OAuthpla_…Se emite para una app MCP (Claude.ai, ChatGPT, Claude Code…) después de que inicies sesión y la apruebesIgual que un token de API, pero solo MCP (REST responde 401). Dura 1 hora y se renueva solo

Solo almacenamos hashes de los tokens, así que un token perdido no se puede volver a mostrar. Crea uno nuevo.

Errores

json
{ "error": { "code": "conflict", "message": "…" }, "agent_message": "…" }

agent_message aparece cuando la IA debe decirle algo a la persona usuaria. Transmítelo en el idioma de la persona, con cada enlace, código, número, fecha y dominio exactos; las horas están en UTC, y los campos *_at las traen en formato ISO.

CódigoEstadoSignificado
bad_request400Archivo comprimido, cuerpo o parámetro incorrecto
unauthorized401Token ausente o no válido
forbidden403El token o el rol no puede hacer esto
not_found404No existe ese sitio o archivo
conflict409X-Base-Revision / base_revision desactualizado
gone410El sitio caducó
too_large413Supera un límite de tamaño
blocked_secret422La protección contra filtraciones encontró una clave secreta
limit429Límite del plan o de frecuencia

Despliegue

POST /v1/deploy: un archivo comprimido

El cuerpo de la solicitud es el archivo comprimido: .tar.gz, .tgz, .tar o .zip. El servidor detecta el formato a partir de los bytes, así que Content-Type es opcional.

bash
tar -czf - -C <dir> . | curl -sS --data-binary @- https://api.pagelemon.com/v1/deploy
SolicitudResultado
Sin ?site, sin tokenCreación anónima. Un nombre aleatorio como brave-otter-4821; caduca a las 72 horas si no se reclama
Sin ?site, token de APISe crea en tu cuenta. Sin caducidad
?site=<name> + X-Base-Revision: <revision id> + token del sitio o token de APIActualización. Si la revisión en línea no es X-Base-Revision, recibes 409 conflict y no se publica nada

Cada despliegue reemplaza el sitio entero: los archivos que no incluyas se eliminan del sitio en línea. Si todos los archivos están dentro de una única carpeta de nivel superior (dist/index.html, …), esa carpeta se elimina de las rutas.

Respuesta 201:

json
{
  "site": { "name": "brave-otter-4821", "url": "https://brave-otter-4821.pagelemon.dev", "claimed": false, "expires_at": "2026-10-14T14:40:00Z" },
  "revision": { "id": "rev_…", "number": 1, "files": 12, "bytes": 48213 },
  "site_token": "st_…",
  "claim_url": "https://app.pagelemon.com/claim/ct_…",
  "skipped": [".env", "node_modules/…"],
  "agent_message": "Your site is live at …"
}

site_token y claim_url solo aparecen en una creación anónima.

POST /v1/deploy con JSON: archivos en línea

Para clientes MCP y sitios pequeños: envía Content-Type: application/json al mismo endpoint.

json
{ "site": "brave-otter-4821", "base_revision": "rev_…", "files": [ { "path": "index.html", "content": "<h1>Hi</h1>", "encoding": "utf8" } ] }

encoding es utf8 o base64. Omite site y base_revision para crear un sitio nuevo. La respuesta es la misma que arriba.

Parche: añade "patch": true para enviar solo los files modificados más "deleted": ["old.html"] sobre base_revision; todo lo demás se conserva. Mismos límites y comprobaciones; un base_revision desactualizado da 409 conflict.

Reglas de subida

ArchivosPor archivoPor sitioCaducidad
Sin cuenta1001 MB1 MB72 horas si no se reclama
Gratis5005 MB5 MBninguna
Prompter1,00050 MB5 GB (todo su almacenamiento)ninguna
Builder2,00050 MB25 GB (todo su almacenamiento)ninguna
Team3,00050 MB50 GB (todo su almacenamiento)ninguna
Company5,00050 MB150 GB (todo su almacenamiento)ninguna

Por sitio significa el sitio completo en línea tras un despliegue; un parche cuenta el sitio completo resultante. En los planes de pago un sitio puede usar todo el almacenamiento del plan, pero una solicitud lleva como máximo 90 MB (40 MB por MCP): envía un sitio más grande como primer despliegue y el resto como despliegues de parche. Si superas un límite: 413 too_large con un agent_message para mostrar.

  • Se rechazan: enlaces simbólicos, enlaces duros, dispositivos, rutas absolutas, .. y rutas duplicadas que solo se diferencian en mayúsculas y minúsculas.
  • Se omiten y se enumeran en skipped: .git/, node_modules/, .env*, *.map, *.pem, *.key; archivos ocultos (dotfiles) excepto .well-known/; .DS_Store, Thumbs.db.
  • Protección contra filtraciones: los archivos de texto se analizan en busca de tipos conocidos de claves secretas y claves privadas. Una coincidencia devuelve 422 blocked_secret con {file, line, kind}. La clave en sí nunca se devuelve.
  • Obligatorio: index.html en la raíz.
  • Solo anónimos: se bloquean ejecutables e instaladores, y cada red dispone de un número reducido de sitios y despliegues anónimos. Reclama el sitio o inicia sesión para tener más.

Sitios

MétodoRutaAutenticaciónNotas
GET/v1/sitesToken de APISitios de los que eres miembro
GET/v1/sites/:nametoken del sitio, miembro{name, url, claimed, expires_at, plan, role, live_revision: {id, number, created_at, created_by}, badge}. Con el token del sitio, consúltalo periódicamente después de que el usuario abra el enlace de reclamación: {claimed: false, …} o {claimed: true, account_token?}; es la única llamada que un token de sitio puede seguir haciendo una vez reclamado su sitio
GET/v1/sites/:name/filestoken del sitio, miembro{revision, files: [{path, size, sha256}]} para la versión en línea
GET/v1/sites/:name/files/<path>token del sitio, miembroContenido sin procesar del archivo (la lectura), con un encabezado X-Revision
GET/v1/sites/:name/revisionstoken del sitio, miembroLas más recientes primero. Anónimo: solo la actual. Gratis: 7 días. Prompter: 90 días. Builder y Team: 1 año. Company: 2 años
POST/v1/sites/:name/rollbacktoken del sitio, editor o propietario{revision} vuelve a poner en línea esa versión, con un nuevo número de versión
POST/v1/sites/:name/renameeditor o propietario (solo cuenta){name}: de 4 a 63 caracteres de a-z, 0-9 y -. No puede parecer un nombre aleatorio (word-word-1234), estar reservado ni haberse usado antes
DELETE/v1/sites/:namepropietarioPermanente. Con un token de API devuelve 202 con un approve_url: una página donde la persona escribe la dirección del sitio y hace clic en Eliminar definitivamente. Después, GET /v1/approvals/<token> indica si se eliminó
GET/v1/sites/:name/membersmiembro{members: [{email, role}], invites: [{email, role}]}
POST/v1/sites/:name/memberspropietario{email, role: "editor" or "viewer"} envía un correo de invitación
DELETE/v1/sites/:name/members/:emailpropietarioEn dos pasos: la primera llamada devuelve {confirm_token}; repite con ?confirm=<token> en un plazo de 5 minutos

Roles: los lectores pueden ver el sitio y su historial. Los editores además pueden desplegar y revertir. Los propietarios además pueden invitar, renombrar y eliminar.

Cuenta

MétodoRutaAutenticaciónNotas
GET/v1/meToken de API{email, plan, sites_used, sites_limit}

Reclamar sitios, aceptar invitaciones, los tokens y la facturación se gestionan en app.pagelemon.com.

Servicio en pagelemon.dev

  • / sirve index.html. /about sirve about.html o about/index.html.
  • Los archivos que no existen reciben el 404.html del sitio si lo hay; si no, el nuestro.
  • Alternativa para aplicaciones de una sola página: si el sitio no tiene 404.html y la ruta no tiene extensión de archivo, se sirve index.html.
  • Encabezados: X-Content-Type-Options: nosniff, Referrer-Policy: strict-origin-when-cross-origin, Cache-Control: public, max-age=60 para HTML y max-age=300 para los demás archivos. Los tipos de contenido salen de una lista permitida; los tipos desconocidos se sirven como application/octet-stream.
  • Los sitios anónimos y Free llevan un pequeño distintivo "Publicado en Page Lemon" antes de </body>. Es HTML y CSS simples, sin scripts, e incluye un enlace para denunciar el sitio.
  • Los sitios caducados o eliminados devuelven 410. Los sitios retirados por abuso devuelven 451.

.pagelemon.json

Después de desplegar, los agentes escriben este archivo en la carpeta del proyecto y lo añaden a .gitignore, para que la siguiente sesión pueda actualizar el mismo sitio:

json
{ "site": "brave-otter-4821", "url": "https://brave-otter-4821.pagelemon.dev", "revision": "rev_…", "site_token": "st_…" }

¿Algo poco claro o desactualizado? Cuéntanoslo y corregiremos la página.