Skip to content

Usage and costs

A LeadHunter campaign costs money in two completely different ways, and the docs split them along that line:

  • Auto-tracked API costs — every LLM call, Google Maps lookup, Tavily search, etc. that the platform fires on your behalf. LeadHunter records these for you; you don’t enter them.
  • User-entered expenses — agency fees, internal labor hours, software subscriptions, content production, event costs against a campaign; ad spend against the acquisition channel it paid for; fees and in-kind costs against a marketing action. You log these.

Both attribute back to the campaign (or channel, action, run) that triggered them, so the full picture is auto-tracked API costs + user-entered expenses = real campaign cost. Both surfaces show side-by-side on the campaign’s Settings & costs tab. Cost-of-acquisition (CAC) is computed from the user-entered side only — auto-tracked API spend is reported alongside but kept separate (it’s in USD, your expenses may not be, and we don’t FX-convert).

Every external call the platform makes is logged as a usage row with an attributed cost. These providers are tracked out of the box:

ProviderCategoryWhat it’s used for
Google Maps Places APIDiscoveryText searches and place-detail lookups
Tavily AI SearchResearchWeb search during AI deep research
OpenAI GPT-6 LunaLLMThe default model since October 2026, through OpenRouter: fit criteria, scoring, drafting, translation, enrichment
Google Gemini Flash-LiteLLMWebsite discovery (with Google Search grounding); the default model for every other step until October 2026
OpenAI GPT-4oLLMEarlier default for fit criteria, scoring, drafting
OpenAI GPT-4o MiniLLMCheaper drafting and translation
Google Gemini ProLLMHigher-quality reasoning on demand
Anthropic Claude OpusLLMHighest-tier reasoning
Anthropic Claude SonnetLLMMid-tier reasoning
Anthropic Claude HaikuLLMFastest Anthropic tier

The provider list lives in seeded data and grows over time. New providers added to the platform get their own rows; the API exposes them at GET /api/api-providers/.

Each usage row carries:

  • Provider — which service the call went to.
  • Model name — for LLM calls, the exact model (e.g. openrouter:openai/gpt-6-luna, google:gemini-3.1-flash-lite) so a campaign’s spend can be split across the models that ran it.
  • Operation type — what kind of call it was (e.g. completion, places_search, details).
  • Project, research, campaign, account — four-way attribution (a ranking run’s calls also carry the run, which is how its spend is counted against its cap). Per-account is the lever for “how much did this account cost to enrich?”; per-campaign is the lever for “what’s this campaign actually burning?”.
  • API calls + input/output tokens — the volume that produced the cost.
  • Cost in USD, computed from the provider’s pricing model (per-call or per-token).
  • Langfuse trace id — when LLM observability is on, the trace id links the cost row back to the prompt/response in Langfuse.

Costs are also rolled up nightly for fast trend queries — that’s what powers the daily-trend chart on the cost endpoints.

  • Per campaign — the Costs & expenses panel on every campaign’s Settings & costs tab shows the auto-tracked LLM total in USD with a per-model breakdown, side-by-side with your user-entered expenses. The top models by spend appear with their call count.
  • Per account — the auto-tracked LLM cost for one account (its website discovery, AI enrichment, single-account rescores) is exposed on the account detail payload of the API (api_cost).
  • Per run — the Runs page (sidebar → Runs) shows what each piece of background work spent. Campaign scoring runs show their cost; Ranking runs show what they spent against their budget cap (“$spent of $cap cap”); Imports, enrichment and searches have a Cost column with the USD spend and total tokens of each run ($0.0234 · 12.4k tok), with a per-model breakdown in the cell tooltip. The same numbers are on the runs’ API payloads.
  • Whole project, one page — Insights → Usage (sidebar → Insights, then the Usage tab) is the unified view: this-month / last-30-days / all-time totals, a 90-day daily cost trend, 30-day breakdowns by model and by provider, the top campaigns and runs by AI spend (each row links through), and your user-entered campaign + channel expense totals per currency side by side with the auto-tracked spend.

Distinct from auto-tracked API costs. These are the things LeadHunter has no way of knowing about — ad spend on platforms you pay directly, agency invoices, the hours your team puts in. You log them as line items against a specific campaign.

Six kinds on a campaign: agency, labor, software, content, event, other. Ad spend (Google Ads, Meta Ads, LinkedIn Ads, other ads) goes on the channel that paid for it, and a marketing action’s fees and in-kind costs on the action. Multi-currency aware (no FX conversion); CAC is only computed when a campaign’s expenses share one currency.

The mechanics — the panel on the campaign’s Settings & costs tab, the quick-add on the campaigns list, the Cost column on Insights → Breakdown — live in their own guide: see Track campaign costs and CAC.

Both surfaces share an attribution model so the underlying data can always answer “what did this cost?” — per campaign, per account, per research record, per provider. The campaign’s Settings & costs tab covers the campaign-level slice; the account’s API payload covers the per-account enrichment slice; deeper breakdowns (per-provider, per-research, cross-campaign) are on Insights → Usage.

Estimates before scoring, and a cap on ranking runs

Section titled “Estimates before scoring, and a cap on ranking runs”

Scoring is the biggest AI cost, so nothing scores without telling you first. Score N remaining, Give feedback & rescore and the campaigns list’s Score remaining show how many accounts will be scored, the batches, the model and the estimated cost, and start only when you confirm. A ranking run shows the same estimate and also needs a Budget cap (USD): the run checks its spend before every step that costs money and stops, keeping what it scored, when the next step would go over the cap (a step can cost a little more than set aside, so the final spend can pass the cap by about one batch). The cap covers everything the run pays for, finding websites for accounts that have none included. A run can only start when its model has a known price, so the cap can be enforced.

Set a monthly API budget per project on Insights → Usage: a progress bar tracks month-to-date spend against it, and LeadHunter emails every team member when spend crosses your alert threshold (default 80%) and again at 100% — once per level per month, re-arming automatically on the 1st. The budget is an alert, not a cut-off: nothing stops running when you cross it (quota enforcement remains on the roadmap below).

Today, LeadHunter doesn’t block operations when project usage hits a threshold — there’s no project-wide quota enforcement. The only spending limit that stops work is the budget cap you set on each ranking run, and it stops only that run: the run checks its spend before every AI call (website lookups and scoring batches) and stops when the cap is reached. Calls already in flight finish, so the final spend can go a little over the cap, typically by less than one batch. Several chunks run in parallel, so the overshoot can be up to one call per running chunk. Heavy usage just produces bigger provider costs. The provider keys (AI models, Google Maps, Tavily) are managed by LeadHunter, not set per project, so Insights → Usage is where you watch what a project spends; set a monthly budget there to get the alert emails above.

Two things do limit you, and neither is a spending cap: AI and data-provider actions share a rate limit of 60 per minute per user (it stops a runaway script, not normal work; past it the action answers “too many requests” for up to a minute), and sign-in allows 10 attempts per minute per network. Quota / billing-period enforcement is on the roadmap.

Six concrete patterns:

  1. Score reuse across campaigns. The fit score belongs to the account for a product and purpose, not to a campaign. Adding the same account to a second campaign of the same product and purpose (without its own scoring brief) reuses the existing score — zero AI cost, instant — and Rank skips accounts that already have an up-to-date score. A campaign with its own scoring brief keeps its own scores, so scoring it costs again. Don’t create per-campaign products unless you genuinely need different fit criteria.
  2. Rank a sample first. On a big list, Try a sample first in the Rank dialog scores 50 accounts; check the scores before paying for the rest.
  3. Auto-enrichment short-circuits. New accounts get website-discovery + scraping for free only when they arrive without those fields. Imports that ship a populated website + website_content skip the enrichment job — the auto-enrichment signal checks for this. Pre-populating the import file saves quota.
  4. Dry-run before bulk imports. Set dry_run=true on /import_mapped/. It runs every dedupe check and shows you how many rows would be created and how many skipped as duplicates, without spending an AI call on extraction. Stops the “I just discovered the wrong column mapping after spending €40 on enrichment” problem.
  5. Use saved filters over fresh Google Maps sweeps. Once your database has the bike shops in Berlin, building a saved filter that finds them is free. Re-running the original Google Maps query a month later only catches new shops — and it still pays for every search it runs, even when most results are places you already have. If you don’t expect a lot of new places, prefer the filter.
  6. Specific Product descriptions. A sharp Product description + good example URLs means the first batch of scoring is well-calibrated. A vague description means a lot of moderate-confidence scores, more manual overrides, more rescoring as you tighten the fit criteria — every rescore is fresh AI cost.
  • Confusing the two cost surfaces. CAC is computed from the user-entered side only — the auto-tracked side is reported in USD next to it, not folded in. A campaign with €0 user-entered expenses but $40 of auto-tracked AI scoring will read “no CAC” but still show the $40 LLM total. For full-cost analysis, eyeball both cards together.
  • Forgetting to log user-entered spend. Auto-tracked costs accumulate by themselves. Ad invoices and agency fees only show up in the CAC math if you log them. Make logging spend a weekly habit.
  • Re-running the same Google Maps search. Each re-run pays for the searches again. Places already in the project are skipped before their details are fetched, so a re-run is cheaper than the first run, but not free.
  • Expecting plan limits to stop you. They won’t, today. Set a monthly budget on Insights → Usage for the alert emails, and a tight budget cap on every ranking run.