Skip to main content

Overview

Client Tokens allow you to call Reminix APIs directly from browsers and mobile apps without exposing your API key. They are short-lived, scoped tokens created by your backend.
Client tokens use the /client API endpoints, which are separate from the server-side /v1 endpoints.

How It Works

  1. User visits your app — Your frontend needs to interact with a Reminix agent
  2. Your backend creates a token — Using your API key, call POST /v1/client-tokens with publicMetadata and serverContext
  3. Token sent to browser — Your backend returns the token to the frontend
  4. Browser calls Client API — Use the token to call /client/agents/{name}/invoke

Creating Client Tokens

Create tokens from your backend using your API key:
import Reminix from '@reminix/sdk';

const reminix = new Reminix();

// Create a client token for the current user
const { token } = await reminix.clientTokens.create({
  // Public metadata - exposed via GET /client/token
  publicMetadata: {
    userId: 'user_123',
    sessionId: 'sess_abc',
    plan: 'pro'
  },
  // Server context - only accessible to agents, never exposed to client
  serverContext: {
    internalCustomerId: 'int_456',
    quotaLimit: 1000
  },
  ttlSeconds: 3600 // 1 hour (default). Max: 86400 (24 hours)
});

// Return token to your frontend
res.json({ token });

Payload: publicMetadata and serverContext

Tokens support two payloads:
TypeDescriptionAccessible To
publicMetadataPublic dataClient (via GET /client/token) and agents
serverContextPrivate dataAgents only — never exposed to client
Public metadata (publicMetadata) — Use for data the client needs to see:
FieldDescription
userIdIdentify the end user
sessionIdTrack conversation sessions
planUser’s subscription tier (for UI display)
Server context (serverContext) — Use for sensitive server-side data:
FieldDescription
internalCustomerIdInternal database ID
quotaLimitUser’s actual quota (for enforcement)
permissionsDetailed permission flags
Both payloads are trusted and cannot be tampered with by the client. Use serverContext for any data you don’t want exposed to browsers.

Using Client Tokens

In the Browser

Once you have a token, use it to call the Client API:
// Fetch token from your backend
const { token } = await fetch('/api/auth/reminix-token').then(r => r.json());

// Call Reminix Client API
const response = await fetch('https://api.reminix.com/client/agents/{name}/invoke', {
  method: 'POST',
  headers: {
    'Authorization': `Bearer ${token}`,
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    agentId: 'my-agent',
    messages: [{ role: 'user', content: 'Hello!' }]
  })
});

With the Client SDK (Coming Soon)

import { ReminixClient } from '@reminix/client';

const client = new ReminixClient({ token });

const response = await client.invokeAgent('my-agent', {
  messages: [{ role: 'user', content: 'Hello!' }]
});

Client API Endpoints

Client tokens can only access these endpoints:
EndpointDescription
GET /client/tokenRetrieve the token (projectId + publicMetadata)
POST /client/agents/{name}/invokeInvoke an agent
Client tokens cannot access management endpoints like creating agents, viewing logs, or managing deployments.

Token Lifecycle

Expiration

Client tokens expire after the specified duration (default: 1 hour). When a token expires, the client receives a 401 Unauthorized error and should request a new token from your backend.

Revocation

You can revoke a token before it expires:
await reminix.clientTokens.revoke('ct_abc123');

Best Practices

Use the default 1-hour expiration or shorter. This limits the window if a token is compromised.
Don’t pre-generate tokens. Create them when the user needs to interact with an agent.
Only include the public metadata your agents and UI actually need. Less data means less risk.
Always authenticate users on your backend before creating a client token for them.

Security Model

AspectAPI KeyClient Token
Where to useServer onlyBrowser/mobile
LifespanUntil revokedShort-lived (hours)
PermissionsFull project accessClient API only
Created byDashboardYour backend via API
ContainsProject IDProject ID + public metadata

Next Steps