Clerk Integration
Use Clerk as your identity provider with AINative Studio. This guide walks through connecting your Clerk application so your users can authenticate with Clerk JWTs and access AINative APIs, ZeroDB, and ZeroMemory. Clerk includes built-in user management, so you get sign-up, sign-in, and profile management out of the box.
Prerequisites
- A Clerk account with an application
- An AINative Studio account with a project and API key
- Your AINative project ID (found in the dashboard under Settings)
Step 1: Create an Application in Clerk
- Log in to the Clerk Dashboard
- Click Create application (or select an existing one)
- Choose your sign-in methods:
- Email address
- Google, GitHub, or other social providers
- Phone number
- Note your credentials under API Keys:
- Publishable Key (e.g.
pk_live_abc...orpk_test_abc...) - Secret Key (e.g.
sk_live_abc...orsk_test_abc...)
- Publishable Key (e.g.
Your Clerk domain follows the pattern {app}.clerk.accounts.dev.
Step 2: Configure Allowed Origins
In the Clerk Dashboard under Paths > Allowed origins:
| Field | Value |
|---|---|
| Production origins | https://your-app.com |
| Development origins | http://localhost:3000 |
Clerk supports standard OIDC discovery at https://{app}.clerk.accounts.dev/.well-known/openid-configuration.
JWT Templates (Optional)
To customize the claims included in your JWT, go to JWT Templates in the Clerk Dashboard:
- Click New template
- Choose Blank or start from a preset
- Add custom claims your application needs (e.g.
org_id,role) - Note the template name -- you will use it when requesting tokens
Step 3: Register Clerk as an Identity Provider in AINative
Call the AINative API to register your Clerk application as a trusted identity provider:
curl -X POST https://api.ainative.studio/api/v1/auth/providers \
-H "Authorization: Bearer YOUR_AINATIVE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"provider": "clerk",
"domain": "YOUR_APP.clerk.accounts.dev",
"client_id": "YOUR_CLERK_PUBLISHABLE_KEY",
"jwks_uri": "https://YOUR_APP.clerk.accounts.dev/.well-known/jwks.json",
"issuer": "https://YOUR_APP.clerk.accounts.dev",
"claim_mapping": {
"user_id": "sub",
"email": "email"
}
}'
Claim Mapping
Clerk JWTs include these claims that AINative maps automatically:
| Clerk Claim | AINative Field | Description |
|---|---|---|
sub | user_id | Unique user identifier (e.g. user_2abc123) |
email | email | User primary email address |
If you use Clerk Organizations, you can add org_id to your JWT template and map it to AINative's tenant field for multi-tenant isolation.
Step 4: Test the Connection
Obtain a test token from Clerk and verify it works with AINative.
Using the Clerk Backend API
# Get a session token via Clerk Backend API
# First, create a test user session through the Clerk Dashboard or SDK
# Then retrieve the session token:
TOKEN=$(curl -s https://api.clerk.com/v1/sessions/SESSION_ID/tokens \
-H "Authorization: Bearer YOUR_CLERK_SECRET_KEY" | jq -r '.jwt')
# Verify against AINative
curl -s https://api.ainative.studio/api/v1/auth/verify \
-H "Authorization: Bearer $TOKEN"
Using the Clerk Frontend SDK (React)
import { useAuth } from '@clerk/clerk-react';
function MyComponent() {
const { getToken } = useAuth();
async function callAINative() {
const token = await getToken();
const response = await fetch(
'https://api.ainative.studio/api/v1/auth/verify',
{ headers: { Authorization: `Bearer ${token}` } }
);
const data = await response.json();
console.log(data);
}
return <button onClick={callAINative}>Verify Token</button>;
}
A successful response returns:
{
"valid": true,
"provider": "clerk",
"user_id": "user_2abc123",
"email": "user@example.com"
}
Step 5: Use Clerk JWTs with AINative APIs
Once the provider is registered, your users can authenticate with their Clerk tokens across all AINative services.
Chat Completions
curl -X POST https://api.ainative.studio/api/v1/chat/completions \
-H "Authorization: Bearer CLERK_USER_JWT" \
-H "Content-Type: application/json" \
-d '{
"model": "llama-3.3-70b",
"messages": [
{"role": "user", "content": "Hello from Clerk!"}
]
}'
ZeroDB Vector Search
curl -X POST https://api.ainative.studio/api/v1/zerodb/vectors/search \
-H "Authorization: Bearer CLERK_USER_JWT" \
-H "X-Project-ID: YOUR_PROJECT_ID" \
-H "Content-Type: application/json" \
-d '{
"query": "user authentication patterns",
"top_k": 5
}'
ZeroMemory Store
curl -X POST https://api.ainative.studio/api/v1/public/memory/v2/remember \
-H "Authorization: Bearer CLERK_USER_JWT" \
-H "Content-Type: application/json" \
-d '{
"content": "User signed up via Google OAuth",
"entity_name": "user_events"
}'
Using Clerk React SDK with AINative
import { useAuth } from '@clerk/clerk-react';
function AIChatComponent() {
const { getToken } = useAuth();
const [response, setResponse] = useState('');
async function sendMessage(message: string) {
const token = await getToken();
const res = await fetch(
'https://api.ainative.studio/api/v1/chat/completions',
{
method: 'POST',
headers: {
Authorization: `Bearer ${token}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
model: 'llama-3.3-70b',
messages: [{ role: 'user', content: message }],
}),
}
);
const data = await res.json();
setResponse(data.choices[0].message.content);
}
return (
<div>
<button onClick={() => sendMessage('Hello!')}>Send</button>
<p>{response}</p>
</div>
);
}
Step 6: Enable Row-Level Security for ZeroDB (Optional)
Row-Level Security (RLS) ensures that each user can only access their own data in ZeroDB. When enabled, the user_id claim from the Clerk JWT is automatically applied as a filter on all queries.
curl -X POST https://api.ainative.studio/api/v1/zerodb/projects/YOUR_PROJECT_ID/rls \
-H "Authorization: Bearer YOUR_AINATIVE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"enabled": true,
"user_id_claim": "sub",
"policy": "strict"
}'
With RLS enabled:
- Vectors: Automatically filtered by the
user_idextracted from the JWTsubclaim - Tables: Row-level filtering applied on reads and writes
- Files: Users can only access files they uploaded
- Memory: Each user gets isolated memory namespaces
Clerk User Management
Clerk provides built-in user management components. You can use these alongside AINative to manage your users without building custom UI:
<SignIn />-- Pre-built sign-in form<SignUp />-- Pre-built sign-up form<UserButton />-- User avatar with profile/sign-out menu<UserProfile />-- Full profile management page<OrganizationSwitcher />-- Multi-tenant organization picker
These components handle authentication and return JWTs that work directly with AINative APIs.
Troubleshooting
| Issue | Cause | Fix |
|---|---|---|
401 Unauthorized | Token expired or publishable key mismatch | Verify the domain and publishable key match your Clerk app |
403 Forbidden | RLS blocking access | Check that the sub claim in the JWT matches the data owner |
invalid_token error | JWKS URI unreachable | Confirm your Clerk domain is correct (check for typos in clerk.accounts.dev) |
Missing email claim | Email not in default JWT | Create a JWT template in Clerk that includes the email claim |
getToken() returns null | User not signed in | Wrap your component in <SignedIn> or check isSignedIn first |
Next Steps
- ZeroMemory Guide -- Add persistent memory to your Clerk-authenticated agents
- API Reference -- Full API documentation
- SDK Quick Start -- Client SDKs for React, Next.js, Vue, Svelte, and Python