Skip to content

Authentication

The Excellent Banking API uses Clerk JWT for authentication. All endpoints under /files, /dashboards, /billing, and /usage require a valid Clerk session token in the Authorization header.

Tokens are issued by Clerk when a user signs in through the web app. The frontend obtains a session JWT from Clerk’s client SDK and attaches it to API requests.

If you’re integrating programmatically:

  1. Create an account at app.excellent-banking.com
  2. Use Clerk’s client-side SDK to obtain a session token
  3. Pass it as a Bearer token

Include the token in the Authorization header on every request:

Terminal window
curl -H "Authorization: Bearer eyJhbGciOiJSUzI1NiIs..." \
https://api.excellent-banking.com/files/
import requests
headers = {"Authorization": f"Bearer {clerk_jwt}"}
response = requests.get("https://api.excellent-banking.com/files/", headers=headers)
const response = await fetch("https://api.excellent-banking.com/files/", {
headers: { Authorization: `Bearer ${clerkJwt}` },
});

Not every endpoint requires a user token. Here’s the breakdown:

Endpoint GroupAuth MethodDetails
/files, /dashboards, /usageClerk JWTAuthorization: Bearer <token>
/billing/* (most)Clerk JWTRequired except /billing/plans
/billing/plansNonePublic — list available credit packs
/webhooks/clerkSvix signaturesvix-signature header
/webhooks/stripeStripe signaturestripe-signature header
/webhooks/paypalPayPal auth headerspaypal-auth-algo, paypal-cert-url, etc.
/admin/*API keyX-Admin-Key header
/meClerk JWTAuthorization: Bearer <token>

If you omit the token or provide an invalid one, the API returns:

HTTP/1.1 401 Unauthorized
Content-Type: application/json
{
"detail": "Not authenticated"
}

An expired or malformed token yields the same 401 response.

Clerk JWT tokens have a configurable expiry (typically 1 hour for session tokens). The web app automatically refreshes tokens via Clerk’s SDK. For long-running server-side integrations, use Clerk’s Backend API to generate short-lived tokens rather than hard-coding a user’s JWT.

Once authenticated, the API looks up the local User record by clerk_user_id. If no local record exists, the API still returns 401 — users must sync through the web app first.

The admin endpoint (/admin/credits/adjust) uses a separate authentication mechanism — a static API key set via the ADMIN_API_KEY environment variable on the server:

Terminal window
curl -X POST https://api.excellent-banking.com/admin/credits/adjust \
-H "X-Admin-Key: YOUR_ADMIN_KEY" \
-H "Content-Type: application/json" \
-d '{"user_id": 42, "credits": 100, "reason": "Support ticket #1234"}'

Incorrect or missing admin key returns:

HTTP/1.1 403 Forbidden
{
"detail": "Invalid or missing admin key"
}