Référence de l’API
Les endpoints publics sont en lecture seule, sans authentification, et limités en débit par IP. Les endpoints `/me/*` servent à l’outil en ligne de commande `bsbot` : ils demandent un jeton (`Authorization: Bearer`), que `bsbot login` obtient via le navigateur (`POST /cli/token`). Ils n’envoient aucun en-tête CORS. Servie uniquement sur le site principal, jamais sur le sous-domaine du handle d’un bot. Versions : la version majeure figure dans le chemin (`/api/v1`) ; la v1 ne reçoit que des changements rétrocompatibles (nouveaux endpoints, nouveaux champs ou paramètres facultatifs). Un changement incompatible sort en `/api/v2`, et la v1 continue alors de fonctionner au moins 6 mois, annoncée par les en-têtes `Deprecation` et `Sunset`. Voir docs/api.md.
- URL de base
- https://bluesky.bot/api/v1
- Version
- 1.0.0
Un handle est-il libre ?
GET/handles/{name}/availability
Applique exactement les règles serveur d’une réservation : format, noms réservés, mots injurieux, puis si un bot le détient déjà.
Paramètres
| Nom | Emplacement | Type | Description |
|---|---|---|---|
| name (obligatoire) | path | string | La partie nom, par ex. `weather` ; `@weather.bluesky.bot` est aussi accepté. |
Réponses
| Statut | Description | Corps |
|---|---|---|
| 200 | La disponibilité, avec la raison quand le handle n’est pas disponible. | Availability |
| 404 | Introuvable. Également renvoyé sur le sous-domaine du handle d’un bot : l’API n’est servie que sur le site principal. | Error |
| 429 | Limite de débit atteinte (politique `publicApi`, par IP). | Error |
| 500 | Erreur inattendue. | Error |
Exemple
curl https://bluesky.bot/api/v1/handles/weather/availabilityLe DID derrière un handle réservé
GET/resolve/{handle}
Même réponse que `https://<handle>/.well-known/atproto-did`. Seulement les handles `*.bluesky.bot`.
Paramètres
| Nom | Emplacement | Type | Description |
|---|---|---|---|
| handle (obligatoire) | path | string | Un handle complet, par ex. `weather.bluesky.bot` (insensible à la casse). |
Réponses
| Statut | Description | Corps |
|---|---|---|
| 200 | Le handle et son DID. | Resolution |
| 400 | Pas un handle `*.bluesky.bot` (code `invalid_handle`). | Error |
| 404 | Introuvable. Également renvoyé sur le sous-domaine du handle d’un bot : l’API n’est servie que sur le site principal. | Error |
| 429 | Limite de débit atteinte (politique `publicApi`, par IP). | Error |
| 500 | Erreur inattendue. | Error |
Exemple
curl https://bluesky.bot/api/v1/resolve/weather.bluesky.botBots inscrits dans l’annuaire
GET/bots
Seulement les bots que leur créateur a inscrits dans l’annuaire, du plus récent au plus ancien. Pagination par curseur : passez le `cursor` d’une page pour obtenir la suivante ; il vaut null sur la dernière page.
Paramètres
| Nom | Emplacement | Type | Description |
|---|---|---|---|
| limit | query | integer (1–100), default 20 | |
| cursor | query | string | Curseur opaque d’une page précédente. |
| category | query | string | Catégorie exacte. |
| verified | query | string: "true", "false" | Seulement les bots dont le handle est (true) ou n’est pas encore (false) actif sur Bluesky. |
| q | query | string | Recherche insensible à la casse dans le handle et le nom affiché. |
Réponses
| Statut | Description | Corps |
|---|---|---|
| 200 | Une page de bots. | BotList |
| 400 | Paramètre de requête invalide (code `bad_request`). | Error |
| 404 | Introuvable. Également renvoyé sur le sous-domaine du handle d’un bot : l’API n’est servie que sur le site principal. | Error |
| 429 | Limite de débit atteinte (politique `publicApi`, par IP). | Error |
| 500 | Erreur inattendue. | Error |
Exemple
curl https://bluesky.bot/api/v1/botsUn bot inscrit dans l’annuaire
GET/bots/{handle}
Paramètres
| Nom | Emplacement | Type | Description |
|---|---|---|---|
| handle (obligatoire) | path | string | Un handle complet, par ex. `weather.bluesky.bot` (insensible à la casse). |
Réponses
| Statut | Description | Corps |
|---|---|---|
| 200 | Le bot. | Bot |
| 404 | Introuvable. Également renvoyé sur le sous-domaine du handle d’un bot : l’API n’est servie que sur le site principal. | Error |
| 429 | Limite de débit atteinte (politique `publicApi`, par IP). | Error |
| 500 | Erreur inattendue. | Error |
Exemple
curl https://bluesky.bot/api/v1/bots/weather.bluesky.botÉchanger un code de connexion de la CLI contre un jeton
POST/cli/token
Étape 4 de `bsbot login` : le code à usage unique que /cli/authorize a remis à l’adresse de loopback de la CLI, avec le vérificateur PKCE et la même URI de redirection. Un code sert une seule fois, pendant deux minutes ; une tentative ratée le consomme. Le jeton est valable 30 jours. Limité en débit par IP (`cliToken`).
Réponses
| Statut | Description | Corps |
|---|---|---|
| 200 | Un jeton pour les endpoints `/me/*`. | CliToken |
| 400 | Corps mal formé (`bad_request`), ou code inconnu, expiré, déjà utilisé, ou qui ne correspond pas au vérificateur ou à l’URI de redirection (`invalid_grant`). | Error |
| 404 | Introuvable. Également renvoyé sur le sous-domaine du handle d’un bot : l’API n’est servie que sur le site principal. | Error |
| 429 | Limite de débit atteinte (politique `publicApi`, par IP). | Error |
| 500 | Erreur inattendue. | Error |
Exemple
curl \
-X POST \
-H "Content-Type: application/json" \
-d '{"code":"…","code_verifier":"…","redirect_uri":"…"}' \
https://bluesky.bot/api/v1/cli/tokenLe compte derrière le jeton
GET/me
Réponses
| Statut | Description | Corps |
|---|---|---|
| 200 | Votre compte et l’expiration du jeton. | Me |
| 401 | Jeton absent, expiré ou révoqué (code `unauthorized`). Relancez `bsbot login`. | Error |
| 404 | Aucun bot de ce nom dans votre compte, ou sous-domaine du handle d’un bot (l’API n’est servie que sur le site principal). | Error |
| 429 | Limite de débit atteinte : `publicApi` par IP, `creatorApi` par compte, et `handleChange` par compte pour les réservations, changements, vérifications et libérations (partagée avec le tableau de bord). | Error |
| 500 | Erreur inattendue. | Error |
Exemple
curl \
-H "Authorization: Bearer $BLUESKY_BOT_TOKEN" \
https://bluesky.bot/api/v1/meVos bots
GET/me/bots
Tous les bots de votre compte, inscrits dans l’annuaire ou non, du plus ancien au plus récent. Ajoutez un bot depuis le tableau de bord : il faut se connecter au compte du bot.
Réponses
| Statut | Description | Corps |
|---|---|---|
| 200 | Vos bots. | MyBotList |
| 401 | Jeton absent, expiré ou révoqué (code `unauthorized`). Relancez `bsbot login`. | Error |
| 404 | Aucun bot de ce nom dans votre compte, ou sous-domaine du handle d’un bot (l’API n’est servie que sur le site principal). | Error |
| 429 | Limite de débit atteinte : `publicApi` par IP, `creatorApi` par compte, et `handleChange` par compte pour les réservations, changements, vérifications et libérations (partagée avec le tableau de bord). | Error |
| 500 | Erreur inattendue. | Error |
Exemple
curl \
-H "Authorization: Bearer $BLUESKY_BOT_TOKEN" \
https://bluesky.bot/api/v1/me/botsRéserver un handle pour l’un de vos bots, et le lui appliquer
POST/me/bots/{did}/claim
Les règles du tableau de bord : format, noms réservés, mots injurieux, disponibilité (garantie par un index unique), délai de grâce des handles libérés. Le handle du bot est ensuite changé sur Bluesky immédiatement ; `switch` indique comment cela s’est passé. Changer le handle d’un bot qui en a déjà un libère l’ancien.
Paramètres
| Nom | Emplacement | Type | Description |
|---|---|---|---|
| did (obligatoire) | path | string | Le DID du bot, tel que listé par `GET /me/bots`. |
Réponses
| Statut | Description | Corps |
|---|---|---|
| 200 | Le handle réservé et le résultat du changement. | ClaimResult |
| 400 | Corps mal formé (`bad_request`), ou nom non autorisé (`invalid_handle`, avec `reason`). | Error |
| 401 | Jeton absent, expiré ou révoqué (code `unauthorized`). Relancez `bsbot login`. | Error |
| 403 | Le bot est suspendu (`forbidden`). | Error |
| 404 | Aucun bot de ce nom dans votre compte, ou sous-domaine du handle d’un bot (l’API n’est servie que sur le site principal). | Error |
| 409 | Un autre bot détient le handle, ou il est dans son délai de grâce (`conflict`, raison `taken`). | Error |
| 429 | Limite de débit atteinte : `publicApi` par IP, `creatorApi` par compte, et `handleChange` par compte pour les réservations, changements, vérifications et libérations (partagée avec le tableau de bord). | Error |
| 500 | Erreur inattendue. | Error |
Exemple
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/claimRedemander au PDS du bot d’utiliser son handle réservé
POST/me/bots/{did}/switch
Paramètres
| Nom | Emplacement | Type | Description |
|---|---|---|---|
| did (obligatoire) | path | string | Le DID du bot, tel que listé par `GET /me/bots`. |
Réponses
| Statut | Description | Corps |
|---|---|---|
| 200 | Le résultat du changement. | SwitchResult |
| 401 | Jeton absent, expiré ou révoqué (code `unauthorized`). Relancez `bsbot login`. | Error |
| 404 | Aucun bot de ce nom dans votre compte, ou sous-domaine du handle d’un bot (l’API n’est servie que sur le site principal). | Error |
| 429 | Limite de débit atteinte : `publicApi` par IP, `creatorApi` par compte, et `handleChange` par compte pour les réservations, changements, vérifications et libérations (partagée avec le tableau de bord). | Error |
| 500 | Erreur inattendue. | Error |
Exemple
curl \
-X POST \
-H "Authorization: Bearer $BLUESKY_BOT_TOKEN" \
https://bluesky.bot/api/v1/me/bots/did:plc:yourbot/switchVérifier si le handle réservé est actif sur Bluesky
POST/me/bots/{did}/verify
Paramètres
| Nom | Emplacement | Type | Description |
|---|---|---|---|
| did (obligatoire) | path | string | Le DID du bot, tel que listé par `GET /me/bots`. |
Réponses
| Statut | Description | Corps |
|---|---|---|
| 200 | Le résultat de la vérification. | SwitchResult |
| 401 | Jeton absent, expiré ou révoqué (code `unauthorized`). Relancez `bsbot login`. | Error |
| 404 | Aucun bot de ce nom dans votre compte, ou sous-domaine du handle d’un bot (l’API n’est servie que sur le site principal). | Error |
| 429 | Limite de débit atteinte : `publicApi` par IP, `creatorApi` par compte, et `handleChange` par compte pour les réservations, changements, vérifications et libérations (partagée avec le tableau de bord). | Error |
| 500 | Erreur inattendue. | Error |
Exemple
curl \
-X POST \
-H "Authorization: Bearer $BLUESKY_BOT_TOKEN" \
https://bluesky.bot/api/v1/me/bots/did:plc:yourbot/verifyLibérer le handle d’un bot
POST/me/bots/{did}/release
Le bot retrouve son handle Bluesky précédent quand c’est possible, le handle cesse d’être résolu, et il reste bloqué pour les autres pendant son délai de grâce.
Paramètres
| Nom | Emplacement | Type | Description |
|---|---|---|---|
| did (obligatoire) | path | string | Le DID du bot, tel que listé par `GET /me/bots`. |
Réponses
| Statut | Description | Corps |
|---|---|---|
| 200 | Le handle libéré et le résultat du retour en arrière. | ReleaseResult |
| 401 | Jeton absent, expiré ou révoqué (code `unauthorized`). Relancez `bsbot login`. | Error |
| 403 | Le bot est suspendu (`forbidden`). | Error |
| 404 | Aucun bot de ce nom dans votre compte, ou sous-domaine du handle d’un bot (l’API n’est servie que sur le site principal). | Error |
| 409 | Le bot n’a aucun handle à libérer (`conflict`, raison `no_handle`). | Error |
| 429 | Limite de débit atteinte : `publicApi` par IP, `creatorApi` par compte, et `handleChange` par compte pour les réservations, changements, vérifications et libérations (partagée avec le tableau de bord). | Error |
| 500 | Erreur inattendue. | Error |
Exemple
curl \
-X POST \
-H "Authorization: Bearer $BLUESKY_BOT_TOKEN" \
https://bluesky.bot/api/v1/me/bots/did:plc:yourbot/releaseRévoquer le jeton de cette requête
DELETE/me/token
Ce qu’appelle `bsbot logout`.
Réponses
| Statut | Description | Corps |
|---|---|---|
| 204 | Révoqué. Pas de corps. | |
| 401 | Jeton absent, expiré ou révoqué (code `unauthorized`). Relancez `bsbot login`. | Error |
| 404 | Aucun bot de ce nom dans votre compte, ou sous-domaine du handle d’un bot (l’API n’est servie que sur le site principal). | Error |
| 429 | Limite de débit atteinte : `publicApi` par IP, `creatorApi` par compte, et `handleChange` par compte pour les réservations, changements, vérifications et libérations (partagée avec le tableau de bord). | Error |
| 500 | Erreur inattendue. | Error |
Exemple
curl \
-X DELETE \
-H "Authorization: Bearer $BLUESKY_BOT_TOKEN" \
https://bluesky.bot/api/v1/me/tokenSchémas
Error
| Champ | Type | Description |
|---|---|---|
| error (obligatoire) | object | |
| error.code (obligatoire) | string: "bad_request", "invalid_handle", "not_found", "rate_limited", "internal_error", "unauthorized", "forbidden", "conflict", "invalid_grant" | |
| error.message (obligatoire) | string | |
| error.reason | string | Avec `invalid_handle`, `conflict` et `forbidden` : par ex. `reserved`, `taken`, `no_handle`, `suspended`. |
| error.parameter | string | Le paramètre de requête invalide. |
| error.retryAfterSeconds | integer (1–) | Avec `rate_limited`. |
Availability
| Champ | Type | Description |
|---|---|---|
| name (obligatoire) | string | Le nom normalisé (tel que saisi s’il est invalide). |
| handle (obligatoire) | string | null | Le handle complet, par ex. `weather.bluesky.bot` ; null quand le nom est invalide. |
| available (obligatoire) | boolean | |
| reason (obligatoire) | null | string: "required", "too_short", "too_long", "invalid_characters", "invalid_hyphen", "reserved", "not_allowed", "taken" | Pourquoi il n’est pas disponible ; null s’il l’est. Les noms font 3 à 30 caractères parmi a-z, 0-9 et des tirets isolés. |
Resolution
| Champ | Type | Description |
|---|---|---|
| handle (obligatoire) | string | |
| did (obligatoire) | string |
Bot
| Champ | Type | Description |
|---|---|---|
| did (obligatoire) | string | |
| handle (obligatoire) | string | |
| displayName (obligatoire) | string | null | |
| avatar (obligatoire) | string | null | URL de l’avatar. |
| description (obligatoire) | string | null | |
| category (obligatoire) | string | null | |
| verifiedAt (obligatoire) | string | null, date-time | Quand le handle a été confirmé actif sur Bluesky ; null sinon. |
BotList
| Champ | Type | Description |
|---|---|---|
| bots (obligatoire) | Bot[] | |
| cursor (obligatoire) | string | null | Curseur de la page suivante ; null sur la dernière page. |
CliTokenRequest
| Champ | Type | Description |
|---|---|---|
| code (obligatoire) | string | |
| code_verifier (obligatoire) | string | Le vérificateur PKCE (RFC 7636). |
| redirect_uri (obligatoire) | string | La même `http://127.0.0.1:<port>/callback` que sur /cli/authorize. |
CliToken
| Champ | Type | Description |
|---|---|---|
| token (obligatoire) | string | Gardez-le secret : il agit en votre nom sur `/me/*`. |
| tokenType (obligatoire) | string = "Bearer" | |
| expiresAt (obligatoire) | string, date-time | |
| creator (obligatoire) | Account |
Account
| Champ | Type | Description |
|---|---|---|
| did (obligatoire) | string | |
| handle (obligatoire) | string | Votre handle Bluesky. |
| displayName | string | null |
Me
| Champ | Type | Description |
|---|---|---|
| creator (obligatoire) | Account | |
| token (obligatoire) | object | |
| token.name (obligatoire) | string | Le nom de machine donné à la connexion. |
| token.createdAt (obligatoire) | string, date-time | |
| token.expiresAt (obligatoire) | string, date-time |
MyBot
| Champ | Type | Description |
|---|---|---|
| did (obligatoire) | string | |
| handle (obligatoire) | string | null | Le handle `*.bluesky.bot` réservé ; null s’il n’y en a pas. |
| previousHandle (obligatoire) | string | null | Le handle du bot avant qu’il n’en obtienne un ici. |
| displayName (obligatoire) | string | null | |
| avatar (obligatoire) | string | null | |
| verifiedAt (obligatoire) | string | null, date-time | Quand le handle réservé a été confirmé actif sur Bluesky. |
| listed (obligatoire) | boolean | Affiché dans l’annuaire public. |
| status (obligatoire) | string: "active", "suspended" |
MyBotList
| Champ | Type | Description |
|---|---|---|
| bots (obligatoire) | MyBot[] |
ClaimRequest
| Champ | Type | Description |
|---|---|---|
| name (obligatoire) | string | La partie nom, par ex. `weather` pour `weather.bluesky.bot`. |
SwitchOutcome
| Champ | Type | Description |
|---|---|---|
| status (obligatoire) | string: "verified", "pending", "manual" | |
| verifiedAt | string, date-time | |
| reason | string: "reauthorize", "pds_refused", "pds_unreachable" |
ClaimResult
| Champ | Type | Description |
|---|---|---|
| handle (obligatoire) | string | |
| switch (obligatoire) | SwitchOutcome |
SwitchResult
| Champ | Type | Description |
|---|---|---|
| switch (obligatoire) | SwitchOutcome |
ReleaseResult
| Champ | Type | Description |
|---|---|---|
| handle (obligatoire) | string | Le handle libéré. |
| revert (obligatoire) | object | `reverted` : le bot a retrouvé `handle`. `manual` : changez vous-même le handle du bot sur Bluesky ; `reason` indique pourquoi. |
| revert.status (obligatoire) | string: "reverted", "manual" | |
| revert.handle | string | |
| revert.reason | string: "reauthorize", "pds_refused", "pds_unreachable", "no_previous_handle" | |
| revert.previousHandle | string | null |