# Authentication

> Authenticate Nodaro API calls with a personal API token, an OAuth app token or a session JWT, and create, scope, bind and revoke your API tokens.

Source: https://nodaro.ai/docs/developers/api/authentication

Every Nodaro API request authenticates with a **bearer token** in the `Authorization` header. Use a personal API token (`ndr_…`) when your own server calls Nodaro for your account, an OAuth access token (`ndr_app_…`) when your product acts for other Nodaro users, and your session JWT on a self-hosted Community Edition install.

```http
Authorization: Bearer ndr_4f1c…
```

## Which credential to use

| You are | Use | Token format |
| --- | --- | --- |
| Scripting your own Nodaro account from a server, a cron job or a CI pipeline | Personal API token | `ndr_` followed by 64 hex characters |
| Building a product that runs workflows on other users' Nodaro accounts | OAuth access token | `ndr_app_` followed by 64 hex characters |
| Running the self-hosted Community Edition for yourself | Your session JWT | A JWT, starting with `eyJ` |

A quick test: if your server needs one set of credentials and no consent screen, use an API token. If many customers must each give your app access to their own account, use [OAuth](https://nodaro.ai/docs/developers/oauth).

API tokens are available on Nodaro Cloud and on the Business edition. On the Community Edition, call the same endpoints with the access token of your signed-in session instead. See [Editions](https://nodaro.ai/docs/concepts/editions).

## Create an API token

### Open the API Tokens page

Sign in to Nodaro and open **Settings › API Tokens**. On Nodaro Cloud the page is at `https://app.nodaro.ai/settings/api`.

### Create the token

Click **Create Token**. In the **Create API Token** dialog, enter a **Name** for your records, such as `prod-scheduler`, and a **Rate Limit (requests/min)** from 1 to 120. The default is 30 requests per minute.

### Copy it now

Click **Create** and copy the token into your secret store. The token is shown only once. Nodaro stores only a SHA-256 hash of it, so a lost token cannot be recovered: create a new one instead.

The page lists each token with its name, its prefix, its rate limit, when it was last used and when it was created. The switch next to a token turns it on or off, and the trash button deletes it.

### Rules for API tokens

- **Up to 10 tokens per account**, active or not. A deactivated token still counts, so delete it to free the slot. An eleventh token is refused with `400 limit_reached`.
- **No expiry and no spend cap.** A token works until you deactivate or delete it. Deleting a token revokes it immediately.
- **The token acts as you.** Every call it makes runs as your account and spends your credits.
- **It is not re-checked against your sign-in provider.** A token created before your account was removed from an identity provider keeps working until you revoke it. Treat every token as a permanent credential.

## Limit a token to some workflows

A token can be limited to a list of workflows, its **workflow scope**. A scoped token can run and inspect only those workflows, and any other workflow answers `403 forbidden`. An empty list means the token can run every workflow you own.

Set the scope with the `workflowIds` field when you create or update a token through the endpoints below. Only workflows in your personal space can be listed: a workflow that lives in a workspace answers `400 invalid_workflow`.

## Manage tokens from code

| Method | Path | What it does |
| --- | --- | --- |
| `POST` | `/v1/api-tokens` | Create a token. Body `{ name, workflowIds, rateLimit }`. The response is the only time the full token is shown. |
| `GET` | `/v1/api-tokens` | List your tokens with their settings and their workspace binding (`workspaceId`). The token itself is never returned. |
| `PATCH` | `/v1/api-tokens/:id` | Change the name, the workflow scope, the rate limit, the active flag or the workspace binding. |
| `DELETE` | `/v1/api-tokens/:id` | Delete the token. It stops working at once. |

These four routes work only from a signed-in session, so send your session JWT, not an API token. A personal API token or an OAuth token is refused with `403 forbidden`, with the message "API token management is only available from a logged-in session". On a Community Edition install, the create and list routes answer `403 edition_required` with `required_edition: "business"`.

To bind a token to one workspace, see [Bind a token to a workspace](https://nodaro.ai/docs/developers/api/workspaces#bind-a-token-to-a-workspace).

## Send the token

`GET /v1/me` returns the account behind any valid token, so it is the quickest way to check a token. A missing, invalid or revoked token answers `401 unauthorized`.

**curl**

```bash
curl https://app.nodaro.ai/v1/me \
  -H "Authorization: Bearer $NODARO_API_KEY"
```

```json
{
"data": {
"id": "5bf0d884-47b1-468e-a7b2-2433f957b267",
"email": "ada@example.com",
"displayName": "Ada",
"avatarUrl": null,
"tier": "pro",
"isAdmin": false
}
}
```

**TypeScript SDK**

```ts

const client = createClient({
baseUrl: 'https://app.nodaro.ai',
auth: new StaticTokenAuth(process.env.NODARO_API_KEY!),
})

const me = await client.me()
console.log(me.email, me.tier)
```

**CLI**

```bash
nodaro auth login --token "$NODARO_API_KEY"
nodaro auth status
```

On an account that belongs to an organization, the same response also carries the organizations and workspaces the account belongs to. See [Workspaces and organizations](https://nodaro.ai/docs/developers/api/workspaces).

The SDK takes the token from an auth provider, so you choose how the token is found:

| Provider | Use it for |
| --- | --- |
| `StaticTokenAuth` | A fixed token on a server: an API token or an OAuth access token. |
| `supabaseAuth(supabase)` | A browser app that shares the Nodaro install's sign-in. The session token is read on every request, so refresh is automatic. |
| `CallbackAuth` | Your own logic, for example a session store that refreshes tokens. The callback may return `null` to send no header. |

The CLI saves the token in `~/.config/nodaro/config.json` with file mode `0600`. Add `--profile` and `--base-url` to keep a second login for a self-hosted install, for example `nodaro auth login --profile local --base-url http://localhost:3000`.

## OAuth access tokens

Use OAuth when each of your users connects their own Nodaro account to your product. Your server exchanges an authorization code for an access token that starts with `ndr_app_`. The token lives 90 days, and there are no refresh tokens: after it expires, send the user through the consent screen again.

An OAuth token carries only the scopes the user granted. A route that needs a scope the token lacks answers `403 insufficient_scope`, and the error names the scope in `missingScope`. The scopes most API integrations need:

| Scope | Grants |
| --- | --- |
| `workflows:read` | Read the user's workflows: `GET /v1/workflows`, `GET /v1/workflows/:id`, its export, and the per-project list. |
| `workflows:write` | Create, change, import and delete workflows. |
| `workflows:execute` | Run workflows with `POST /v1/workflows/:id/run`. |
| `jobs:read` | Read job status and results, including batch polling. |

Personal API tokens and session JWTs have no scopes: they act as your own account. Read the full flow, every scope and the consent screen in [OAuth apps](https://nodaro.ai/docs/developers/oauth).

## Routes that need a signed-in session

A few routes exist for the Nodaro web app and refuse both API tokens and OAuth tokens:

| Route | Answer to a token |
| --- | --- |
| `/v1/api-tokens` (token management) | `403 forbidden` |
| `/v1/billing/*` (checkout, loads, auto-recharge, purchase history) | `403 forbidden` |
| Writes to node presets | `403 forbidden` |
| `/v1/copilot/*` (the [Workflow Copilot](https://nodaro.ai/docs/get-started/workflow-copilot)) | `403 in_app_only` |
| `/v1/http-credentials` (stored keys for Webhook Output) | `403 in_app_only` |

To build workflows from code, use the [workflow endpoints](https://nodaro.ai/docs/developers/api/workflows), the [SDK](https://nodaro.ai/docs/developers/sdk) or the [MCP server](https://nodaro.ai/docs/mcp).

## Identify your client

Send an `X-Nodaro-Client` header and Nodaro records it as the origin of every job the request creates:

```http
X-Nodaro-Client: sdk/1.10.0
```

Only three forms are recognized: `sdk/<version>`, `cli/<version>` and `extension/<name>`. Any other value is ignored, because the header is not authenticated. `@nodaro/sdk` and `@nodaro/cli` send it for you, so you need it only when you call the REST API directly. Omitting it is fine: those jobs are recorded as generic API calls.

Browser callers should not send the header. The browser's `Origin` header already names the site, and Nodaro prefers it. The SDK leaves the header out automatically when it runs in a browser.

## Keep tokens on your server

A token in browser code is readable by anyone with developer tools, and it can spend your credits. Keep the token in a server route, an edge function or your platform's secret store, and let the browser talk only to your server:

```text
Browser  ->  your server (holds NODARO_API_KEY)  ->  Nodaro API
```

In Next.js, for example, read the token in a route handler from an environment variable without the `NEXT_PUBLIC_` prefix. If you do call Nodaro from a browser with an OAuth token, add your site's origin to the developer app's allowed origins.

## Connect a self-hosted install with a token

A personal API token is also the simplest way to run a self-hosted install's generations on Nodaro Cloud. On the self-hosted install, set `NODARO_CLOUD_URL` to the Nodaro Cloud address and `NODARO_API_KEY` to your token. Every generation then runs on Nodaro Cloud and is billed to the token's account, with no OAuth connection. See [Connect to Nodaro Cloud](https://nodaro.ai/docs/self-hosting/cloud-connect).

## Deployments with one billing account

Some deployments have a single billing account that pays for every user. On those deployments:

- Only the billing account can create a token. Anyone else gets `403 api_tokens_payer_only`, and existing tokens stay listable and revocable by their owners.
- The API Tokens card is not shown in Settings. The billing account opens `/settings/api` directly.
- Every call a token makes is paid from the deployment's pool.
- A token cannot read that pool. Balance reads made with the billing account's token answer `403 payer_balance_jwt_only`, and the deployment billing routes answer `403 payer_required`.

## Errors

| Status | Code | Meaning |
| --- | --- | --- |
| 400 | `limit_reached` | You already have 10 tokens, active or not. Delete one first. |
| 400 | `invalid_workflow` | A `workflowIds` entry is not a workflow in your personal space. |
| 400 | `token_workspace_mismatch` | A token bound to one workspace was sent with an `X-Nodaro-Workspace` header naming another. |
| 401 | `unauthorized` | The token is missing, invalid, expired or revoked. |
| 403 | `forbidden` | The token's workflow scope does not include this workflow, or the route needs a signed-in session. |
| 403 | `insufficient_scope` | An OAuth token lacks a scope the route needs. `missingScope` names it. |
| 403 | `in_app_only` | The route exists only for the Nodaro web app. |
| 403 | `edition_required` | The route needs a higher edition. `required_edition` names the minimum. |
| 403 | `api_tokens_payer_only` | On a deployment with one billing account, only that account can create tokens. |
| 403 | `sso_required` | The deployment restricts sign-in to its identity provider, and this session's account was not created through it. API tokens and OAuth tokens are not affected. |

Every error uses the same envelope. See [Errors](https://nodaro.ai/docs/developers/api/errors) for the full list.

## Frequently asked questions

### How do I get a Nodaro API key?

Sign in to Nodaro, open Settings › API Tokens and click Create Token. Give the token a name and a rate limit, then copy it. The token starts with ndr_ and is shown only once.

### Do Nodaro API tokens expire?

No. A personal API token works until you deactivate or delete it, and it has no spend cap. Store it like a password and delete it when you no longer need it.

### Should I use an API token or OAuth?

Use a personal API token when your own server calls Nodaro for your own account. Use OAuth when you build a product and each of your users connects their own Nodaro account.

### Can I use the API on the self-hosted Community Edition?

Yes. API tokens are available on Nodaro Cloud and the Business edition. On a Community Edition install, send the JWT of your signed-in session as the bearer token instead.

### Can I call the Nodaro API from a browser?

Never put a personal API token in browser code, because anyone can read it there. Call Nodaro from your own server, or use OAuth and register your site's origin on the developer app.
