- Public Tenders Get
Fetch one tender by its public id.
The response carries a strong ETag over the tender content; pass it back as If-Match on PATCH /tenders/{tender_id} for optimistic concurrency. The ETag covers the live content only, so it is unaffected by include_deleted and a document fetched either way round-trips through PATCH (echoed deleted lines are ignored).
Also report lines that were removed from the tender: they come back flagged (is_deleted / deleted_at) instead of being omitted, so an ERP that already imported the offer can drop what is no longer on it. Removals are reported per line: taking one article off a position yields that article flagged next to the position's live lines, and a position that vanished completely comes back with all of its lines flagged — so a consumer keyed on the ordinal number can still tell the two apart. Deleted lines never count toward totals, and a position merely flagged 'not relevant' is not a deletion and stays hidden.
- Mock serverhttps://docs.mercura.ai/_mock/openapi/tenders/{tender_id}
- https://docs.mercura.ai/api/public/v1https://docs.mercura.ai/api/public/v1/tenders/{tender_id}
- Productionhttps://prod-euapi.mercura.ai/api/public/v1/tenders/{tender_id}
curl -i -X GET \
'https://docs.mercura.ai/_mock/openapi/tenders/{tender_id}?include_deleted=false' \
-H 'authorization: string'Successful Response
Lifecycle state of a tender (open enum — new values are SemVer MINOR).
A translated subset of the internal RequestStatus. The mapping lives in tenders.service._TENDER_STATUS_MAP and a test asserts it covers every internal value.
When the tender was last completed (offer exported / sent). Refreshed on every completion; null if never completed. Use it with the GET /tenders?completed_since=… completion feed.
Customer reference only — resolve full details via GET /customers/{customer_id}. Null when the tender has no customer.
Indirect-customer reference (Mercura's indirekter Kunde) — resolve full details via GET /customers/{customer_id}. Distinct from customer_id (the direct customer / Sold-To). Null when the tender has no indirect customer.
Project reference only — resolve full details via GET /projects/{project_id}. Null when the tender has no project.
The project's display name, surfaced inline for convenience (same value as name on GET /projects/{project_id}). Null when the tender has no project. Read-only.
Bid-submission date (Submissions-/Abgabetermin) as originally supplied on the project — an ISO date or free text; null when unknown. This is the tender's submission deadline, not an offer-validity ("gültig bis") date.
Mercura's internal handling deadline for this request (typically the submission date minus a buffer) — an ISO date or free text; null when unset. Informational only; not the submission deadline and not an offer-validity date.
Email of the Mercura user responsible for this tender (its Bearbeiter / Sachbearbeiter) — not necessarily the user who triggered the export. Null when no responsible user is assigned.
The primary Mercura branch (Niederlassung) assigned to this tender ({id, name}), or null when none is assigned. Read-only.
{ "id": "7", "name": "Niederlassung München" }
Organisation-defined custom fields on the request, keyed by display label. Null when none.
{ "Angebots-Nr": "AN-2026-0042" }
Organisation-defined custom fields on the responsible Mercura user (the user_email above), keyed by display label — e.g. a user's SGI. Null when the tender has no responsible user or the user has no custom fields.
{ "SGI": "12345" }
[ { "chapter_number": "01", "chapters": [ … ], "id": "5502", "is_pretext": false, "name": "Elektroinstallation", "positions": [] } ]
Aggregate amounts for the tender, all in EUR.
positions_subtotal is a derived helper: the sum of line_net across lines with is_counted_in_total = true (i.e. excluding alternatives and Bedarfspositionen ohne Gesamtbetrag / OPTIONAL_WITHOUT_TOTAL). net_total / gross_total are the authoritative request totals — the same figures Mercura prints on the PDF — preferring the request-level persisted values (which a partner can override via PATCH — see PublicTenderTotalsUpdate) and otherwise falling back to the line sums.
The two can legitimately differ: net_total is after the header additional_discount_percentage (positions_subtotal is before it), and Mercura's persisted total may include optional positions or other adjustments that the counted-line subtotal omits. Treat net_total as the source of truth for the amount owed and positions_subtotal as an informational sum.
{ "additional_discount_percentage": "3.00", "gross_total": "5992.80", "net_total": "4941.41", "positions_subtotal": "5094.24" }
The partner-side ERP offer id, when known — from your acknowledgement's external_id or a previous Mercura-managed export; otherwise null.
Your last reported ERP/CRM import outcome for this tender, or null if none yet.
{ "acknowledged_at": "2026-07-09T12:00:12Z", "external_id": "AB-2026-5567", "message": "Angebot in ERP angelegt.", "metadata": { "erp_document": "AB-2026-5567", "warehouse": "Z-100" }, "status": "SUCCESS" }
{ "acknowledgement": { "acknowledged_at": "2026-07-09T12:00:12Z", "external_id": "AB-2026-5567", "message": "Angebot in ERP angelegt.", "metadata": { … }, "status": "SUCCESS" }, "branch": { "id": "7", "name": "Niederlassung München" }, "chapters": [ { … } ], "completed_at": "2026-07-09T11:59:58Z", "created_at": "2026-07-08T09:14:00Z", "customer_id": "K-10042", "deadline": "2026-08-13", "erp_offer_id": "AB-2026-5567", "id": "12345", "indirect_customer_id": "K-20099", "project_id": "90", "project_name": "Neubau Bürogebäude Nord", "request_custom_fields": { "Angebots-Nr": "AN-2026-0042" }, "request_id": "12345", "status": "DONE", "submission_date": "2026-08-20", "totals": { "additional_discount_percentage": "3.00", "gross_total": "5992.80", "net_total": "4941.41", "positions_subtotal": "5094.24" }, "updated_at": "2026-07-09T12:00:12Z", "user_custom_fields": { "SGI": "12345" }, "user_email": "anna.schmidt@example.com" }