Auth & API Keys

User authentication and scoped API key management

Overview

The Auth resource handles user authentication (sign up, sign in, sign out) and API key management. Authentication uses email/password with session tokens. API keys provide scoped access for SDK operations.

All auth methods are available on r.auth.

Methods

MethodDescription
signUp(input)Create a new user account.
signIn(input)Sign in with email and password.
getSession(token)Validate a session token and get user info.
signOut(token)Sign out (invalidate session).
createApiKey(input, sessionToken)Create a scoped API key.

Sign up

Create a new user account with email and password.

1const session = await r.auth.signUp({
2 name: 'Alice Johnson',
3 email: 'alice@example.com',
4 password: 'securePassword123',
5});
6
7console.log(session.token); // Session token — store this securely
8console.log(session.user.id);
9console.log(session.user.name);
10console.log(session.user.email);

Input fields:

FieldTypeRequiredDescription
namestringYesDisplay name.
emailstringYesEmail address.
passwordstringYesPassword (12+ characters, at least one letter and one number).

Returns: AuthSession

1interface AuthSession {
2 token: string;
3 user: {
4 id: string;
5 name: string;
6 email: string;
7 image: string | null;
8 };
9}

Password requirements:

  • Minimum 12 characters
  • At least one letter
  • At least one number

The session token is returned in the response body. Store it securely — on mobile, use expo-secure-store or the platform keychain. Never store tokens in AsyncStorage or localStorage in production.

Sign in

1const session = await r.auth.signIn({
2 email: 'alice@example.com',
3 password: 'securePassword123',
4});
5
6console.log(session.token);
7console.log(session.user.name);

Input fields:

FieldTypeRequiredDescription
emailstringYesEmail address.
passwordstringYesPassword.

Error handling:

1import { AuthenticationError, ValidationError } from '@recursiv/sdk';
2
3try {
4 const session = await r.auth.signIn({
5 email: 'alice@example.com',
6 password: 'wrongpassword',
7 });
8} catch (err) {
9 if (err instanceof AuthenticationError) {
10 // err.code === 'invalid_credentials'
11 console.error('Invalid email or password');
12 }
13}

Get session

Validate a session token and retrieve the associated user. Returns null if the session is invalid or expired.

1const session = await r.auth.getSession(storedToken);
2
3if (session) {
4 console.log(`Logged in as ${session.user.name}`);
5} else {
6 console.log('Session expired — redirect to login');
7}

Sign out

Invalidate a session token.

1await r.auth.signOut(sessionToken);

Create an API key

API keys provide scoped access to the SDK. They are created using a session token (not another API key).

1const apiKey = await r.auth.createApiKey(
2 {
3 name: 'CI/CD Pipeline',
4 scopes: ['projects:read', 'projects:write', 'deploy:create'],
5 },
6 sessionToken,
7);
8
9console.log(apiKey.key); // 'sk_live_...' — only shown once!
10console.log(apiKey.id);
11console.log(apiKey.name);
12console.log(apiKey.prefix); // 'sk_live_abc...' (for identification)
13console.log(apiKey.scopes);

The full API key is only returned once at creation time. Store it immediately in a secure location (environment variable, secrets manager). It cannot be retrieved later.

Input fields:

FieldTypeRequiredDescription
namestringYesA descriptive name for the key.
scopesstring[]YesList of permission scopes.
organizationIdstring?NoScope the key to an organization.

createApiKey requires a session token (from signIn or signUp), not an API key. This is because creating API keys is a privileged operation that requires active user authentication.

Available scopes

ScopeDescription
projects:readRead project details and list projects.
projects:writeCreate, update, and delete projects.
deploy:createTrigger deployments.
deploy:readRead deployment status and logs.
sandbox:executeExecute code in sandboxes.
agents:readRead agent details and list agents.
agents:writeCreate, update, and delete agents.
agents:chatChat with agents.
posts:readRead posts and feeds.
posts:writeCreate, update, and delete posts.
chat:readRead conversations and messages.
chat:writeSend messages and manage conversations.
communities:readRead community details.
communities:writeCreate and manage communities.
users:readRead user profiles.
organizations:readRead organization details.
organizations:writeManage organization members and settings.
storage:readRead storage buckets and objects.
storage:writeUpload and delete objects.
databases:readRead database details and credentials.
databases:writeCreate and manage databases.
billing:readRead billing and usage information.
billing:writeManage billing settings.
memory:readRead memory (facts, decisions).
memory:writeWrite memory (add facts, log decisions).

Full example: sign up, create API key, use it

1import { Recursiv } from '@recursiv/sdk';
2
3// Step 1: Initialize without an API key (for auth only)
4const authClient = new Recursiv({
5 apiKey: 'placeholder', // Auth methods don't use the API key
6});
7
8// Step 2: Sign up
9const session = await authClient.auth.signUp({
10 name: 'Bob Builder',
11 email: 'bob@example.com',
12 password: 'securePassword123',
13});
14
15console.log('Signed up as:', session.user.name);
16
17// Step 3: Create an API key using the session token
18const apiKey = await authClient.auth.createApiKey(
19 {
20 name: 'Development',
21 scopes: [
22 'projects:read',
23 'projects:write',
24 'agents:read',
25 'agents:write',
26 'agents:chat',
27 ],
28 },
29 session.token,
30);
31
32console.log('API Key created:', apiKey.prefix);
33// Store apiKey.key securely — it's only shown once!
34
35// Step 4: Use the API key for all future SDK operations
36const r = new Recursiv({ apiKey: apiKey.key });
37
38const { data: me } = await r.users.me();
39console.log('Authenticated as:', me.name);

Token storage best practices

PlatformRecommended storage
Node.js / CIEnvironment variable (RECURSIV_API_KEY)
Next.jsServer-side env var. Never expose in client bundles.
React Native / Expoexpo-secure-store for session tokens
iOS nativeKeychain
Android nativeEncryptedSharedPreferences
BrowserHttpOnly cookie (via your backend)

Never store API keys or session tokens in:

  • localStorage or sessionStorage (XSS vulnerable)
  • AsyncStorage (unencrypted on disk)
  • Source code or git repositories
  • Client-side JavaScript bundles