---
name: stophy
description: Get structured public web data (search, video, social, maps, shopping, jobs, real estate, finance and more) from one API. Use when a task needs live data from the web.
---

# Stophy

Stophy gives agents structured public web data from one API: web search,
YouTube, Reddit, TikTok, Instagram, LinkedIn, maps, shopping, jobs, real
estate, finance and more. There are 161 endpoints across 41 sources. Every
endpoint answers with clean JSON, or with markdown when that is easier to read.

## How you got here

- **The API returned 401.** Most endpoints need an API key. Go to path C.
- **A human or a doc sent you.** Pick a path below.
- **`STOPHY_API_KEY` is already set.** Skip to path A or B.

## Choose your path

- **A.** You need data during this session.
- **B.** You are adding Stophy to app code.
- **C.** You need an API key.
- **D.** You have no key and no human to ask.

### A. Get data now

If your client supports remote MCP, connect to `https://api.stophy.dev/mcp`.
It needs an API key. Claude Code:

```bash
claude mcp add --transport http stophy https://api.stophy.dev/mcp --header "Authorization: Bearer $STOPHY_API_KEY"
```

You get three tools:

- `stophy_search_endpoints` `{ query?, category? }` finds endpoints by words
  or source, with their credit cost.
- `stophy_describe_endpoint` `{ id }` returns one endpoint's input schema, its
  cost, and whether it pages.
- `stophy_call` `{ id, input?, format? }` runs it. Results are markdown unless
  `format` is `json`.

Add `?toolsets=reddit,youtube` to the URL to also get one tool per endpoint of
those sources.

Without MCP, use curl:

```bash
curl -X POST https://api.stophy.dev/v1/youtube/search \
  -H "Authorization: Bearer $STOPHY_API_KEY" \
  -H "content-type: application/json" \
  -H "accept: text/markdown" \
  -d '{"query":"rust async runtime","limit":5}'
```

### B. Add Stophy to app code

Call the REST API directly. TypeScript:

```ts
const response = await fetch("https://api.stophy.dev/v1/web/search", {
  method: "POST",
  headers: {
    authorization: `Bearer ${process.env.STOPHY_API_KEY}`,
    "content-type": "application/json",
  },
  body: JSON.stringify({ query: "bun runtime", limit: 5 }),
});
const { data, creditsUsed } = await response.json();
```

Python:

```python
import os
import httpx

response = httpx.post(
    "https://api.stophy.dev/v1/web/search",
    headers={"Authorization": f"Bearer {os.environ['STOPHY_API_KEY']}"},
    json={"query": "bun runtime", "limit": 5},
    timeout=30,
)
data = response.json()["data"]
```

Read the key from the environment. Never put it in code.

### C. Get an API key

1. Ask your human to sign up at https://stophy.dev/signup.
2. New accounts start with 500 free credits.
3. They create a key and give it to you. Store it as `STOPHY_API_KEY`, for
   example in `.env` or your client's secret settings.
4. Never print the key, log it, or commit it.

### D. No key and no human

Three endpoints work without a key:

- `web.search`
- `youtube.search`
- `youtube.transcript`

Without a key you get 10 requests a minute and 50 a day, the first page only,
and `limit` at most 10. Move to a key as soon as you can.

```bash
curl -X POST https://api.stophy.dev/v1/web/search \
  -H "content-type: application/json" \
  -d '{"query":"bun runtime","limit":5}'
```

## Reference

**Base URL and auth.** Every endpoint is
`POST https://api.stophy.dev/v1/<source>/<endpoint>` with a JSON body. Send
`Authorization: Bearer <key>`.

**Find endpoints.** `GET https://api.stophy.dev/v1/endpoints` lists every
endpoint with its input JSON schema, its credit cost, whether it works without
a key, and an example input when there is one. Read the schema before you call. Unknown
fields are rejected. The full OpenAPI document is at
`https://api.stophy.dev/openapi.json`.

**Markdown.** Send `Accept: text/markdown` to get a readable page instead of
JSON. It uses fewer tokens.

**Paging.** When a response has a `cursor`, send the same input again with
that `cursor` to get the next page.

**Responses.** Success is
`{ "success": true, "data": ..., "creditsUsed": n, "requestId": "..." }`.
Errors are
`{ "success": false, "error": { "code", "message", "retryable", "retryAfterSeconds"?, "requestId" } }`.
Retry only when `retryable` is true. Wait for `Retry-After` or
`retryAfterSeconds` first when present.

**Limits.** With a key: 600 requests a minute and 10 requests running at once.
Every call answers or fails within 25 seconds.

**Credits.** 1,000 credits cost $2. Each endpoint's cost is in
`/v1/endpoints`. Some endpoints charge per group of results (`perItems`). The
`x-credits-used` header and `creditsUsed` show what a call cost. Failed calls
cost nothing.
