# CLI

> Authorize with OAuth 2.1, then search the web, read pages and check trends from your terminal.

Canonical URL: https://s1.dev/docs/integrations/cli

`s1` puts the whole API in your terminal — and, because it prints JSON on demand, in your shell scripts too.

## Install

```bash
curl -fsSL https://cli.search1api.com/install.sh | bash
```

That installs a standalone binary; no Node.js required. If you would rather use npm:

```bash
npm install -g search1api-cli
```

## Log in

```bash
s1 login
```

This is an OAuth 2.1 login, not an API-key handoff. The CLI:

1. Discovers Search1API's authorization server.
2. Dynamically registers itself as a public native client.
3. Opens the authorization page with Authorization Code + PKCE (`S256`).
4. Saves the resulting access and refresh tokens in its local configuration.
5. Refreshes the access token automatically when it expires.

The account owner still signs in and approves the connection in the browser. Run `s1 config show` afterward to confirm that the active authentication method is OAuth 2.1.

If the CLI cannot open a browser automatically, print the authorization URL instead:

```bash
s1 login --no-browser
```

The redirect must still be able to reach the loopback callback on the machine running `s1`.

## API key fallback

Existing API keys remain supported for scripts, CI, and environments where an interactive OAuth login is not practical:

```bash
s1 config set-key YOUR_API_KEY
# or
export SEARCH1API_KEY=YOUR_API_KEY
```

`SEARCH1API_KEY` takes precedence over saved OAuth credentials. Remove it when you want the CLI to use the OAuth tokens created by `s1 login`. See [Authentication](https://s1.dev/docs/essentials/authentication) for the complete OAuth and API-key model.

## Commands

| Command | What it does |
| --- | --- |
| `s1 search "<query>"` | Search the web |
| `s1 news "<query>"` | Search the news |
| `s1 ask "<request>"` | Describe what you need; Search1API picks the engines (5 credits) |
| `s1 maps "<query>"` | Find places on Google Maps (3 credits per page of up to 20 places) |
| `s1 crawl <url>` | Read a page |
| `s1 sitemap <url>` | List a site's links |
| `s1 deepcrawl <url>` | Crawl many pages of a site and return them as JSON or a ZIP (20 credits per task) |
| `s1 trending <github\|hackernews>` | Trending topics |
| `s1 balance` | Remaining credits |
| `s1 feedback "<message>"` | Report a wrong result, an error, or a missing capability to the Search1API team (free) |
| `s1 login` | Authorize with OAuth 2.1 in the browser |
| `s1 config set-key \| show` | Manage configuration |
| `s1 update` | Update `s1` in place |

## Examples

```bash
# Five results from Google
s1 search "rust async" -n 5 -s google

# Search, then crawl the top 3 results for their full text
s1 search "web framework" -c 3

# Today's news, from Hacker News
s1 news "tech layoffs" -s hackernews -t day

# Second page of Bing results
s1 search "kubernetes" -s bing -p 2

# Let Search1API choose the engines and time window
s1 ask "What are developers saying about Bun 1.3 this month?"

# Ten coffee shops near a point on Google Maps
s1 maps "coffee shops" --near 40.7455,-74.0083 -n 10

# Machine-readable output, straight into jq
s1 search "test" --json | jq '.results[0].title'
```

The `--json` flag is what makes `s1` scriptable: pipe it into `jq`, feed it to a model, commit it to a file.

## Flags worth knowing

| Flag | Meaning |
| --- | --- |
| `-n, --max-results` | 1–50, defaults to 10 |
| `-s, --service` | Pick an engine; defaults to `google` |
| `-p, --page <N>` | Results page; supported on `bing`, `bingcn`, `baidu`, and `grokipedia` |
| `-c, --crawl <N>` | Crawl the top N results for full text |
| `--include` / `--exclude` | Restrict or exclude sites |
| `-t, --time <day\|week\|month\|year>` | Time range |
| `--json` | Raw JSON instead of formatted output |

> **info:** `-c/--crawl` is the same deep-search feature as the API's `crawl_results`, and bills the same way: 1 credit for the search plus 1 per page successfully crawled. See [Credits and limits](https://s1.dev/docs/essentials/credits-and-limits).

## Crawl a site

`s1 deepcrawl` starts a [deepcrawl](https://s1.dev/docs/advanced/deepcrawl) task, waits up to 300 seconds for it, and prints each page's title and URL with the page counts. It asks for JSON results unless you pass `--format zip`. A task costs 20 credits however many pages it crawls; checking a task with `s1 deepcrawl status` is free.

```bash
# At most 20 pages under /docs/, saved with their Markdown
s1 deepcrawl https://hono.dev/docs/ -n 20 --include /docs/ -o pages.json

# Skip a section and download the ZIP instead
s1 deepcrawl https://example.com --exclude /blog/ --format zip -o site.zip

# Start without waiting, then check the task later
s1 deepcrawl https://example.com --no-wait
s1 deepcrawl status <taskId> --json
```

| Flag | Meaning |
| --- | --- |
| `--type <sitemap\|all>` | Where URLs come from; defaults to `sitemap` |
| `-n, --max-pages <N>` | 1–1000 pages, counted after the path rules |
| `--include <path>` / `--exclude <path>` | Path rules, repeatable up to 20 each; exclusion wins |
| `--format <json\|zip>` | Result format; defaults to `json` |
| `--no-wait` | Print the task ID and exit |
| `--timeout <seconds>` | How long to wait; defaults to 300 |
| `-o, --output <file>` | Write the JSON pages or download the ZIP to a file |

`s1 deepcrawl` was added in CLI 2.3.0. From that version, options written after a subcommand belong to that subcommand.

The retired `s1 reasoning` and `s1 models` commands were removed in CLI 1.2.3.

Source: [github.com/superagents-lab/search1api-cli](https://github.com/superagents-lab/search1api-cli)