decolua/9router · error

SearchAPI requires an API key

Error message

SearchAPI requires an API key

What it means

buildSearchApiRequest builds the request for the SearchAPI (searchapi.io) provider. SearchAPI authenticates via an `api_key` query parameter, so without params.token the request cannot succeed; the builder throws immediately with this message when the token is falsy.

Solutions

  1. Sign up at searchapi.io, copy the API key, and save it for the SearchAPI provider in the dashboard
  2. Confirm params.token is a non-empty string at the call site
  3. Check the credential is stored under the searchapi provider id, not another provider
  4. If key rotation emptied the field, re-enter the key

Example fix

// before
await search({ provider: 'searchapi', query: 'openai news', searchType: 'news' });
// after
await search({ provider: 'searchapi', query: 'openai news', searchType: 'news', token: process.env.SEARCHAPI_KEY });
Defensive patterns

Strategy: validation

Validate before calling

if (!params?.token || typeof params.token !== 'string' || !params.token.trim()) {
  throw new Error('SearchAPI search requires a non-empty token');
}

Type guard

function hasSearchApiToken(params) {
  return typeof params?.token === 'string' && params.token.trim().length > 0;
}

Try / catch

try {
  const res = await search({ provider: 'searchapi', query, token });
} catch (err) {
  if (err.message === 'SearchAPI requires an API key') {
    // surface a config error to the user; do not retry
  } else throw err;
}

Prevention

When it happens

Trigger: Invoking the SearchAPI search route with params.token undefined/null/empty — no API key saved for the searchapi provider, or a caller constructing params manually without `token`.

Common situations: Enabled the SearchAPI provider without pasting a key from searchapi.io; key stored under a different provider entry; dashboard account deleted or rotated leaving an empty value; automation scripts passing partial params.

Understand the failure class

Background: "API key is required" / "API key not found" / "No API key was set": the missing-api-key error family across 16 libraries — this error's family across 16 libraries.

Related errors


AI-assisted analysis of decolua/9router@90b52e06ff (2026-08-30). Data as JSON: /api/errors/c6f2548872dfcec5. Report an issue: GitHub.

Appendix: source

Thrown at open-sse/handlers/search/callers.js:269

    if (params.timeRange === "month") from.setUTCMonth(from.getUTCMonth() - 1);
    if (params.timeRange === "year") from.setUTCFullYear(from.getUTCFullYear() - 1);
    body.fromDate = from.toISOString().slice(0, 10);
    body.toDate = toDate;
  }

  return {
    url: resolveBaseUrl(config, params),
    init: {
      method: "POST",
      headers: { "Content-Type": "application/json", Authorization: `Bearer ${apiKey}` },
      body: JSON.stringify(body),
    },
  };
}

function buildSearchApiRequest(config, params) {
  const apiKey = params.token;
  if (!apiKey) throw new Error("SearchAPI requires an API key");

  const qp = new URLSearchParams({
    engine: params.searchType === "news" ? "google_news" : "google",
    q: params.query,
    api_key: apiKey,
  });
  if (params.country) qp.set("gl", params.country.toLowerCase());
  if (params.language) qp.set("hl", params.language);

  const page = toPageNumber(params.offset, params.maxResults);
  if (page) qp.set("page", String(page));

  return {
    url: `${resolveBaseUrl(config, params)}?${qp}`,
    init: {
      method: "GET",
      headers: { Accept: "application/json" },
    },

View on GitHub (pinned to 90b52e06ff)