Skip to article

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.

On this page

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.

Create the server handler

Build the current TypeScript artifact 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
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.

Connect your app SDK

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.

The gateway contract

POST body · protocol v1
{
  "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.

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.