Documentación
Teddy publica páginas HTML (artifacts) y pequeñas APIs (funciones) con una URL al instante. Pensado para que lo use tu agente de IA, y también tú desde código.
Empezar
1. Crea tu cuenta con tu email (enlace mágico, sin contraseña). Para scripts o clientes sin OAuth, crea además una clave de agente tdy_ en Claves de agente.
2. Conecta tu agente. En Claude (web, escritorio, móvil, Cowork o Claude Code), añade un conector personalizado con esta URL. Claude te pedirá iniciar sesión en Teddy y dar permiso; no hace falta clave:
https://teddyagent.app/mcp3. Publica. Pídeselo a tu agente («publica esto en Teddy») o hazlo tú:
curl -X POST https://teddyagent.app/api/artifacts \
-H "Authorization: Bearer $TEDDY_KEY" \
-H "Content-Type: text/html" \
--data-binary @pagina.htmlLa respuesta trae url: compártela. Cada artifact se sirve aislado (iframe con sandbox y CSP), sin acceso a tu sesión.
Artifacts
Un artifact es un HTML autocontenido (CSS y JS dentro). Se publica en /a/<id> con una barra mínima de Teddy y el botón de reportar.
curl -X POST https://teddyagent.app/api/artifacts -H "Authorization: Bearer $TEDDY_KEY" \
-H "Content-Type: application/json" \
-d '{"html":"<h1>Hola</h1>","title":"Saludo","folder":"Demos","expires_in":"7d"}'- Actualizar:
PUT /api/artifacts/{id}con el HTML nuevo (misma URL). - Pausar / publicar:
PATCHcon{"status":"paused"}o"live". Pausado responde «no disponible». - Carpetas:
folderpor nombre (se crea) ofolder_id. Lista conGET /api/artifacts?folder=<id>|none&status=live|paused|hidden. - Caducidad:
expires_incon unidadm(minutos),h,dow:30m,12h,7d,2w;neverla quita. Al caducar se borra. (Ojo: en las claves de consumo,mson meses y también valey.) - Varios archivos: además del HTML,
filescon CSS, JS, imágenes, fuentes u otras páginas, enlazados con rutas relativas (<img src="img/logo.png">):{"html":"…","files":[{"path":"css/estilo.css","content":"…"},{"path":"img/logo.png","content":"<base64>","encoding":"base64"}]}. O sube un .zip conindex.html:curl -X POST …/api/artifacts -H "Content-Type: application/zip" --data-binary @web.zip(también desde Publicar en el panel). EnPUT,filessustituye todos los archivos; si solo mandashtml, se conservan. Cuenta para el tamaño máximo del plan y el filtro de seguridad revisa también las otras páginas y scripts. Lista:GET /api/artifacts/{id}/files. - Privado:
"visibility":"private"(al publicar o conPATCH): solo tú lo ves; para los demás la URL responde «no existe». Para compartirlo, crea enlaces secretos conPOST /api/artifacts/{id}/links({"label":"Cliente Acme","expires_in":"7d"}): uno por persona, con contador de visitas, revocables conDELETE …/links/{linkId}. La URL del enlace solo se muestra al crearlo. - Contraseña:
"password":"…"(6–200 caracteres;nullla quita). Se pide a cualquiera que lo abra, salvo a ti. Se puede combinar con privado. Todo esto también desde el panel: Biblioteca → compartir. Al pasar de público a privado, navegadores y cachés pueden seguir mostrando la versión pública hasta 60 s; quien ya lo tenga abierto con un enlace revocado puede seguir viéndolo unos minutos. - Moderación: un filtro anti-phishing revisa cada publicación: lo evidente se rechaza (422) y lo dudoso queda oculto hasta que un admin lo revise. Tres reportes de visitantes distintos lo ocultan también.
Funciones
Una función es un módulo JavaScript que Teddy ejecuta en un sandbox (isolate V8, el mismo motor que Cloudflare Workers) y expone en /f/<id>, con cualquier método y subruta.
export default {
async fetch(request, env) {
const { importe = 0 } = await request.json().catch(() => ({}));
return Response.json({ importe, iva: +(importe * 0.21).toFixed(2) });
}
};curl -X POST https://teddyagent.app/api/functions -H "Authorization: Bearer $TEDDY_KEY" \
-H "Content-Type: application/json" \
-d '{"name":"IVA","code":"export default { async fetch(r) { return Response.json({ ok: true }) } }"}'- Probar sin publicar:
POST /api/runconcodeeinput(método, ruta, query, cabeceras, body). - Sin red por defecto. Declara los dominios con
allow_net: ["api.ejemplo.com"]; solo IPs públicas. - Solo APIs web estándar:
fetch,crypto.subtle,URL,TextEncoder, streams. Sin npm ni disco. - Tiempo: cada invocación tiene un límite (10 s en Free). Agotarlo varias veces suspende la función hasta que publiques una versión nueva.
- CORS abierto: un artifact puede llamar a tu función. Las respuestas se sirven en un origen aislado (CSP
sandbox) y no pueden poner cookies. - Logs:
console.logse guarda con cada invocación (GET /api/functions/{id}/logs).
Acceso a tus APIs
Cada función tiene un modo de acceso (access):
public: cualquiera con la URL, con límite por IP.key: exige una clave de consumotfk_…que tú emites, para una función o para todas, con límite por minuto, cuota diaria y caducidad opcionales. Se revoca al instante.owner: solo tu clave de agentetdy_….user: solo clientes que han iniciado sesión en tu página (ver Login de tus clientes).
curl -X POST https://teddyagent.app/api/functions/<id>/keys -H "Authorization: Bearer $TEDDY_KEY" \
-H "Content-Type: application/json" -d '{"name":"Cliente Acme","rate_per_min":60,"expires_in":"30d"}'
curl https://teddyagent.app/f/<id> -H "Authorization: Bearer tfk_…" # o X-API-Key, o ?api_key=La función nunca ve la clave: recibe x-teddy-key-name con su nombre (codificado con encodeURIComponent) y x-teddy-key-id; cualquier cabecera x-teddy-* que mande el cliente se descarta. Las llamadas con clave tfk_ reciben X-RateLimit-Limit y X-RateLimit-Remaining. Los intentos rechazados (401/403/404/429) se registran con su motivo, se ven en el panel y en /rejections, y no gastan cuota ni límite.
Funciones programadas (cron)
Una función puede ejecutarse sola. Defines una expresión cron de 5 campos en UTC (minuto hora día-del-mes mes día-de-la-semana; admite listas, rangos, pasos, nombres como mon-fri y alias @hourly, @daily, @weekly) y Teddy llama a la función con un POST a la ruta que elijas, con el cuerpo que configures. Llegan tres cabeceras que nadie de fuera puede falsificar: x-teddy-cron: 1, x-teddy-schedule-id y x-teddy-scheduled-for (la hora prevista).
curl -X POST https://teddyagent.app/api/functions/<id>/schedules \
-H "Authorization: Bearer $TEDDY_KEY" -H "Content-Type: application/json" \
-d '{"cron":"0 9 * * mon-fri","path":"/informe","body":{"dias":7},"name":"Informe diario"}'Cuenta contra las invocaciones diarias del plan y respeta el tiempo máximo por invocación. Free: 2 programaciones, como mucho una por hora; Pro: 50, cada 5 minutos. Si Teddy está parado en el momento previsto, la ejecución se hace una vez al volver (no todas las perdidas). Cada ejecución queda en un registro de 14 días (GET /api/functions/<id>/schedules/<sid>/runs, o en el panel); tras 10 fallos seguidos la programación se desactiva sola y lo dice, y al reactivarla se pone a cero. Si la función está pausada o la cuenta suspendida, la ejecución se omite y se anota.
Secretos
Para claves de APIs externas. Nunca las pongas en el código: guárdalas como secreto y léelas con env.NOMBRE.
curl -X PUT https://teddyagent.app/api/functions/<id>/secrets/OPENAI_API_KEY -H "Authorization: Bearer $TEDDY_KEY" \
-H "Content-Type: application/json" -d '{"value":"sk-…"}'export default {
async fetch(request, env) {
const r = await fetch("https://api.openai.com/v1/models", { headers: { Authorization: "Bearer " + env.OPENAI_API_KEY } });
return new Response(r.body, r);
}
}; // con allow_net: ["api.openai.com"]Nombres en MAYÚSCULAS con números y _ (KV, FN_* y TEDDY_* están reservados); valores de 4 B a 4 KB. Se guardan cifrados (AES-256-GCM). El valor no se puede volver a leer y, si aparece en un log o en un error, sale como ••••.
Memoria (KV)
Cada función publicada tiene su propio almacén clave-valor, persistente entre llamadas:
export default {
async fetch(request, env) {
const visitas = Number(await env.KV.get("visitas") ?? 0) + 1;
await env.KV.put("visitas", String(visitas));
await env.KV.put("ultima", JSON.stringify({ t: Date.now() }), { expirationTtl: 86400 });
const { keys } = await env.KV.list({ prefix: "u:" });
return Response.json({ visitas, ultima: await env.KV.get("ultima", "json"), usuarios: keys.length });
}
};Los valores son texto (usa JSON.stringify). Desde el panel o la API ves, lees y borras claves. run_code no tiene KV.
Datos (colecciones)
Una colección es una lista de registros JSON con su propia API en https://teddyagent.app/d/<id>: guardas pedidos, respuestas de un formulario o el estado de una app sin montar una base de datos. La lectura y la escritura tienen cada una su acceso: public (cualquiera, con límite por IP), key (clave tfk_… o de gestión) u owner (solo tú). Las páginas que publicas pueden llamarla con fetch directamente (CORS abierto).
# crear un registro y leerlos con filtros
curl -X POST https://teddyagent.app/d/ID -H "Content-Type: application/json" -d '{"nombre":"Ana","mesas":2}'
curl "https://teddyagent.app/d/ID?mesas__gte=2&_order=-mesas&_limit=20"
# cambiar un campo (null lo borra) solo si nadie lo cambió antes
curl -X PATCH https://teddyagent.app/d/ID/REGISTRO -H "If-Match: 1" -d '{"mesas":3}'Filtros: campo=valor, campo__gt, __gte, __lt, __lte, __ne; orden _order=-campo; _limit (máx. 100), _offset, _count=1. Cada registro tiene id, version y fechas; If-Match: <versión> evita pisar cambios ajenos (409 version_conflict). Un esquema opcional (subconjunto de JSON Schema) valida lo que se escribe.
Desde una función: env.DB.collection("pedidos") con find, get, insert, put, patch y delete; solo ve las colecciones de su dueño. run_code no tiene DB. Desde el panel (Datos) ves los registros, cambias accesos y exportas a CSV o JSON; la API de gestión (/api/collections) también importa hasta 1 000 registros por llamada.
Tiempo real
Un canal (https://teddyagent.app/c/<id>) reparte mensajes JSON al instante a todo el que lo escucha: chat, marcadores, avisos, paneles que se actualizan solos. Publicar y escuchar tienen cada uno su acceso (public, key u owner), como en las colecciones. Se crean en el panel (Canales), con la API o con tu agente.
// en una página publicada: escuchar (SSE; se reconecta solo y no pierde mensajes)
const es = new EventSource("https://teddyagent.app/c/ID");
es.onmessage = (e) => console.log(JSON.parse(e.data));
es.addEventListener("marcador", (e) => console.log("gol", JSON.parse(e.data)));
// publicar
fetch("https://teddyagent.app/c/ID?event=marcador", { method: "POST", body: JSON.stringify({ local: 2, visitante: 1 }) });
// WebSocket: lo que llega es {id, event, data}; lo que escribas (JSON) se publica
const ws = new WebSocket("wss://TU-DOMINIO/c/ID");
ws.onmessage = (e) => console.log(JSON.parse(e.data));
ws.onopen = () => ws.send(JSON.stringify({ hola: "mundo" }));Los canales con clave (tfk_…, de toda la cuenta) la reciben en Authorization: Bearer o X-API-Key; los navegadores no pueden poner cabeceras en EventSource ni WebSocket, así que ahí va en ?api_key=. Nunca se usan cookies. Al reconectar, Last-Event-ID (o ?after=) recupera lo perdido entre los últimos 100 mensajes del canal: los mensajes no se guardan en disco, si necesitas histórico guárdalos en una colección.
GET /d/<id>/_events emite en directo los cambios de una colección (created, updated, deleted) con la misma regla de acceso que su lectura: una página puede mostrar los datos y mantenerlos al día sin consultar. Desde una función, await env.CHANNELS.publish("nombre", datos, "evento") avisa a los oyentes del canal de tu cuenta (no existe en run_code).
Límite conocido: el bus de mensajes vive en la memoria de un único proceso de Teddy; con varias instancias haría falta un bus compartido (Postgres LISTEN/NOTIFY). Los latidos (: ping cada 25 s) mantienen viva la conexión tras proxies.
Login de tus clientes
Tu página puede pedir a sus propios visitantes que inicien sesión (con Google) sin que montes nada: Teddy hace el login en su dominio, el cliente confirma que quiere entrar, y tu página y tus funciones saben quién es. No son cuentas de Teddy: son tus clientes, solo tuyos (los ves en Clientes).
<script src="https://teddyagent.app/sdk/teddy.js"></script>
<script>
await Teddy.ready; // recupera la sesión si ya había una
if (!Teddy.user) await Teddy.login(); // abre el popup de Teddy
console.log(Teddy.user.email, Teddy.user.name);
Teddy.onChange((u) => console.log("ahora:", u));
// Teddy.fetch añade la sesión; tu función recibe la identidad en cabeceras de confianza
const r = await Teddy.fetch("https://teddyagent.app/f/ID_FUNCION/mis-pedidos");
await Teddy.logout();
</script>La función (con access: "user") recibe x-teddy-user-id (eu_…, estable por cliente y dueño), x-teddy-user-email, x-teddy-user-name (codificados con encodeURIComponent) y x-teddy-user-provider. Son de confianza: Teddy descarta cualquier cabecera x-teddy-* que mande el cliente y la función nunca ve el token. Sin sesión válida responde 401 (login_required o invalid_session). Guardar los datos de cada cliente por separado (p. ej. un campo owner_email en tus registros y filtrar por él dentro de la función con env.DB) lo haces tú: así la página nunca lee datos de otros.
export default { async fetch(req, env) {
const email = decodeURIComponent(req.headers.get("x-teddy-user-email"));
const mine = await env.DB.query("presupuestos", { filters: { cliente: email } });
return Response.json(mine.items.map((r) => r.data));
} }/a/<id>), no en el modo ?bare=1 (Teddy.login() falla con no_shell). La sesión dura 14 días, vive en el navegador de ese cliente y se puede cerrar o borrar desde el panel; deja de valer si pausas o borras la página donde se inició. Los clientes que llevan 90 días sin entrar y sin sesión se eliminan solos (liberan cupo). Teddy.fetch solo envía la sesión a las funciones de este Teddy (/f/…). Máximo de clientes por plan: Free 100, Pro 100.000. Tus páginas siguen en un entorno aislado: no puedes insertar el botón de Google dentro de ella (su origen es opaco); usa Teddy.login(). Puedes insertar contenido de terceros con <iframe>, que hereda ese aislamiento y no recibe Referer: los que lo exigen (el reproductor de YouTube) muestran error; los que no (muchos mapas y widgets) funcionan. Proveedores: Google (requiere GOOGLE_CLIENT_ID y GOOGLE_CLIENT_SECRET en el servidor y registrar https://teddyagent.app/eu/google/callback como URI de redirección); la «cuenta de prueba» es solo para demostración y nunca está activa en producción.MCP para agentes
Servidor MCP remoto (Streamable HTTP) en https://teddyagent.app/mcp. Dos formas de autenticarse:
- OAuth 2.1 (lo que usa Claude): el cliente recibe un 401 con
resource_metadata, lee/.well-known/oauth-protected-resourcey/.well-known/oauth-authorization-server, se registra solo (registro dinámico), y tú das permiso en Teddy. PKCE S256 obligatorio; tokens de 1 h con refresh rotatorio. Retiras el acceso en Ajustes → Apps conectadas. - Clave de agente:
Authorization: Bearer tdy_…, para scripts y clientes MCP sin OAuth.
Todas las herramientas declaran título y si solo leen o si cambian/borran cosas (readOnlyHint / destructiveHint). Herramientas disponibles:
publish_artifact | Publica HTML y devuelve la URL. Acepta título, carpeta (por nombre), estado y caducidad. |
update_artifact | Sustituye el HTML o cambia título, carpeta, estado (live/paused) o caducidad. |
delete_artifact | Borra un artifact. |
get_artifact | Metadatos de un artifact. |
list_artifacts | Lista tus artifacts; filtra por carpeta y estado. |
list_artifact_versions | Historial de versiones de un artifact. |
restore_artifact_version | Vuelve a publicar una versión anterior (como versión nueva). |
create_share_link | Crea un enlace secreto para compartir (también si es privado), con etiqueta y caducidad opcionales. |
list_share_links | Enlaces secretos de un artifact con sus visitas. |
revoke_share_link | Revoca un enlace secreto (deja de abrir el artifact). |
list_folders | Tus carpetas y cuántos artifacts tiene cada una. |
list_templates | Plantillas para estudiantes, programadores y equipos: apuntes de clase, test, tarjetas, plan de estudio, guía de proyecto y acta. |
get_template | El HTML de una plantilla para conservar su estructura y cambiar solo el contenido. |
run_code | Ejecuta código una vez en el sandbox, sin publicar. |
publish_function | Publica una función como endpoint /f/<id>. |
update_function | Nueva versión, nombre, acceso, red o estado. |
list_functions | Lista tus funciones. |
function_logs | Últimas invocaciones con estado, tiempos, console.log y rechazos. |
delete_function | Borra una función. |
create_function_key | Crea una clave de consumo tfk_ con límites y caducidad. |
list_function_keys | Lista las claves de consumo y su uso. |
revoke_function_key | Revoca una clave al instante. |
set_function_secret | Guarda un secreto cifrado (env.NOMBRE). |
list_function_secrets | Nombres de los secretos (nunca valores). |
delete_function_secret | Borra un secreto. |
create_schedule | Programa una función con un cron (UTC). |
list_schedules | Lista tus funciones programadas y su último resultado. |
update_schedule | Cambia cron/ruta/cuerpo o activa y desactiva una programación. |
delete_schedule | Borra una programación. |
schedule_runs | Registro de ejecuciones de una programación. |
get_usage | Cuánto llevas usado de tu plan (artefactos, espacio, funciones) y cuánto te queda. |
whoami | Tu email, plan, límites y uso. |
list_collections | Lista tus colecciones de datos con su acceso y tamaño. |
create_collection | Crea una colección de datos con su API /d/<id> (acceso y esquema opcional). |
update_collection | Cambia nombre, acceso o esquema de una colección. |
delete_collection | Borra una colección y todos sus registros. |
list_channels | Lista tus canales de tiempo real con su acceso y oyentes. |
create_channel | Crea un canal de tiempo real (/c/<id>) para mensajes en directo por SSE o WebSocket. |
update_channel | Cambia nombre o acceso de un canal (cierra las conexiones abiertas). |
delete_channel | Borra un canal y corta a sus oyentes. |
publish_message | Publica un mensaje JSON en un canal: llega al instante a sus oyentes. |
read_messages | Lee los últimos mensajes de un canal (anillo en memoria). |
query_records | Lee registros con filtros, orden y paginación. |
write_record | Crea, reemplaza o fusiona un registro (con control de versión). |
delete_record | Borra un registro. |
list_end_users | Lista los clientes que han iniciado sesión en tus páginas. |
delete_end_user | Borra a un cliente y cierra sus sesiones. |
Planes y límites
| Free | Pro | |
|---|---|---|
| Artifacts | 50 | 1000 |
| Tamaño por artifact | 2 MB | 10 MB |
| Publicaciones por hora | 60 | 600 |
| Claves de agente | 5 | 20 |
| Funciones | 10 | 200 |
| Código por función | 256 KB | 1 MB |
| Tiempo por invocación | 10 s | 30 s |
| Invocaciones al día | 10.000 | 1.000.000 |
| Llamadas/min por clave (por defecto) | 600 | 6000 |
| Llamadas/min por IP (APIs públicas) | 120 | 600 |
| Ejecuciones run_code por hora | 120 | 1200 |
| Secretos por función | 20 | 100 |
| KV: claves / espacio | 1000 / 10 MB | 100.000 / 1 GB |
| KV: tamaño por valor | 64 KB | 1 MB |
| Colecciones | 5 | 50 |
| Registros por cuenta | 5000 | 500.000 |
| Tamaño por registro | 16 KB | 256 KB |
| Datos: espacio total | 20 MB | 5 GB |
| Canales | 5 | 100 |
| Mensaje de canal | 16 KB | 64 KB |
| Mensajes/s por canal | 20 | 200 |
| Oyentes por canal | 100 | 2000 |
| Conexiones abiertas por cuenta | 200 | 5000 |
Superar un límite devuelve 429 (o 403 si es de cupo), con un mensaje claro y, cuando aplica, Retry-After.
Pasar a Pro: en el panel, Plan → «Pasar a Pro» (pago mensual; cancelas cuando quieras y mantienes Pro hasta el final del mes pagado). Al volver a Free no se borra nada: lo que supere los límites sigue ahí, pero no podrás crear más hasta estar por debajo. Comprar o cancelar solo se hace desde el panel; con una clave puedes consultar el estado en GET /api/billing.
API REST
Base https://teddyagent.app. Autenticación Authorization: Bearer tdy_…. Especificación completa en /openapi.json (OpenAPI 3.1): impórtala en Postman, Insomnia o genera un cliente.
Cuenta
| GET | /api/health | Estado del servicio sin clave |
| GET | /api/plans | Planes y límites sin clave |
| GET | /api/me | Quién soy: email, plan, límites y uso |
| GET | /api/billing | Plan, suscripción e historial de pagos |
| GET | /api/me/export | Descargar todos tus datos (ZIP) |
| GET | /api/me/onboarding | Estado de «Primeros pasos» |
| GET | /api/usage | Uso del plan: artefactos, espacio y funciones frente a los límites (level ok, warn al 80 %, full al 100 %) |
Artifacts
| GET | /api/artifacts | Listar mis artifacts |
| POST | /api/artifacts | Publicar un artifact |
| GET | /api/artifacts/{id} | Ver un artifact (metadatos) sin clave |
| PUT | /api/artifacts/{id} | Sustituir el HTML |
| PATCH | /api/artifacts/{id} | Cambiar título, estado (live/paused), carpeta, caducidad, visibilidad (public/private) o contraseña |
| DELETE | /api/artifacts/{id} | Borrar |
| GET | /api/artifacts/{id}/files | Archivos del artifact además del HTML (versión actual) |
| GET | /api/artifacts/{id}/versions | Historial de versiones (cada HTML publicado) |
| GET | /api/artifacts/{id}/versions/{n} | Contenido de una versión (JSON con html, o ?format=html para descargarlo) |
| POST | /api/artifacts/{id}/versions/{n}/restore | Restaurar una versión (se publica como versión nueva) |
| GET | /api/artifacts/{id}/diff | Diferencias línea a línea entre dos versiones |
| POST | /api/artifacts/{id}/report | Reportar un artifact (abuso, phishing…) sin clave |
Carpetas
| GET | /api/folders | Listar carpetas |
| POST | /api/folders | Crear carpeta |
| PATCH | /api/folders/{id} | Renombrar |
| DELETE | /api/folders/{id} | Borrar (los artifacts pasan a «sin carpeta») |
| POST | /api/folders/{id}/index | Crear (o actualizar) la página «Índice · carpeta» con enlaces a todo lo de la carpeta |
Claves de agente
| GET | /api/keys | Listar mis claves tdy_ |
| POST | /api/keys | Crear una clave tdy_ (solo se muestra una vez) |
| DELETE | /api/keys/{id} | Revocar |
Funciones
| GET | /api/functions | Listar mis funciones |
| POST | /api/functions | Publicar una función como endpoint /f/{id} |
| GET | /api/functions/{id} | Ver una función (con código) |
| PUT | /api/functions/{id} | Publicar nueva versión del código |
| PATCH | /api/functions/{id} | Cambiar nombre, estado (live/paused), acceso, red o carpeta |
| DELETE | /api/functions/{id} | Borrar (con sus claves, secretos y memoria) |
| GET | /api/functions/{id}/logs | Últimas invocaciones (incluye rechazadas, con motivo) |
Acceso a funciones
| GET | /api/functions/{id}/usage | Uso de los últimos 7 días por clave |
| GET | /api/functions/{id}/rejections | Intentos rechazados (7 días) por motivo |
| GET | /api/functions/{id}/keys | Claves de consumo válidas para esta función |
| POST | /api/functions/{id}/keys | Crear clave de consumo tfk_ solo para esta función |
| GET | /api/function-keys | Todas mis claves de consumo |
| POST | /api/function-keys | Crear clave de consumo (de una función o de todas) |
| PATCH | /api/function-keys/{id} | Cambiar nombre y límites |
| DELETE | /api/function-keys/{id} | Revocar al instante |
Secretos
| GET | /api/functions/{id}/secrets | Listar nombres de secretos (nunca valores) |
| POST | /api/functions/{id}/secrets | Crear o reemplazar un secreto |
| PUT | /api/functions/{id}/secrets/{name} | Crear o reemplazar un secreto por nombre |
| DELETE | /api/functions/{id}/secrets/{name} | Borrar un secreto |
Programaciones
| GET | /api/schedules | Todas mis funciones programadas |
| GET | /api/functions/{id}/schedules | Programaciones de esta función |
| POST | /api/functions/{id}/schedules | Programar la función (cron de 5 campos, en UTC) |
| GET | /api/functions/{id}/schedules/{sid} | Ver una programación |
| PATCH | /api/functions/{id}/schedules/{sid} | Cambiar cron, ruta, cuerpo, nombre o activarla/desactivarla |
| DELETE | /api/functions/{id}/schedules/{sid} | Borrar la programación (y su registro) |
| GET | /api/functions/{id}/schedules/{sid}/runs | Registro de ejecuciones (14 días) |
| POST | /api/functions/{id}/schedules/{sid}/run | Ejecutarla ahora (máx. 20 por hora) |
Memoria (KV)
| GET | /api/functions/{id}/kv | Listar claves del KV de la función |
| DELETE | /api/functions/{id}/kv | Vaciar el KV |
| GET | /api/functions/{id}/kv/{key} | Leer una clave |
| DELETE | /api/functions/{id}/kv/{key} | Borrar una clave |
Ejecución
| POST | /api/run | Ejecutar código una vez, sin publicar |
Datos (colecciones)
| GET | /api/collections | Listar tus colecciones |
| POST | /api/collections | Crear una colección de datos |
| GET | /api/data-usage | Uso de datos: colecciones, registros y bytes frente al plan |
| GET | /api/collections/{id} | Ver una colección |
| PATCH | /api/collections/{id} | Cambiar nombre, acceso o esquema |
| DELETE | /api/collections/{id} | Borrar la colección y todos sus registros |
| GET | /api/collections/{id}/records | Registros de la colección (vista del dueño; mismos filtros que la API pública) |
| POST | /api/collections/{id}/records | Crear un registro (el cuerpo es el propio objeto JSON) |
| DELETE | /api/collections/{id}/records | Vaciar la colección |
| GET | /api/collections/{id}/records/{rid} | Leer un registro |
| PUT | /api/collections/{id}/records/{rid} | Reemplazar (o crear con ese id) un registro; cabecera `If-Match` con la versión |
| PATCH | /api/collections/{id}/records/{rid} | Fusionar campos en un registro (null elimina un campo) |
| DELETE | /api/collections/{id}/records/{rid} | Borrar un registro |
| POST | /api/collections/{id}/import | Importar hasta 1000 registros de una vez (todo o nada) |
| GET | /api/collections/{id}/export | Exportar todos los registros (`format`: json, ndjson o csv) |
Canales (tiempo real)
| GET | /api/channels | Listar tus canales |
| POST | /api/channels | Crear un canal de tiempo real |
| GET | /api/channel-usage | Uso de canales y conexiones abiertas frente al plan |
| GET | /api/channels/{id} | Ver un canal |
| PATCH | /api/channels/{id} | Cambiar nombre o acceso (cierra las conexiones abiertas) |
| DELETE | /api/channels/{id} | Borrar el canal y cortar a sus oyentes |
| POST | /api/channels/{id}/publish | Publicar un mensaje como dueño |
| GET | /api/channels/{id}/messages | Últimos mensajes (anillo en memoria; `after` = último id visto) |
Canales: API pública
| GET | /c/{id} | Escuchar: SSE (`Accept: text/event-stream`), WebSocket (`Upgrade: websocket`) o, sin ellos, los últimos mensajes en JSON sin clave |
| POST | /c/{id} | Publicar un mensaje (cuerpo: cualquier JSON; `?event=nombre`) sin clave |
Usuarios finales
| GET | /api/end-users | Listar los clientes que han iniciado sesión en tus apps |
| DELETE | /api/end-users/{id} | Borrar a un cliente y cerrar sus sesiones |
Usuarios finales: API de sesión
| GET | /eu/api/me | Quién es el cliente de esta sesión (`Authorization: Bearer tus_…`) sin clave |
| POST | /eu/api/logout | Cerrar la sesión del cliente sin clave |
Datos: API pública
| GET | /d/{id} | Listar registros con filtros sin clave |
| POST | /d/{id} | Crear un registro sin clave |
| GET | /d/{id}/{rid} | Leer un registro sin clave |
| PUT | /d/{id}/{rid} | Reemplazar o crear con id elegido (`If-Match`: versión) sin clave |
| PATCH | /d/{id}/{rid} | Fusionar campos (null elimina; `If-Match`: versión) sin clave |
| DELETE | /d/{id}/{rid} | Borrar (`If-Match`: versión) sin clave |
| GET | /d/{id}/_events | Cambios de la colección en directo (SSE): `created`, `updated`, `deleted` sin clave |
Errores
Siempre JSON con error (texto legible) y a veces code (estable, para programas): unauthorized, invalid_api_key, quota_exceeded, rate_limited, too_large, moderation_rejected, no_default_export…
{ "error": "Tu plan permite 20 secretos por función", "code": "quota_exceeded" }