Clerk provides developer-focused authentication with built-in UI components. This integration uses Clerk’s JWT templates feature for seamless token validation.
Prerequisites
- A Clerk account and application
- Access to your Clerk Dashboard
- Access to the Char dashboard
Quick Links
Clerk Dashboard
Sign in to your Clerk Dashboard
Clerk Docs
Clerk documentation
JWT Templates
JWT Templates documentation
React SDK
Clerk React SDK reference
SDK References
@clerk/clerk-react
React SDK for Clerk
@clerk/nextjs
Next.js SDK for Clerk
@clerk/clerk-js
Vanilla JavaScript SDK
Configuration Steps
1
Create or Select Your Clerk Application
- Sign in to the Clerk Dashboard
- Select your application (or create a new one)
- Note your application instance (Development or Production)
Clerk provides separate Development and Production instances. Use Development for testing and Production for live applications.
2
Create a JWT Template
By default, Clerk session tokens may not include all required claims. Create a JWT template to ensure proper token format:
- Navigate to JWT Templates in the left sidebar
- Click New template
- Select Blank template
- Name it
char-ai(or your preferred name) - Configure the template:
- Click Save
3
Note Your Keys and Issuer
From the Clerk Dashboard:
- Navigate to API Keys
- Copy your Publishable key (starts with
pk_) - Find your Issuer URL in JWT Templates → your template → Issuer
https://{your-frontend-api-domain}For example:- Development:
https://grateful-macaw-1.clerk.accounts.dev - Production:
https://clerk.yourapp.com(or custom domain)

Find your API keys in the Clerk Dashboard
4
Configure Char
In the Char Dashboard:
- Navigate to Settings → Integration
- Under SSO Configuration, select Custom OIDC as the provider
- Enter your configuration:
| Field | Value |
|---|---|
| Client ID | Your Clerk Publishable Key (or configured aud) |
| Issuer URL | Your Clerk Frontend API domain |
- Click Test Connection to verify
- Click Save Changes
Configuration Reference
| Char Field | Clerk Value | Example |
|---|---|---|
| Provider Type | Custom OIDC | custom_oidc |
| Client ID | Publishable Key or configured audience | pk_live_... |
| Issuer URL | Frontend API domain | https://clerk.yourapp.com |
Your Clerk Frontend API domain varies based on your setup:
- Development:
https://{random}.clerk.accounts.dev - Production (default):
https://clerk.{your-domain}.com - Production (custom): Your configured custom domain
Token Requirements
Char validates Clerk tokens with these requirements:| Claim | Requirement |
|---|---|
iss | Must match your Clerk Frontend API domain |
aud | Must include your configured audience (Publishable Key) |
sub | Required - Clerk user ID |
exp | Must not be expired |
azp | Must match your Publishable Key |
Standard Clerk Session Claims
| Claim | Description |
|---|---|
sub | Clerk user ID (e.g., user_2abc...) |
azp | Authorized party (your Publishable Key) |
sid | Session ID |
email | User’s email (if configured in template) |
name | User’s name (if configured in template) |
org_id | Organization ID (if using Organizations) |
org_role | Organization role (if using Organizations) |
Example: Obtaining and Passing the Token
- Clerk React
- Next.js (App Router)
- Next.js (Pages Router)
- Vanilla JavaScript
Using Session Token (Without JWT Template)
If you prefer to use the default session token without a JWT template:Clerk Organizations
If you’re using Clerk Organizations for B2B scenarios:Troubleshooting
INVALID_ISSUER error
INVALID_ISSUER error
The issuer URL doesn’t match:
- Check your Frontend API domain in Clerk Dashboard → API Keys
- Development vs Production: Ensure you’re using the correct environment’s domain
- Custom domains: If using a custom domain, use that as the issuer
- No trailing slash: The issuer URL should not end with
/
INVALID_AUDIENCE error
INVALID_AUDIENCE error
The token’s audience doesn’t match the configured Client ID:
- Verify you’re using a JWT template with the correct
audclaim - If using default tokens, check the
azpclaim value - Ensure the Client ID in Char matches exactly (Publishable Key or custom audience)
getToken returns null
getToken returns null
If
getToken() returns null:- Ensure the user is signed in (
isSignedInis true) - Check that the JWT template name is correct
- Verify the template exists in your Clerk Dashboard
- Check the browser console for Clerk errors
JWKS_FETCH_FAILED error
JWKS_FETCH_FAILED error
Char couldn’t reach Clerk’s JWKS endpoint:
- JWKS endpoint:
{issuer}/.well-known/jwks.json - Verify your Frontend API domain is correct
- Use Test Connection in the Char dashboard
Token doesn't include custom claims
Token doesn't include custom claims
If custom claims aren’t appearing:
- Verify you’re using the correct JWT template name in
getToken({ template: 'name' }) - Check template syntax in Clerk Dashboard
- Ensure the template is enabled
Custom Domains
When using a custom domain with Clerk:- Configure your custom domain in Clerk Dashboard → Domains
- Update your issuer URL in Char to match the custom domain
- Update your application’s Clerk configuration
Security Best Practices
- Use JWT templates to control exactly what claims are included
- Rotate keys periodically using Clerk’s key rotation feature
- Enable MFA for sensitive applications
- Use Organizations for proper B2B access control
- Monitor sign-in activity in Clerk Dashboard
- Configure allowed origins in Clerk Dashboard
- Use Production instance for live applications (separate from Development)

