> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.recursiv.io/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.recursiv.io/_mcp/server.

# Auth & API Keys

## 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

| Method                                      | Description                                        |
| ------------------------------------------- | -------------------------------------------------- |
| `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.                           |
| `signUpAndCreateKey(input, keyInput)`       | One-shot: sign up → create API key → return it.    |
| `signInAndCreateKey(credentials, keyInput)` | One-shot: sign in → create API key → return it.    |
| `verifyOtpAndCreateKey(input, keyInput)`    | One-shot: verify OTP → create API key → return it. |

## Sign up

Create a new user account with email and password.

```typescript
const session = await r.auth.signUp({
  name: 'Alice Johnson',
  email: 'alice@example.com',
  password: 'Example-Passw0rd!',
});

console.log(session.token);        // Session token — store this securely
console.log(session.user.id);
console.log(session.user.name);
console.log(session.user.email);
```

**Input fields:**

| Field      | Type     | Required | Description                                                                |
| ---------- | -------- | -------- | -------------------------------------------------------------------------- |
| `name`     | `string` | Yes      | Display name.                                                              |
| `email`    | `string` | Yes      | Email address.                                                             |
| `password` | `string` | Yes      | Password (12–128 characters with lowercase, uppercase, digit, and symbol). |

**Returns:** `AuthSession`

```typescript
interface AuthSession {
  token: string;
  user: {
    id: string;
    name: string;
    email: string;
    image: string | null;
  };
}
```

**Password requirements:**

* 12–128 characters
* At least one lowercase letter, one uppercase letter, one digit, and one symbol
* Not a known compromised password (e.g. `password123!` is rejected)

Failing the policy returns a `400` with code `WEAK_PASSWORD`.

> **Note**
>
> 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

```typescript
const session = await r.auth.signIn({
  email: 'alice@example.com',
  password: 'Example-Passw0rd!',
});

console.log(session.token);
console.log(session.user.name);
```

**Input fields:**

| Field      | Type     | Required | Description    |
| ---------- | -------- | -------- | -------------- |
| `email`    | `string` | Yes      | Email address. |
| `password` | `string` | Yes      | Password.      |

**Error handling:**

```typescript
import { AuthenticationError, ValidationError } from '@recursiv/sdk';

try {
  const session = await r.auth.signIn({
    email: 'alice@example.com',
    password: 'wrongpassword',
  });
} catch (err) {
  if (err instanceof AuthenticationError) {
    // err.code === 'invalid_credentials'
    console.error('Invalid email or password');
  }
}
```

## Get session

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

```typescript
const session = await r.auth.getSession(storedToken);

if (session) {
  console.log(`Logged in as ${session.user.name}`);
} else {
  console.log('Session expired — redirect to login');
}
```

## Sign out

Invalidate a session token.

```typescript
await 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).

```typescript
const apiKey = await r.auth.createApiKey(
  {
    name: 'CI/CD Pipeline',
    scopes: ['projects:read', 'projects:write'],
  },
  sessionToken,
);

console.log(apiKey.key);     // 'sk_live_...' — only shown once!
console.log(apiKey.id);
console.log(apiKey.name);
console.log(apiKey.prefix);  // 'sk_live_abc...' (for identification)
console.log(apiKey.scopes);
```

> **Warning**
>
> 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:**

| Field            | Type       | Required | Description                                                             |
| ---------------- | ---------- | -------- | ----------------------------------------------------------------------- |
| `name`           | `string`   | Yes      | A descriptive name for the key.                                         |
| `scopes`         | `string[]` | Yes      | List of permission scopes.                                              |
| `organizationId` | `string?`  | No       | Scope the key to an organization (mutually exclusive with `projectId`). |
| `projectId`      | `string?`  | No       | Scope the key to a project (mutually exclusive with `organizationId`).  |

> **Note**
>
> `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

This is the complete list of valid scopes. Anything else (e.g. `deploy:create`, `agents:chat`) is rejected with an `invalid_scope` error. Deployments are covered by `projects:write`; chatting with agents by `agents:write`; sandbox execution by `projects:write`.

| Scope                 | Description                                                     |
| --------------------- | --------------------------------------------------------------- |
| `projects:read`       | Read project details, list projects, view deployments and logs. |
| `projects:write`      | Create/delete projects, deploy, execute code, manage sandboxes. |
| `agents:read`         | Read agent details and list agents.                             |
| `agents:write`        | Create, update, and delete agents; chat; grant project access.  |
| `posts:read`          | Read posts and feeds.                                           |
| `posts:write`         | Create, update, and delete posts.                               |
| `chat:read`           | Read conversations and messages.                                |
| `chat:write`          | Send messages and manage conversations.                         |
| `communities:read`    | Read community details.                                         |
| `communities:write`   | Create and manage communities.                                  |
| `users:read`          | Read user profiles.                                             |
| `users:write`         | Update user profiles, follow/unfollow.                          |
| `organizations:read`  | Read organization details.                                      |
| `organizations:write` | Manage organization members and settings.                       |
| `notifications:read`  | List notifications.                                             |
| `notifications:write` | Mark notifications read, manage preferences.                    |
| `settings:read`       | Read user settings.                                             |
| `settings:write`      | Update user settings.                                           |
| `tags:read`           | List and get tags.                                              |
| `tags:write`          | Create and delete tags.                                         |
| `uploads:write`       | Upload files.                                                   |
| `wallet:read`         | View wallet balances.                                           |
| `wallet:write`        | Wallet operations.                                              |
| `commands:read`       | Read command results.                                           |
| `commands:write`      | Execute AI commands.                                            |
| `storage:read`        | Read storage buckets and objects.                               |
| `storage:write`       | Upload and delete objects.                                      |
| `databases:read`      | Read database details and credentials.                          |
| `databases:write`     | Create and manage databases.                                    |
| `billing:read`        | Read billing and usage information.                             |
| `billing:write`       | Manage billing settings.                                        |
| `memory:read`         | Read memory (facts, decisions).                                 |
| `memory:write`        | Write memory (add facts, log decisions).                        |
| `admin`               | Platform administration (restricted to platform admins).        |

## One-shot onboarding

`signUpAndCreateKey` collapses sign up + key creation into a single call — the recipe for agents and mobile apps that need to go from nothing to an authenticated client:

```typescript
import { Recursiv } from '@recursiv/sdk';

const anon = new Recursiv({ anonymous: true });

const { apiKey, user, session } = await anon.auth.signUpAndCreateKey(
  { name: 'Bob Builder', email: 'bob@example.com', password: 'Example-Passw0rd!' },
  { name: 'my-app', scopes: ['projects:read', 'projects:write'] },
);

const r = new Recursiv({ apiKey });
```

`signInAndCreateKey(credentials, keyInput)` does the same for existing users, and `verifyOtpAndCreateKey(otpInput, keyInput)` for passwordless OTP flows. All three return `{ apiKey, user, session }`.

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

```typescript
import { Recursiv } from '@recursiv/sdk';

// Step 1: Initialize without an API key (for auth only)
const authClient = new Recursiv({
  allowNoKey: true, // Auth methods don't need an API key
});

// Step 2: Sign up
const session = await authClient.auth.signUp({
  name: 'Bob Builder',
  email: 'bob@example.com',
  password: 'Example-Passw0rd!',
});

console.log('Signed up as:', session.user.name);

// Step 3: Create an API key using the session token
const apiKey = await authClient.auth.createApiKey(
  {
    name: 'Development',
    scopes: [
      'projects:read',
      'projects:write',
      'agents:read',
      'agents:write',
    ],
  },
  session.token,
);

console.log('API Key created:', apiKey.prefix);
// Store apiKey.key securely — it's only shown once!

// Step 4: Use the API key for all future SDK operations
const r = new Recursiv({ apiKey: apiKey.key });

const { data: me } = await r.users.me();
console.log('Authenticated as:', me.name);
```

## Token storage best practices

| Platform            | Recommended storage                                  |
| ------------------- | ---------------------------------------------------- |
| Node.js / CI        | Environment variable (`RECURSIV_API_KEY`)            |
| Next.js             | Server-side env var. Never expose in client bundles. |
| React Native / Expo | `expo-secure-store` for session tokens               |
| iOS native          | Keychain                                             |
| Android native      | EncryptedSharedPreferences                           |
| Browser             | HttpOnly 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