# Your first search

Run a key-free fixture first, then configure a real provider on your server.

Canonical: https://searchsdk.dev/docs/quickstart
Markdown: https://searchsdk.dev/docs/quickstart.md

<a id="try-without-credentials"></a>

## Try without credentials

[Install the alpha package](https://searchsdk.dev/docs/installation#install). Save the following example as `first-search.mjs` in your server application, then run `node first-search.mjs` on Node 24. It uses plain ESM JavaScript and needs no compiler. For an immediate browser demo, [open the playground](https://searchsdk.dev/playground) and choose “Demo · no key”.

**first-search.mjs · fixture**

```typescript
import { createSearch } from '@belweave/search-sdk';
import { createMockProvider } from '@belweave/search-sdk/testing';

const provider = createMockProvider();
const client = createSearch({ provider });
const response = await client.web.search({ query: 'SQLite concurrency' });

console.log(response.results); // Fixed example-domain fixtures
console.log(provider.calls.length); // 1; no network requests
```

The mock returns three fixed example-domain results and performs no outbound requests. This validates your application integration, not a provider's retrieval quality.

<a id="connect-context"></a>

## Connect Context.dev

Save this example as `search.mjs`. Configure `CONTEXT_API_KEY` in a server-only environment or [local .env file](https://searchsdk.dev/docs/installation#server-credentials), then run `node --env-file=.env search.mjs`. With a production-injected environment, use `node search.mjs`. This makes a real provider request and may incur charges.

**search.mjs · server**

```typescript
import { createSearch } from '@belweave/search-sdk';
import { context } from '@belweave/search-sdk/context';

const apiKey = process.env.CONTEXT_API_KEY;
if (!apiKey) throw new Error('CONTEXT_API_KEY is required');

const client = createSearch({
  provider: context({ apiKey }),
  timeoutMs: 10_000,
});

const response = await client.web.search({
  query: 'SQLite write concurrency',
  limit: 5,
});

for (const result of response.results) {
  console.log(result.title ?? result.url, result.url);
}
console.log(response.provider, response.attempts);
```

The same ESM example can be saved as `search.ts` and run directly with Node 24 in a type: module project. Missing, blank, or invalid keys must be resolved through your provider account. A configured factory is not proof that the key is valid.

<a id="read-the-response"></a>

## Read the response

- `results` contains up to your requested limit in provider order.
- `provider` identifies the winning provider. Every result also has its own `provenance`.
- `attempts` records successes and failures. `warnings` uses stable SDK codes.
- `usage` is provider-reported usage from the winner, or `null` when unknown.

> **Context.dev result count**
> Context requests at least ten native results to satisfy conflicting provider documents, then caps the SDK output. Trimmed results can still affect reported credits.

<a id="next-step"></a>

## Add one policy at a time

- [Filter by domain](https://searchsdk.dev/docs/guides/domain-filters)
- [Configure explicit fallback](https://searchsdk.dev/docs/reliability/fallback)
- [Connect a different provider](https://searchsdk.dev/docs/providers)
