---
title: "Authentication · Scrape.ly Docs"
description: "Log in, manage tokens, and control which credentials and API the CLI uses."
url: https://scrape.ly/docs/cli-auth
markdown: https://scrape.ly/docs/cli-auth.md
---

# Authentication

> Log in, manage tokens, and control which credentials and API the CLI uses.

The CLI sends a bearer token with every API request. You can log in once on your machine and let the CLI store the token, or set `SCRAPELY_TOKEN` in CI. This page covers the login methods, where credentials are stored, and the order in which the CLI resolves the token and the API URL.

## Log in

```bash
scrapely login
```

`scrapely auth login` does the same thing.

| Option | Description |
| --- | --- |
| `-m, --method <method>` | `browser`, `console`, or `manual`. Any other value is an error. |
| `-t, --token <token>` | Log in with this token without prompting |

On an interactive terminal with neither option, the CLI asks you to choose a method:

| Method | What happens |
| --- | --- |
| `browser` | The CLI starts a one-shot server on `127.0.0.1`, opens the dashboard in your browser, and asks you to approve the CLI. The dashboard sends a token back to the local server. The browser has 5 minutes to complete the flow. If it fails, the CLI asks you to paste a token instead. |
| `console` | The CLI opens the dashboard. Copy an API key from **Settings → API & Integrations** and paste it at the prompt. |
| `manual` | The CLI asks you to paste a token. Input is masked. |

On a terminal that isn't interactive, `login` without `--token` uses the `console` method. Use `--token` or `SCRAPELY_TOKEN` in scripts.

If you are already logged in, `login` asks whether to log in with a different account. `--token` skips that question.

The CLI validates the token with `GET /v2/users/me`, then writes the token, the API URL it used, and your user details to `~/.scrapely/credentials.json`.

> [!WARNING]
> If neither `SCRAPELY_API_BASE_URL` nor `SCRAPELY_API_URL` is set and no API URL is saved, `login` prints `Using default API at …`. The built-in default is not the production API. Set `SCRAPELY_API_URL=https://api.scrape.ly` before you log in.

### Browser tokens and API keys

The two kinds of token behave differently:

- **Browser login** stores an OAuth access token. It expires, by default after 24 hours, and then commands fail with an authentication error until you log in again. It can't read or reset your API key.
- **API keys** from **Settings → API & Integrations** don't expire. Use one for CI, servers, and anything long-running, with `scrapely login --token` or `SCRAPELY_TOKEN`.

`scrapely login` accepts any API key, including a scoped key you created under **Settings → API keys**: it only checks the key with `GET /v2/users/me`. Commands then succeed or fail according to the key's scopes. For CI, prefer a scoped key, for example `actors:build` + `actors:read` for deploys. See [API keys & permissions](https://scrape.ly/docs/api-keys.md).

## Check the account

```bash
scrapely info
```

`info` fetches your account from the API and prints the username, email, user ID, plan, and the API URL in use. It also refreshes the cached user details in `credentials.json`. If the API can't be reached, it prints the cached details with a warning that they may be stale.

To print the stored token, for example to pass it to another tool:

```bash
scrapely auth token
```

`auth token` fails if you are not logged in. Treat its output as a secret: it gives full access to your account.

## Log out

```bash
scrapely logout
```

`scrapely auth logout` does the same thing. Both empty `~/.scrapely/credentials.json`. If no token is stored, they print `Not logged in.`

Logging out does not revoke the token. To invalidate an API key, reset it in the dashboard or call `POST /v2/api-keys/reset` with your API key. A browser login token expires on its own.

## The `auth` group

| Command | Purpose |
| --- | --- |
| `scrapely auth login` | Same as `scrapely login`, with the same options |
| `scrapely auth logout` | Same as `scrapely logout` |
| `scrapely auth token` | Print the stored token |

## Credentials and precedence

The CLI keeps its state in `~/.scrapely/`. Both files are written with mode `0600`.

| File | Contents |
| --- | --- |
| `credentials.json` | Token, API URL, and cached user details |
| `secrets.json` | Local secrets for `scrapely run`. See [Secrets](https://scrape.ly/docs/cli-webhooks-secrets.md#secrets). |

The token comes from the first of:

1. The token saved in `~/.scrapely/credentials.json`
2. `SCRAPELY_TOKEN`

The API URL comes from the first of:

1. `SCRAPELY_API_BASE_URL`
2. `SCRAPELY_API_URL`
3. The API URL saved in `~/.scrapely/credentials.json`
4. The built-in default

The dashboard URL used in printed links and by `push --open` comes from `SCRAPELY_WEB_URL`. Without it, the CLI derives one from the API URL, which doesn't give the right dashboard address for production. Set `SCRAPELY_WEB_URL=https://my.scrape.ly`.

> [!WARNING]
> A saved token wins over `SCRAPELY_TOKEN`. If you logged in on a machine and then set `SCRAPELY_TOKEN` to another key, the CLI still uses the saved token. Run `scrapely logout` first. The API URL works the other way: the environment variables win over the saved URL.

Commands that need authentication fail with `You are not logged in. Call "scrapely login" first.` when no token is available. `actors search` and `templates ls` work without logging in.

## CI and other non-interactive use

Set an API key in the environment. Don't run `scrapely login` in the pipeline.

```bash
export SCRAPELY_API_URL=https://api.scrape.ly
export SCRAPELY_TOKEN=<your API key>
scrapely push --wait-for-finish 600
```

In GitHub Actions:

```yaml
- name: Deploy
  env:
    SCRAPELY_API_URL: https://api.scrape.ly
    SCRAPELY_TOKEN: ${{ secrets.SCRAPELY_TOKEN }}
  run: scrapely push --wait-for-finish 600
```

Keep the key in your CI provider's secret store, never in the repository. Pass `-y` to delete commands so nothing waits on a prompt. More pipeline examples are in [Config & troubleshooting](https://scrape.ly/docs/cli-config.md#cicd).

## Tokens inside an Actor container

The `scrapely actor` runtime commands resolve credentials differently, because the platform gives each run its own environment.

The token comes from the first of `ACTOR_TOKEN`, `APIFY_TOKEN`, `SCRAPELY_TOKEN`, and the saved token. The API URL comes from the first of `APIFY_API_BASE_URL`, `SCRAPELY_API_BASE_URL`, `SCRAPELY_API_URL`, and the saved API URL.

If any of those API URL variables is set, the saved token is never used. A container that has an API URL but no token can't act with the account saved on the machine. See [Actor runtime](https://scrape.ly/docs/cli-actor-runtime.md#environment).

## What's next

- [Actor runtime](https://scrape.ly/docs/cli-actor-runtime.md): the commands and variables inside a container.
- [Config & troubleshooting](https://scrape.ly/docs/cli-config.md): pipelines and common authentication errors.
- [Account](https://scrape.ly/docs/account.md): create and reset API keys in the dashboard.
- [API keys & permissions](https://scrape.ly/docs/api-keys.md): scoped keys, expiry, and limits.
- [Security](https://scrape.ly/docs/security.md): how tokens and permissions work.

---

- Previous: [CLI reference](https://scrape.ly/docs/cli.md)
- Next: [Projects & running](https://scrape.ly/docs/cli-projects.md)
- All docs: [Docs index](https://scrape.ly/docs.md), [llms.txt](https://scrape.ly/llms.txt)
