Skip to content

Public Tenders Update

Request

Edit one tender in place and read back the re-projected result.

Two addressing modes: a sparse top-level positions[] (recommended — edit or delete existing lines by id) and the nested chapters tree (required for adds; also accepts edits). Edit a line by id; delete one with {"id": "…", "op": "delete"} (soft-delete); add a line by sending it without an id (article_number for an article line — with optional price/discount — else a free-text line under a chapter). Omitted lines are left untouched. totals.net_total / gross_total persist as the partner's authoritative amounts. Pass the GET's ETag as If-Match to be rejected with 412 if the tender changed since you read it.

Closing a tender. Send {"status": "CANCELLED"} for a tender that was resolved outside Mercura — its CRM case was closed, or it was quoted by hand — so it leaves the open inbox instead of accumulating there. It is the only writable transition; echoing the tender's current status is a no-op, so a full GET body still round-trips.

Path
tender_idstring(Tender Id)required
Headers
If-Matchstring or null(If-Match)

Optional strong ETag from a prior GET; a mismatch is a 412 (someone else edited the tender).

authorizationstring or null(Authorization)

Bearer <mrc_live_…> API key

Bodyapplication/jsonrequired
totalsobject(PublicTenderTotalsUpdate)

Optional summary-total overrides (net/gross totals, header discount).

Example:
{ "additional_discount_percentage": "3.00" }
positionsArray of objects(Positions)

Sparse edits/deletes addressed by line id (no chapter path). Adds must use chapters, except an article note (parent_line_id), which is accepted here.

Example:
[ { "id": "840210", "net_price": "74.90" }, { "article_number": "LEU-1200-30-830", "id": "840215", "net_price": "71.10" }, { "id": "840290", "op": "delete" } ]
chaptersArray of objects(Chapters)
erp_offer_idstring or null, [ 1 .. 255 ] characters(Erp Offer Id)

Your ERP's id for the offer created from this tender. Set-only: a value is written and kept, null (or omitting the key) leaves the stored id untouched so a full GET body round-trips, and there is no way to clear it — send a new value to replace it. The same field is set by an acknowledgement's external_id; use whichever fits your flow (the acknowledgement additionally records the import outcome).

Example:"SAP-4500012345"
request_custom_fieldsobject or null(Request Custom Fields)

Label-keyed REQUEST custom-field values to shallow-merge onto the tender's underlying request. Keys are the organisation's custom-column labels; multi_select values are option labels. A null value clears that field; sending the whole object as null (or omitting it) is a no-op, so a full GET body round-trips. Unknown labels or option labels are a 400. Symmetric with the request_custom_fields you read on GET.

statusstring(PublicTenderStatus)

Lifecycle status. The only writable transition is to CANCELLED — use it to close a tender that was resolved outside Mercura (e.g. its case was closed in your CRM), so it leaves the open inbox. Sending the tender's current status is a no-op, so a full GET body still round-trips. Any other target is a 400; cancelling a tender that is PARSING or already DONE is a 409.

Enum:"NEW""IN_PROGRESS""DONE""CANCELLED""PARSING""PARSING_FAILED"
idstring or null(Id)

Ignored on write.

request_idstring or null(Request Id)

Ignored on write.

completed_atstring or null, (date-time)(Completed At)

Ignored on write.

customer_idstring or null(Customer Id)

Ignored on write.

indirect_customer_idstring or null(Indirect Customer Id)

Ignored on write (read-only).

project_idstring or null(Project Id)

Ignored on write.

project_namestring or null(Project Name)

Ignored on write (read-only).

submission_datestring or null(Submission Date)

Ignored on write (read-only).

deadlinestring or null(Deadline)

Ignored on write (read-only).

user_emailstring or null(User Email)

Ignored on write.

branchobject or null(Branch)

Ignored on write (read-only).

user_custom_fieldsobject or null(User Custom Fields)

Ignored on write (read-only).

acknowledgementobject or null(Acknowledgement)

Ignored on write.

created_atstring or null, (date-time)(Created At)

Ignored on write.

updated_atstring or null, (date-time)(Updated At)

Ignored on write.

curl -i -X PATCH \
  'https://docs.mercura.ai/_mock/openapi/tenders/{tender_id}' \
  -H 'Content-Type: application/json' \
  -H 'If-Match: string' \
  -H 'authorization: string' \
  -d '{
    "erp_offer_id": "SAP-4500012345",
    "positions": [
      {
        "id": "840210",
        "net_price": "74.90"
      },
      {
        "article_number": "LEU-1200-30-830",
        "id": "840215",
        "net_price": "71.10"
      },
      {
        "id": "840290",
        "op": "delete"
      }
    ],
    "totals": {
      "additional_discount_percentage": "3.00"
    }
  }'

Responses

Successful Response

Bodyapplication/json
idstring(Id)required

Public id; equals request_id for a tender.

Example:"12345"
request_idstring(Request Id)required

Mercura request id backing this tender.

Example:"12345"
statusstring(PublicTenderStatus)required

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.

Enum:"NEW""IN_PROGRESS""DONE""CANCELLED""PARSING""PARSING_FAILED"
Example:"DONE"
completed_atstring or null, (date-time)(Completed At)

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.

Example:"2026-07-09T11:59:58Z"
customer_idstring or null(Customer Id)

Customer reference only — resolve full details via GET /customers/{customer_id}. Null when the tender has no customer.

Example:"K-10042"
indirect_customer_idstring or null(Indirect Customer Id)

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.

Example:"K-20099"
project_idstring or null(Project Id)

Project reference only — resolve full details via GET /projects/{project_id}. Null when the tender has no project.

Example:"90"
project_namestring or null(Project Name)

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.

Example:"Neubau Bürogebäude Nord"
submission_datestring or null(Submission Date)

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.

Example:"2026-08-20"
deadlinestring or null(Deadline)

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.

Example:"2026-08-13"
user_emailstring or null(User Email)

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.

Example:"anna.schmidt@example.com"
branchobject(PublicTenderBranch)

The primary Mercura branch (Niederlassung) assigned to this tender ({id, name}), or null when none is assigned. Read-only.

Example:
{ "id": "7", "name": "Niederlassung München" }
request_custom_fieldsobject or null(Request Custom Fields)

Organisation-defined custom fields on the request, keyed by display label. Null when none.

Example:
{ "Angebots-Nr": "AN-2026-0042" }
user_custom_fieldsobject or null(User Custom Fields)

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.

Example:
{ "SGI": "12345" }
chaptersArray of objects(Chapters)
Example:
[ { "chapter_number": "01", "chapters": [], "id": "5502", "is_pretext": false, "name": "Elektroinstallation", "positions": [] } ]
totalsobject(PublicTenderTotals)required

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.

Example:
{ "additional_discount_percentage": "3.00", "gross_total": "5992.80", "net_total": "4941.41", "positions_subtotal": "5094.24" }
erp_offer_idstring or null(Erp Offer Id)

The partner-side ERP offer id, when known — from your acknowledgement's external_id or a previous Mercura-managed export; otherwise null.

Example:"AB-2026-5567"
acknowledgementobject(PublicTenderAcknowledgement)

Your last reported ERP/CRM import outcome for this tender, or null if none yet.

Example:
{ "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" }
created_atstring, (date-time)(Created At)required
Example:"2026-07-08T09:14:00Z"
updated_atstring, (date-time)(Updated At)required
Example:"2026-07-09T12:00:12Z"
Response
{ "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" }