cse-compat is an open-source Cloudflare Worker serving the same endpoint, parameters, response schema, and error envelope as the retiring Custom Search JSON API, backed by your own key from a modern search provider.
SEARCH_CX=017576662512468239146:omuauf_lfve- SEARCH_BASE=https://www.googleapis.com/customsearch/v1+ SEARCH_BASE=https://csecompat.com/customsearch/v1 # items[].link, items[].snippet, queries.nextPage: unchanged
Live demo
A live query against this endpoint with the public
demo key.
Google's exact legacy schema comes back.
The public demo key allows 10 requests a minute per visitor. Testing something bigger? Self-host with your own free-tier key.
Compatibility
Not "similar JSON." The same envelope your parser was written against, pinned by a public conformance suite.
items[], htmlSnippet highlighting,
queries.nextPage pagination, honest totalResults.
The fields your code already reads, where it already reads them.
Per-provider circuit breaker with timeout budgets. Pagination stays on one index, so page 2 never skips or repeats.
Your Brave or serper.dev key. You stay their direct customer. No resale, no markup, just a translation layer.
Quota answers the way your client library expects.
Queries are never logged or stored. The worker is a pure pipe.
A public conformance suite pins the contract: pagination windows, error envelopes, zero-result behavior, the 100-result cap.
The core is open source. Run it on Cloudflare's free tier and it costs you nothing but your own search-API usage. No lock-in, which is the point of the whole project.
Self-host
Deploy the worker to your Cloudflare account.
git clone https://github.com/csecompat/cse-compat cd cse-compat npm i && npx wrangler deploy
Add your upstream key. One provider is enough.
npx wrangler secret put SERPER_API_KEY
# or BRAVE_API_KEY
Change the base URL. That's the migration.
SEARCH_BASE=https://cse.you.workers.dev/customsearch/v1
Managed version
The hosted version adds multi-provider fallback, cx site-restriction profiles, usage analytics, and an SLA. Same endpoint, no worker to run. Launching before the shutdown.