> ## 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, make your first call with no key, then add a key to page through results, handle errors and read your usage.

The `stophy` package gives you typed calls to Stophy from Node.js, Bun, Deno and the browser.

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

## Make a call

No account, no key.

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

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

<Accordion title="Response">
  ```json theme={null}
  {
    "success": true,
    "data": {
      "engine": "google",
      "results": [
        {
          "type": "web",
          "url": "https://bun.com/",
          "title": "Bun — A fast all-in-one JavaScript runtime",
          "description": "Bun is a fast JavaScript runtime & toolkit. All in one. Runtime, package manager, test runner and bundler in a single binary. Use bun install or bun test in an ...",
          "position": 1
        }
      ]
    },
    "creditsUsed": 0,
    "requestId": "9532e2f9-ea3d-4ba4-8bc2-8ee5685668ee"
  }
  ```
</Accordion>

Every response has `success`, `data`, `creditsUsed` and `requestId`. A list is in `data.results`.

Methods follow the endpoint id. `google.search` is `stophy.google.search(...)`, and `reddit.search` is `stophy.reddit.search(...)`. The inputs and results are typed, so a missing required field is a compile error. The [API reference](/api-reference/introduction) lists every endpoint.

## Use a key

Without a key you can call the endpoints marked `keyless: true` in the catalog, and you get the first page only. Every other call throws a `StophyError` with code `unauthorized`.

Set `STOPHY_API_KEY` and `new Stophy()` picks it up. Or pass it in:

```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.length, posts.creditsUsed);
```

`new Stophy("your key")` works too.

## Find endpoints

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

const catalog = await new Stophy().endpoints();
const free = catalog.endpoints.filter((endpoint) => endpoint.keyless);
console.log(catalog.endpoints.length, free.length);
```

## Page through results

A list call returns one page. When there is more, `data.cursor` is set. Pass it back to get the next page. This needs a key.

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

const stophy = new Stophy();
let cursor: string | undefined;
for (let page = 1; page <= 2; page++) {
  const result = await stophy.reddit.search({ query: "bun runtime", cursor });
  console.log(result.data.results.length);
  cursor = result.data.cursor;
  if (!cursor) break;
}
```

Some endpoints take a `page` number instead, like `google.search`. See [Page through results](/guides/paging).

## Handle errors

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

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

The SDK retries network errors and the statuses 429, 500, 502, 503 and 504 for you, and waits as long as the API asks. If the API asks for more than 60 seconds, it throws at once with `retryAfterSeconds` set. A failed call costs nothing. See [Errors](/api-reference/errors) for every code.

## 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 |
| `baseUrl` | `STOPHY_BASE_URL` or `https://api.stophy.dev` | Where requests go |
| `timeoutMs` | `30000` | Time limit for each attempt. A timed-out attempt is not retried. |
| `maxRetries` | `2` | Retries per request. `0` turns them off. |
| `retryInitialDelayMs` | `500` | Base delay before a retry. Each retry waits longer. |
| `headers` | none | Extra headers on every request |
| `fetch` | global `fetch` | Your own `fetch` |

## Check your usage

These need a key.

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

const stophy = new Stophy();

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

const logs = await stophy.logs({ days: 7, endpoint: "reddit.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 1,500, so divide by 1,500 to get credits. See [Usage](/api-reference/usage) and [Logs](/api-reference/logs).


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