# Introduction

> Search1API gives AI applications one API for discovering, reading, and structuring information from the live web.

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

Search1API gives AI applications live web access through one API. It combines web and news search, page crawling, webpage screenshots, site discovery, trending feeds, and schema-driven extraction behind the same base URL and API key.

Use it when an agent, RAG pipeline, or backend needs current information without maintaining search-engine adapters or scraping infrastructure.

## A simple mental model

- [Discover](https://s1.dev/docs/basic/search): Find relevant pages with web search, recent coverage with news search, or current developer topics with trending feeds.
- [Read](https://s1.dev/docs/basic/crawl): Turn one page into clean text, fetch the top search results with crawl_results, or crawl a site asynchronously.
- [Capture](https://s1.dev/docs/basic/screenshot): Render a full page, viewport, or page element as PNG, JPEG, or WebP.
- [Structure](https://s1.dev/docs/advanced/extract): Extract fields from a page into a JSON shape you define.

Most agent workflows begin with `/search`. Add `crawl_results` when the model needs the source text rather than links and snippets. If you already have a URL, start with `/crawl` instead.

For the complete decision guide, see [Choosing an endpoint](https://s1.dev/docs/guides/choosing-an-endpoint).

## Choose your starting point

- [Make your first API call](https://s1.dev/docs/get-started/quickstart): Create a key, run one request, and understand the response.
- [Add an official SDK](https://s1.dev/docs/integrations/sdks): Install the TypeScript or Python client for application code.
- [Connect an AI tool](https://s1.dev/docs/integrations/mcp): Use Search1API through MCP, the CLI, or an agent skill.
- [Choose an endpoint](https://s1.dev/docs/guides/choosing-an-endpoint): Match search, crawl, screenshot, extract, sitemap, and deepcrawl to your task.

## When you are ready for production

- [Authentication](https://s1.dev/docs/essentials/authentication): Store, separate, and revoke API keys safely.
- [Credits and limits](https://s1.dev/docs/essentials/credits-and-limits): Understand request costs, balances, and rate limits.
- [Error handling](https://s1.dev/docs/essentials/error-handling): Handle validation, authentication, payment, and upstream failures.

---

# Quickstart

> Create an API key, make one web search request, and understand the response.

Canonical URL: https://s1.dev/docs/get-started/quickstart

<Steps>
  <Step>
    ### Get an API key

    Sign up at [app.s1.dev](https://app.s1.dev), then open **API Keys** and create a key. New accounts receive [100 free Search API credits](https://s1.dev/free-search-api?utm_source=docs\&utm_medium=referral\&utm_campaign=free_search_api) without a credit card or expiration date.

    Keep the key server-side. For local development, put it in an environment variable:

    ```bash
    export SEARCH1API_KEY="YOUR_API_KEY"
    ```
  </Step>

  <Step>
    ### Search the web

    ```bash
    curl -X POST https://api.search1api.com/search \
      -H "Authorization: Bearer $SEARCH1API_KEY" \
      -H "Content-Type: application/json" \
      -d '{"query": "best open source vector databases"}'
    ```
  </Step>

  <Step>
    ### Read the response

    ```json
    {
      "searchParameters": {
        "query": "best open source vector databases",
        "max_results": 5
      },
      "results": [
        {
          "title": "Qdrant - Vector Database",
          "link": "https://qdrant.tech/",
          "snippet": "Qdrant is an open source vector database...",
          "content": ""
        }
      ]
    }
    ```

    Search returns up to five results by default. `snippet` is the search engine summary. `content` is populated when you ask Search1API to crawl a result.
  </Step>

  <Step>
    ### Decide what to build next

    Your first request is complete. From here:

    * If the model needs full page text, learn how to use `crawl_results` in [Improving search results](https://s1.dev/docs/guides/improving-search-results#read-the-results-not-just-the-snippets).
    * If you are starting from a URL or need structured data, use [Choosing an endpoint](https://s1.dev/docs/guides/choosing-an-endpoint).
    * Before production, review [Authentication](https://s1.dev/docs/essentials/authentication), [Credits and limits](https://s1.dev/docs/essentials/credits-and-limits), and [Error handling](https://s1.dev/docs/essentials/error-handling).
  </Step>
</Steps>

## Other ways to connect

- [Official SDKs](https://s1.dev/docs/integrations/sdks): Use typed TypeScript or Python clients with retries, errors, and deepcrawl polling included.
- [Search API reference](https://s1.dev/docs/basic/search): Review every request field and response schema.
- [MCP server](https://s1.dev/docs/integrations/mcp): Connect an MCP-compatible AI client without writing API code.
- [CLI](https://s1.dev/docs/integrations/cli): Search and crawl from your terminal.

---

# Authentication

> Choose OAuth 2.1 or API keys, send bearer credentials safely, and recover from authentication failures.

Canonical URL: https://s1.dev/docs/essentials/authentication

Search1API accepts OAuth access tokens and user-managed API keys as bearer credentials. Send either one in the same header to authenticated endpoints at `https://api.search1api.com`:

```http
Authorization: Bearer YOUR_ACCESS_TOKEN_OR_API_KEY
```

## Choose an authentication method

**Use OAuth 2.1** when an AI agent, native CLI, or OAuth-aware MCP client needs a user to approve access. The client can discover the authorization server, register as a public client, use Authorization Code + PKCE, and refresh access without asking the user to copy a long-lived API key.

**Use an API key** for fixed server-to-server integrations, CI, existing SDK configurations, or clients that do not support OAuth discovery yet. API keys remain fully supported.

Both methods use the same Search1API account, credit balance, billing rules, and rate limits.

## OAuth 2.1

Start with the protected resource used by the client:

* REST API: [`https://api.search1api.com/.well-known/oauth-protected-resource`](https://api.search1api.com/.well-known/oauth-protected-resource)
* Hosted MCP: [`https://mcp.search1api.com/.well-known/oauth-protected-resource`](https://mcp.search1api.com/.well-known/oauth-protected-resource)

These documents advertise the Search1API authorization server. A `401` response for an invalid bearer credential also includes a `WWW-Authenticate` challenge with the applicable `resource_metadata` URL. The Hosted MCP endpoint sends the same discovery challenge when no credential is present.

Search1API supports Dynamic Client Registration, Authorization Code with PKCE (`S256`), access and refresh tokens, and token revocation. A human account owner must still sign in and approve the client; dynamic registration does not silently create a Search1API user.

For the complete protocol flow and endpoint list, read the agent-friendly [`auth.md`](https://s1.dev/auth.md).

### First-party CLI

The Search1API CLI implements the complete public-client flow:

```bash
s1 login
s1 config show
```

It dynamically registers, opens the browser for approval, stores the resulting OAuth credentials locally, and refreshes expired access tokens automatically. See [CLI](https://s1.dev/docs/integrations/cli) for installation and fallback options.

### Hosted MCP

OAuth-aware MCP clients can point directly at `https://mcp.search1api.com/mcp` and follow the server's protected-resource challenge. Clients without OAuth support can continue using an API key. See [MCP server](https://s1.dev/docs/integrations/mcp) for both configurations.

## API keys

### Get a key

Sign in at [app.s1.dev](https://app.s1.dev), open **API Keys**, and create a key. The dashboard lets you label, reveal, copy, and delete existing keys.

### Keep keys server-side

Treat a key like a password. Store it in an environment variable or secret manager, and never expose it in browser code, mobile binaries, logs, or a public repository.

> **warn:** Anyone who has the key can make requests against your account balance. If a key leaks, replace it and delete the old key immediately.

### Separate keys by workload

Use different keys for environments or services so you can identify traffic and revoke one integration without interrupting the others. Add a clear label in the dashboard, such as `production-api`, `staging`, or `claude-mcp`.

All keys owned by the same account draw from the same credit balance. Separate keys improve attribution and revocation; they do not create separate balances.

### Rotate or revoke a key

There is no in-place rotation action. To replace a key:

1. Create a new key.
2. Update the application or integration.
3. Confirm requests succeed with the new key.
4. Delete the old key.

Deleting a key revokes it. Requests that continue using it return `401 Unauthorized`.

## Authentication failures

An invalid, expired, or revoked bearer credential returns `401`. OAuth-aware clients should use the accompanying `WWW-Authenticate` metadata to discover authorization or refresh an expired token before retrying.

A request with no bearer credential currently receives a `402` payment challenge on paid API endpoints because Search1API also supports pay-per-request payment protocols. The Hosted MCP endpoint instead returns a `401` OAuth discovery challenge when no credential is present.

See [Error handling](https://s1.dev/docs/essentials/error-handling) for response bodies and recovery guidance.

---

# Credits and limits

> Understand Search1API request costs, account balances, top-ups, auto top-up, rate limits, and timeouts.

Canonical URL: https://s1.dev/docs/essentials/credits-and-limits

Search1API deducts credits when a request completes successfully. A search that completes but finds zero results is a successful request and is charged; requests that fail with an error status — including `502` service failures — are not charged.

## Request costs

| Endpoint                         | Credits |
| -------------------------------- | ------- |
| `POST /search`                   | 1       |
| `POST /news`                     | 1       |
| `POST /crawl`                    | 1       |
| `POST /screenshot`               | 2       |
| `POST /sitemap`                  | 1       |
| `POST /trending`                 | 1       |
| `POST /extract`                  | 10      |
| `POST /deepcrawl`                | 20      |
| `GET /deepcrawl/status/{taskId}` | free    |
| `GET /usage`                     | free    |

## Search with full page content

`/search` and `/news` have a dynamic cost when you set `crawl_results`:

```text
1 credit for the search + 1 credit for each page crawled successfully
```

For example, if `crawl_results` is `4` and three pages return content, the request costs 4 credits. The unsuccessful crawl is not charged. `crawl_results` cannot be greater than `max_results`.

Batch requests are calculated item by item. A failed item has a cost of zero even when other items in the batch succeed.

## Free and paid credits

New accounts receive 100 credits without a credit card or expiration date. Subscriptions reset an allowance each month. Top-up credits never expire. When both balances are available, subscription credits are deducted before top-up credits.

See the [pricing page](https://s1.dev/pricing) for current plans and top-up amounts.

## Top up credits

Top up any amount from **$5 to $2,000*&#x2A;. The base rate is **$1 = 1,000 credits**. Larger top-ups receive a bonus on the whole amount:

* $19 or more: +5%
* $99 or more: +20%
* $499 or more: +60%

You can start a top-up from the [pricing page](https://s1.dev/pricing#pay-as-you-go) or from the dashboard. For amounts above $2,000, contact [sys@search1api.com](mailto:sys@search1api.com).

## Auto top-up

Auto top-up is optional and off by default. In the [dashboard](https://app.s1.dev/), set a credit threshold, a top-up amount, and a card. Search1API charges that amount only after your combined available subscription and top-up credits fall below the threshold.

Automatic top-ups use the same bonus tiers as a manual top-up. Saving the rule does not charge the card. Automatic top-ups are capped at three charges in any 24-hour window, and the feature turns itself off after three consecutive payment failures. The threshold must be lower than the credits one top-up grants, so a single refill can move the balance back above the line.

If auto top-up is enabled and can still run, Search1API skips the generic low-balance email. A failed charge sends its own notice; after repeated failures you can update the card and turn the rule back on.

## Check your balance

```bash
curl https://api.search1api.com/usage \
  -H "Authorization: Bearer YOUR_API_KEY"
```

```json
{ "usage": 24980 }
```

The `usage` field is the number of credits remaining. When the balance cannot cover a successful request, the API returns `402 Payment Required` instead of the original success response.

## Rate limit

For bearer-authenticated requests billed to account credits, most endpoints allow **200 requests per minute per account**. Screenshot rendering has a separate limit of **10 requests per minute per account**. Requests made with different API keys from the same account share these limits.

A request above its endpoint limit returns `429 Too Many Requests` with a `Retry-After: 60` header. Wait for that interval before retrying. Contact [sys@search1api.com](mailto:sys@search1api.com) if you need a higher limit.

## Client timeouts

Search and result-crawling operations can wait up to 20 seconds for an upstream service. Screenshot requests accept a `timeout_ms` value from 1 to 30 seconds. Set the client timeout above the API timeout so the server can return a useful error response.

`POST /deepcrawl` is asynchronous. A successful start returns `202 Accepted` with a `taskId`; poll `GET /deepcrawl/status/{taskId}` for the result. Status checks cost no credits.

> **info:** For status-specific recovery behavior, see [Error handling](https://s1.dev/docs/essentials/error-handling).

---

# Error handling

> Handle Search1API authentication, payment, validation, rate-limit, and upstream errors.

Canonical URL: https://s1.dev/docs/essentials/error-handling

Most API errors are JSON objects with `ok: false` and either `error`, `message`, or both. Validation errors also include an `errors` array.

```json
{ "error": "Unauthorized: Invalid API Key", "ok": false }
```

`POST /screenshot` is the exception on success: it returns image bytes with an `image/png`, `image/jpeg`, or `image/webp` content type. Its error responses still use JSON, so check `response.ok` before choosing how to read the body.

## Status codes

| Status | Meaning                                                                                                    | What to do                                                                                                                                                                                                                                                                       |
| ------ | ---------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `400`  | Malformed JSON or an invalid request value handled outside schema validation                               | Fix the request body and headers.                                                                                                                                                                                                                                                |
| `401`  | Invalid, revoked, or malformed bearer token                                                                | Check the key and the `Authorization` header.                                                                                                                                                                                                                                    |
| `402`  | Payment challenge or insufficient account credits                                                          | Add a bearer token, complete the payment flow, or add credits.                                                                                                                                                                                                                   |
| `403`  | Screenshot target failed URL safety or hostname-resolution checks                                          | Use a public HTTP or HTTPS URL without credentials. Verify that its public DNS resolves before retrying.                                                                                                                                                                         |
| `404`  | A deepcrawl task was not found, or the `/crawl` target server confirmed the URL does not exist             | For deepcrawl, verify the task ID before polling again. For `/crawl`, the dead link is a verified, completed answer (see below) — fix the URL instead of retrying. `/search` and `/news` no longer return `404` — zero results come back as `200` with an empty `results` array. |
| `410`  | A discontinued reasoning endpoint, or the `/crawl` target server confirmed the URL was permanently removed | Remove calls to `/v1/chat/completions` and `/v1/models`. For `/crawl`, treat it like a verified dead link.                                                                                                                                                                       |
| `422`  | Request body failed schema validation                                                                      | Read the `errors` array and fix the named fields.                                                                                                                                                                                                                                |
| `429`  | The endpoint's per-key rate limit was exceeded                                                             | Wait for the `Retry-After` interval, then retry.                                                                                                                                                                                                                                 |
| `502`  | An upstream service failed or timed out                                                                    | Retry with backoff.                                                                                                                                                                                                                                                              |
| `500`  | An unexpected gateway or service error                                                                     | Retry; contact support if it persists.                                                                                                                                                                                                                                           |

## Understand 402 responses

A paid endpoint can return `402` for two different reasons.

### No bearer token

Search1API supports pay-per-request payment protocols. A request without a bearer token receives a payment challenge such as:

```json
{
  "type": "https://paymentauth.org/problems/payment-required",
  "title": "Payment Required",
  "status": 402,
  "detail": "Payment is required (Search1API - Search API)."
}
```

If you intended to use account credits, add `Authorization: Bearer YOUR_API_KEY`. A bearer token that is present but invalid returns `401` instead.

### Not enough credits

When a request succeeds but its final cost is higher than the remaining balance, billing replaces the success response with `402` and an insufficient-credits message. Check the balance with `GET /usage`, [top up credits](https://s1.dev/pricing#pay-as-you-go), or turn on auto top-up in the [dashboard](https://app.s1.dev/).

## Fix validation errors

Search and news validation failures return `422` with an `errors` array:

```json
{
  "ok": false,
  "message": "Query cannot be empty",
  "errors": [
    { "field": "query", "message": "Query cannot be empty", "code": "too_small" }
  ]
}
```

Common causes include an empty `query`, `max_results` below 1, or `crawl_results` greater than `max_results`. See the endpoint's API reference for its complete schema.

## Zero results vs. service failures

`/search` and `/news` distinguish between a search that finds nothing and a search that could not run:

* **Zero results**: when the search completes and the engines confirm there are no matches, the response is `200` with an empty `results` array. This is a successful, completed search and is charged normally (1 credit). Broaden the query or remove narrow site and time filters to get matches.
* **Service failure**: when the search could not be completed on our side (upstream outage, timeout, anti-bot interference), the response is `502` and the request is **not** charged. Retry with backoff.

`/crawl` follows the same principle for dead links:

* **Verified dead link**: when the target server itself confirms the URL does not exist (`404`) or was permanently removed (`410`), the crawl ran to completion and the authoritative answer is "there is nothing here". The response passes that status through with an explanatory message, and the request is charged normally (1 credit) — the same way a confirmed zero-result search is. Do not retry; fix the URL.
* **Service failure**: when we could not reach or process the target (timeout, upstream outage, blocked exit), the response is `502` and the request is **not** charged. Retry with backoff.

## Retry safely

Search, crawl, and screenshot requests have no write-side effects. Retry `429`, `502`, `503`, `504`, and transient `500` responses with exponential backoff and jitter. Do not retry `400`, `401`, `402`, or `422` until you have changed the request or account state. Do not retry a `/crawl` `404` or `410` — the target server has confirmed the URL is dead, and each retry is a new billable lookup. For a Screenshot `403`, correct the target or confirm that its public DNS resolves before retrying.

> **info:** Requests that fail because the service could not complete them are not charged. Two completed outcomes are charged even though they carry a non-`200` status or empty payload: a search that completes with zero results (`200` with an empty `results` array), and a `/crawl` whose target server confirmed the URL is dead (`404`/`410`) — both are verified answers, not failures. In a batch request, successful items — including confirmed zero-result searches — are charged, and failed items have a cost of zero.

If a `500` or `502` persists, contact [sys@search1api.com](mailto:sys@search1api.com) with the endpoint, timestamp, and a redacted request body. Never send your API key.

---

# Choosing an endpoint

> Match a Search1API endpoint to the information you have and the result you need.

Canonical URL: https://s1.dev/docs/guides/choosing-an-endpoint

Start with two questions:

1. Do you have a topic, a URL, or an entire site?
2. Do you need links, readable text, structured fields, or a list of pages?

## Endpoint map

| Your starting point | What you need                       | Use                                                  |
| ------------------- | ----------------------------------- | ---------------------------------------------------- |
| A topic or question | Ranked web pages                    | [`POST /search`](https://s1.dev/docs/basic/search)                      |
| A topic or question | Ranked pages plus full text         | [`POST /search`](https://s1.dev/docs/basic/search) with `crawl_results` |
| A current event     | Recent coverage from news sources   | [`POST /news`](https://s1.dev/docs/basic/news)                          |
| One URL             | Readable page content               | [`POST /crawl`](https://s1.dev/docs/basic/crawl)                        |
| One URL             | A rendered PNG, JPEG, or WebP image | [`POST /screenshot`](https://s1.dev/docs/basic/screenshot)              |
| One URL             | Fields that match a JSON Schema     | [`POST /extract`](https://s1.dev/docs/advanced/extract)                 |
| One site            | A list of its URLs                  | [`POST /sitemap`](https://s1.dev/docs/advanced/sitemap)                 |
| One site            | Content from many pages             | [`POST /deepcrawl`](https://s1.dev/docs/advanced/deepcrawl)             |
| No query            | GitHub or Hacker News trends        | [`POST /trending`](https://s1.dev/docs/advanced/trending)               |

## Topic or URL: search vs. crawl

Use `/search` when you need to discover relevant pages. Use `/crawl` when you already know which page to read.

When you begin with a topic but also need source text, set `crawl_results` on `/search`. Search1API will crawl the top results in the same request. See [Improving search results](https://s1.dev/docs/guides/improving-search-results#read-the-results-not-just-the-snippets) for the request pattern.

## Text or fields: crawl vs. extract

Use `/crawl` when a model or person will read the page as text: summarization, question answering, or RAG ingestion.

Use `/extract` when your application needs typed fields in a predictable shape. You provide the URL, an extraction prompt, and a JSON Schema; the endpoint returns data that follows that schema.

If you plan to crawl a page and immediately ask a model to convert it into fields, `/extract` combines those steps.

## Page content or pixels: crawl vs. screenshot

Use `/crawl` when you need the page as readable text for an agent, search index, summary, or RAG pipeline.

Use `/screenshot` when layout and visual state matter: link previews, visual regression inputs, archived page images, or vision-model input. It renders the page in a managed browser and returns image bytes directly.

## URL list or site content: sitemap vs. deepcrawl

Use `/sitemap` to discover which URLs a site contains. It returns links synchronously and is useful when your application will decide what to fetch next.

Use `/deepcrawl` when you need content from many pages. It runs asynchronously: the start request returns `202 Accepted` with a `taskId`, and you poll `GET /deepcrawl/status/{taskId}` until the task finishes.

## Web coverage or recent reporting: search vs. news

Use `/search` for general web discovery. Use `/news` when recency and news-specific sources are central to the task. Both endpoints support `time_range`, but they search different source sets.

## A common agent workflow

For research and answer-generation agents:

1. Start with `/search` and a small `crawl_results` value to collect ranked sources and readable text.
2. Use `/crawl` when you need to revisit a specific URL as text, or `/screenshot` when the workflow needs its visual state.
3. Use `/extract` when the output must follow a stable data schema.

Review [Credits and limits](https://s1.dev/docs/essentials/credits-and-limits) before choosing crawl depth or running the workflow in a batch.

---

# Improving search results

> Choose sources, retrieve full page text, and narrow Search1API results by site, time, and language.

Canonical URL: https://s1.dev/docs/guides/improving-search-results

Begin with the default search behavior, then add constraints only when the results show that you need them.

## Let Search1API choose sources by default

If you omit `search_service`, Search1API runs several engines concurrently and fuses their rankings into one result list. Keep this default when you want broad web coverage.

Set `search_service` when the source itself is part of the request:

```json
{ "query": "rust async runtime", "search_service": "reddit" }
```

For example, Reddit is useful for experience reports, GitHub for code and issues, arXiv for papers, and YouTube for video.

## Available web search sources

| Source       | Useful for                         |
| ------------ | ---------------------------------- |
| `google`     | General web                        |
| `bing`       | General web                        |
| `duckduckgo` | General web                        |
| `yahoo`      | General web                        |
| `x`          | Posts and reactions on X           |
| `reddit`     | Discussions and experience reports |
| `github`     | Code, repositories, and issues     |
| `youtube`    | Video                              |
| `arxiv`      | Preprints and academic papers      |
| `wikipedia`  | Encyclopedic background            |
| `imdb`       | Film and television                |
| `wechat`     | WeChat public-account articles     |
| `bilibili`   | Chinese-language video             |
| `baidu`      | Chinese-language general web       |
| `sogou`      | Chinese-language general web       |
| `quark`      | Chinese-language general web       |
| `360`        | Chinese-language general web       |

`/news` uses a separate source set: `google`, `bing`, `duckduckgo`, `yahoo`, `hackernews`, and `reuters`. Omitting `search_service` also enables the default multi-source behavior for news.

`/trending` supports `github` and `hackernews`, and requires `search_service`.

## Read the results, not just the snippets

Search results include a short `snippet`. When a model needs the source text, set `crawl_results` to crawl the top results and populate their `content` fields:

```bash
curl -X POST https://api.search1api.com/search \
  -H "Authorization: Bearer $SEARCH1API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "query": "postgres connection pooling best practices",
    "max_results": 10,
    "crawl_results": 3
  }'
```

This returns up to ten ranked results and attempts to add full text to the top three. `crawl_results` must be no greater than `max_results`.

> **info:** A search costs 1 credit, plus 1 credit for each page crawled successfully. See [Credits and limits](https://s1.dev/docs/essentials/credits-and-limits#search-with-full-page-content).

## Narrow by site

Use `include_sites` to search only selected domains and `exclude_sites` to remove unwanted ones:

```json
{
  "query": "vector database benchmarks",
  "include_sites": ["github.com", "news.ycombinator.com"],
  "exclude_sites": ["pinterest.com"]
}
```

> **warn:** A narrow `include_sites` list combined with a specific query can produce an empty `results` array — a completed, charged search that simply found no matches. Remove constraints one at a time to widen the match pool.

## Narrow by time or language

`time_range` accepts `day`, `week`, `month`, or `year`. Use it when freshness matters instead of adding words such as “latest” to the query.

`language` accepts a language code such as `en`, `zh-CN`, or `fr`. Search1API does not expose a separate country or region parameter.

## Control result count

`max_results` defaults to 5 and accepts values from 1 to 50. The gateway clamps numeric values above 50 to 50.

For the complete request schema, image results, batch bodies, and response fields, see the [Search API reference](https://s1.dev/docs/basic/search).

---

# Official SDKs

> Use the official TypeScript and Python clients for typed requests, errors, retries, batches, and deepcrawl polling.

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

The official SDKs are the shortest path for application code that calls
Search1API repeatedly. They cover every endpoint in the public OpenAPI contract
and add language-native configuration, typed responses, error classes, safe
retries, and deepcrawl polling.

Use [MCP](https://s1.dev/docs/integrations/mcp) when an AI client should call Search1API as a tool.
Use an SDK when your own TypeScript or Python application makes the calls.

## TypeScript

```bash
npm install @search1api/client
```

```ts
import { Search1API } from '@search1api/client';

const client = new Search1API({
  apiKey: process.env.SEARCH1API_API_KEY,
});

const response = await client.search('latest AI agent frameworks', {
  maxResults: 10,
  crawlResults: 3,
});

for (const result of response.results) {
  console.log(result.title, result.link);
}
```

The TypeScript package supports Node.js 18+ and other runtimes with a
standards-compatible `fetch` implementation.

[View the TypeScript SDK source on GitHub](https://github.com/superagents-lab/search1api-js).

## Python

```bash
pip install search1api
```

```python
from search1api import Search1API

client = Search1API()  # reads SEARCH1API_API_KEY
response = client.search(
    "latest AI agent frameworks",
    max_results=10,
    crawl_results=3,
)

for result in response["results"]:
    print(result["title"], result["link"])
```

An asynchronous client exposes the same operations:

```python
from search1api import AsyncSearch1API

async with AsyncSearch1API() as client:
    response = await client.search("latest AI agent frameworks")
```

[View the Python SDK source on GitHub](https://github.com/superagents-lab/search1api-python).

## Binary Screenshot responses

The Screenshot API returns image bytes rather than a JSON object. Both SDKs
preserve the response content type and request ID alongside the binary body.

```ts
import { writeFile } from 'node:fs/promises';

const screenshot = await client.screenshot('https://example.com', {
  format: 'png',
  fullPage: true,
});

await writeFile('screenshot.png', screenshot.data);
console.log(screenshot.contentType, screenshot.requestId);
```

```python
from pathlib import Path

screenshot = client.screenshot(
    "https://example.com",
    format="png",
    full_page=True,
)

Path("screenshot.png").write_bytes(screenshot["data"])
print(screenshot["content_type"], screenshot.get("request_id"))
```

## Deepcrawl without hand-written polling

Both SDKs provide a convenience method that starts the task and waits until it
completes.

```ts
const result = await client.deepcrawl('https://example.com', { type: 'all' });
console.log(result.zipUrl);
```

```python
result = client.deepcrawl("https://example.com", type="all")
print(result["zipUrl"])
```

Use the separate start, status, and wait methods when the task ID needs to be
persisted by your application.

## Errors, retries, and timeouts

The SDKs expose separate errors for authentication (`401`), payment or credits
(`402`), validation (`400`/`422`), not found (`404`), rate limits (`429`), and
server failures. The status code and parsed response body remain available on
the error.

Requests use a 30-second timeout and retry `429` and transient `5xx` responses
twice by default. Authentication, payment, and validation errors are never
retried. Starting a deepcrawl task is also not retried automatically because a
lost response could otherwise create and charge a duplicate task. Configure
the defaults on the client when your workload needs a different policy.

## API coverage

The first-party clients support search and news (single and batch), crawl
(single and batch), Screenshot, sitemap, trending, extract, deepcrawl, usage,
and health. The generated OpenAPI types are also exported from the TypeScript
package for applications that need the exact wire-level contract.

---

# LangChain

> Give LangChain agents live web search, news, and page content with the official search1api-langchain toolkit.

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

`search1api-langchain` is the official Search1API integration for LangChain. It
exposes web search, news search, and page crawling through LangChain's standard
tool interface, and relies on the official Search1API Python SDK for
authentication, retries, timeouts, and API errors.

> **info:** The similarly named `langchain-search1api` package on PyPI is an independent
> third-party project. `search1api-langchain` is the package maintained by
> Search1API.

## Install

```bash
pip install search1api-langchain
```

Create a key in the [dashboard](https://app.s1.dev), then export it:

```bash
export SEARCH1API_API_KEY="your-api-key"
```

`SEARCH1API_KEY` is also accepted, so the same environment works for the
[Search1API CLI](https://s1.dev/docs/integrations/cli).

## Use the whole toolkit

`Search1APIToolkit` returns all three tools at once, ready to hand to an agent.

```python
from langchain.agents import create_agent
from search1api_langchain import Search1APIToolkit

agent = create_agent(
    model="openai:gpt-5.4",
    tools=Search1APIToolkit().get_tools(),
)

response = agent.invoke(
    {"messages": [{"role": "user", "content": "What changed in LangChain this month?"}]}
)
```

The toolkit provides `search1api_search`, `search1api_news`, and
`search1api_crawl`. Each tool is also importable on its own when an agent should
only receive one capability.

Every tool supports asynchronous invocation:

```python
from search1api_langchain import Search1APISearchTool

search = Search1APISearchTool()
result = await search.ainvoke({"query": "async Python agents"})
```

An explicit key and client settings can be supplied when environment-based
configuration is not appropriate:

```python
from search1api_langchain import Search1APISearchTool

search = Search1APISearchTool(
    api_key="your-api-key",
    timeout=45,
    max_retries=3,
)
```

API keys use Pydantic's secret type and are excluded from model serialization.

## Search

`search1api_search` returns ranked web results for a query.

```python
from search1api_langchain import Search1APISearchTool

search = Search1APISearchTool()

results = search.invoke(
    {
        "query": "latest LangChain agent releases",
        "max_results": 5,
        "time_range": "month",
    }
)
```

Each result carries `title`, `link`, and `snippet`. Setting `crawl_results` also
fills `content` with the readable page text, and image queries return an
`images` list. `search_service` selects the upstream engine when a specific one
is required.

See [Search](https://s1.dev/docs/basic/search) for the full request and response contract.

## News

`search1api_news` returns recent news articles for a query, with the same
result shape as search.

```python
from search1api_langchain import Search1APINewsTool

news = Search1APINewsTool()

articles = news.invoke({"query": "AI regulation", "time_range": "day"})
```

See [News](https://s1.dev/docs/basic/news) for supported sources and parameters.

## Crawl

`search1api_crawl` reads a known URL and returns clean, readable content. It
fetches and extracts page content; it does not drive a browser session.

```python
from search1api_langchain import Search1APICrawlTool

crawl = Search1APICrawlTool()

page = crawl.invoke({"url": "https://example.com/article"})
```

Pass a URL returned by search when an agent needs the full article rather than a
snippet. See [Crawl](https://s1.dev/docs/basic/crawl) for the full contract.

## Credits

Search and news requests cost one credit each. Setting `crawl_results` asks
Search1API to read the top result pages and costs one additional credit for each
page crawled successfully, so the tools default it to `0`. A crawl request costs
one credit.

New accounts receive 100 credits without a credit card or expiration date. See
[Credits and limits](https://s1.dev/docs/essentials/credits-and-limits) for current rates.

## Source

[github.com/superagents-lab/search1api-langchain](https://github.com/superagents-lab/search1api-langchain)
· [PyPI](https://pypi.org/project/search1api-langchain/)

---

# MCP server

> Give Claude, Cursor, VS Code or any MCP client live web access with a hosted Search1API MCP endpoint — no code required.

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

Search1API runs a hosted MCP server at:

```
https://mcp.search1api.com/mcp
```

Point an OAuth-aware MCP client at it and Search1API will advertise the authorization flow automatically. Clients that do not support OAuth discovery can continue using an API key. Either way, the model can search the web, read pages and check what's trending without you writing an integration.

## Tools it exposes

| Tool       | What it does                | Required         |
| ---------- | --------------------------- | ---------------- |
| `search`   | Web search                  | `query`          |
| `news`     | News search                 | `query`          |
| `crawl`    | Read a URL                  | `url`            |
| `sitemap`  | List a site's links         | `url`            |
| `trending` | GitHub / Hacker News trends | `search_service` |

## Connect your client

### OAuth 2.1 (preferred)

For a client that supports OAuth discovery, start with the endpoint only:

```json
{
  "mcpServers": {
    "search1api": {
      "url": "https://mcp.search1api.com/mcp"
    }
  }
}
```

The exact outer configuration key varies by client, but the server URL is the same. On the first connection, the server returns a `WWW-Authenticate` challenge pointing to:

```
https://mcp.search1api.com/.well-known/oauth-protected-resource/mcp
```

The client can then discover Search1API's authorization server, dynamically register, and use Authorization Code + PKCE. The account owner signs in and approves access in the browser. A client that requests `offline_access` can refresh its access token for long-running sessions.

> **info:** OAuth support depends on the MCP client. If a client does not follow protected-resource discovery, use the API-key configuration below.

### API key fallback

Create a key at [app.s1.dev](https://app.s1.dev), then use the configuration for your client. The dashboard's **MCP** page can generate these examples with the key filled in.

<Tabs items="['Claude Code', 'Claude Desktop', 'Cursor', 'VS Code', 'Windsurf', 'Claude.ai']">
  <Tab value="Claude Code">
    ```bash
    claude mcp add --transport http search1api https://mcp.search1api.com/mcp \
      --header "Authorization: Bearer YOUR_SEARCH1API_KEY"
    ```
  </Tab>

  <Tab value="Claude Desktop">
    ```json
    {
      "mcpServers": {
        "search1api": {
          "url": "https://mcp.search1api.com/mcp",
          "headers": {
            "Authorization": "Bearer YOUR_SEARCH1API_KEY"
          }
        }
      }
    }
    ```
  </Tab>

  <Tab value="Cursor">
    ```json
    {
      "mcpServers": {
        "search1api": {
          "url": "https://mcp.search1api.com/mcp",
          "headers": {
            "Authorization": "Bearer YOUR_SEARCH1API_KEY"
          }
        }
      }
    }
    ```
  </Tab>

  <Tab value="VS Code">
    Note the different key (`servers`, not `mcpServers`) and the required `type`:

    ```json
    {
      "servers": {
        "search1api": {
          "type": "http",
          "url": "https://mcp.search1api.com/mcp",
          "headers": {
            "Authorization": "Bearer YOUR_SEARCH1API_KEY"
          }
        }
      }
    }
    ```
  </Tab>

  <Tab value="Windsurf">
    Windsurf passes the key in the URL rather than a header:

    ```json
    {
      "mcpServers": {
        "search1api": {
          "serverUrl": "https://mcp.search1api.com/mcp?apiKey=YOUR_SEARCH1API_KEY"
        }
      }
    }
    ```
  </Tab>

  <Tab value="Claude.ai">
    **Settings → Connectors → Add custom connector**, then paste:

    ```
    https://mcp.search1api.com/mcp?apiKey=YOUR_SEARCH1API_KEY
    ```
  </Tab>
</Tabs>

### Install via Smithery (optional)

Prefer a one-click install? Search1API is listed on [Smithery](https://smithery.ai/servers/superagents-lab/search1api-mcp), which supports 20+ MCP clients (Claude Code, Codex, Cursor, Windsurf, Gemini CLI, and more). A [search1api agent skill](https://smithery.ai/skills/superagents-lab/search1api) is also available for hosts that support skills.

## How auth works

The hosted server accepts either an OAuth access token or a Search1API API key in the `Authorization: Bearer <credential>` header. OAuth tokens and API keys use the same Search1API account credits, billing, and rate limits.

When no credential is present, the server returns a `401` challenge with its protected-resource metadata URL. Invalid or expired OAuth tokens return the same challenge with `error="invalid_token"`, allowing a compatible client to refresh or repeat authorization.

For legacy clients that cannot send headers, the server also accepts an API key in the `?apiKey=<key>` query parameter. The header wins when both are present.

Query-parameter auth means your key travels in a URL, where it can end up in logs and shell history. Prefer OAuth or a bearer header whenever the client supports one of them.

## Protocol support

The hosted server implements the Model Context Protocol revision `2026-07-28`, published on 28 July 2026. That revision removes protocol-level sessions and the `initialize` handshake: every request carries its own protocol version and client capabilities in `_meta`, and the server identifies itself in each result.

A request on `2026-07-28` needs two things beyond the ordinary JSON-RPC body:

* an `Mcp-Method` header matching the `method` in the body;
* a `_meta` object carrying `io.modelcontextprotocol/protocolVersion`, `io.modelcontextprotocol/clientInfo`, and `io.modelcontextprotocol/clientCapabilities`.

Call `server/discover` to read the supported versions, capabilities, and server identity before sending anything else:

```bash
curl -sS -X POST https://mcp.search1api.com/mcp \
  -H "Authorization: Bearer YOUR_SEARCH1API_KEY" \
  -H "Mcp-Method: server/discover" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -d '{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "server/discover",
    "params": {
      "_meta": {
        "io.modelcontextprotocol/protocolVersion": "2026-07-28",
        "io.modelcontextprotocol/clientInfo": { "name": "my-client", "version": "1.0.0" },
        "io.modelcontextprotocol/clientCapabilities": {}
      }
    }
  }'
```

It answers with the supported revisions and the server identity:

```json
{
  "result": {
    "supportedVersions": ["2026-07-28"],
    "capabilities": {
      "tools": { "listChanged": true },
      "resources": { "listChanged": true }
    },
    "resultType": "complete",
    "_meta": {
      "io.modelcontextprotocol/serverInfo": {
        "name": "search1api-server",
        "version": "0.5.1"
      }
    }
  }
}
```

Swap the `Mcp-Method` header and the `method` field for `tools/list` and the same envelope returns the tools above.

> **info:** Clients on the 2025 protocol revisions keep working unchanged. A client that sends `initialize` with `2025-06-18` still receives a normal response over both HTTP and stdio, so nothing you have configured today needs to move.

## Running it locally instead

The server also runs over stdio, straight from npm:

```json
{
  "mcpServers": {
    "search1api": {
      "command": "npx",
      "args": ["-y", "search1api-mcp"],
      "env": {
        "SEARCH1API_KEY": "YOUR_SEARCH1API_KEY"
      }
    }
  }
}
```

The local stdio package currently uses an API key. There is no network hop to us for the MCP protocol itself, but its API calls still go to `api.search1api.com`.

## Billing

MCP tool calls are ordinary API calls: they spend the same credits at the same rates as calling the endpoints yourself. See [Credits and limits](https://s1.dev/docs/essentials/credits-and-limits).

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

---

# LobeHub

> Configure Search1API as the search and crawler provider for LobeHub's built-in Web Search in a self-hosted deployment.

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

Search1API is built into LobeHub as both a search provider and a page crawler. In a self-hosted LobeHub deployment, you can use it to find current sources and read the pages behind those results without installing a marketplace plugin.

> **info:** This guide is for LobeHub's native **Web Search** skill on a self-hosted deployment. LobeHub
> Cloud already manages its own search infrastructure. If you want Search1API as a separate set of
> agent tools, see [MCP server](https://s1.dev/docs/integrations/mcp).

## Before you start

You need:

* a self-hosted LobeHub deployment;
* access to its server-side environment variables; and
* a Search1API API key.

Sign in at [app.s1.dev](https://app.s1.dev), open **API Keys**, and create a key. Keep it on the server and do not expose it in browser code or commit it to your repository.

## Configure search and page reading

Add these variables to the environment of your LobeHub server:

```bash
SEARCH_PROVIDERS="search1api"
CRAWLER_IMPLS="search1api,naive"
SEARCH1API_API_KEY="YOUR_SEARCH1API_KEY"
```

Then restart or redeploy LobeHub so the server process receives the new values.

This configuration gives Search1API two roles:

| Variable             | What it controls                                           |
| -------------------- | ---------------------------------------------------------- |
| `SEARCH_PROVIDERS`   | Providers LobeHub uses to find web results.                |
| `CRAWLER_IMPLS`      | Crawlers available to LobeHub when it reads a result page. |
| `SEARCH1API_API_KEY` | One shared key for Search1API search and crawl requests.   |

For ordinary URLs, `CRAWLER_IMPLS="search1api,naive"` makes LobeHub try Search1API first and fall back to its built-in crawler when Search1API returns an error or insufficient content. LobeHub may apply its own crawler rules for specific kinds of URLs.

## Use separate keys

For independent traffic attribution and revocation, create two Search1API keys and configure them by workload:

```bash
SEARCH_PROVIDERS="search1api"
CRAWLER_IMPLS="search1api,naive"
SEARCH1API_SEARCH_API_KEY="YOUR_SEARCH_KEY"
SEARCH1API_CRAWL_API_KEY="YOUR_CRAWL_KEY"
```

LobeHub resolves the keys as follows:

| Operation | First choice                | Fallback             |
| --------- | --------------------------- | -------------------- |
| Search    | `SEARCH1API_SEARCH_API_KEY` | `SEARCH1API_API_KEY` |
| Crawl     | `SEARCH1API_CRAWL_API_KEY`  | `SEARCH1API_API_KEY` |

All keys on the same Search1API account use the same credit balance. Separate keys make usage easier to identify and let you revoke one integration without interrupting the other.

## Add another fallback provider

`SEARCH_PROVIDERS` is also ordered. LobeHub tries providers from left to right and moves to the next configured provider when an earlier provider errors or returns no usable results.

For example:

```bash
SEARCH_PROVIDERS="search1api,searxng"
SEARXNG_URL="https://your-searxng-instance.example"
```

Keep `search1api` first when you want it to be the primary search provider. Each fallback provider needs its own required environment variables.

## Enable and verify Web Search

After the deployment restarts:

1. Open an Agent's **Profile** in LobeHub.
2. Select **+ Add Skill** and enable **Web Search**.
3. Start a new conversation and ask: `Search the web for the latest LobeHub release notes and cite the sources.`
4. Open one of the cited pages or ask the Agent to read and summarize that source.

The first request verifies search. Reading a cited URL verifies the crawler separately. LobeHub should show its search-grounding interface with the queries and cited sources.

## Troubleshooting

### Web Search does not run

* Confirm `SEARCH_PROVIDERS` contains the exact lowercase value `search1api`.
* Confirm Web Search is enabled for the Agent.
* Confirm the variables are attached to the LobeHub server process, not only your local shell.
* Restart or redeploy LobeHub after changing the environment.

### Search works, but pages are not read

* Confirm `CRAWLER_IMPLS` contains `search1api`.
* Test search and URL reading separately; they use different LobeHub implementations and may use different keys.
* Keep `naive` after `search1api` if you want LobeHub's built-in crawler as a fallback.

### `401 Unauthorized`

The API key is invalid or revoked. Create a replacement key, update the LobeHub environment, restart the deployment, verify requests with the new key, and then delete the old key. See [Authentication](https://s1.dev/docs/essentials/authentication).

### `402 Payment Required`

Either the key is not reaching the LobeHub process or the Search1API account does not have enough credits. Recheck the environment variable and then check the account balance. See [Credits and limits](https://s1.dev/docs/essentials/credits-and-limits).

### Search returns no results

Try a broader query without site or time constraints. LobeHub currently lets Search1API choose the underlying search engine automatically and does not pass every LobeHub search filter through to Search1API.

## Built-in provider or MCP?

Use the **built-in provider** when you want LobeHub's native Web Search experience, including its search-grounding UI and citations. Configure it with the environment variables on this page.

Use the **Search1API MCP server** when you want explicit `search`, `news`, `crawl`, `sitemap`, and `trending` tools in LobeHub or another MCP client. MCP is a separate integration and is not required for LobeHub's built-in Web Search.

You can enable both, but calls made through either path use Search1API credits. Start with the built-in provider for native LobeHub Web Search, then add MCP only when you need its additional tools or direct tool control.

## Related documentation

* [Search API](https://s1.dev/docs/basic/search)
* [Crawl API](https://s1.dev/docs/basic/crawl)
* [Authentication](https://s1.dev/docs/essentials/authentication)
* [Credits and limits](https://s1.dev/docs/essentials/credits-and-limits)
* [LobeHub: Configuring Online Search](https://lobehub.com/docs/self-hosting/advanced/online-search)

---

# 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 crawl <url>`                   | Read a page                             |
| `s1 sitemap <url>`                 | List a site's links                     |
| `s1 trending <github\|hackernews>` | Trending topics                         |
| `s1 balance`                       | Remaining credits                       |
| `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

# 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; omit to race several  |
| `-c, --crawl <N>`               | Crawl the top N results for full text |
| `--include` / `--exclude`       | Restrict or exclude sites             |
| `-t, --time <day\|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).

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)

---

# Agent skill

> Install the Search1API skill so Claude knows when to search, when to crawl, and how to tune the query — not just how to call the API.

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

An MCP server tells an agent *what it can call*. A skill tells it *when and how* — which is the part that actually determines whether the answers are any good.

## Install

```bash
npm install -g search1api-cli
npx skills add superagents-lab/search1api-cli
```

The skill drives the `s1` CLI, so the CLI has to be installed and logged in first. If it isn't, the skill will walk the user through it.

## What it changes

Without the skill, an agent with web access tends to fire one default search and paste the snippets back. The skill teaches it to adapt:

* A URL in the conversation means **crawl it**, not search for it.
* A quick factual lookup gets `-n 5` and no crawling. A deep research question gets `-n 15`, then crawls the top 3–5 for full text.
* Words like "latest" or "today" become `-t day`, rather than being typed into the query.
* It defines end-to-end workflows — deep research, URL summarization, trending deep-dives — instead of one-shot calls.
* It always synthesizes an answer rather than dumping raw results.

That is the difference between an agent that *has* a search tool and one that *knows how to search*.

## Using it

Once installed, just talk to your agent normally:

* "search for the latest AI news"
* "what does this link say? [https://example.com](https://example.com)"
* "what's trending on GitHub?"
* "research quantum computing thoroughly"

The skill picks the command, the engine, the result count and whether to crawl.

## Cost

The skill calls the same API as everything else, and spends the same credits — deep research modes crawl pages, so they cost more than a plain search. See [Credits and limits](https://s1.dev/docs/essentials/credits-and-limits).

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

---

# n8n

> Add web search, news, page retrieval, sitemap discovery and trending topics to n8n workflows with the verified n8n-nodes-search1api community node.

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

`n8n-nodes-search1api` is a [verified n8n community node](https://n8n.io/integrations/) that gives n8n workflows live web access through Search1API — web search, news search, readable page retrieval, sitemap discovery, and trending topics, all through the native n8n node interface.

> **info:** **Verified status:** `n8n-nodes-search1api` has passed n8n's automated and manual review and is listed in the [official n8n community node catalog](https://n8n.io/integrations/).

## Install

In n8n, install the community node `n8n-nodes-search1api` from **Settings → Community Nodes**, or from the command line:

```bash
npm install n8n-nodes-search1api
```

Then restart n8n. The node appears under **Search1API** in the node panel.

## Credentials

1. Create a key in the [Search1API dashboard](https://app.s1.dev).
2. In n8n, create a **Search1API API** credential and paste the key.
3. Test the credential — the test calls the read-only `/usage` endpoint and does not run a search.

Keep API keys in n8n credentials, never in workflow fields or exported workflow JSON.

## Operations

| Operation                    | What it does                                                                                                   |
| ---------------------------- | -------------------------------------------------------------------------------------------------------------- |
| **Web Search: Search**       | Search the live web with Google, Bing, DuckDuckGo, Reddit, GitHub, YouTube, arXiv, Wikipedia and other sources |
| **News Search: Search**      | Search current news from Bing, Google, DuckDuckGo, Yahoo, Hacker News or Reuters                               |
| **Page: Retrieve**           | Retrieve readable content from a public URL                                                                    |
| **Sitemap: Discover**        | Discover a site's sitemap URLs or all public links                                                             |
| **Trending Topic: Get Many** | Get current GitHub or Hacker News trends                                                                       |
| **Usage: Get**               | Inspect API-key usage over a selected period                                                                   |

The Search1API node can also be used as an n8n AI tool inside AI-agent workflows.

## Tips

For a focused lookup use **Web Search** with five to ten results. For deeper research, increase the result count and set **Crawl Results** to retrieve the full text of the most relevant results.

Use a vertical source when the workflow has a clear target:

* **GitHub** for repositories and code projects
* **Reddit** for community discussions
* **ArXiv** for research papers
* **YouTube** for videos
* **WeChat** or **Bilibili** for Chinese-language content

Every operation is read-only. Search results include source URLs that can be passed to later workflow steps.

## Credits

Search and news requests cost one credit each; crawling a page costs one additional credit per successfully crawled page. New accounts receive 100 credits without a credit card. See [Credits and limits](https://s1.dev/docs/essentials/credits-and-limits) for current rates.

## Source

[github.com/superagents-lab/n8n-nodes-search1api](https://github.com/superagents-lab/n8n-nodes-search1api)
· [npm](https://www.npmjs.com/package/n8n-nodes-search1api)
· [n8n community nodes](https://docs.n8n.io/integrations/community-nodes/)

---

# OpenAPI and llms.txt

> Machine-readable entry points to Search1API — an OpenAPI schema for code generators, and llms.txt for agents.

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

Machine-readable entry points let tools discover Search1API without scraping the rendered docs.

## OpenAPI schema

```
https://api.search1api.com/openapi.json
```

This is the canonical contract used to validate the [official SDKs](https://s1.dev/docs/integrations/sdks). You can also point a code generator at it to create a lower-level client in another language, or import it into tools such as Postman and Insomnia.

Every response we serve advertises it too, via a `Link` header with `rel="service-desc"` — so a client that follows link relations can find the schema on its own.

## llms.txt files

```
https://s1.dev/llms.txt
```

This is the curated, product-wide index for language models: product overview, pricing, documentation, agent interfaces, and the OpenAPI schema, all as links with one-line descriptions.

The docs app also publishes two files generated from the current Fumadocs source:

* [`/docs/llms.txt`](https://s1.dev/docs/llms.txt) — a compact index of every documentation page.
* [`/docs/llms-full.txt`](https://s1.dev/docs/llms-full.txt) — the full documentation as clean Markdown, with imports and rendering code removed.

The product-wide [`/llms-full.txt`](https://s1.dev/llms-full.txt) automatically combines the curated product index, the agent-friendly [`/pricing.md`](https://s1.dev/pricing.md), and the generated full documentation.

## Which to use

Writing TypeScript or Python application code? Use an [official SDK](https://s1.dev/docs/integrations/sdks). Generating another language client, or importing the API into a tool? Use the OpenAPI schema. Helping a model discover the product? Use the root `llms.txt`. Providing the documentation as context? Use `/docs/llms-full.txt` or the combined root `/llms-full.txt`. Building an agent that will actually *call* the API? Use the [MCP server](https://s1.dev/docs/integrations/mcp).

---

# DeepSeek Harness

> Give your DeepSeek Harness agent live web access with the native dsh-s1 plugin — web search, news, page retrieval, sitemap discovery, and trending topics as first-class dsh tools.

Canonical URL: https://s1.dev/docs/integrations/deepseek-harness

`dsh-s1` is a native [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness) (DSH) plugin that gives your dsh agent live web access through Search1API — web search, news search, readable page retrieval, sitemap discovery, and trending topics.

Unlike an MCP bridge, the plugin registers these capabilities as **first-class DSH tools** — the same layer as `read`, `bash`, and `subagent` — and runs in-process against the official [@search1api/client](https://www.npmjs.com/package/@search1api/client) SDK.

> **info:** A bundled `s1` skill teaches the model when to search, crawl, or go deeper, and which parameters fit a quick lookup versus deep research.

## Install

Add the plugin to a DSH profile:

```bash
dsh plugin --profile web add dsh-s1
```

For a local checkout, use a path spec after building the package:

```bash
cd /path/to/dsh-s1
npm run build
cd ~/.dsh
dsh plugin --profile web add file:/path/to/dsh-s1
```

## Credentials

1. Create a key in the [Search1API dashboard](https://app.s1.dev).
2. Export it as `S1_KEY`:

```bash
export S1_KEY=...
```

The SDK reads the key lazily, so a missing key fails the tool call rather than plugin activation.

## What your agent can do

* **Live web search** across Google, Bing, DuckDuckGo, Reddit, GitHub, YouTube, arXiv, and more
* **News** aggregation from multiple sources
* **Page crawling** with clean content extraction from a public URL
* **Sitemap discovery** to map a site's URLs or all public links
* **Trending topics** to surface what is hot right now

Every operation is read-only. Search results include source URLs that the agent can follow up on with a crawl.

## Configuration

Each capability can be disabled independently in the plugin config:

| Key        | Default | Description        |
| ---------- | ------- | ------------------ |
| `search`   | `true`  | Live web search    |
| `news`     | `true`  | News aggregation   |
| `crawl`    | `true`  | Page crawling      |
| `sitemap`  | `true`  | Sitemap discovery  |
| `trending` | `true`  | Trending topics    |
| `skill`    | `true`  | Bundled `s1` skill |

## Credits

Search and news requests cost one credit each; crawling a page costs one additional credit per successfully crawled page. New accounts receive 100 credits without a credit card. See [Credits and limits](https://s1.dev/docs/essentials/credits-and-limits) for current rates.

## Source

[github.com/superagents-lab/dsh-s1](https://github.com/superagents-lab/dsh-s1)
· [npm](https://www.npmjs.com/package/dsh-s1)
· [awesome-dsh-plugin](https://awesome-dsh-plugin.com/p/superagents-lab/dsh-s1/)

---

# Search

> Search the web across multiple engines and return ranked results, optional images, and full page content for selected results.

Canonical URL: https://s1.dev/docs/basic/search



Complete machine-readable schema: https://api.search1api.com/openapi.json

---

# News

> Search recent news across multiple sources with site, language, and time filters, plus optional full page content.

Canonical URL: https://s1.dev/docs/basic/news



Complete machine-readable schema: https://api.search1api.com/openapi.json

---

# Crawl

> Fetch a web page and return clean, readable content for agents, summarization, and retrieval workflows.

Canonical URL: https://s1.dev/docs/basic/crawl



Complete machine-readable schema: https://api.search1api.com/openapi.json

---

# Screenshot

> Render a public webpage as PNG, JPEG, or WebP with controls for the viewport, page readiness, and capture area.

Canonical URL: https://s1.dev/docs/basic/screenshot

The success response is image binary data, not JSON. Save the response body to a file, return it from your own service, or create a browser object URL for preview.

Use `full_page` to capture the whole document, or `selector` to capture one visible element. These options cannot be enabled together.

Choose **Full-page PNG**, **Page element as WebP**, or **Dark-mode viewport** in the request example selector below. The cURL example writes the binary response to a correctly named image file; the official SDK examples return bytes plus the response content type and request ID.

The target must be a public HTTP or HTTPS URL without embedded credentials. Requests for private or special-use network addresses are rejected with `403 Forbidden`.

> **info:** A successful screenshot costs 2 credits. Failed requests are not charged.

Complete machine-readable schema: https://api.search1api.com/openapi.json

---

# Extract (Beta)

> Extract structured data from a URL based on a prompt and schema. Every request costs 10 credits.

Canonical URL: https://s1.dev/docs/advanced/extract



Complete machine-readable schema: https://api.search1api.com/openapi.json

---

# Deepcrawl (Beta)

> API endpoints for initiating and monitoring asynchronous deep crawl tasks. Starting a task costs 20 credits; status checks are free.

Canonical URL: https://s1.dev/docs/advanced/deepcrawl



Complete machine-readable schema: https://api.search1api.com/openapi.json

---

# Trending

> API endpoint for retrieving trending topics from popular platforms

Canonical URL: https://s1.dev/docs/advanced/trending



Complete machine-readable schema: https://api.search1api.com/openapi.json

---

# Reasoning (Discontinued)

> The legacy reasoning endpoint has been permanently discontinued.

Canonical URL: https://s1.dev/docs/advanced/reasoning

> **warn:** `POST /v1/chat/completions` has been permanently discontinued and returns
> `410 Gone`. Do not build new integrations against this endpoint.

Remove calls to this endpoint from existing integrations. Search1API does not
currently expose a replacement reasoning or chat-completions API.

---

# Sitemap

> API endpoint for retrieving sitemap links from a website

Canonical URL: https://s1.dev/docs/advanced/sitemap



Complete machine-readable schema: https://api.search1api.com/openapi.json

---

# Models (Discontinued)

> The legacy reasoning models endpoint has been permanently discontinued.

Canonical URL: https://s1.dev/docs/utility/models

> **warn:** `GET /v1/models` has been permanently discontinued and returns `410 Gone`.
> Do not build new integrations against this endpoint.

The models endpoint belonged to the retired reasoning API and has no current
replacement in Search1API.

---

# Usage

> Return the remaining credit balance for the authenticated Search1API account.

Canonical URL: https://s1.dev/docs/utility/usage



Complete machine-readable schema: https://api.search1api.com/openapi.json