# Connect an app to search

Keep provider keys and search policy on your server while Swift, Android, React Native, Expo and other clients use one normalized HTTPS contract.

Canonical: https://searchsdk.dev/docs/guides/application-gateway
Markdown: https://searchsdk.dev/docs/guides/application-gateway.md

<a id="architecture"></a>

## Your app, your server, your provider

The app sends a query and optional normalized filters to the exact HTTPS URL you configure. Your server authenticates the caller, chooses the provider and fallback policy, and returns results with provenance and attempt metadata. The app sends an application token; it never needs a provider key.

- App: owns session refresh, UI state and cancellation.
- Gateway: owns authorization, per-user access and spending controls, browser origin policy and bounded requests.
- Provider SDK: owns the configured search calls and explicit reliability policy.

<a id="server"></a>

## Create the server handler

Build the current [TypeScript artifact](https://searchsdk.dev/docs/sdks/typescript) to use `@belweave/search-sdk/gateway`. Mount the returned Fetch-compatible handler at an exact route in your framework. This example makes application authorization a required dependency.

**search-gateway.ts · server**

```typescript
import { createSearch } from '@belweave/search-sdk';
import { createSearchGateway } from '@belweave/search-sdk/gateway';
import { exa } from '@belweave/search-sdk/exa';

export function makeSearchHandler(
  providerKey: string,
  authorizeApplication: (authorization: string | null, signal: AbortSignal) => Promise<boolean>,
) {
  return createSearchGateway({
    search: createSearch({ provider: exa({ apiKey: providerKey }) }),
    authorize: ({ headers, signal }) =>
      authorizeApplication(headers.get('authorization'), signal),
    allowedOrigins: ['https://app.example.com'],
    timeoutMs: 10_000,
    maxConcurrency: 32,
  });
}
```

Implement authorizeApplication with your existing session or access-token verifier. Authorization runs before body reading and provider dispatch. A callback that always returns true is appropriate only for an intentionally public or separately protected route. The SDK does not issue tokens or create an identity service.

<a id="app"></a>

## Connect your app SDK

- [Swift](https://searchsdk.dev/docs/sdks/swift): Swift 6 · iOS 16+ · macOS 13+ · tvOS 16+ · watchOS 9+ · visionOS 1+. Application gateway client.
- [Android / Kotlin](https://searchsdk.dev/docs/sdks/android): Android API 26+. Application gateway client.
- [React Native](https://searchsdk.dev/docs/sdks/react-native): React Native · iOS 15.1+ · Android API 24+. Application gateway client.
- [Expo](https://searchsdk.dev/docs/sdks/expo): Expo SDK 55–57 · native development builds and web. Application gateway client.

Supply the exact HTTPS route and a callback for a fresh application token. No path suffix is appended. Native applications still require authorization even when they send no Origin header. Browser callers need an explicitly allowed HTTPS origin; use the same app origin in the handler's allowedOrigins.

<a id="wire"></a>

## The gateway contract

**POST body · protocol v1**

```json
{
  "query": "SQLite write concurrency",
  "limit": 3,
  "includeDomains": ["sqlite.org"]
}
```

Only query, limit, includeDomains and excludeDomains are accepted. Provider names, credentials, arbitrary URLs, retry settings and native operations are not request fields. HTTP 200 returns the normalized response; failures return a sanitized error envelope. The handler sets X-SearchSDK-Protocol: 1 and Cache-Control: no-store.

Default handler bounds are 64 KiB of request data, 10 MiB of decoded response data, ten seconds for the whole operation and 32 concurrent operations. Overload returns 429. The deadline covers authorization, body reading, provider work, validation and serialization.

<a id="deployment"></a>

## Deploy and verify your boundary

- Mount only the intended route, use HTTPS and map client disconnects to the Fetch Request's signal.
- Keep provider secrets in server configuration. Do not log authorization headers or provider keys.
- Test authorization failure before dispatch, cancellation, deadline exhaustion, response ceilings and successful sibling batch outcomes with fixtures.
- Set your own quotas and spending policy. Retries and fallback can repeat billable work; cancellation does not undo accepted requests.

> **Separate from the hosted playground**
> The public playground accepts visitor keys for individual demonstrations. The public MCP endpoint serves documentation only. Neither is the authenticated application gateway you deploy for your users.

- [Gateway handler reference](https://github.com/Belweave/searchSDK/blob/main/packages/sdk/GATEWAY.md)
- [Language-neutral wire protocol](https://github.com/Belweave/searchSDK/tree/main/sdk-contract#readme)
