Stytch Integration
Use Stytch as your identity provider with AINative Studio. This guide walks through connecting your Stytch project so your users can authenticate with Stytch JWTs and access AINative APIs, ZeroDB, and ZeroMemory. Stytch also supports passwordless authentication via magic links.
Prerequisites
- A Stytch account with a project
- An AINative Studio account with a project and API key
- Your AINative project ID (found in the dashboard under Settings)
Step 1: Create a Project in Stytch
- Log in to the Stytch Dashboard
- Create a new project or select an existing one
- Navigate to API Keys and note your:
- Project ID (e.g.
project-live-abc123-def456) - Secret (e.g.
secret-live-...) - Public Token (for client-side SDKs)
- Project ID (e.g.
- Choose your authentication methods under Authentication:
- Email magic links (passwordless)
- OAuth (Google, GitHub, etc.)
- Passwords
- One-time passcodes (OTP)
Step 2: Configure Redirect URLs
In the Stytch Dashboard under Redirect URLs:
| Field | Value |
|---|---|
| Login redirect URL | https://your-app.com/authenticate |
| Signup redirect URL | https://your-app.com/authenticate |
| Development URLs | http://localhost:3000/authenticate |
Add your application domains under SDK Configuration > Authorized domains.
Step 3: Register Stytch as an Identity Provider in AINative
Call the AINative API to register your Stytch project 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": "stytch",
"domain": "stytch.com",
"client_id": "YOUR_STYTCH_PROJECT_ID",
"jwks_uri": "https://stytch.com/v1/sessions/jwks/YOUR_STYTCH_PROJECT_ID",
"issuer": "stytch.com/YOUR_STYTCH_PROJECT_ID",
"claim_mapping": {
"user_id": "sub",
"email": "emails"
}
}'
Claim Mapping
Stytch JWTs include these claims that AINative maps automatically:
| Stytch Claim | AINative Field | Description |
|---|---|---|
sub | user_id | Unique user identifier (e.g. user-live-abc123) |
https://stytch.com/session | -- | Session metadata (session ID, started/last accessed timestamps) |
Stytch stores emails as an array in the session. AINative extracts the primary email from the emails array in the authenticated session response.
Step 4: Test the Connection
Obtain a test token from Stytch and verify it works with AINative:
# Authenticate a magic link token (after user clicks email link)
RESPONSE=$(curl -s -X POST https://api.stytch.com/v1/magic_links/authenticate \
-u "YOUR_STYTCH_PROJECT_ID:YOUR_STYTCH_SECRET" \
-H "Content-Type: application/json" \
-d '{
"token": "MAGIC_LINK_TOKEN_FROM_EMAIL",
"session_duration_minutes": 60
}')
TOKEN=$(echo $RESPONSE | jq -r '.session_jwt')
# Verify against AINative
curl -s https://api.ainative.studio/api/v1/auth/verify \
-H "Authorization: Bearer $TOKEN"
A successful response returns:
{
"valid": true,
"provider": "stytch",
"user_id": "user-live-abc123",
"email": "user@example.com"
}
Step 5: Use Stytch JWTs with AINative APIs
Once the provider is registered, your users can authenticate with their Stytch session JWTs across all AINative services.
Chat Completions
curl -X POST https://api.ainative.studio/api/v1/chat/completions \
-H "Authorization: Bearer STYTCH_SESSION_JWT" \
-H "Content-Type: application/json" \
-d '{
"model": "llama-3.3-70b",
"messages": [
{"role": "user", "content": "Hello from Stytch!"}
]
}'
ZeroDB Vector Search
curl -X POST https://api.ainative.studio/api/v1/zerodb/vectors/search \
-H "Authorization: Bearer STYTCH_SESSION_JWT" \
-H "X-Project-ID: YOUR_PROJECT_ID" \
-H "Content-Type: application/json" \
-d '{
"query": "passwordless authentication",
"top_k": 5
}'
ZeroMemory Store
curl -X POST https://api.ainative.studio/api/v1/public/memory/v2/remember \
-H "Authorization: Bearer STYTCH_SESSION_JWT" \
-H "Content-Type: application/json" \
-d '{
"content": "User authenticated via magic link",
"entity_name": "user_events"
}'
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 Stytch 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
Magic Links (Passwordless)
Stytch's magic links provide passwordless authentication. Here is a typical flow with AINative:
1. Send a Magic Link
curl -X POST https://api.stytch.com/v1/magic_links/email/send \
-u "YOUR_STYTCH_PROJECT_ID:YOUR_STYTCH_SECRET" \
-H "Content-Type: application/json" \
-d '{
"email": "user@example.com",
"login_magic_link_url": "https://your-app.com/authenticate",
"signup_magic_link_url": "https://your-app.com/authenticate"
}'
2. Authenticate the Token
When the user clicks the link, they are redirected to your app with a token parameter:
RESPONSE=$(curl -s -X POST https://api.stytch.com/v1/magic_links/authenticate \
-u "YOUR_STYTCH_PROJECT_ID:YOUR_STYTCH_SECRET" \
-H "Content-Type: application/json" \
-d '{
"token": "TOKEN_FROM_URL",
"session_duration_minutes": 60
}')
SESSION_JWT=$(echo $RESPONSE | jq -r '.session_jwt')
3. Use the Session JWT with AINative
curl -X POST https://api.ainative.studio/api/v1/chat/completions \
-H "Authorization: Bearer $SESSION_JWT" \
-H "Content-Type: application/json" \
-d '{
"model": "llama-3.3-70b",
"messages": [
{"role": "user", "content": "Authenticated via magic link!"}
]
}'
Troubleshooting
| Issue | Cause | Fix |
|---|---|---|
401 Unauthorized | Session JWT expired | Request a new session or refresh the existing one |
403 Forbidden | RLS blocking access | Check that the sub claim in the JWT matches the data owner |
invalid_token error | JWKS URI unreachable or project ID wrong | Confirm the JWKS URL contains the correct Stytch project ID |
| Missing email | Email not in session claims | Stytch stores emails in the session response, not always in the JWT -- fetch from the /v1/sessions/authenticate endpoint |
| Magic link expired | Token older than 10 minutes | Magic link tokens expire after 10 minutes by default -- send a new one |
Next Steps
- ZeroMemory Guide -- Add persistent memory to your Stytch-authenticated agents
- API Reference -- Full API documentation
- SDK Quick Start -- Client SDKs for React, Next.js, Vue, Svelte, and Python