Skill detail

clerk-backend-api

Explores and executes the Clerk Backend REST API for listing users, managing organizations, and calling authenticated endpoints with safety checks.

Why we recommend it: Clerk backend API for user/org management is adjacent to the Auth facet but vendor-specific.

MatchPossibleRecommended for Backend Developer
Sourceclerk/​skillsExternal source
Reported installs49,680Popularity signal only

Inspect before use

Read the source instructions and check the requirements before you install this skill.

Saved source preview

SKILL.md

The saved excerpt is a snapshot from when this skill was listed. The external source remains the complete and most current version.

---
name: clerk-backend-api
description: "Clerk Backend REST API explorer and executor. Browse tags, inspect endpoint schemas, and execute authenticated requests. Use when listing users, managing organizations, or calling any Clerk API endpoint."
allowed-tools: Bash, Read, Grep, Skill, WebFetch
license: MIT
compatibility: Requires CLERK_SECRET_KEY (sk_*) for Backend API calls.
---

## Options context

User Prompt: $ARGUMENTS

## CRITICAL: Mandatory checks before EVERY write request

Before ANY POST / PATCH / PUT / DELETE, you MUST do ALL of the following in your response:

1. **Check CLERK_SECRET_KEY** — verify it is set:
   ```bash
   echo $CLERK_SECRET_KEY | head -c 10
   ```
   If empty, stop and ask the user. Do not proceed without a valid key.

2. **Check CLERK_BAPI_SCOPES** — run:
   ```bash
   echo $CLERK_BAPI_SCOPES
   ```
   Inspect the output. If scopes are missing or do not include the required write permission, tell the user: *"This is a write operation and your current scopes may not allow it. Rerun with --admin to bypass?"* Do NOT attempt the request and fail — ask first.

3. **For DELETE requests:** warn explicitly that the action is **IRREVERSIBLE** and list exactly what data will be permanently destroyed (user record, all sessions, all memberships, all associated data). Require explicit confirmation before proceeding. This warning is MANDATORY — never skip it.

4. **For metadata operations:** always explain which metadata type is being used and why (see Metadata types section below).

---

## FAST PATH: Common operations (use directly, no spec fetching needed)

For the operations below, skip spec fetching and execute immediately using these exact templates. Substitute `$CLERK_SECRET_KEY`, `$USER_ID`, `$ORG_ID`, `$EMAIL` as needed from the user's context.

### Create organization + invite member (two-step)

```bash
# Step 1 — Create organization
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))"

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

# Step 3 — Invite member with role
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\": \"[email protected]\", \"role\": \"org:admin\"}" \
  | python3 -c "import sys,json; print(json.dumps(json.load(sys.stdin), indent=2))"
```

**Roles:** use `"org:admin"` or `"org:member"` (always prefix with `org:`).

### SDK equivalent (for Next.js / TypeScript projects with `@clerk/nextjs` or `@clerk/backend`)

```typescript
import { clerkClient } from '@clerk/nextjs/server'
// OR if using @clerk/backend directly:
// import { createClerkClient } from '@clerk/backend'
// const clerkClient = createClerkClient({ secretKey: process.env.CLERK_SECRET_KEY })

// Step 1: Create organization
const org = await clerkClient.organizations.createOrganization({
  name: 'Acme Corp',
  createdBy: userId,  // required — the ID of the user creating the org
})

// Step 2: Invite member to the org
const invitation = await clerkClient.organizations.createOrganizationInvitation({
  organizationId: org.id,
  emailAddress: '[email protected]',
  role: 'org:admin',  // or 'org:member'
})
```

### Update user metadata

**Always explain the three metadata types before asking which to use:**

| Type | Field | Readable by | Writable by | Use for |
|------|-------|-------------|-------------|---------|
| Public | `public_metadata` | Client + Server | **Server only** | Plan tier, roles, feature flags the frontend reads |
| Private | `private_metadata` | **Server only** | **Server only** | Stripe IDs, compliance flags, internal identifiers |
| Unsafe |
Read the full source on GitHub (opens external page)
Context

Related work