Referencia de la API
Los endpoints públicos son de solo lectura, sin autenticación y con límite de uso por IP. Los endpoints `/me/*` son para la herramienta de línea de comandos `bsbot`: necesitan un token (`Authorization: Bearer`), que `bsbot login` obtiene a través del navegador (`POST /cli/token`). No envían cabeceras CORS. Solo se sirve en el sitio principal, nunca en el subdominio del handle de un bot. Versiones: la versión mayor va en la ruta (`/api/v1`); la v1 solo recibe cambios compatibles (nuevos endpoints, nuevos campos o parámetros opcionales). Un cambio incompatible sale como `/api/v2`, y la v1 sigue funcionando al menos 6 meses, anunciado con las cabeceras `Deprecation` y `Sunset`. Consulta docs/api.md.
- URL base
- https://bluesky.bot/api/v1
- Versión
- 1.0.0
¿Está libre un handle?
GET/handles/{name}/availability
Aplica exactamente las reglas del servidor para una reclamación: formato, nombres reservados, palabras ofensivas y, por último, si algún bot ya lo tiene.
Parámetros
| Nombre | Ubicación | Tipo | Descripción |
|---|---|---|---|
| name (obligatorio) | path | string | La parte del nombre, p. ej. `weather`; también se acepta `@weather.bluesky.bot`. |
Respuestas
| Estado | Descripción | Cuerpo |
|---|---|---|
| 200 | La disponibilidad, con el motivo cuando no está disponible. | Availability |
| 404 | No encontrado. También se devuelve en el subdominio del handle de un bot: la API solo se sirve en el sitio principal. | Error |
| 429 | Límite de uso alcanzado (política `publicApi`, por IP). | Error |
| 500 | Error inesperado. | Error |
Ejemplo
curl https://bluesky.bot/api/v1/handles/weather/availabilityEl DID detrás de un handle reclamado
GET/resolve/{handle}
La misma respuesta que `https://<handle>/.well-known/atproto-did`. Solo handles `*.bluesky.bot`.
Parámetros
| Nombre | Ubicación | Tipo | Descripción |
|---|---|---|---|
| handle (obligatorio) | path | string | Un handle completo, p. ej. `weather.bluesky.bot` (sin distinguir mayúsculas). |
Respuestas
| Estado | Descripción | Cuerpo |
|---|---|---|
| 200 | El handle y su DID. | Resolution |
| 400 | No es un handle `*.bluesky.bot` (código `invalid_handle`). | Error |
| 404 | No encontrado. También se devuelve en el subdominio del handle de un bot: la API solo se sirve en el sitio principal. | Error |
| 429 | Límite de uso alcanzado (política `publicApi`, por IP). | Error |
| 500 | Error inesperado. | Error |
Ejemplo
curl https://bluesky.bot/api/v1/resolve/weather.bluesky.botBots publicados en el directorio
GET/bots
Solo los bots que su creador publicó en el directorio, del más reciente al más antiguo. Paginación por cursor: pasa el `cursor` de una página para obtener la siguiente; es null en la última página.
Parámetros
| Nombre | Ubicación | Tipo | Descripción |
|---|---|---|---|
| limit | query | integer (1–100), default 20 | |
| cursor | query | string | Cursor opaco de una página anterior. |
| category | query | string | Categoría exacta. |
| verified | query | string: "true", "false" | Solo los bots cuyo handle está (true) o aún no está (false) activo en Bluesky. |
| q | query | string | Búsqueda sin distinguir mayúsculas en el handle y el nombre visible. |
Respuestas
| Estado | Descripción | Cuerpo |
|---|---|---|
| 200 | Una página de bots. | BotList |
| 400 | Parámetro de consulta no válido (código `bad_request`). | Error |
| 404 | No encontrado. También se devuelve en el subdominio del handle de un bot: la API solo se sirve en el sitio principal. | Error |
| 429 | Límite de uso alcanzado (política `publicApi`, por IP). | Error |
| 500 | Error inesperado. | Error |
Ejemplo
curl https://bluesky.bot/api/v1/botsUn bot publicado en el directorio
GET/bots/{handle}
Parámetros
| Nombre | Ubicación | Tipo | Descripción |
|---|---|---|---|
| handle (obligatorio) | path | string | Un handle completo, p. ej. `weather.bluesky.bot` (sin distinguir mayúsculas). |
Respuestas
| Estado | Descripción | Cuerpo |
|---|---|---|
| 200 | El bot. | Bot |
| 404 | No encontrado. También se devuelve en el subdominio del handle de un bot: la API solo se sirve en el sitio principal. | Error |
| 429 | Límite de uso alcanzado (política `publicApi`, por IP). | Error |
| 500 | Error inesperado. | Error |
Ejemplo
curl https://bluesky.bot/api/v1/bots/weather.bluesky.botCambiar un código de inicio de sesión de la CLI por un token
POST/cli/token
Paso 4 de `bsbot login`: el código de un solo uso que /cli/authorize entregó a la dirección loopback de la CLI, con el verificador PKCE y la misma URI de redirección. Un código sirve una vez y durante dos minutos; un intento fallido lo invalida. El token es válido 30 días. Límite de uso por IP (`cliToken`).
Respuestas
| Estado | Descripción | Cuerpo |
|---|---|---|
| 200 | Un token para los endpoints `/me/*`. | CliToken |
| 400 | Cuerpo mal formado (`bad_request`), o un código desconocido, caducado, ya usado o que no coincide con el verificador o la URI de redirección (`invalid_grant`). | Error |
| 404 | No encontrado. También se devuelve en el subdominio del handle de un bot: la API solo se sirve en el sitio principal. | Error |
| 429 | Límite de uso alcanzado (política `publicApi`, por IP). | Error |
| 500 | Error inesperado. | Error |
Ejemplo
curl \
-X POST \
-H "Content-Type: application/json" \
-d '{"code":"…","code_verifier":"…","redirect_uri":"…"}' \
https://bluesky.bot/api/v1/cli/tokenLa cuenta detrás del token
GET/me
Respuestas
| Estado | Descripción | Cuerpo |
|---|---|---|
| 200 | Tu cuenta y la caducidad del token. | Me |
| 401 | Token ausente, caducado o revocado (código `unauthorized`). Vuelve a ejecutar `bsbot login`. | Error |
| 404 | No hay ningún bot así en tu cuenta, o es el subdominio del handle de un bot (la API solo se sirve en el sitio principal). | Error |
| 429 | Límite de uso alcanzado: `publicApi` por IP, `creatorApi` por cuenta y `handleChange` por cuenta para reclamaciones, cambios, comprobaciones y liberaciones (compartido con el panel). | Error |
| 500 | Error inesperado. | Error |
Ejemplo
curl \
-H "Authorization: Bearer $BLUESKY_BOT_TOKEN" \
https://bluesky.bot/api/v1/meTus bots
GET/me/bots
Todos los bots de tu cuenta, publicados en el directorio o no, del más antiguo al más reciente. Añade un bot desde el panel: hace falta iniciar sesión en la cuenta del bot.
Respuestas
| Estado | Descripción | Cuerpo |
|---|---|---|
| 200 | Tus bots. | MyBotList |
| 401 | Token ausente, caducado o revocado (código `unauthorized`). Vuelve a ejecutar `bsbot login`. | Error |
| 404 | No hay ningún bot así en tu cuenta, o es el subdominio del handle de un bot (la API solo se sirve en el sitio principal). | Error |
| 429 | Límite de uso alcanzado: `publicApi` por IP, `creatorApi` por cuenta y `handleChange` por cuenta para reclamaciones, cambios, comprobaciones y liberaciones (compartido con el panel). | Error |
| 500 | Error inesperado. | Error |
Ejemplo
curl \
-H "Authorization: Bearer $BLUESKY_BOT_TOKEN" \
https://bluesky.bot/api/v1/me/botsReclamar un handle para uno de tus bots y aplicárselo
POST/me/bots/{did}/claim
Las propias reglas del panel: formato, nombres reservados, palabras ofensivas, disponibilidad (garantizada por un índice único) y periodo de gracia de los handles liberados. Después, el handle del bot se cambia en Bluesky al momento; `switch` dice cómo fue. Cambiar el handle de un bot que ya tiene uno libera el anterior.
Parámetros
| Nombre | Ubicación | Tipo | Descripción |
|---|---|---|---|
| did (obligatorio) | path | string | El DID del bot, tal como lo lista `GET /me/bots`. |
Respuestas
| Estado | Descripción | Cuerpo |
|---|---|---|
| 200 | El handle reclamado y el resultado del cambio. | ClaimResult |
| 400 | Cuerpo mal formado (`bad_request`), o un nombre no permitido (`invalid_handle`, con `reason`). | Error |
| 401 | Token ausente, caducado o revocado (código `unauthorized`). Vuelve a ejecutar `bsbot login`. | Error |
| 403 | El bot está suspendido (`forbidden`). | Error |
| 404 | No hay ningún bot así en tu cuenta, o es el subdominio del handle de un bot (la API solo se sirve en el sitio principal). | Error |
| 409 | Otro bot tiene el handle, o está en su periodo de gracia (`conflict`, motivo `taken`). | Error |
| 429 | Límite de uso alcanzado: `publicApi` por IP, `creatorApi` por cuenta y `handleChange` por cuenta para reclamaciones, cambios, comprobaciones y liberaciones (compartido con el panel). | Error |
| 500 | Error inesperado. | Error |
Ejemplo
curl \
-X POST \
-H "Authorization: Bearer $BLUESKY_BOT_TOKEN" \
-H "Content-Type: application/json" \
-d '{"name":"weather"}' \
https://bluesky.bot/api/v1/me/bots/did:plc:yourbot/claimVolver a pedir al PDS del bot que use su handle reclamado
POST/me/bots/{did}/switch
Parámetros
| Nombre | Ubicación | Tipo | Descripción |
|---|---|---|---|
| did (obligatorio) | path | string | El DID del bot, tal como lo lista `GET /me/bots`. |
Respuestas
| Estado | Descripción | Cuerpo |
|---|---|---|
| 200 | El resultado del cambio. | SwitchResult |
| 401 | Token ausente, caducado o revocado (código `unauthorized`). Vuelve a ejecutar `bsbot login`. | Error |
| 404 | No hay ningún bot así en tu cuenta, o es el subdominio del handle de un bot (la API solo se sirve en el sitio principal). | Error |
| 429 | Límite de uso alcanzado: `publicApi` por IP, `creatorApi` por cuenta y `handleChange` por cuenta para reclamaciones, cambios, comprobaciones y liberaciones (compartido con el panel). | Error |
| 500 | Error inesperado. | Error |
Ejemplo
curl \
-X POST \
-H "Authorization: Bearer $BLUESKY_BOT_TOKEN" \
https://bluesky.bot/api/v1/me/bots/did:plc:yourbot/switchComprobar si el handle reclamado está activo en Bluesky
POST/me/bots/{did}/verify
Parámetros
| Nombre | Ubicación | Tipo | Descripción |
|---|---|---|---|
| did (obligatorio) | path | string | El DID del bot, tal como lo lista `GET /me/bots`. |
Respuestas
| Estado | Descripción | Cuerpo |
|---|---|---|
| 200 | El resultado de la comprobación. | SwitchResult |
| 401 | Token ausente, caducado o revocado (código `unauthorized`). Vuelve a ejecutar `bsbot login`. | Error |
| 404 | No hay ningún bot así en tu cuenta, o es el subdominio del handle de un bot (la API solo se sirve en el sitio principal). | Error |
| 429 | Límite de uso alcanzado: `publicApi` por IP, `creatorApi` por cuenta y `handleChange` por cuenta para reclamaciones, cambios, comprobaciones y liberaciones (compartido con el panel). | Error |
| 500 | Error inesperado. | Error |
Ejemplo
curl \
-X POST \
-H "Authorization: Bearer $BLUESKY_BOT_TOKEN" \
https://bluesky.bot/api/v1/me/bots/did:plc:yourbot/verifyLiberar el handle de un bot
POST/me/bots/{did}/release
El bot vuelve a su handle anterior de Bluesky cuando es posible, el handle deja de resolverse y queda bloqueado para los demás durante su periodo de gracia.
Parámetros
| Nombre | Ubicación | Tipo | Descripción |
|---|---|---|---|
| did (obligatorio) | path | string | El DID del bot, tal como lo lista `GET /me/bots`. |
Respuestas
| Estado | Descripción | Cuerpo |
|---|---|---|
| 200 | El handle liberado y el resultado de la reversión. | ReleaseResult |
| 401 | Token ausente, caducado o revocado (código `unauthorized`). Vuelve a ejecutar `bsbot login`. | Error |
| 403 | El bot está suspendido (`forbidden`). | Error |
| 404 | No hay ningún bot así en tu cuenta, o es el subdominio del handle de un bot (la API solo se sirve en el sitio principal). | Error |
| 409 | El bot no tiene ningún handle que liberar (`conflict`, motivo `no_handle`). | Error |
| 429 | Límite de uso alcanzado: `publicApi` por IP, `creatorApi` por cuenta y `handleChange` por cuenta para reclamaciones, cambios, comprobaciones y liberaciones (compartido con el panel). | Error |
| 500 | Error inesperado. | Error |
Ejemplo
curl \
-X POST \
-H "Authorization: Bearer $BLUESKY_BOT_TOKEN" \
https://bluesky.bot/api/v1/me/bots/did:plc:yourbot/releaseRevocar el token de esta petición
DELETE/me/token
Lo que llama `bsbot logout`.
Respuestas
| Estado | Descripción | Cuerpo |
|---|---|---|
| 204 | Revocado. Sin cuerpo. | |
| 401 | Token ausente, caducado o revocado (código `unauthorized`). Vuelve a ejecutar `bsbot login`. | Error |
| 404 | No hay ningún bot así en tu cuenta, o es el subdominio del handle de un bot (la API solo se sirve en el sitio principal). | Error |
| 429 | Límite de uso alcanzado: `publicApi` por IP, `creatorApi` por cuenta y `handleChange` por cuenta para reclamaciones, cambios, comprobaciones y liberaciones (compartido con el panel). | Error |
| 500 | Error inesperado. | Error |
Ejemplo
curl \
-X DELETE \
-H "Authorization: Bearer $BLUESKY_BOT_TOKEN" \
https://bluesky.bot/api/v1/me/tokenEsquemas
Error
| Campo | Tipo | Descripción |
|---|---|---|
| error (obligatorio) | object | |
| error.code (obligatorio) | string: "bad_request", "invalid_handle", "not_found", "rate_limited", "internal_error", "unauthorized", "forbidden", "conflict", "invalid_grant" | |
| error.message (obligatorio) | string | |
| error.reason | string | Con `invalid_handle`, `conflict` y `forbidden`: p. ej. `reserved`, `taken`, `no_handle`, `suspended`. |
| error.parameter | string | El parámetro de consulta no válido. |
| error.retryAfterSeconds | integer (1–) | Con `rate_limited`. |
Availability
| Campo | Tipo | Descripción |
|---|---|---|
| name (obligatorio) | string | El nombre normalizado (tal como se escribió si no es válido). |
| handle (obligatorio) | string | null | El handle completo, p. ej. `weather.bluesky.bot`; null cuando el nombre no es válido. |
| available (obligatorio) | boolean | |
| reason (obligatorio) | null | string: "required", "too_short", "too_long", "invalid_characters", "invalid_hyphen", "reserved", "not_allowed", "taken" | Por qué no está disponible; null cuando lo está. Los nombres tienen de 3 a 30 caracteres entre a-z, 0-9 y guiones sueltos. |
Resolution
| Campo | Tipo | Descripción |
|---|---|---|
| handle (obligatorio) | string | |
| did (obligatorio) | string |
Bot
| Campo | Tipo | Descripción |
|---|---|---|
| did (obligatorio) | string | |
| handle (obligatorio) | string | |
| displayName (obligatorio) | string | null | |
| avatar (obligatorio) | string | null | URL del avatar. |
| description (obligatorio) | string | null | |
| category (obligatorio) | string | null | |
| verifiedAt (obligatorio) | string | null, date-time | Cuándo se confirmó que el handle está activo en Bluesky; null si aún no. |
BotList
| Campo | Tipo | Descripción |
|---|---|---|
| bots (obligatorio) | Bot[] | |
| cursor (obligatorio) | string | null | Cursor de la página siguiente; null en la última página. |
CliTokenRequest
| Campo | Tipo | Descripción |
|---|---|---|
| code (obligatorio) | string | |
| code_verifier (obligatorio) | string | El verificador PKCE (RFC 7636). |
| redirect_uri (obligatorio) | string | La misma `http://127.0.0.1:<port>/callback` que en /cli/authorize. |
CliToken
| Campo | Tipo | Descripción |
|---|---|---|
| token (obligatorio) | string | Mantenlo en secreto: actúa en tu nombre en `/me/*`. |
| tokenType (obligatorio) | string = "Bearer" | |
| expiresAt (obligatorio) | string, date-time | |
| creator (obligatorio) | Account |
Account
| Campo | Tipo | Descripción |
|---|---|---|
| did (obligatorio) | string | |
| handle (obligatorio) | string | Tu handle de Bluesky. |
| displayName | string | null |
Me
| Campo | Tipo | Descripción |
|---|---|---|
| creator (obligatorio) | Account | |
| token (obligatorio) | object | |
| token.name (obligatorio) | string | El nombre de máquina indicado al iniciar sesión. |
| token.createdAt (obligatorio) | string, date-time | |
| token.expiresAt (obligatorio) | string, date-time |
MyBot
| Campo | Tipo | Descripción |
|---|---|---|
| did (obligatorio) | string | |
| handle (obligatorio) | string | null | El handle `*.bluesky.bot` reclamado; null si no hay ninguno. |
| previousHandle (obligatorio) | string | null | El handle del bot antes de tener uno aquí. |
| displayName (obligatorio) | string | null | |
| avatar (obligatorio) | string | null | |
| verifiedAt (obligatorio) | string | null, date-time | Cuándo se confirmó que el handle reclamado está activo en Bluesky. |
| listed (obligatorio) | boolean | Se muestra en el directorio público. |
| status (obligatorio) | string: "active", "suspended" |
MyBotList
| Campo | Tipo | Descripción |
|---|---|---|
| bots (obligatorio) | MyBot[] |
ClaimRequest
| Campo | Tipo | Descripción |
|---|---|---|
| name (obligatorio) | string | La parte del nombre, p. ej. `weather` para `weather.bluesky.bot`. |
SwitchOutcome
| Campo | Tipo | Descripción |
|---|---|---|
| status (obligatorio) | string: "verified", "pending", "manual" | |
| verifiedAt | string, date-time | |
| reason | string: "reauthorize", "pds_refused", "pds_unreachable" |
ClaimResult
| Campo | Tipo | Descripción |
|---|---|---|
| handle (obligatorio) | string | |
| switch (obligatorio) | SwitchOutcome |
SwitchResult
| Campo | Tipo | Descripción |
|---|---|---|
| switch (obligatorio) | SwitchOutcome |
ReleaseResult
| Campo | Tipo | Descripción |
|---|---|---|
| handle (obligatorio) | string | El handle liberado. |
| revert (obligatorio) | object | `reverted`: el bot ha vuelto a `handle`. `manual`: cambia tú mismo el handle del bot en Bluesky; `reason` dice por qué. |
| revert.status (obligatorio) | string: "reverted", "manual" | |
| revert.handle | string | |
| revert.reason | string: "reauthorize", "pds_refused", "pds_unreachable", "no_previous_handle" | |
| revert.previousHandle | string | null |