decolua/9router · error
Xquik requires an API key
Error message
Xquik requires an API key
What it means
buildXquikRequest builds the request for the Xquik (X/Twitter search) provider, which authenticates with an API key in params.token. It throws this error when the token is falsy, since the upstream endpoint requires credentials on every request.
Solutions
- Configure an Xquik API key for the xquik provider in the dashboard/accounts store
- Pass token explicitly in the params object at the call site
- Confirm the credential is saved under the correct provider id and is a non-empty string
- If using env-based setup, ensure the env var is loaded before the request
Example fix
// before
await search({ provider: 'xquik', query: 'ai agents', maxResults: 20 });
// after
await search({ provider: 'xquik', query: 'ai agents', maxResults: 20, token: process.env.XQUIK_API_KEY }); Defensive patterns
Strategy: validation
Validate before calling
if (!params?.token || typeof params.token !== 'string' || !params.token.trim()) {
throw new Error('Xquik search requires a non-empty token');
} Type guard
function hasXquikToken(params) {
return typeof params?.token === 'string' && params.token.trim().length > 0;
} Try / catch
try {
const res = await search({ provider: 'xquik', query, token });
} catch (err) {
if (err.message.includes('requires an API key')) {
// configure the Xquik key, then retry
} else throw err;
} Prevention
- Configure the Xquik API key before enabling the provider
- Preflight-check tokens for all enabled providers on startup
- Ensure env vars are loaded in CI/scripts before making search calls
When it happens
Trigger: Calling the Xquik search route with params.token undefined/null/empty — credential not configured, blank field, or a programmatically built params object missing `token`.
Common situations: Xquik provider enabled without a key; key stored under another provider id; env var missing in CI/scripts; credential wiped by rotation or account deletion.
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
- Linkup Search requires an API key
- SearchAPI requires an API key
- You.com Search requires an API key
- Google Programmable Search requires both apiKey and cx
- Invalid baseUrl
AI-assisted analysis of decolua/9router@90b52e06ff (2026-08-30).
Data as JSON: /api/errors/a48c46a7d4622961.
Report an issue: GitHub.
Appendix: source
Thrown at open-sse/handlers/search/callers.js:352
});
if (params.language) qp.set("language", params.language);
if (params.timeRange && params.timeRange !== "any") qp.set("time_range", params.timeRange);
const page = toPageNumber(params.offset, params.maxResults);
if (page) qp.set("pageno", String(page));
return {
url: `${url}?${qp}`,
init: {
method: "GET",
headers: { Accept: "application/json" },
},
};
}
function buildXquikRequest(config, params) {
const apiKey = params.token;
if (!apiKey) throw new Error("Xquik requires an API key");
const queryType = getProviderSetting(params, "queryType");
if (queryType && !["Latest", "Top"].includes(queryType)) {
throw new Error("Xquik queryType must be Latest or Top");
}
const qp = new URLSearchParams({
q: params.query,
limit: String(params.maxResults),
});
const cursor = getProviderSetting(params, "cursor");
if (cursor) qp.set("cursor", cursor);
if (queryType) qp.set("queryType", queryType);
if (params.language) qp.set("language", params.language);
return {
url: `${resolveBaseUrl(config, params)}?${qp}`,
init: {View on GitHub (pinned to 90b52e06ff)