Referência da API REST
A API REST do Page Lemon fica em https://api.pagelemon.com/v1. Agentes de código com acesso a um terminal a usam para publicar uma pasta com um único comando; agentes de IA devem começar pelo guia de publicação para IAs (Markdown).
Última atualização: · Ver em Markdown
Nesta página
Início rápido
Publique uma pasta sem conta (ela fica no ar por 72 horas, a menos que você a mantenha):
tar -czf - -C dist . | curl -sS --data-binary @- https://api.pagelemon.com/v1/deployCom um token de API, o site vai direto para a sua conta:
tar -czf - -C dist . | curl -sS -H "Authorization: Bearer $PAGELEMON_TOKEN" --data-binary @- https://api.pagelemon.com/v1/deployHosts
| Host | Serve |
|---|---|
https://pagelemon.com | Este site, /agents, /llms.txt, /docs/* |
https://api.pagelemon.com | API REST em /v1 |
https://mcp.pagelemon.com | Servidor MCP remoto (streamable HTTP) em / (alias /mcp) |
https://app.pagelemon.com | Sua conta: sites, pessoas, tokens, cobrança |
https://<name>.pagelemon.dev | Seus sites |
Autenticação
Envie as credenciais como Authorization: Bearer <token>.
| Credencial | Formato | De onde vem | O que pode fazer |
|---|---|---|---|
| Token do site | st_… | Retornado uma única vez por uma publicação anônima | Atualizar, ler de volta, reverter e ver aquele site, até ele ser resgatado. Depois do resgate, só informa o resgate (GET /v1/sites/:name) |
| Link de resgate | https://app.pagelemon.com/claim/ct_… | Retornado uma única vez por uma publicação anônima | Uma pessoa com login resgata o site |
| Token de API | pl_… | app.pagelemon.com/account/tokens (Configurações da conta → Tokens de API; veja Tokens de API) | Tudo o que você pode fazer na sua conta, via REST e MCP |
| Token de acesso OAuth | pla_… | Emitido para um app MCP (Claude.ai, ChatGPT, Claude Code…) depois que você entra e aprova | O mesmo que um token de API, mas só MCP (a REST responde 401). Dura 1 hora e se renova sozinho |
Armazenamos apenas hashes dos tokens, então um token perdido não pode ser mostrado de novo. Crie um novo.
Erros
{ "error": { "code": "conflict", "message": "…" }, "agent_message": "…" }agent_message aparece quando a IA deve avisar algo ao usuário. Repasse o aviso no idioma do usuário, com todos os links, códigos, números, datas e domínios exatos; os horários são em UTC, e os campos *_at os trazem no formato ISO.
| Código | Status | Significado |
|---|---|---|
bad_request | 400 | Arquivo compactado, corpo ou parâmetro inválido |
unauthorized | 401 | Token ausente ou inválido |
forbidden | 403 | O token ou a função não tem permissão para isso |
not_found | 404 | Site ou arquivo inexistente |
conflict | 409 | X-Base-Revision / base_revision desatualizado |
gone | 410 | O site expirou |
too_large | 413 | Acima de um limite de tamanho |
blocked_secret | 422 | A proteção contra vazamentos encontrou uma chave secreta |
limit | 429 | Limite do plano ou de taxa |
Publicar
POST /v1/deploy: um arquivo compactado
O corpo da requisição é o arquivo compactado: .tar.gz, .tgz, .tar ou .zip. O servidor detecta o formato pelos bytes, então Content-Type é opcional.
tar -czf - -C <dir> . | curl -sS --data-binary @- https://api.pagelemon.com/v1/deploy| Requisição | Resultado |
|---|---|
Sem ?site, sem token | Criação anônima. Um nome aleatório como brave-otter-4821, expira após 72 horas se não for resgatado |
Sem ?site, token de API | Cria na sua conta. Não expira |
?site=<name> + X-Base-Revision: <revision id> + token do site ou token de API | Atualização. Se a revisão no ar não for X-Base-Revision, você recebe 409 conflict e nada é publicado |
Cada publicação substitui o site inteiro: arquivos que você deixar de fora são removidos do site no ar. Se todos os arquivos estiverem dentro de uma única pasta de nível superior (dist/index.html, …), essa pasta é removida.
Resposta 201:
{
"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 e claim_url só aparecem em uma criação anônima.
POST /v1/deploy com JSON: arquivos inline
Para clientes MCP e sites pequenos: envie Content-Type: application/json para o mesmo endpoint.
{ "site": "brave-otter-4821", "base_revision": "rev_…", "files": [ { "path": "index.html", "content": "<h1>Hi</h1>", "encoding": "utf8" } ] }encoding é utf8 ou base64. Deixe de fora site e base_revision para criar um site novo. A resposta é a mesma de cima.
Patch: adicione "patch": true para enviar só os files alterados mais "deleted": ["old.html"] sobre base_revision; todo o resto é mantido. Mesmos limites e verificações; um base_revision desatualizado é um 409 conflict.
Regras de upload
| Arquivos | Por arquivo | Por site | Expiração | |
|---|---|---|---|---|
| Sem conta | 100 | 1 MB | 1 MB | 72 horas, se não for resgatado |
| Grátis | 500 | 5 MB | 5 MB | nenhuma |
| Prompter | 1,000 | 50 MB | 5 GB (todo o armazenamento dele) | nenhuma |
| Builder | 2,000 | 50 MB | 25 GB (todo o armazenamento dele) | nenhuma |
| Team | 3,000 | 50 MB | 50 GB (todo o armazenamento dele) | nenhuma |
| Company | 5,000 | 50 MB | 150 GB (todo o armazenamento dele) | nenhuma |
Por site significa o site inteiro no ar após um deploy; um patch conta o site inteiro resultante. Nos planos pagos, um site pode usar todo o armazenamento do plano, mas uma requisição leva no máximo 90 MB (40 MB pelo MCP): envie um site maior como primeiro deploy e o resto em deploys de patch. Acima do limite: 413 too_large com um agent_message para mostrar.
- Recusados: links simbólicos, hard links, dispositivos, caminhos absolutos,
..e caminhos duplicados que só diferem em maiúsculas/minúsculas. - Ignorados e listados em
skipped:.git/,node_modules/,.env*,*.map,*.pem,*.key; arquivos ocultos (dotfiles), exceto.well-known/;.DS_Store,Thumbs.db. - Proteção contra vazamentos: arquivos de texto são verificados em busca de tipos conhecidos de chaves secretas e chaves privadas. Uma ocorrência retorna
422 blocked_secretcom{file, line, kind}. A chave em si nunca é retornada. - Obrigatório:
index.htmlna raiz. - Só para anônimos: executáveis e instaladores são bloqueados, e cada rede tem um número pequeno de sites e publicações anônimas. Resgate ou entre para ter mais.
Sites
| Método | Caminho | Autenticação | Observações |
|---|---|---|---|
| GET | /v1/sites | Token de API | Sites dos quais você é membro |
| GET | /v1/sites/:name | token do site, membro | {name, url, claimed, expires_at, plan, role, live_revision: {id, number, created_at, created_by}, badge}. Com o token do site, consulte depois que o usuário abrir o link de resgate: {claimed: false, …} ou {claimed: true, account_token?}; é a única chamada que um token de site ainda pode fazer depois que o site é resgatado |
| GET | /v1/sites/:name/files | token do site, membro | {revision, files: [{path, size, sha256}]} para a versão no ar |
| GET | /v1/sites/:name/files/<path> | token do site, membro | Conteúdo bruto do arquivo (a leitura de volta), com um cabeçalho X-Revision |
| GET | /v1/sites/:name/revisions | token do site, membro | Mais recentes primeiro. Anônimo: só a atual. Grátis: 7 dias. Prompter: 90 dias. Builder e Team: 1 ano. Company: 2 anos |
| POST | /v1/sites/:name/rollback | token do site, editor ou proprietário | {revision} coloca aquela versão no ar de novo, com um novo número de versão |
| POST | /v1/sites/:name/rename | editor ou proprietário (só conta) | {name}: 4 a 63 caracteres entre a-z, 0-9 e -. Não pode parecer um nome aleatório (word-word-1234), ser reservado nem já ter sido usado |
| DELETE | /v1/sites/:name | proprietário | Permanente. Com um token de API, retorna 202 com um approve_url: uma página onde a pessoa digita o endereço do site e clica em Excluir permanentemente. Depois, GET /v1/approvals/<token> informa se o site foi excluído |
| GET | /v1/sites/:name/members | membro | {members: [{email, role}], invites: [{email, role}]} |
| POST | /v1/sites/:name/members | proprietário | {email, role: "editor" or "viewer"} envia um e-mail de convite |
| DELETE | /v1/sites/:name/members/:email | proprietário | Em duas etapas: a primeira chamada retorna {confirm_token}; repita com ?confirm=<token> em até 5 minutos |
Funções: leitores podem ver o site e seu histórico. Editores também podem publicar e reverter. Proprietários também podem convidar, renomear e apagar.
Conta
| Método | Caminho | Autenticação | Observações |
|---|---|---|---|
| GET | /v1/me | Token de API | {email, plan, sites_used, sites_limit} |
Resgatar sites, aceitar convites, tokens e cobrança são feitos em app.pagelemon.com.
Entrega em pagelemon.dev
/serveindex.html./aboutserveabout.htmlouabout/index.html.- Arquivos inexistentes recebem o
404.htmldo site, se houver; caso contrário, o nosso. - Fallback para single-page apps: se o site não tiver
404.htmle o caminho não tiver extensão de arquivo,index.htmlé servido. - Cabeçalhos:
X-Content-Type-Options: nosniff,Referrer-Policy: strict-origin-when-cross-origin,Cache-Control: public, max-age=60para HTML emax-age=300para os demais arquivos. Os tipos de conteúdo vêm de uma lista permitida; tipos desconhecidos são servidos comoapplication/octet-stream. - Sites anônimos e Free recebem um pequeno selo "No ar no Page Lemon" antes de
</body>. É HTML e CSS simples, sem script, e inclui um link para denunciar o site. - Sites expirados ou apagados retornam
410. Sites removidos por abuso retornam451.
.pagelemon.json
Depois de publicar, os agentes gravam este arquivo na pasta do projeto e o adicionam ao .gitignore, para que a próxima sessão possa atualizar o mesmo site:
{ "site": "brave-otter-4821", "url": "https://brave-otter-4821.pagelemon.dev", "revision": "rev_…", "site_token": "st_…" }