A user-facing CLI for Synthetic web search, quotas, and local credential management.
- Search the public web with Synthetic (
/v2/search) - View account usage and limits (
/v2/quotas) - Interactive local auth setup (
auth login/auth logout/auth status) - Readable terminal output by default
--jsonoutput mode for scripts and automation- Tolerant JSON parsing for malformed control characters in API responses
- Node.js 18+
- Synthetic API key
npm install -g synthetic-searchOr run directly with npx:
npx -y synthetic-search --helpA key saved with auth login takes priority over the SYNTHETIC_API_KEY
environment variable. Run auth logout to fall back to the environment variable.
Use this when no key is saved locally — for example in CI:
export SYNTHETIC_API_KEY=your_api_key_heresynthetic-search auth loginThis validates the key via GET /v2/quotas before saving.
Skip validation:
synthetic-search auth login --no-validateCheck status:
synthetic-search auth statusRemove saved key:
synthetic-search auth logout
synthetic-search auth logout --forceRoot command and subcommand are equivalent:
synthetic-search latest model context protocol news
synthetic-search search latest model context protocol newsRead query from piped stdin:
echo "latest ai safety research" | synthetic-search searchJSON output:
synthetic-search search "latest mcp updates" --jsonClient-side result limit:
synthetic-search search "latest mcp updates" --limit 2synthetic-search quotas
synthetic-search quotas --jsonQuotas are reported per bucket. The search (hourly) bucket — the limit that actually constrains searches — is shown first, followed by the account subscription bucket:
Search (hourly):
Limit: 250
Requests used: 38
Remaining: 212
Renews at: 2026-06-25T21:00:02.537Z
Subscription:
Limit: 750
Requests used: 0
Remaining: 750
Renews at: 2026-06-26T01:49:17.537Z
--json emits { "buckets": [ … ] } with key, label, limit,
requestsUsed, remaining, and renewsAt for each bucket.
synthetic-search --version- A key saved with
auth loginis written to the local config file with owner-only (0600) permissions; a file left looser by an older version is tightened the next time the CLI opens it (with a warning if it cannot be). - Untrusted text printed to the terminal — search results, quota fields, and
error messages (including Commander usage errors) — is sanitized of terminal
escape sequences, so a result or upstream error cannot manipulate your
terminal.
--jsonoutput is escaped to stay terminal-safe too. - Upstream API error bodies are redacted of the active key / bearer-token-like material before being shown or logged.
- Response bodies and piped stdin are read with size bounds to prevent a hostile upstream or an unbounded pipe from exhausting memory.
POST https://api.synthetic.new/v2/searchGET https://api.synthetic.new/v2/quotas
See the Synthetic API docs for the full schema.
npm install
npm run typecheck # type-check src, tests, and scripts (no emit)
npm run test # run the node:test suite
npm run build # compile to dist/
npm run fuzz # sandboxed CLI fuzzer (no network, no real config)Run in dev mode:
npm run dev -- search "latest llm tooling"Continuous integration runs typecheck, test, and build on Node 18, 20, and 22
(see .github/workflows/ci.yml).
MIT