> ## Documentation Index
> Fetch the complete documentation index at: https://docs.qoder.com/llms.txt
> Use this file to discover all available pages before exploring further.

# SDK Authentication

`query()` requires authentication configuration to start a session. The recommended approach is to use a Personal Access Token (PAT) injected via environment variables, ideal for scripts, CI, and host application integration.

If you have already logged in locally via `qodercli`, you can also reuse the existing credentials.

<div id="generating-a-pat" />

## Generating a PAT

Generate a Personal Access Token at [qoder.com/account/integrations](https://qoder.com/account/integrations):

1. Sign in to your Qoder account
2. Open **Account → Integrations**
3. Create a new PAT, picking expiry and scopes as needed
4. **Copy it immediately** — the value cannot be retrieved again after the page is closed; if lost, you must regenerate

> A single account can hold multiple PATs. Issuing separate tokens per environment (local scripts, CI, production) makes per-token revocation possible.

<div id="recommended-usage" />

## Recommended Usage

<div id="reading-pat-from-the-default-environment-variable" />

### Reading PAT from the Default Environment Variable

The default environment variable name is `QODER_PERSONAL_ACCESS_TOKEN`.

```bash theme={null}
export QODER_PERSONAL_ACCESS_TOKEN="<your-qoder-personal-access-token>"
node agent.mjs
```

```js theme={null}
import { accessTokenFromEnv, query } from '@qoder-ai/qoder-agent-sdk';

const q = query({
  prompt: 'Summarize the purpose of this project in one sentence.',
  options: {
    auth: accessTokenFromEnv(),
  },
});

try {
  for await (const message of q) {
    if (message.type === 'result') {
      console.log(message.subtype);
    }
  }
} finally {
  await q.close?.();
}
```

<div id="reading-pat-from-a-custom-environment-variable" />

### Reading PAT from a Custom Environment Variable

```js theme={null}
import { accessTokenFromEnv, query } from '@qoder-ai/qoder-agent-sdk';

const q = query({
  prompt: 'Check whether the README contains installation steps.',
  options: {
    auth: accessTokenFromEnv('MY_QODER_PAT'),
  },
});
```

Equivalent explicit form:

```js theme={null}
auth: {
  type: 'accessToken',
  accessToken: { envVar: 'MY_QODER_PAT' },
}
```

If the same-named variable is set in both `options.env` and `process.env`, the SDK reads the value from `options.env` first.

<div id="passing-the-pat-directly" />

### Passing the PAT Directly

If your host application has already obtained a PAT from a secrets management service, existing credentials, or backend API, you can pass it directly. Do not hard-code token literals in source code.

```js theme={null}
import { accessToken, query } from '@qoder-ai/qoder-agent-sdk';

const token = await readTokenFromSecretManager();

const q = query({
  prompt: 'List the most recently modified files.',
  options: {
    auth: accessToken(token),
  },
});
```

<div id="reusing-qodercli-login-session" />

### Reusing qodercli Login Session

If you have already completed login via `qodercli` on the local machine, you can let the SDK delegate to the CLI to read the existing credentials. This method works well in interactive local environments and is not recommended for stateless CI.

```js theme={null}
import { qodercliAuth, query } from '@qoder-ai/qoder-agent-sdk';

const q = query({
  prompt: 'Summarize the current workspace.',
  options: {
    auth: qodercliAuth(),
  },
});
```

<div id="api-overview" />

## API Overview

| Option                       | Purpose                                                                                                                           |
| ---------------------------- | --------------------------------------------------------------------------------------------------------------------------------- |
| `accessTokenFromEnv()`       | Read PAT from `QODER_PERSONAL_ACCESS_TOKEN`.                                                                                      |
| `accessTokenFromEnv(envVar)` | Read PAT from a specified environment variable.                                                                                   |
| `accessToken(token)`         | Use a PAT already obtained by the caller.                                                                                         |
| `qodercliAuth()`             | Reuse the local `qodercli` login session.                                                                                         |
| `onAuthExpired`              | Callback when the token expires, authentication fails, or the CLI exits with an auth error. Fires at most once per query session. |

<div id="error-handling" />

## Error Handling

<div id="missing-auth-configuration" />

### Missing auth Configuration

`query()` will throw `auth_not_configured` before starting:

```js theme={null}
try {
  query({ prompt: 'hello' });
} catch (error) {
  if (error?.code === 'auth_not_configured') {
    console.error('Please configure options.auth');
  }
}
```

<div id="environment-variable-not-set" />

### Environment Variable Not Set

When using `{ envVar }` but the variable is empty, the SDK will throw `auth_access_token_env_var_not_configured`:

```js theme={null}
try {
  const q = query({
    prompt: 'hello',
    options: {
      auth: accessTokenFromEnv('MY_QODER_PAT'),
    },
  });

  for await (const _message of q) {
    // Initialization failures do not reach this loop.
  }
} catch (error) {
  if (error?.code === 'auth_access_token_env_var_not_configured') {
    console.error('MY_QODER_PAT is not set');
  }
}
```

<div id="authentication-failure-during-execution" />

### Authentication Failure During Execution

When the remote rejects the token, the token expires, or the CLI exits with an auth error, use `onAuthExpired` to trigger a re-login or token refresh flow:

```js theme={null}
const q = query({
  prompt: 'Continue with the current task.',
  options: {
    auth: accessTokenFromEnv(),
    onAuthExpired() {
      showSignInRequired();
    },
  },
});

for await (const message of q) {
  if (message.type === 'result' && message.subtype !== 'success') {
    console.error(message.errors?.join('\n') ?? message.subtype);
  }
}
```

The SDK does not automatically refresh PATs. The host application should create a new `query()` session with a new `auth` configuration after obtaining a new token.

<div id="best-practices" />

## Best Practices

* In production and CI, prefer environment variables or secrets management services; never hard-code tokens.
* Do not write tokens to logs, error objects, or debug output.
* For automated environments, use PATs rather than relying on local `qodercli` login session.
* For user-facing applications, register `onAuthExpired` to convert authentication failures into clear sign-in prompts.
* When rotating tokens, create a new query session; do not reuse a session that has already failed authentication.
