> ## Documentation Index
> Fetch the complete documentation index at: https://docs.stophy.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# TypeScript SDK

> Install the Stophy TypeScript SDK, authenticate, call an endpoint with typed inputs, page through results, and handle errors and retries.

## Install

```bash theme={null}
npm install stophy
```

The package has no runtime dependencies and ships ESM, CommonJS and type definitions. It runs on Node.js, Bun, Deno and in the browser.

## Authenticate

`apiKey` defaults to the `STOPHY_API_KEY` environment variable, so a bare `new Stophy()` picks it up. Pass a key directly with `new Stophy("your key")` or `new Stophy({ apiKey: "your key" })`.

```ts theme={null}
import { Stophy } from "stophy";

const stophy = new Stophy({ apiKey: process.env.STOPHY_API_KEY });
```

Without a key, Google search, Google News, YouTube search, video details and transcripts, Reddit search and Google Maps search still work. Here is Google search:

```ts theme={null}
import { Stophy } from "stophy";

const result = await new Stophy().google.search({ query: "bun runtime" });
console.log(result.data.results);
```

Every other endpoint throws `StophyError` with code `unauthorized` and status `401` when called without a key.

## Make a call

```ts theme={null}
import { Stophy } from "stophy";

const stophy = new Stophy({ apiKey: process.env.STOPHY_API_KEY });

const posts = await stophy.reddit.search({ query: "bun runtime" });
console.log(posts.data.results, posts.creditsUsed);

const transcript = await stophy.youtube.transcript({ videoUrl: "https://youtu.be/dQw4w9WgXcQ" });
console.log(transcript.data.text);

const ads = await stophy.meta.ads.search({ query: "running shoes" });
console.log(ads.data.results);
```

Methods follow the endpoint id. Nested ids are nested properties: `reddit.search` is `stophy.reddit.search(...)`, and `google.maps.search` is `stophy.google.maps.search(...)`. Inputs and responses are typed from the [API reference](/api-reference/introduction), so a missing required field is a compile error.

To point at one thing, send its link or its id, never both: `videoUrl` or `videoId`, `placeUrl` or `placeId`, `userUrl` or `username`. The types show the pair.

Every response is `{ success, data, creditsUsed, requestId }`. `data` is a single object, and lists are in `data.results`.

## Paging

```ts theme={null}
import { Stophy } from "stophy";

const stophy = new Stophy({ apiKey: process.env.STOPHY_API_KEY });
let cursor: string | undefined;
do {
  const page = await stophy.reddit.search({ query: "bun runtime", cursor });
  console.log(page.data.results);
  cursor = page.data.cursor;
} while (cursor);
```

## Find endpoints

```ts theme={null}
import { Stophy } from "stophy";

const catalog = await new Stophy().endpoints();
console.log(catalog.endpoints.length);
```

## Handle errors and retries

```ts theme={null}
import { Stophy, StophyError } from "stophy";

const stophy = new Stophy();

try {
  await stophy.reddit.search({ query: "bun runtime" });
} catch (error) {
  if (error instanceof StophyError) {
    console.log(error.status, error.code, error.message);
    console.log(error.retryable, error.retryAfterSeconds, error.requestId);
  }
}
```

`StophyError` has `status`, `code`, `message`, `retryable`, `retryAfterSeconds` and `requestId`. See [Errors](/api-reference/errors) for every code.

The SDK retries network errors and `429`/`5xx` responses on its own, honoring `Retry-After`, before it throws. Set `maxRetries: 0` to turn that off. `StophyError` only reaches your code after retries are exhausted.

## Options

```ts theme={null}
import { Stophy } from "stophy";

const stophy = new Stophy({
  apiKey: process.env.STOPHY_API_KEY,
  timeoutMs: 20_000,
  maxRetries: 3,
  retryInitialDelayMs: 500,
  headers: { "x-app": "my-app" },
});

const controller = new AbortController();
setTimeout(() => controller.abort(), 5_000);
await stophy.google.search({ query: "bun runtime" }, { signal: controller.signal });
```

| Option | Default | What it does |
| - | - | - |
| `apiKey` | `STOPHY_API_KEY` | Your API key. Leave it unset to use Google search only. |
| `baseUrl` | `STOPHY_BASE_URL` or `https://api.stophy.dev` | Where requests go |
| `timeoutMs` | `30000` | Timeout for each attempt. A timeout is not retried. |
| `maxRetries` | `2` | Retries for network errors and `429`/`5xx`. `0` turns them off. |
| `retryInitialDelayMs` | `500` | Base backoff delay. Each retry waits longer than the last. |
| `headers` | none | Extra headers on every request |
| `fetch` | global `fetch` | Your own `fetch` |

Per call, pass `{ signal }` to cancel a request.

## Usage and logs

These need an API key.

```ts theme={null}
import { Stophy } from "stophy";

const stophy = new Stophy({ apiKey: process.env.STOPHY_API_KEY });

const usage = await stophy.usage();
console.log(usage.balanceMicros, usage.creditsUsed, usage.requestCount);

const logs = await stophy.logs({ days: 7, page: 0, endpoint: "google.search" });
for (const entry of logs.logs) {
  console.log(entry.createdAt, entry.endpoint, entry.credits);
}
```

`balanceMicros` is your balance in millionths of a dollar. One credit is `1500`, so divide by 1,500 to get credits.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.