raindrop-api

Par mkurman · zorai

npx skills add https://github.com/mkurman/zorai --skill raindrop-api

name: raindrop-api description: > Cette skill fournit des instructions complètes pour interagir avec le service de signets Raindrop.io via son API REST en utilisant curl et jq. Elle couvre l'authentification, les opérations CRUD pour les collections, les raindrops (signets), les tags, les highlights, les filtres, l'import/export et les sauvegardes. Utilisez cette skill chaque fois que l'utilisateur demande de travailler avec ses signets depuis Raindrop.io, incluant la lecture, création, mise à jour, suppression, recherche, ou organisation des signets et collections.

tags: [productivity, agent-skills, raindrop-api, api] --------|--------|----------| | Obtenir un raindrop | GET | /raindrop/{id} | | Créer un raindrop | POST | /raindrop | | Mettre à jour un raindrop | PUT | /raindrop/{id} | | Supprimer un raindrop | DELETE | /raindrop/{id} | | Charger un fichier | PUT | /raindrop/file | | Charger une couverture | PUT | /raindrop/{id}/cover | | Obtenir une copie permanente | GET | /raindrop/{id}/cache | | Suggérer (nouvelle URL) | POST | /raindrop/suggest | | Suggérer (existant) | GET | /raindrop/{id}/suggest |

Docs: https://developer.raindrop.io/v1/raindrops/single

Champs de création/mise à jour de raindrop:

  • link (string, requis pour la création) - URL du signet
  • title (string) - Titre du signet
  • excerpt (string) - Courte description
  • note (string) - Notes de l'utilisateur (supporte Markdown)
  • tags (array of strings) - Noms des tags
  • collection (object) - {"$id": collectionId}
  • type (string) - link, article, image, video, document, audio
  • important (boolean) - Marquer comme favori
  • order (number) - Ordre de tri (croissant)
  • media (array) - Info média/vignette
  • highlights (array) - Highlights de texte
  • cover (string) - URL de l'image de couverture, ou <screenshot> pour capture auto
  • pleaseParse (object) - {} pour déclencher l'analyse des métadonnées en arrière-plan
  • created (string) - Date de création ISO 8601
  • lastUpdate (string) - Date de dernière mise à jour ISO 8601
  • reminder (object) - Paramètres de rappel

Comportement de suppression: Supprimer un raindrop le déplace à la Corbeille (collection ID -99). Supprimer de la Corbeille supprime définitivement.

Opérations Multiple Raindrop

Opération Méthode Endpoint
Obtenir les raindrops GET /raindrops/{collectionId}
Créer plusieurs POST /raindrops
Mettre à jour plusieurs PUT /raindrops/{collectionId}
Supprimer plusieurs DELETE /raindrops/{collectionId}
Exporter GET /raindrops/{collectionId}/export.{format}

Docs: https://developer.raindrop.io/v1/raindrops/multiple

Valeurs collectionId:

  • 0 - Tous les raindrops
  • -1 - Non trié
  • -99 - Corbeille
  • Tout entier positif - Collection spécifique

Paramètres de requête pour GET /raindrops/{collectionId}:

  • sort - Ordre de tri: -created (défaut), created, score, -sort, title, -title, domain, -domain
  • perpage - Résultats par page (max 50)
  • page - Numéro de page (indexé à partir de 0)
  • search - Requête de recherche (voir references/search-operators.md)
  • nested - Booléen, inclure les signets des collections enfants

Champs de mise à jour en masse (PUT avec tableau ids ou requête search):

  • important (boolean)
  • tags (array) - Ajoute des tags; un tableau vide efface tous
  • media (array) - Ajoute; un tableau vide efface
  • cover (string) - URL ou <screenshot>
  • collection (object) - {"$id": collectionId} pour déplacer

Formats d'export: csv, html, zip

Collections

Docs: https://developer.raindrop.io/v1/collections

Opération Méthode Endpoint
Lister les collections racine GET /collections
Lister les collections enfants GET /collections/childrens
Obtenir une collection GET /collection/{id}
Créer une collection POST /collection
Mettre à jour une collection PUT /collection/{id}
Charger une couverture PUT /collection/{id}/cover
Supprimer une collection DELETE /collection/{id}
Supprimer plusieurs DELETE /collections
Réorganiser/dérouler tous PUT /collections
Fusionner les collections PUT /collections/merge
Supprimer les vides PUT /collections/clean
Vider la corbeille DELETE /collection/-99
Compteurs de collection système GET /user/stats
Rechercher couvertures/icônes GET /collections/covers/{text}
Couvertures en vedette GET /collections/covers

Docs: https://developer.raindrop.io/v1/collections/methods

Champs de collection:

  • title (string) - Nom de la collection
  • view (string) - Style d'affichage: list, simple, grid, masonry
  • public (boolean) - Accessibilité publique
  • parent (object) - {"$id": parentCollectionId} pour imbrication
  • sort (number) - Position de tri
  • cover (array) - URLs des images de couverture
  • expanded (boolean) - Si les sous-collections sont déroulées
  • color (string) - Couleur de la collection

Collections système (non supprimables):

  • ID -1 - "Non trié"
  • ID -99 - "Corbeille"

Niveaux d'accès (access.level):

  • 1 - Lecture seule
  • 2 - Collaborateur (écriture)
  • 3 - Collaborateur (écriture + gestion)
  • 4 - Propriétaire

Pour le partage/collaborateurs, voir references/collections-sharing.md.

Tags

Docs: https://developer.raindrop.io/v1/tags

Opération Méthode Endpoint
Obtenir les tags GET /tags/{collectionId}
Renommer un tag PUT /tags/{collectionId}
Fusionner des tags PUT /tags/{collectionId}
Supprimer le(s) tag(s) DELETE /tags/{collectionId}

collectionId: Omis ou utilisez 0 pour les tags de toutes les collections.

Réponse d'obtention des tags:

{
  "result": true,
  "items": [{"_id": "tagname", "count": 42}]
}

Renommer un tag:

curl -s -X PUT \
  -H "Authorization: Bearer $RAINDROP_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"replace": "new-name", "tags": ["old-name"]}' \
  "https://api.raindrop.io/rest/v1/tags/0"

Fusionner des tags (même endpoint, plusieurs tags dans le tableau):

curl -s -X PUT \
  -H "Authorization: Bearer $RAINDROP_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"replace": "merged-name", "tags": ["tag1", "tag2", "tag3"]}' \
  "https://api.raindrop.io/rest/v1/tags/0"

Supprimer des tags:

curl -s -X DELETE \
  -H "Authorization: Bearer $RAINDROP_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"tags": ["tag-to-remove"]}' \
  "https://api.raindrop.io/rest/v1/tags/0"

Highlights

Docs: https://developer.raindrop.io/v1/highlights

Opération Méthode Endpoint
Obtenir tous les highlights GET /highlights
Obtenir les highlights de la collection GET /highlights/{collectionId}
Obtenir les highlights du raindrop GET /raindrop/{id}
Ajouter un highlight PUT /raindrop/{id}
Mettre à jour un highlight PUT /raindrop/{id}
Supprimer un highlight PUT /raindrop/{id}

Pour plus de détails, voir references/highlights.md.

Filtres

Docs: https://developer.raindrop.io/v1/filters

curl -s -H "Authorization: Bearer $RAINDROP_TOKEN" \
  "https://api.raindrop.io/rest/v1/filters/{collectionId}" | jq '.'

Utilisez 0 pour toutes les collections. Retourne les comptages agrégés pour les liens cassés, les doublons, les favoris, les éléments sans tags, les tags et les types de contenu.

Paramètres de requête:

  • tagsSort - -count (défaut) ou _id (alphabétique)
  • search - Filtre de recherche supplémentaire

Utilisateur

Docs: https://developer.raindrop.io/v1/user

Opération Méthode Endpoint
Obtenir l'utilisateur actuel GET /user
Mettre à jour l'utilisateur PUT /user

Import

Docs: https://developer.raindrop.io/v1/import

Opération Méthode Endpoint
Analyser l'URL GET /import/url/parse?url={url}
Vérifier l'existence de l'URL POST /import/url/exists
Analyser le fichier de signets HTML POST /import/file

Sauvegardes

Docs: https://developer.raindrop.io/v1/backups

Opération Méthode Endpoint
Lister les sauvegardes GET /backups
Télécharger une sauvegarde GET /backup/{id}.{format}
Générer une nouvelle sauvegarde GET /backup

Formats: html ou csv

Authentification: Flux OAuth2

Docs: https://developer.raindrop.io/v1/authentication/token

Pour les apps accédant aux données d'autres utilisateurs (pas un usage personnel), utilisez le flux OAuth2 complet:

Étape 1: Autoriser

Dirigez les utilisateurs vers:

https://raindrop.io/oauth/authorize?client_id=YOUR_CLIENT_ID&redirect_uri=YOUR_REDIRECT_URI&response_type=code

Étape 2: Échanger le code pour un token

curl -s -X POST "https://raindrop.io/oauth/access_token" \
  -H "Content-Type: application/json" \
  -d '{
    "code": "AUTH_CODE",
    "client_id": "YOUR_CLIENT_ID",
    "client_secret": "YOUR_CLIENT_SECRET",
    "redirect_uri": "YOUR_REDIRECT_URI",
    "grant_type": "authorization_code"
  }' | jq '.'

Réponse:

{
  "access_token": "...",
  "refresh_token": "...",
  "expires_in": 1209599,
  "token_type": "Bearer"
}

Étape 3: Rafraîchir le token

Les tokens d'accès expirent après deux semaines. Rafraîchissez avec:

curl -s -X POST "https://raindrop.io/oauth/access_token" \
  -H "Content-Type: application/json" \
  -d '{
    "client_id": "YOUR_CLIENT_ID",
    "client_secret": "YOUR_CLIENT_SECRET",
    "refresh_token": "YOUR_REFRESH_TOKEN",
    "grant_type": "refresh_token"
  }' | jq '.'

Gestion des erreurs

Vérifiez les codes de statut HTTP:

  • 200 - Succès
  • 204 - Succès, pas de contenu
  • 400 - Requête invalide
  • 401 - Authentification échouée (vérifiez le token)
  • 403 - Interdit (permissions insuffisantes)
  • 404 - Ressource non trouvée
  • 429 - Limité en débit (120 req/min dépassé)
  • 5xx - Erreur serveur

Exemple avec gestion des erreurs

response=$(curl -s -w "\n%{http_code}" \
  -H "Authorization: Bearer $RAINDROP_TOKEN" \
  "https://api.raindrop.io/rest/v1/raindrops/0")

http_code=$(echo "$response" | tail -1)
body=$(echo "$response" | sed '$d')

if [ "$http_code" -ge 200 ] && [ "$http_code" -lt 300 ]; then
  echo "$body" | jq '.'
else
  echo "Error: HTTP $http_code"
  echo "$body"
fi

Modèles courants

Lister tous les signets dans une collection

curl -s -H "Authorization: Bearer $RAINDROP_TOKEN" \
  "https://api.raindrop.io/rest/v1/raindrops/COLLECTION_ID?perpage=50" | jq '.items[] | {title, link}'

Créer un signet

curl -s -X POST \
  -H "Authorization: Bearer $RAINDROP_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "link": "https://example.com",
    "title": "Example Site",
    "tags": ["reference", "example"],
    "collection": {"$id": COLLECTION_ID},
    "pleaseParse": {}
  }' \
  "https://api.raindrop.io/rest/v1/raindrop" | jq '.'

Rechercher des signets

# Rechercher dans toutes les collections
curl -s -H "Authorization: Bearer $RAINDROP_TOKEN" \
  "https://api.raindrop.io/rest/v1/raindrops/0?search=YOUR_QUERY" | jq '.items[] | {title, link}'

# Rechercher avec filtre de tag
curl -s -H "Authorization: Bearer $RAINDROP_TOKEN" \
  "https://api.raindrop.io/rest/v1/raindrops/0?search=%23tagname" | jq '.items[] | {title, link}'

Voir references/search-operators.md pour la syntaxe complète des requêtes de recherche.

Déplacer un signet vers une collection

curl -s -X PUT \
  -H "Authorization: Bearer $RAINDROP_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"collection": {"$id": TARGET_COLLECTION_ID}}' \
  "https://api.raindrop.io/rest/v1/raindrop/RAINDROP_ID" | jq '.'

Obtenir tous les tags

curl -s -H "Authorization: Bearer $RAINDROP_TOKEN" \
  "https://api.raindrop.io/rest/v1/tags/0" | jq '.items[] | {tag: ._id, count}'

Créer une collection

curl -s -X POST \
  -H "Authorization: Bearer $RAINDROP_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"title": "My Collection", "view": "list"}' \
  "https://api.raindrop.io/rest/v1/collection" | jq '.'

Lister toutes les collections (Racine + Enfants)

# Collections racine
curl -s -H "Authorization: Bearer $RAINDROP_TOKEN" \
  "https://api.raindrop.io/rest/v1/collections" | jq '.items[] | {id: ._id, title}'

# Collections enfants
curl -s -H "Authorization: Bearer $RAINDROP_TOKEN" \
  "https://api.raindrop.io/rest/v1/collections/childrens" | jq '.items[] | {id: ._id, title, parent: .parent."$id"}'

Paginer dans tous les signets

page=0
while true; do
  response=$(curl -s -H "Authorization: Bearer $RAINDROP_TOKEN" \
    "https://api.raindrop.io/rest/v1/raindrops/0?perpage=50&page=$page")

  count=$(echo "$response" | jq '.items | length')
  echo "$response" | jq '.items[] | {title, link}'

  if [ "$count" -lt 50 ]; then
    break
  fi
  page=$((page + 1))
done

Exporter les signets

# Exporter tous les signets en CSV
curl -s -H "Authorization: Bearer $RAINDROP_TOKEN" \
  "https://api.raindrop.io/rest/v1/raindrops/0/export.csv" -o bookmarks.csv

# Exporter en HTML
curl -s -H "Authorization: Bearer $RAINDROP_TOKEN" \
  "https://api.raindrop.io/rest/v1/raindrops/0/export.html" -o bookmarks.html

Vérifier si l'URL est déjà sauvegardée

curl -s -X POST \
  -H "Authorization: Bearer $RAINDROP_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"urls": ["https://example.com"]}' \
  "https://api.raindrop.io/rest/v1/import/url/exists" | jq '.'

Pagination

Raindrop utilise la pagination basée sur les pages (pas sur les curseurs):

  • page - Numéro de page (indexé à partir de 0)
  • perpage - Éléments par page (max 50, défaut 25 pour highlights)

Quand le nombre d'éléments retournés est inférieur à perpage, vous avez atteint la dernière page.

Structure des collections imbriquées

Les collections sont organisées hiérarchiquement. Reconstruire la barre latérale complète nécessite:

  1. GET /user - Retourne un tableau groups avec l'ordre des collections
  2. GET /collections - Collections racine
  3. GET /collections/childrens - Collections imbriquées

L'ordre de tri des collections racine est conservé dans le tableau groups[].collections de l'utilisateur. L'ordre de tri des collections enfants est stocké dans le champ sort de la collection.

Références supplémentaires

Pour la documentation détaillée sur des sujets spécifiques, consultez:

  • references/search-operators.md - Syntaxe et opérateurs des requêtes de recherche
  • references/collections-sharing.md - Partage des collections et collaborateurs
  • references/highlights.md - Gestion des highlights

Résumé du flux de travail

  1. Résoudre le token - Environnement, contexte, ou demander à l'utilisateur
  2. Vérifier l'authentification - Tester avec GET /user
  3. Opérations de lecture - Exécuter directement sans confirmation
  4. Opérations d'écriture - Demander confirmation avant exécution
  5. Gérer la pagination - Boucler avec le numéro de page jusqu'à ce que items < perpage
  6. Analyser les réponses - Utiliser jq pour extraire et formater les données

Skills similaires