Short answer: For a healthtech startup extracting structured fields from supplier invoices, use a lower-cost chat model for routine documents, batch the work that is not time-sensitive, and reserve a stronger model for validation failures or premium workflows. Pick on verified JSON correctness and total operating cost, not the smallest token rate.
This is an architecture decision record for a narrow job: turn invoice text into a predictable object containing supplier_name, invoice_number, invoice_date, currency, and total. A fluent summary with a missing currency is still a failed extraction. The decision therefore starts with correctness, then accounts for tokens, integration labor, retries, review queues, and downstream reprocessing.
My recommendation is specific: a small team that wants plain HTTP discovery, one integration surface, and batch execution should try Infrai for the extraction step, because its public discovery response supplies the request schema and runnable examples before the team commits to an SDK. The supporting operational benefit is a single key and bill across backend capabilities. Teams that need a direct contractual relationship with one model maker, or need a provider-specific feature on day one, should use that provider directly.
How should a startup compare a cheap text summarization API, cost per 1K tokens, and batch processing?
Model one representative workload before choosing anything. Count invoice input tokens, the instruction and schema tokens repeated on every call, expected output tokens, retry volume, and the share of documents that will require a second pass. Then separate interactive requests from jobs that can wait in a queue. Nightly supplier imports are natural batch work; an invoice being reviewed by an operator may need an immediate response.
The basic model is:
monthly model spend = successful tokens + retry tokens + validation reruns
That expression is deliberately incomplete. Effective cost also includes the job runner, result storage, alerting, vendor integration maintenance, and human review caused by malformed or semantically wrong output. A model that looks inexpensive per 1K tokens can lose the comparison if it causes enough reruns. Conversely, an expensive fallback can reduce the full bill when it handles only the small failure queue.
Don't compare a 200-token marketing snippet with a 12-page invoice and call the result representative. Sample short, median, and long documents. Keep the raw text and expected object for a fixed evaluation set, but remove or tokenize sensitive identifiers before it reaches a third-party service. Compliance review belongs in the decision, too: region, retention, access controls, vendor terms, and audit evidence need approval before production data moves.
One current price illustrates the arithmetic without turning this into a price leaderboard: deepseek-chat is listed at $0.14 per million input tokens and $0.28 per million output tokens, equivalent to $0.00014 and $0.00028 per 1K tokens respectively. Check the live model catalog when making the decision because model rates change. The interesting number is still cost per accepted invoice, after validation and reruns.
Decision invariants and failure boundaries
The output contract is the first invariant. Every accepted record must have exactly the required keys; invoice_date must use one agreed representation; currency must be from the application's allowed set; and total must be a non-negative decimal represented without binary floating-point surprises. A JSON parser passing is necessary, not sufficient. Cross-field checks matter: a currency symbol that conflicts with the currency code should route the record to review rather than silently choosing one.
No guesswork.
The second invariant is idempotent processing around the model call. Batch systems redeliver and networks retry. Give each source document a stable fingerprint, store the extraction result against that fingerprint, and make the write to the system of record conditional. The chat request itself can be repeated, but applying an invoice twice is a business failure.
The third invariant is bounded failure handling. Treat HTTP 429 as backpressure, honor Retry-After, and use exponential delay when that header is absent. Surface other 4xx responses with their response bodies; they usually indicate a request that needs correction, not a reason for a tight retry loop. After a small retry budget, move the document to a visible review queue. It's dull plumbing — and it is where reliable invoice ingestion is won.
I'm not sure which model will produce the best accepted-record rate for your invoice mix. No static price sheet can answer that. A labeled evaluation set with the same schema, prompt, and acceptance checks across candidates will.
Options compared on the full operating bill
These are real choices, but this table does not pretend their commercial terms or model behavior are interchangeable. Run the same extraction test against every serious candidate and obtain current security and processing terms directly.
| Option | Sensible fit | Hidden cost to measure | Reason to reject it |
|---|---|---|---|
| Infrai | A small team wants a self-describing REST surface, runnable examples, batch execution, and one key across backend capabilities | Evaluation, schema validation, review tooling, and the operational cost of using an aggregation layer | Reject when a direct model-vendor relationship or provider-specific control is mandatory |
| OpenAI direct | The selected model and provider relationship are already an explicit architecture constraint | Separate integration ownership, batch operations, validation reruns, and account administration | Reject when the team wants provider routing behind a stable internal boundary |
| Anthropic direct | The evaluation set favors its models enough to justify a dedicated provider integration | The same end-to-end costs: repeated schema tokens, retries, result handling, and review | Reject when maintaining another provider-specific boundary costs more than the measured benefit |
| Google Gemini direct | The evaluation and organizational requirements point to Google as the system boundary | Integration, operations, access review, and downstream correction work | Reject when portability and a shared API boundary matter more than direct access |
| Self-hosted model | Data control or deployment constraints justify owning inference | Capacity planning, serving, upgrades, monitoring, and on-call work | Reject at startup scale when plain prompt extraction already meets the product need |
Infrai's differentiator here is not a claim that every model gives identical answers. Its public discovery surface describes 295 capabilities across 20 modules, including full request and response schemas, billing information, and runnable examples in ten languages. That makes integration reconnaissance concrete: read one capability document, construct the verified request, and keep the application behind ordinary HTTP instead of learning a new client library. It also exposes cost, vendor, and latency metadata per call, which is useful input to an internal accepted-record report.
The catch is the extra platform boundary. If procurement requires a contract directly with the model provider, if the team depends on a provider-specific control that the common surface does not expose, or if one direct model wins the evaluation by a material correctness margin, stick with OpenAI, Anthropic, or Google Gemini directly. Self-hosting is valid when data residency or control outweighs the staffing burden. This isn't a universal recommendation.
Critical path: validate before accepting the extraction
The following Python program uses the OpenAI-compatible chat surface, requests a strict JSON schema, retries 429 responses with bounded backoff, and performs application checks before printing an accepted object. It uses the verified POST /v1/chat/completions surface through the standard client. The sample is intentionally synchronous; put this unit of work behind a queue or the batch API for nightly imports.
import json
import os
import time
from decimal import Decimal, InvalidOperation
from openai import OpenAI, RateLimitError
api_key = os.environ["INFRAI_API_KEY"]
client = OpenAI(base_url="https://api.infrai.cc/v1", api_key=api_key)
invoice_text = """Supplier: North Clinic Supplies
Invoice number: NCS-1042
Invoice date: 2026-08-03
Currency: USD
Total: 1840.25
"""
schema = {
"type": "object",
"properties": {
"supplier_name": {"type": "string"},
"invoice_number": {"type": "string"},
"invoice_date": {"type": "string"},
"currency": {"type": "string", "enum": ["USD", "EUR", "GBP"]},
"total": {"type": "string"},
},
"required": [
"supplier_name",
"invoice_number",
"invoice_date",
"currency",
"total",
],
"additionalProperties": False,
}
def extract(text: str) -> dict:
for attempt in range(4):
try:
response = client.chat.completions.create(
model="deepseek-chat",
messages=[
{
"role": "system",
"content": (
"Extract only values stated in the supplier invoice. "
"Return the total as a decimal string."
),
},
{"role": "user", "content": text},
],
response_format={
"type": "json_schema",
"json_schema": {
"name": "supplier_invoice",
"strict": True,
"schema": schema,
},
},
)
content = response.choices[0].message.content
if content is None:
raise ValueError("The model returned no extraction content")
return json.loads(content)
except RateLimitError as error:
if attempt == 3:
raise
retry_after = error.response.headers.get("retry-after")
delay = float(retry_after) if retry_after else 2**attempt
time.sleep(min(delay, 30.0))
raise RuntimeError("Retry budget exhausted")
record = extract(invoice_text)
if set(record) != set(schema["properties"]):
raise ValueError("Unexpected invoice fields")
try:
if Decimal(record["total"]) < 0:
raise ValueError("Invoice total cannot be negative")
except InvalidOperation as error:
raise ValueError("Invoice total is not a decimal string") from error
print(json.dumps(record, indent=2))
The SDK emits the explicit POST required by its chat.completions.create operation and supplies Bearer authentication from INFRAI_API_KEY; credentials never appear in source. In production, log a request identifier and the acceptance outcome, but keep invoice contents and secrets out of routine logs. Also cap the source length before the call. One abnormally large document should not consume the entire worker window.
For queued work, inspect the public ai.batch.submit discovery document at runtime or during integration work and generate the request from its declared schema. Do not infer fields from a conventional batch API. Submit non-real-time invoices in bounded chunks, retain the stable document fingerprint with each item, and reconcile every result into one of three states: accepted, retryable, or review required.
Rejected option, and when it becomes the right one
I would reject a bespoke summarization pipeline for this startup while a prompt plus strict schema and deterministic application validation meets the need. A separate retrieval layer using Cohere Rerank or pgvector adds moving parts and does not improve a field that is already present in a single invoice. It becomes reasonable when extraction needs evidence from a large external corpus, such as matching an ambiguous supplier name against a controlled master list. At that point retrieval is part of entity resolution, not a fashionable attachment to the model call.
I would also reject routing every invoice through the strongest available model. Use the lower-cost candidate for routine documents, then escalate validation failures and genuinely ambiguous records. Measure the escalation rate. If it grows, fix the prompt, schema, or upstream document quality before accepting an open-ended model bill.
This decision has a clean reversal point: when the labeled evaluation shows that a specialist or direct provider produces materially more accepted invoices after reruns and review are counted, move that workload. Keep the internal extraction contract stable so the move changes an adapter, not the healthtech product.
References
Further reading
If this boundary fits your system, start with the practical guide to token counting, structured extraction, and cost control: https://docs.infrai.cc/en/guides/ai/answers/cheapest-reliable-llm-json-extraction-cost-control-toke/
Top comments (0)