Skip to main content
CornectAPI Docsv1
Sign inGet an API tokenGet started free

Credit Consumption

The Credits page covers the basics. This guide details the dedup model, how to estimate a job's cost, and how to track usage over time.

The dedup model#

Exports charge 1 credit per company that your workspace has not exported before. The first time you export Acme Inc. you're charged; every later export that includes Acme is free. This makes overlapping or repeated exports cheap — you only ever pay once per company, per workspace.

The create response makes the math explicit:

json
{
  "export_job": { "id": "...", "status": "pending" },
  "requested_count": 500,    // companies the source resolved to
  "already_unlocked": 320,   // previously exported — free
  "new_count": 180,          // newly unlocked
  "credits_charged": 180,    // always == new_count; all or nothing
  "capped_at_10k": false,
  "transaction_id": "..."
}
10k cap
A single export is capped at 10,000 companies (capped_at_10k). For larger sets, split the work into multiple exports.

Check the cost before you spend#

POST /exports/preview takes the same body as Create Export and returns the exact charge — including the dedup against everything your workspace has already exported. It is free, it uses the read scope, and it creates nothing. Send it the body you are about to submit:

// Exactly what this export will cost, before creating it.
const p = await api("POST", "/api/v1/exports/preview", {
  source_type: "search",
  search_filters: filters,
});

// p.cost           credits this will charge (= p.new_count)
// p.already_unlocked  companies you already own, free again
// p.balance        your balance right now
// p.would_export   rows the export would contain
// p.would_skip     your SHORTFALL — above zero means create is refused

if (p.would_skip > 0) {
  // Create Export would return 402 and charge nothing.
  throw new Error(
    `Short by ${p.would_skip} credits — top up, or narrow the filters.`
  );
}
All or nothing — a short balance is refused

This is the reason to preview. If your balance cannot cover cost in full, Create Export returns 402 insufficient_balance and nothing happens: no credits charged, no job created, no companies unlocked. A balance of zero and a balance that is merely short behave identically.

The 402 carries details.shortfall, details.cost, details.balance and details.matched_count, so you can tell a user exactly how many more credits they need without another request. Preview is free, so checking would_skip first is cheaper than being refused.

Estimating without a preview#

If you want a rough ceiling without a round trip, run the same search and read total: your charge is at most min(total, 10000), and less to the extent you have already exported some of those companies. Prefer the preview above when the number matters — this one cannot see your dedup history.

// Upper-bound estimate before creating an export.
const [search, credits] = await Promise.all([
  api("POST", "/api/v1/companies/search", filters),
  api("GET", "/api/v1/credits"),
]);
const upperBound = Math.min(search.total, 10000);
if (credits.balance < upperBound) {
  console.warn(`May be short: balance ${credits.balance} < up to ${upperBound}`);
  // top up at app.cornect.io/account/credits, or proceed —
  // already-exported companies won't be charged again.
}

Tracking usage#

GET /credits returns recent_transactions with a signed amount and a reason (e.g. export_charge). Negative amounts are charges, positive are grants/refunds. Poll it after exports to reconcile spend, and store the transaction_id from each create response to tie a charge to a specific export job.