clerk-backend-api

Explorateur et exécuteur de l'API REST Backend de Clerk. Parcourez les tags, inspectez les schémas d'endpoint et exécutez des requêtes authentifiées. À utiliser pour lister des utilisateurs, gérer des organisations ou appeler n'importe quel endpoint de l'API Clerk.

npx skills add https://github.com/clerk/skills --skill clerk-backend-api

Contexte des options

Prompt utilisateur : $ARGUMENTS

CRITIQUE : Vérifications obligatoires avant CHAQUE demande d'écriture

Avant TOUT POST / PATCH / PUT / DELETE, tu DOIS faire TOUS les points suivants dans ta réponse :

  1. Vérifier CLERK_SECRET_KEY — s'assurer qu'elle est définie :

    echo $CLERK_SECRET_KEY | head -c 10

    Si vide, arrête et demande à l'utilisateur. Ne procède pas sans une clé valide.

  2. Vérifier CLERK_BAPI_SCOPES — exécute :

    echo $CLERK_BAPI_SCOPES

    Inspecte la sortie. Si les scopes manquent ou n'incluent pas la permission d'écriture requise, dis à l'utilisateur : « Ceci est une opération d'écriture et tes scopes actuels pourraient ne pas l'autoriser. Relance avec --admin pour contourner ? » Ne TENTE PAS la requête et n'échoue pas — demande d'abord.

  3. Pour les requêtes DELETE : avertis explicitement que l'action est IRRÉVERSIBLE et énumère exactement quelles données seront définitivement détruites (enregistrement utilisateur, toutes les sessions, tous les abonnements, toutes les données associées). Exige une confirmation explicite avant de procéder. Cet avertissement est OBLIGATOIRE — ne le saute jamais.

  4. Pour les opérations de métadonnées : explique toujours quel type de métadonnées est utilisé et pourquoi (voir section Types de métadonnées ci-dessous).


CHEMIN RAPIDE : Opérations courantes (utilise directement, pas besoin de récupérer la spec)

Pour les opérations ci-dessous, saute la récupération de spec et exécute immédiatement en utilisant ces modèles exacts. Substitue $CLERK_SECRET_KEY, $USER_ID, $ORG_ID, $EMAIL selon le contexte de l'utilisateur.

Créer une organisation + inviter un membre (deux étapes)

# Étape 1 — Créer l'organisation
ORG=$(curl -s -X POST "https://api.clerk.com/v1/organizations" \
  -H "Authorization: Bearer $CLERK_SECRET_KEY" \
  -H "Content-Type: application/json" \
  -d "{\"name\": \"Acme Corp\", \"created_by\": \"$USER_ID\"}")
echo "$ORG" | python3 -c "import sys,json; d=json.load(sys.stdin); print(json.dumps(d, indent=2))"

# Étape 2 — Extraire l'ID org
ORG_ID=$(echo "$ORG" | python3 -c "import sys,json; print(json.load(sys.stdin)['id'])")

# Étape 3 — Inviter un membre avec rôle
curl -s -X POST "https://api.clerk.com/v1/organizations/${ORG_ID}/invitations" \
  -H "Authorization: Bearer $CLERK_SECRET_KEY" \
  -H "Content-Type: application/json" \
  -d "{\"email_address\": \"user@example.com\", \"role\": \"org:admin\"}" \
  | python3 -c "import sys,json; print(json.dumps(json.load(sys.stdin), indent=2))"

Rôles : utilise "org:admin" ou "org:member" (toujours préfixe avec org:).

Équivalent SDK (pour projets Next.js / TypeScript avec @clerk/nextjs ou @clerk/backend)

import { clerkClient } from '@clerk/nextjs/server'
// OU si tu utilises @clerk/backend directement :
// import { createClerkClient } from '@clerk/backend'
// const clerkClient = createClerkClient({ secretKey: process.env.CLERK_SECRET_KEY })

// Étape 1 : Créer l'organisation
const org = await clerkClient.organizations.createOrganization({
  name: 'Acme Corp',
  createdBy: userId,  // requis — l'ID de l'utilisateur créant l'org
})

// Étape 2 : Inviter un membre à l'org
const invitation = await clerkClient.organizations.createOrganizationInvitation({
  organizationId: org.id,
  emailAddress: 'user@example.com',
  role: 'org:admin',  // ou 'org:member'
})

Mettre à jour les métadonnées utilisateur

Explique toujours les trois types de métadonnées avant de demander lequel utiliser :

Type Champ Lisible par Modifiable par Utiliser pour
Public public_metadata Client + Serveur Serveur uniquement Tier plan, rôles, flags de fonctionnalités que le frontend lit
Privé private_metadata Serveur uniquement Serveur uniquement IDs Stripe, flags de conformité, identifiants internes
Unsafe unsafe_metadata Client + Serveur Client + Serveur État UI éphémère, étapes d'onboarding (modifiable client — évite les données sensibles)

Pour plan: 'pro' et onboarded: true — utilise public_metadata (lisible par le frontend, modifiable par le serveur) :

curl -s -X PATCH "https://api.clerk.com/v1/users/${USER_ID}" \
  -H "Authorization: Bearer $CLERK_SECRET_KEY" \
  -H "Content-Type: application/json" \
  -d '{"public_metadata": {"plan": "pro", "onboarded": true}}' \
  | python3 -c "import sys,json; d=json.load(sys.stdin); print(f'Updated user {d[\"id\"]}: public_metadata={d.get(\"public_metadata\")}')"

Équivalent SDK :

import { clerkClient } from '@clerk/nextjs/server'
// OU : import { createClerkClient } from '@clerk/backend'

await clerkClient.users.updateUser(userId, {
  publicMetadata: { plan: 'pro', onboarded: true },   // lisible par le client, modifiable serveur uniquement
  // privateMetadata: { stripeId: 'cus_xxx' },         // lecture ET écriture serveur uniquement
  // unsafeMetadata: { step: 'welcome' },              // modifiable client, évite les données sensibles
})

Remarque : L'API REST utilise snake_case (public_metadata). Le SDK utilise camelCase (publicMetadata).

Lister les utilisateurs (7 derniers jours)

curl -s "https://api.clerk.com/v1/users?limit=100&offset=0&order_by=-created_at&created_at=gt:$(date -d '7 days ago' +%s 2>/dev/null || date -v-7d +%s)000" \
  -H "Authorization: Bearer $CLERK_SECRET_KEY" \
  | python3 -c "
import sys, json
data = json.load(sys.stdin)
if isinstance(data, list):
    print(f'Found {len(data)} users:')
    for u in data:
        print(f'  {u[\"id\"]}: {u.get(\"email_addresses\", [{}])[0].get(\"email_address\", \"no email\")}')
else:
    print(json.dumps(data, indent=2))
"

Supprimer un utilisateur (confirmation requise)

# SEULEMENT après confirmation explicite de l'utilisateur
curl -s -X DELETE "https://api.clerk.com/v1/users/${USER_ID}" \
  -H "Authorization: Bearer $CLERK_SECRET_KEY" \
  | python3 -c "import sys,json; d=json.load(sys.stdin); print(f'Deleted: {d}')"

API Clerk Backend — Référence complète des endpoints

URL de base : https://api.clerk.com/v1 Auth : Authorization: Bearer $CLERK_SECRET_KEY sur chaque requête.

Utilisateurs

Lister les utilisateurs

GET /v1/users
Paramètres de requête : limit (max 500, défaut 10), offset, order_by (+/-created_at, +/-updated_at, +/-email_address, +/-web3wallet, +/-first_name, +/-last_name, +/-phone_number, +/-username, +/-last_active_at, +/-last_sign_in_at), email_address[], phone_number[], username[], web3wallet[], user_id[], query, created_at (plage ISO 8601 : gt:TIMESTAMP ou lt:TIMESTAMP en Unix ms)
Retour : tableau d'objets User

Obtenir un utilisateur

GET /v1/users/{user_id}
Retour : objet User

Mettre à jour un utilisateur

PATCH /v1/users/{user_id}
Corps (JSON, snake_case) : { public_metadata, private_metadata, unsafe_metadata, first_name, last_name, username, ... }

Supprimer un utilisateur — IRRÉVERSIBLE

DELETE /v1/users/{user_id}
Détruit : enregistrement utilisateur, toutes les sessions, tous les abonnements, toutes les données associées
Retour : { id, object, deleted: true }

Avertis toujours l'utilisateur que c'est permanent et confirme avant de procéder.

Organisations

Créer une organisation

POST /v1/organizations
Corps : { name: string, created_by: string (user_id), public_metadata?, private_metadata?, max_allowed_memberships? }
Retour : objet Organization avec { id, name, slug, ... }

Lister les organisations

GET /v1/organizations
Paramètres de requête : limit, offset, query, order_by

Inviter un membre

POST /v1/organizations/{organization_id}/invitations
Corps : { email_address: string, role: string ("org:admin" ou "org:member"), public_metadata?, private_metadata? }
Retour : objet OrganizationInvitation

Comment exécuter les requêtes

EXÉCUTE TOUJOURS les requêtes avec des commandes curl directes. Utilise les scripts d'extraction de spec (api-specs-context.sh, extract-tags.js, extract-endpoint-detail.sh) pour découvrir les endpoints, mais fais les appels API réels avec curl. N'utilise PAS scripts/execute-request.sh — c'est un helper de dev local, pas pour usage agent.

Modèle pour requêtes GET :

curl -s "https://api.clerk.com/v1${PATH}${QUERY_STRING}" \
  -H "Authorization: Bearer $CLERK_SECRET_KEY"

Modèle pour requêtes POST/PATCH :

curl -s -X ${METHOD} "https://api.clerk.com/v1${PATH}" \
  -H "Authorization: Bearer $CLERK_SECRET_KEY" \
  -H "Content-Type: application/json" \
  -d '${BODY_JSON}'

Modèle pour requêtes DELETE :

curl -s -X DELETE "https://api.clerk.com/v1${PATH}" \
  -H "Authorization: Bearer $CLERK_SECRET_KEY"

Après avoir reçu la réponse : Analyse et affiche-la clairement. Utilise python3 -c "import sys,json; data=json.load(sys.stdin); print(json.dumps(data, indent=2))" pour formater le JSON en joli. Extrais les champs clés (id, email, name, etc.) et résume-les pour l'utilisateur.


Contexte des specs API

Avant de faire quoi que ce soit en dehors du CHEMIN RAPIDE, récupère les versions de spec disponibles et les tags en exécutant :

bash scripts/api-specs-context.sh

Utilise la sortie pour déterminer la dernière version et les tags disponibles.

Cache : Si tu as déjà récupéré le contexte de spec plus tôt dans cette conversation, ne le récupère PAS à nouveau. Réutilise la version et les tags de l'appel précédent.


Règles

  • Pour les opérations courantes (lister les utilisateurs, créer une org, inviter, mettre à jour les métadonnées, supprimer un utilisateur) : utilise le CHEMIN RAPIDE ci-dessus — ne récupère PAS les specs d'abord.
  • Oublie toujours les endpoints/schémas liés à platform.
  • Confirme toujours avant d'effectuer des requêtes d'écriture (POST/PUT/PATCH/DELETE).
  • Pour les opérations DELETE, avertis toujours l'utilisateur que l'action est irréversible et mentionne quelles données seront perdues (enregistrement utilisateur, sessions, abonnements). Cet avertissement est OBLIGATOIRE — ne le saute jamais.
  • Pour les opérations d'écriture (POST/PUT/PATCH/DELETE), vérifie CLERK_BAPI_SCOPES avant de tenter la requête. Si manquant ou insuffisant, demande à l'utilisateur en amont. Ne TENTE PAS et n'échoue pas — demande avant d'exécuter. Cette vérification est OBLIGATOIRE.
  • Pour les opérations de métadonnées, explique toujours les trois types (public, privé, unsafe) et recommande celui approprié.
  • Pagination : utilise toujours limit + offset et mentionne que les résultats peuvent être paginés pour les grands ensembles de données.
  • Utilise des commandes curl directes pour tous les appels API — n'utilise jamais scripts/execute-request.sh.

Limites de débit & Pièges

Limites de débit

Environnement Limite
Production 1 000 requêtes / 10 secondes
Développement 100 requêtes / 10 secondes
Invitations simples 100 / heure
Invitations en masse 25 / heure
Invitations org 250 / heure
Création de connexion Frontend API 5 / 10 secondes
Tentatives de connexion Frontend API 3 / 10 secondes
Max d'utilisateurs listés par page 500

currentUser() effectue un véritable appel API qui compte contre les limites de débit. Utilise auth() pour seulement les revendications de session — cela lit le token sans appel API.

Écrasements de métadonnées (pas de fusion)

updateUser({ publicMetadata: { role: 'admin' } }) REMPLACE toutes les métadonnées publiques, ne fusionne pas. Pour ajouter un champ sans perdre les données existantes : lis d'abord, fais un spread, puis écris.

Mauvais :

await clerkClient.users.updateUser(userId, { publicMetadata: { newField: 'value' } })

Ceci SUPPRIME tous les autres champs publicMetadata.

Bon :

const user = await clerkClient.users.getUser(userId)
await clerkClient.users.updateUser(userId, {
  publicMetadata: { ...user.publicMetadata, newField: 'value' },
})

Modes

Détermine le mode actif en fonction du prompt utilisateur dans Contexte des options :

Mode Déclencheur Comportement
help Le prompt est vide, ou contient seulement help / -h / --help Affiche des exemples d'usage (étape 0)
browse Le prompt est tags, ou un nom de tag (par ex. Users) Liste tous les tags ou endpoints pour un tag
execute Endpoint spécifique (par ex. GET /users) ou action en langage naturel (par ex. "obtenir l'utilisateur john_doe") Cherche l'endpoint, exécute la requête
detail Endpoint + help / -h / --help (par ex. GET /users help) Affiche le schéma de l'endpoint, n'exécute pas

Ta tâche

Utilise la DERNIÈRE VERSION de Contexte des specs API par défaut. Si l'utilisateur spécifie une version différente (par ex. --version 2024-10-01), utilise cette version à la place.

Détermine le mode actif, puis suis les étapes applicables ci-dessous.


0. Afficher l'usage

Modes : help uniquement — Saute pour browse, execute, et detail.

Affiche les exemples suivants à l'utilisateur textuellement :

Browse
  /clerk-backend-api tags                         — lister tous les tags
  /clerk-backend-api Users                        — parcourir les endpoints du tag Users
  /clerk-backend-api Users version 2025-11-10.yml — parcourir en utilisant une version différente

Execute
  /clerk-backend-api GET /users             — récupérer tous les utilisateurs
  /clerk-backend-api get user john_doe      — le langage naturel fonctionne aussi
  /clerk-backend-api POST /invitations      — créer une invitation

Inspect
  /clerk-backend-api GET /users help        — afficher le schéma de l'endpoint sans exécuter
  /clerk-backend-api POST /invitations -h   — voir les détails de requête/réponse

Options
  --admin                            — contourner les restrictions de scope pour écriture/suppression
  --version [date], version [date]   — utiliser une version de spec spécifique
  --help, -h, help                   — inspecter l'endpoint au lieu d'exécuter

Arrête ici.


1. Récupérer les tags

Modes : browse (quand le prompt est tags ou aucun tag spécifié) — Saute pour help, execute, et detail.

Si tu utilises une version non-latest, récupère les tags pour cette version :

curl -s https://raw.githubusercontent.com/clerk/openapi-specs/main/bapi/${version_name} | node scripts/extract-tags.js

Sinon, utilise les TAGS déjà dans Contexte des specs API.

Partage les tags dans un tableau et invite l'utilisateur à sélectionner une requête.


2. Récupérer les endpoints du tag

Modes : browse (quand un nom de tag est fourni) — Saute pour help, execute, et detail.

Récupère tous les endpoints pour le tag identifié :

curl -s https://raw.githubusercontent.com/clerk/openapi-specs/main/bapi/${version_name} | bash scripts/extract-tag-endpoints.sh "${tag_name}"

Partage les résultats (endpoints, schémas, paramètres) avec l'utilisateur.


3. Récupérer le détail de l'endpoint

Modes : execute, detailSaute pour help et browse.

Pour les prompts en langage naturel en mode execute, vérifie d'abord si l'opération correspond à une entrée du CHEMIN RAPIDE ci-dessus. Si c'est le cas, saute cette étape et procède directement à l'étape 4 en utilisant le modèle du CHEMIN RAPIDE.

Pour les autres endpoints, identifie l'endpoint correspondant en cherchant les tags en contexte. Récupère les endpoints du tag si nécessaire pour résoudre le chemin exact et la méthode.

Extrais la définition complète de l'endpoint :

curl -s https://raw.githubusercontent.com/clerk/openapi-specs/main/bapi/${version_name} | bash scripts/extract-endpoint-detail.sh "${path}" "${method}"
  • ${path} — par ex. /users/{user_id}
  • ${method} — minuscules, par ex. get

Mode detail : Partage la définition de l'endpoint et les schémas avec l'utilisateur. Arrête ici.

Mode execute : Continue à l'étape 4.


4. Exécuter la requête

Modes : execute uniquement.

  1. Exécute les vérifications obligatoires de la section CRITIQUE ci-dessus.
  2. Identifie les paramètres obligatoires et optionnels du spec (étape 3) ou du CHEMIN RAPIDE.
  3. Demande à l'utilisateur les paramètres de chemin/requête/corps obligatoires qui n'ont pas été fournis.
  4. Construis et exécute une commande curl directe (voir Comment exécuter les requêtes ci-dessus). N'utilise PAS scripts/execute-request.sh.
  5. Analyse la réponse JSON et affiche-la clairement. Extrais et résume les champs clés pour l'utilisateur.

Exemple — lister les utilisateurs et analyser la réponse :

RESPONSE=$(curl -s "https://api.clerk.com/v1/users?limit=10" \
  -H "Authorization: Bearer $CLERK_SECRET_KEY")
echo "$RESPONSE" | python3 -c "
import sys, json
data = json.load(sys.stdin)
if isinstance(data, list):
    print(f'Found {len(data)} users:')
    for u in data:
        print(f'  {u[\"id\"]}: {u.get(\"email_addresses\", [{}])[0].get(\"email_address\", \"no email\")}')
else:
    print(json.dumps(data, indent=2))
"

Voir aussi

  • clerk-setup - Installation initiale de Clerk
  • clerk-orgs - Gérer les organisations via API
  • clerk-webhooks - Synchronisation d'événements en temps réel

Skills similaires