OpenSERP Cloud uses credits as the unit of billing. Every billable request consumes credits; credits do not expire. Top up in Top up.
The current baseline is $0.009 per credit. For single-engine web search, 1 credit covers a search’s first page - up to 10 returned web result positions. That means 1,000 searches cost about $9 before top-up bonuses.
The current per-credit price and exact per-operation cost are always available live from the API, the pricing page, and the pricing dashboard - fetch from /v1/pricing instead of hardcoding values.
How requests turn into credits
| Operation | Credit cost |
|---|---|
Single-engine web search, /v1/{engine}/search |
1 per 10 returned web results by default, rounded up. Example: 53 results = 6 credits |
Any/Fast web search, /v1/mega/search?mode=any|fast |
1 |
Any/Fast image search, /v1/mega/image?mode=any|fast |
1 |
Single-engine image search, /v1/{engine}/image |
Scales with returned image volume |
Balanced megasearch, /v1/mega/search?mode=balanced |
Dynamic — depends on successful engines |
Balanced mega image search, /v1/mega/image?mode=balanced |
Dynamic — depends on engines and image volume |
URL extraction, /v1/extract |
1 for a fast fetch, 3 when the page needs browser rendering |
Batch URL extraction, POST /v1/extract/batch |
Per URL, at the same rate as /v1/extract. Failed and empty URLs cost nothing |
Extraction from a chosen region (region=DE) |
+1 per successfully extracted URL |
Account, pricing, status, and capability endpoints (/v1/me, /v1/pricing, /v1/engines/*) |
0 |
For dynamic charges and any future pricing changes, the response is the source of truth - read X-Credits-Used (or client.lastResponse?.credits?.used) on every billable call. For web search, billing is based on returned result positions, not the number of query rows in your file.
Reading live pricing
/v1/pricing returns the current per-credit price and per-operation cost in one call:
const pricing = await client.pricing();
console.log(pricing.credit_price_usd);
console.log(pricing.search.credits, pricing.fast_search.credits);
curl https://api.openserp.org/v1/pricing -H "Authorization: Bearer $OPENSERP_API_KEY"
{
"credit_price_usd": 0.009,
"search": { "credits": 1 },
"mega_search": { "credits": 1 },
"image_search": { "credits": 1 },
"any_search": { "credits": 1 },
"fast_search": { "credits": 1 },
"any_image": { "credits": 1 },
"fast_image": { "credits": 1 }
}
If your app displays expected cost to your own users, fetch /v1/pricing periodically instead of hardcoding a rate.
Top-up bonuses
Volume top-ups add bonus credits, starting at +5% from $15. Currently, all accounts get an additional +15% founder discount on every top-up, stacked with volume bonuses and capped so the effective credit price never drops below half of list price.
Your first top-up also earns a one-time +30% bonus (up to 1,000 credits), stacked on top of the volume and founder bonuses.
Free starter credits
Every new account starts with 60 free credits - about 60 first-page searches, no card required. This is a one-time grant, not a recurring allowance: once it is spent, top up to keep searching. Purchased credits never expire.
What counts as billable
You are charged only when the API successfully performs a search.
| Response | Billed? |
|---|---|
200 OK with results |
Yes |
200 OK with an empty results array |
No |
400 Bad Request |
No |
401 Unauthorized |
No |
402 Payment Required |
No |
429 Too Many Requests |
No |
5xx service errors |
No |
For single-engine web search, a request with limit=100 may reserve up to 10 credits before execution. The final charge is ceil(returned results / 10): if 53 results come back, 6 credits are charged and the unused hold is released.
For balanced mega endpoints, the final charge depends on which engines succeeded. For image endpoints, it depends on returned image volume. For Any/Fast endpoints, an all-engines-failed response is 502 and isn’t charged.
Batch extraction is billed per URL, not per request. A batch where some URLs failed still returns 200 OK; only the URLs that produced content are charged, and the items carrying an error cost nothing. The request reserves its worst case up front - every URL rendered, plus any region surcharge - and releases the remainder when it finishes, so a large batch can be refused for insufficient credits even when the real charge would be much smaller. Send fewer URLs if that happens.
Reading credit usage
Every billable response includes:
| Header | Meaning |
|---|---|
X-Credits-Used |
Credits charged for this request |
X-Credits-Remaining |
Account balance after the request |
X-Engine-Used |
Engine used by Any/Fast routing |
Successful JSON responses also carry a billing object (billing.credits_used, billing.credits_remaining) mirroring the headers, so you can read the charge straight from the parsed body.
With the JavaScript SDK:
const response = await client.fastSearch({
text: "openserp api",
engines: ["google", "bing"],
});
console.log("results:", response.results.length);
console.log("used:", client.lastResponse?.credits?.used);
console.log("remaining:", client.lastResponse?.credits?.remaining);
console.log("engine:", client.lastResponse?.engineUsed);
With raw fetch:
const res = await fetch(url, {
headers: { Authorization: `Bearer ${process.env.OPENSERP_API_KEY}` },
});
console.log("used:", res.headers.get("X-Credits-Used"));
console.log("remaining:", res.headers.get("X-Credits-Remaining"));
console.log("engine:", res.headers.get("X-Engine-Used"));
If you pass costs through to your own users, log X-Credits-Used per request and reconcile against the dashboard.
Running out of credits
When your balance reaches zero, billable calls return 402 Payment Required:
{
"error": "insufficient_credits",
"code": 402,
"message": "Insufficient credits. Top up to continue."
}
The response is not charged. Top up in Top up — credits are available immediately after payment.
To avoid interruptions:
- Watch
X-Credits-Remainingin production jobs and alert below a threshold. - Keep a balance buffer for scheduled or high-volume searches.
- Prefer Any/Fast endpoints when predictable 1-credit billing matters more than merged coverage.
Next
- Endpoints reference — paths and parameters.
- Errors & rate limits — retry behavior and status codes.