Skip to main content

Contract Pricing Overview

Turn a supply contract price clause into an evaluable price model, recompute prices from public indices, and check invoices through the /v1/price-baseline API.

Every endpoint on this page answers 404 in a workspace that has not added the Contract Pricing app (catalog slug price-baseline). Add it from the Apps catalog or with POST /v1/apps and slug price-baseline; GET /v1/apps lists the apps a workspace has added.

The Contract Pricing API turns the price clause of a supply contract (heat, cooling, power, gas) into one standard, evaluable price model. From that model it recomputes every price for every price period from the public indices the clause names, and it checks invoices against those prices. The result is a price baseline that is independent of the biller's own price sheet: what the contract entitles the customer to be billed, derived from the contract text and published index values.

Every number in a model, an index table or a comparison carries its source. A value from the contract is kept only with a verbatim quote that occurs in the workspace document and prints the value. A value from an index is backed by a publisher URL plus the publisher's own line. A number without a source is treated as missing: the price that depends on it is reported with a status such as missing_value or missing_index rather than computed from a guess. This rule is what makes a comparison defensible in an audit.

These endpoints belong to the Contract Pricing app, catalog slug price-baseline. A workspace uses them after adding the app; GET /v1/apps lists a workspace's apps by slug. All routes are scoped to the workspace of the authenticated API key, and a model, a comparison or a document of another workspace is never reachable.

Core Concepts

  • Price model. One stored model per contract document: components (the prices, each with a formula, a unit and an adjustment cycle) and variables (the numbers the formulas read). A variable is a base value, a weight, a constant, a contracted quantity, or an index that is resolved per price period from a series.
  • Status. A model is draft straight from extraction, confirmed once a person has checked it, or excluded when the document sets no price (a withdrawn letter, a cover mail) and must stay out of the version chain.
  • Contract and versions. Models that share a contract_key (the contract number) are versions of one contract, ordered by valid_from. Later versions inherit what they do not redefine, so an amendment only needs to state what it changes. superseded_by links an amendment explicitly when no shared key exists.
  • Index series and values. An index variable reads a series (for example a Bundesbank, Destatis, EEX or law series) by key. Published values are shared by every workspace; values entered by hand, printed on an invoice, or read from a workspace library belong to the workspace alone.
  • Assumption. A value assumed where no source exists. It is used only where no real value does, marks every price built on it as assumed, and never counts as independent.
  • Open input. A piece of data the contract workbook still needs, phrased as a question with the ways to answer it: enter the value with its quote, take it from the invoice, request it, or assume it. A choice never fills a number.
  • Invoice check. An invoice read against a model: each billed price is recomputed from the contract version in force for that month, and every line gets a verdict of match, underbilled, overbilled or not_comparable.

Authentication, Scopes and Roles

Every route takes Authorization: Bearer $TALONIC_API_KEY. Reads (GET) need the read scope. Writes (POST, PUT, DELETE) need the write scope and the person behind the key to be a member or above in the workspace. The person is the OAuth user, or the creator of a tlnc_ key, and the role is read from the live membership on every write, so a person who is demoted or removed loses write access at once. A key that belongs to no person, or whose person is not a member of the workspace, cannot write.

Response: 403 when the person is below member

{
  "error": "forbidden",
  "reason": "insufficient_role",
  "message": "This change needs Contract Management or Admin rights; the person this key acts for is a Viewer."
}
Four write routes run the extraction model inside the request: POST /v1/price-baseline/models, POST /v1/price-baseline/models/{id}/enrich, POST /v1/price-baseline/models/{id}/enrich-documents and POST /v1/price-baseline/models/{id}/compare. They can take a while and answer 502 when the model is unavailable; the error is retryable. Plan for a long timeout on the client.
Two routes write publisher data that is shared by every workspace: POST /v1/price-baseline/indices/refresh stores fetched index values as published values, and POST /v1/price-baseline/data/series/sync stores the values of shared series it fetches. Values entered through POST /v1/price-baseline/indices/manual are workspace-scoped and never shared.

Worked Example: From Contract to Checked Invoice

First find the contract among the workspace documents by filename, then extract its price model. Extraction replaces an earlier draft for the same document and keeps a value only when its quote occurs in the document and prints the value.

cURL: 1. Find the contract and extract its price model

curl "https://api.talonic.com/v1/price-baseline/documents?q=waermeliefervertrag" \
  -H "Authorization: Bearer $TALONIC_API_KEY"

curl -X POST "https://api.talonic.com/v1/price-baseline/models" \
  -H "Authorization: Bearer $TALONIC_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"document_id": "3f6c1d2e-8a41-4c57-9b0e-2d7a5c1e9f10"}'

Then recompute the prices per price period. The response lists each component's price with a status and the index values the prices read, so every number can be traced to its publisher.

cURL: 2. Recompute prices for a range of months

curl "https://api.talonic.com/v1/price-baseline/models/7b1f0a52-3c9d-4e08-a6d4-51c2e8f7b3a9/prices?from=2025-01&to=2025-12" \
  -H "Authorization: Bearer $TALONIC_API_KEY"

Finally check an invoice against the model and restate it as the invoice the contract supports. The comparison is stored; its id feeds the audit-proof restatement.

cURL: 3. Check an invoice, then read the audit-proof restatement

curl -X POST "https://api.talonic.com/v1/price-baseline/models/7b1f0a52-3c9d-4e08-a6d4-51c2e8f7b3a9/compare" \
  -H "Authorization: Bearer $TALONIC_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"invoice_document_id": "c91d47e0-52ab-4f63-8e1b-0a7d3c6f2b48"}'

curl "https://api.talonic.com/v1/price-baseline/comparisons/e04a9b17-6d28-47c5-b3f1-9c5e2a8d7016/proof-invoice" \
  -H "Authorization: Bearer $TALONIC_API_KEY"

Route Map

  • Documents and import: find documents, list contract documents without a model, queue them for extraction, poll the queue. See Documents and Import.
  • Price models: list, extract, read, edit or confirm a model, list its versions. See Price Models.
  • Open inputs: set a contract value with its quote, enrich a model, enrich from every document of the contract, record how an open input will be filled. See Open Inputs and Enrichment.
  • Register, prices and workbook: the contract register, recomputed prices, the workbook grid and its xlsx, emissions. See Register, Prices and Workbook.
  • Invoice checks: check an invoice, list earlier checks, the audit-proof restatement as data and PDF. See Invoice Checks.
  • Index values: the series catalog, stored values, on-demand fetch, hand-entered values with a source. See Index Values.
  • Series sync and quality: sync state, intervals, health, quality detectors, remap, sync on demand. See Series Sync and Data Quality.
  • Assumptions: list, make, replace and withdraw assumptions. See Assumptions.
Response envelopes differ by route and are documented per endpoint. Most lists and single reads of derived data come as { "data": ... }; models, comparisons, assumptions and the workbook grid are returned as the object itself; GET /register and POST /data/series/sync return a bare array; GET /models/{id}/prices returns { "prices", "indices" }; GET /data/quality is not wrapped.

Frequently asked questions

What does a workspace need before it can use these endpoints?+
The workspace uses the Contract Pricing app, catalog slug price-baseline, after adding it. GET /v1/apps lists the apps of a workspace by slug. The API key needs the read scope for reads and the write scope for writes, and for writes the person behind the key must be a member or above in the workspace.
Why is a price reported as missing instead of computed?+
A number without a source is treated as missing. A contract value whose quote does not occur in the document, or does not print the value, is not used, and an index value that is not stored cannot be read. The price then carries a status such as missing_value or missing_index with a detail, and the open input appears in the workbook so a person can supply the source.
Which calls run a model inside the request?+
Extracting a model, enriching a model, enriching from the documents of a contract, and checking an invoice. Each runs the extraction model in the request and answers 502 with a retryable error when the model is unavailable. Everything else reads or writes stored data, including the proof invoice, which makes no model call.
Do two workspaces share any data?+
Only published index values. Values fetched from a publisher are stored once and shared by every workspace, which is why the on-demand fetch and the series sync can affect other workspaces. Models, comparisons, assumptions, hand-entered values, invoice-printed values and library values belong to one workspace.