Cost Estimation¶
FirmaDB bills per verified result — a 2xx response that contains a real company record. Search is free, 404s are free, coverage and health calls are free. The agent's job is to estimate the real cost of a planned workflow before running it, especially when the user is paying.
What costs money — and what doesn't¶
| Operation | Cost (billable results) |
|---|---|
| Exact lookup — found | 1 |
| Exact lookup — not found (404) | 0 |
| Search — any result count | 0 (search itself is always free) |
| Batch row — found | 1 per row |
| Batch row — not found | 0 |
| Verify status — found | 1 |
| Verify status — not found | 0 |
GET /v1/countries[/{code}] |
0 |
GET /v1/account/usage |
0 |
GET /v1/health |
0 |
"If we can't find it, we don't charge for it."
A "verified result" requires at least name + country + registry_id + status in the response. Empty search results, well-formed-but-missing IDs, and conditional 304 Not Modified responses all cost zero.
Check current usage¶
GET /v1/account/usage returns your current period's quota, consumption, overage charges, and remaining balance. This is the source of truth for "how much can I still spend today?"
Estimate a job before running it¶
For agents, firmadb_estimate_cost (MCP tool) returns a min/max cost range, a quota-impact prediction, and a human_approval_recommended flag.
// firmadb_estimate_cost({"operation":"enrich","estimated_records":500,"countries":["FR","GB"]})
{
"operation": "enrich",
"estimated_records": 500,
"estimated_cost": {
"min_billable_results": 350,
"max_billable_results": 500,
"cost_per_result_eur": 0.005,
"estimated_cost_eur_min": 1.75,
"estimated_cost_eur_max": 2.50
},
"account_impact": {
"tier": "solo",
"results_remaining_before": 8766,
"results_remaining_after_max": 8266,
"would_exceed_quota": false
},
"recommendation": "Proceed. Estimated cost is within your remaining quota.",
"human_approval_recommended": false
}
| Field | What it tells you |
|---|---|
min_billable_results |
Lower bound — assumes some 404s |
max_billable_results |
Upper bound — assumes 100% match rate |
cost_per_result_eur |
Your tier's overage rate (or marginal cost within bundle) |
would_exceed_quota |
True when max exceeds your remaining balance |
human_approval_recommended |
True when estimated spend > €10 OR > 50% of remaining quota |
Honour human_approval_recommended
When this flag is true, the agent must ask the user before executing. This is the contract that prevents an autonomous workflow from quietly burning through a month's budget. Always plan from max_billable_results, not min.
Estimate without MCP¶
If you're calling the REST API directly, derive the same numbers locally:
def estimate(records: int, tier: str, remaining: int) -> dict:
rate = {"free": 0.0, "solo": 0.005, "team": 0.004, "scale": 0.003}[tier]
max_cost = records * rate
return {
"max_billable_results": records,
"estimated_cost_eur_max": round(max_cost, 2),
"would_exceed_quota": records > remaining,
"human_approval_recommended": max_cost > 10 or records > 0.5 * remaining,
}
The match rate (and therefore min) depends on data quality of your inputs — assume ~70% on dirty CRM exports, ~95% on freshly registered IDs.
Pricing tiers¶
| Tier | Monthly | Included | Overage | Best for |
|---|---|---|---|---|
| Free | €0 | 1,000 (hard cap) | none | Evaluation, demo |
| Solo | €29 | 10,000 | €0.005/result | Indie, single workflow |
| Team | €99 | 50,000 | €0.004/result | Fintech, B2B sales |
| Scale | €399 | 250,000 | €0.003/result | Platforms, high-volume |
| Custom | from €2,000 | Negotiated | Negotiated | Enterprise, govtech |
Free is a hard cap
Free-tier accounts that exhaust 1,000 results return 429 quota_exhausted for all lookup/batch/verify calls until the next billing period. Search keeps working (it's free) — but every click-through to a record fails. The error response includes a price block with the upgrade URL. See Rate Limits.
See the full pricing page for cache windows, attribution requirements, and data licensing terms per tier.
Three patterns to avoid surprise bills¶
1. Always estimate before batch¶
1. firmadb_estimate_cost(operation="enrich", estimated_records=N)
2. if human_approval_recommended → ask user
3. otherwise → proceed
2. Cache aggressively per tier¶
The Solo tier's 7-day cache window means a CRM that re-enriches weekly can stay flat at ~one full batch per week instead of one per day. See Rate Limits & Caching.
3. Use If-None-Match on re-fetches¶
A 304 Not Modified response costs zero billable results. Send the ETag from your previous response back as If-None-Match whenever you're checking for updates rather than fetching fresh.
Account-level guard rails¶
For teams running autonomous agents, set a soft daily cap in your own code:
DAILY_LIMIT = 200 # billable results per day, per agent
def can_spend(needed: int) -> bool:
spent_today = redis.get("firmadb:spend:today") or 0
return int(spent_today) + needed <= DAILY_LIMIT
Combine with firmadb_estimate_cost for a belt-and-braces guard that protects your budget even if the agent's prompt drifts.
What's next¶
- Pricing and licensing per tier → Pricing
- Rate limits, headers, caching → Rate Limits & Caching
- Connect via MCP → MCP Setup
- Full error catalog → Errors