---
title: "Get Extraction Cost"
method: GET
path: "/api/v1/documents/extractions/{document_extraction_id}/cost"
tags: ["Document"]
---

# Get Extraction Cost

`GET /api/v1/documents/extractions/{document_extraction_id}/cost`

## Request

- Base URL: `https://api.gemina.co` (the document declares no server; this is the origin it was published from)
- URL: `https://api.gemina.co/api/v1/documents/extractions/{document_extraction_id}/cost`
- Auth: API key in header `X-API-Key`

Look up what a single extraction cost.

See the bulk variant (`/extractions/costs`) for the `state` semantics. An
extraction the calling API key does not own is reported as not found.

## Path parameters

- `document_extraction_id` string, uuid, required

## Response `200`

Successful Response

- ExtractionCostOutResultDTO
  - `servedAt` string, date-time
  - `servedAtTimestamp` number
  - `createdAt` string, date-time, nullable
  - `createdAtTimestamp` number, nullable
  - `status` 'pending' | 'in_process' | 'failed' | 'success' | 'partial' | 'empty', required
  - `meta` FoundationMetaDTO
    - `externalId` string, nullable
    - `correlationId` string, uuid, nullable
    - `userId` string, uuid, nullable
  - `data` ExtractionCostOutDTO, required: What one extraction cost, and whether that number is final. Deliberately lean on payload: no signed image URLs, no extracted values, no validation lookup. The full extraction view already carries the same cost fields for callers who want everything; this exists so "what did this cost?" does not pay for three storage round trips per extraction. On ``FoundationModel`` rather than ``LeanFoundationModel`` so each row carries the underlying extraction's ``createdAt`` -- per the repo timestamp convention, and the field a client buckets spend by when reconciling a period.
    - `createdAt` string, date-time, nullable
    - `createdAtTimestamp` number, nullable
    - `extractionId` string, uuid, required
    - `creditsConsumed` string, nullable: Credits debited for this extraction. Null for enterprise customers, who are billed in contract dollars via costCents, and whenever state is not 'settled'.
    - `costCents` integer, nullable: Enterprise rate-card cost in cents. Null for credit-billed customers.
    - `meter` 'processing_credits' | 'filetag_credits': Discriminates which balance a credit transaction debits/credits. ``processing_credits`` covers both subscription and enterprise ledgers (distinguished by ``subscription_id IS NULL`` on enterprise rows). ``filetag_credits`` covers the per-user FileTag allowance stored in ``filetag_credit_balances``. Separate meters so reports and history views can filter cleanly without conflating the two accounting pools.
    - `costExplanation` string, nullable
    - `state` 'pending' | 'settled' | 'not_charged', required: Whether an extraction's cost is final, still coming, or never charged. Exists because a bare ``null`` cost is ambiguous across three genuinely different situations, and a client reconciling spend has to tell them apart: - ``pending`` -- the charge has not been written yet. Credits are deducted in the Celery post phase, which runs *after* the extraction result is available, so a freshly finished extraction legitimately has no cost on record. Retry. - ``settled`` -- a charge is on record. This is the authoritative number. - ``not_charged`` -- terminal: no charge exists and none is coming. Either the extraction FAILED (billing follows outcome, so a failure is never charged), or billing ran and did not charge -- usually a real billing failure, since ``post_summary_update_task`` swallows ``SubscriptionError`` to a log line. Never resolves on its own, so a client must not poll it. Two caveats on ``not_charged``, both from ``post_tasks_complete`` being a coarse proxy for "billing finished": 1. It records that ``post_summary_update_task`` *started*, not that it charged -- the flag is written as that task's first statement, well before the charge itself. A read landing in between sees ``not_charged`` for an extraction that is about to be billed. 2. It is per-correlation (per document), so on a multi-extraction document the first extraction to reach billing flips it for its siblings too. Both windows are short (tens of milliseconds), but they mean ``not_charged`` is advisory: alert on it only after a grace period, never treat a single reading as proof of an unbilled extraction.
  - `errors` object[]

## Other responses

- `404`: The resource does not exist, or is not visible to the caller. Ownership failures are deliberately indistinguishable from a missing resource.
- `422`: Validation Error

---

[API](https://skmtc.dev/gemina/apis/gemina-api.md) · [All operations](https://skmtc.dev/gemina/apis/gemina-api/llms.txt) · [OpenAPI document](https://skmtc.dev/gemina/apis/gemina-api/revisions/152fd3f6f6ec?raw)
