procuris

Events

Which events procuris sends, when each one arrives, how a message is structured and how you detect changes.

On request

You receive this service through an individual quote.

procuris sends one message per event to the address of your system. The message carries the full record of the tender instead of just an identifier. Your system therefore needs no second fetch.

The role Owner makes the selection themselves. Under Settings › Organization › Webhooks, they define which events arrive for which tenders. The section appears only once access has been set up after the contract is signed. Until then, the Webhooks row in the On request section of the same page only requests a quote.

Overview

EventWhen it arrivesTypical use
tender.publisheda tender matches your filters: because it is new, because a change made it match or because it matches again after dropping outcreate a sales opportunity in the CRM
tender.updateda field of a tender from your selection changes, for example description, lots, contract value or deadlineupdate the record in your system
tender.deadline_changedthe submission or participation deadline of a tender from your selection, or of one of its lots, changesupdate the date, notify the people responsible
tender.archiveda tender from your selection, including one that has dropped out, has expired, been cancelled, been awarded or been merged with another recordclose or merge the sales opportunity
search.hita saved search of your organization finds a new hit at or above its Thresholdpass the hit to the responsible team
webhook.testthe owner chooses Send test message under Webhookscheck reception, learn the structure in the workflow builder

A saved search is a stored search that keeps running every morning. The Threshold is the Fit from which a hit appears at the top. Which tenders belong to your selection is described under Choose what arrives.

Timing. tender.* events arrive up to one hour after procuris has taken over the change. The reference point is lastModified, the time at which procuris took over the change. The change at the contracting authority can be earlier. The data set receives at most one new state per hour. search.hit arrives once in the morning with the run of the saved search and contains the same hits as its email.

What does not trigger an event. A new data state (checkedAt) without changed fields triggers no event.

Dropping out. A tender outside your selection receives no more changes. This applies when it no longer matches your filters after a change and is not an earlier hit of a selected saved search. It then receives neither tender.updated nor tender.deadline_changed. If it matches the filters again later, tender.published arrives again. tender.archived also arrives for tenders that have dropped out, so that your system can close open cases.

Choose what arrives

Per endpoint, the owner chooses three things. They can change the selection under Webhooks later:

  • Event types, for example only search.hit and tender.archived
  • Filters for the tender.* events, with the same parameters as in the API: cpv, nuts, deadline_after, value_min, value_max, procedure
  • Saved searches: all saved searches of your organization or only certain ones. This selection applies to search.hit.

Filter or saved search, one is enough. As an option, the saved-search selection also applies to tender.updated, tender.deadline_changed and tender.archived. Then these events arrive for a tender if it matches the filters or has ever been a hit of a selected saved search. Both at once are not necessary. This way your system learns about changed values, postponed deadlines and archiving of its hits, even if these lie outside the filters. Without this option, only the filters apply to tender.*. Without filters, but with this option, the three events arrive only for earlier hits of the selected saved searches, not for all tenders.

tender.updated or tender.deadline_changed? Choose tender.updated if your system keeps the whole record current. A postponed deadline then appears in changedFields. Choose tender.deadline_changed if your system only needs deadlines, for example for a calendar. With both, a postponed deadline arrives twice, once per event.

Structure of a message

A message has three fields according to the Standard Webhooks specification:

FieldContent
typethe event, for example tender.published
timestampwhen the event occurred, in ISO 8601. On a retry, this value stays the same.
datatender, the full record as in the Data model, plus the fields below per event
EventAdditional fields in data
tender.publishednone
tender.updatedchangedFields: list of the changed fields, for example ["description", "lots"]. previous: the values of these fields before the change.
tender.deadline_changedchangedFields with submissionDate, participationDeadline or the path of a lot lots[n].submissionDate, for example lots[0].submissionDate for the first lot (counted from 0), previous with the old deadlines under the same keys
tender.archivednone. The reason is in tender.archiveReason, for merged the remaining id is in tender.mergedInto.
search.hitsearch: id and name of the saved search. fit: the Fit from 0 to 100, as shown on the hit in procuris.
webhook.testtest: true. Plus a sample saved search in search and a sample Fit in fit as with search.hit.

Order. The order of messages is not guaranteed. Retries and resends can bring an older state after a newer one. Take over fields from data.tender only if data.tender.lastModified is newer than your stored state. Take over data.fit (only with search.hit) only if the timestamp of the message is newer than the timestamp of the message from which your last taken-over Fit came. Store that timestamp together with the Fit. This way neither a delayed nor a resent search.hit overwrites a newer state.

Examples

The examples show the sample record from the Data model at the respective point in time. The contracting authority published the notice on 17 September without a contract value. Until 22 September the record therefore held an estimate of 334,643 euros. On 22 September the contracting authority stated the contract value of 351,000 euros. Further points in time are the hit on 18 September, the postponed deadline on 24 September and the archiving on 14 October.

tender.published, complete

{
  "type": "tender.published",
  "timestamp": "2026-09-17T14:05:12.000Z",
  "data": {
    "tender": {
      "id": "e9da30eb-50e6-47f1-887f-434016267b2f",
      "status": "open",
      "archiveReason": null,
      "mergedInto": null,
      "title": "Nordhausen - Sanierung Rolandbrunnen, Erneuerung Brunnentechnik",
      "description": "Erneuerung der Brunnentechnik des Rolandbrunnens in Nordhausen. Los 1 umfasst Pumpen und Steuerung, Los 2 die Beckenabdichtung.",
      "tenderNumber": "33/61/2026",
      "url": "https://www.procuris.eu/notices/nordhausen-sanierung-rolandbrunnen-erneuerung-brunnentechnik-e9da30eb",
      "publicationDate": "2026-09-17T13:32:56.000Z",
      "submissionDate": "2026-10-07T08:00:00.000Z",
      "participationDeadline": null,
      "lastModified": "2026-09-17T14:05:12.000Z",
      "checkedAt": "2026-09-17T14:05:12.000Z",
      "contractAmount": {
        "value": 334643,
        "currency": "EUR",
        "estimated": true
      },
      "procedureType": "open",
      "contractNature": "works",
      "legislation": null,
      "organizations": [
        {
          "id": "7c2a9e41-3d8b-4f6a-b1e2-5a0c9d4e8f17",
          "name": "Stadtverwaltung Nordhausen - Vergabestelle",
          "role": "contractingParty",
          "contactName": "Vergabestelle",
          "email": "vergabe@example.org",
          "phone": "+49 3631 000000",
          "address": {
            "street": "Musterstraße 1",
            "postalCode": "99734",
            "city": "Nordhausen",
            "countryCode": "DE"
          }
        }
      ],
      "cpvClassifications": [
        {
          "cpvCode": "45000000",
          "title": "Bauarbeiten"
        },
        {
          "cpvCode": "71000000",
          "title": "Architektur & Ingenieurwesen"
        }
      ],
      "regionCodes": ["DEG"],
      "realizedLocation": "Nordhausen",
      "lots": [
        {
          "lotNumber": "1",
          "title": "Pumpen und Steuerung",
          "description": "Lieferung und Einbau der Umwälzpumpen und der Brunnensteuerung.",
          "contractAmount": {
            "value": 212000,
            "currency": "EUR",
            "estimated": true
          },
          "submissionDate": null,
          "cpvClassifications": [
            {
              "cpvCode": "45232150",
              "title": "Arbeiten an Wasserleitungen"
            }
          ]
        },
        {
          "lotNumber": "2",
          "title": "Beckenabdichtung",
          "description": null,
          "contractAmount": null,
          "submissionDate": null,
          "cpvClassifications": []
        }
      ],
      "sources": [
        {
          "name": "TED",
          "url": "https://ted.europa.eu/de/notice/-/detail/000000-2026",
          "publishedAt": "2026-09-17T13:32:56.000Z"
        }
      ]
    }
  }
}

search.hit, complete

{
  "type": "search.hit",
  "timestamp": "2026-09-18T05:00:00.000Z",
  "data": {
    "search": {
      "id": "3b1f6c2e-8f0a-4d7e-9a51-2c4e7d9b0f13",
      "name": "Brunnen und Wasserspiele Thüringen"
    },
    "fit": 82,
    "tender": {
      "id": "e9da30eb-50e6-47f1-887f-434016267b2f",
      "status": "open",
      "archiveReason": null,
      "mergedInto": null,
      "title": "Nordhausen - Sanierung Rolandbrunnen, Erneuerung Brunnentechnik",
      "description": "Erneuerung der Brunnentechnik des Rolandbrunnens in Nordhausen. Los 1 umfasst Pumpen und Steuerung, Los 2 die Beckenabdichtung.",
      "tenderNumber": "33/61/2026",
      "url": "https://www.procuris.eu/notices/nordhausen-sanierung-rolandbrunnen-erneuerung-brunnentechnik-e9da30eb",
      "publicationDate": "2026-09-17T13:32:56.000Z",
      "submissionDate": "2026-10-07T08:00:00.000Z",
      "participationDeadline": null,
      "lastModified": "2026-09-17T14:05:12.000Z",
      "checkedAt": "2026-09-18T04:00:00.000Z",
      "contractAmount": {
        "value": 334643,
        "currency": "EUR",
        "estimated": true
      },
      "procedureType": "open",
      "contractNature": "works",
      "legislation": null,
      "organizations": [
        {
          "id": "7c2a9e41-3d8b-4f6a-b1e2-5a0c9d4e8f17",
          "name": "Stadtverwaltung Nordhausen - Vergabestelle",
          "role": "contractingParty",
          "contactName": "Vergabestelle",
          "email": "vergabe@example.org",
          "phone": "+49 3631 000000",
          "address": {
            "street": "Musterstraße 1",
            "postalCode": "99734",
            "city": "Nordhausen",
            "countryCode": "DE"
          }
        }
      ],
      "cpvClassifications": [
        {
          "cpvCode": "45000000",
          "title": "Bauarbeiten"
        },
        {
          "cpvCode": "71000000",
          "title": "Architektur & Ingenieurwesen"
        }
      ],
      "regionCodes": ["DEG"],
      "realizedLocation": "Nordhausen",
      "lots": [
        {
          "lotNumber": "1",
          "title": "Pumpen und Steuerung",
          "description": "Lieferung und Einbau der Umwälzpumpen und der Brunnensteuerung.",
          "contractAmount": {
            "value": 212000,
            "currency": "EUR",
            "estimated": true
          },
          "submissionDate": null,
          "cpvClassifications": [
            {
              "cpvCode": "45232150",
              "title": "Arbeiten an Wasserleitungen"
            }
          ]
        },
        {
          "lotNumber": "2",
          "title": "Beckenabdichtung",
          "description": null,
          "contractAmount": null,
          "submissionDate": null,
          "cpvClassifications": []
        }
      ],
      "sources": [
        {
          "name": "TED",
          "url": "https://ted.europa.eu/de/notice/-/detail/000000-2026",
          "publishedAt": "2026-09-17T13:32:56.000Z"
        }
      ]
    }
  }
}

In the following examples, data.tender is also the full record. Shown are only id, lastModified, checkedAt and the fields the event is about.

tender.updated

{
  "type": "tender.updated",
  "timestamp": "2026-09-22T09:40:03.000Z",
  "data": {
    "tender": {
      "id": "e9da30eb-50e6-47f1-887f-434016267b2f",
      "lastModified": "2026-09-22T09:40:03.000Z",
      "checkedAt": "2026-09-22T09:40:03.000Z",
      "contractAmount": {
        "value": 351000,
        "currency": "EUR",
        "estimated": false
      }
    },
    "changedFields": ["contractAmount"],
    "previous": {
      "contractAmount": {
        "value": 334643,
        "currency": "EUR",
        "estimated": true
      }
    }
  }
}

tender.deadline_changed

{
  "type": "tender.deadline_changed",
  "timestamp": "2026-09-24T09:10:00.000Z",
  "data": {
    "tender": {
      "id": "e9da30eb-50e6-47f1-887f-434016267b2f",
      "lastModified": "2026-09-24T09:10:00.000Z",
      "checkedAt": "2026-09-24T09:10:00.000Z",
      "submissionDate": "2026-10-14T08:00:00.000Z",
      "participationDeadline": null
    },
    "changedFields": ["submissionDate"],
    "previous": {
      "submissionDate": "2026-10-07T08:00:00.000Z"
    }
  }
}

Deadline of a lot. For lot deadlines, changedFields and previous carry the path of the lot. The new value is in data.tender.lots[n].submissionDate. In the sample record, the lots have no deadline of their own. The excerpt therefore only shows the structure for the case that lot 1 had a deadline of its own and it changes:

{
  "changedFields": ["lots[0].submissionDate"],
  "previous": {
    "lots[0].submissionDate": "2026-10-07T08:00:00.000Z"
  }
}

A lot deadline set for the first time has the value null in previous. Until then, the deadline of the tender applied to the lot.

tender.archived

{
  "type": "tender.archived",
  "timestamp": "2026-10-14T09:00:00.000Z",
  "data": {
    "tender": {
      "id": "e9da30eb-50e6-47f1-887f-434016267b2f",
      "lastModified": "2026-10-14T09:00:00.000Z",
      "checkedAt": "2026-10-14T09:00:00.000Z",
      "status": "archived",
      "archiveReason": "expired",
      "mergedInto": null
    }
  }
}

webhook.test

The test message carries the sample record in its current state. It is complete under data.tender, plus a sample saved search under data.search and a sample Fit under data.fit. A workflow builder learns the fields of tender.published and search.hit from it. changedFields and previous are missing in the test message because they only arise with a change. Here, data.tender is shortened.

{
  "type": "webhook.test",
  "timestamp": "2026-10-01T08:00:00.000Z",
  "data": {
    "test": true,
    "search": {
      "id": "00000000-0000-0000-0000-000000000000",
      "name": "Mustersuchauftrag"
    },
    "fit": 82,
    "tender": {
      "id": "e9da30eb-50e6-47f1-887f-434016267b2f",
      "lastModified": "2026-09-24T09:10:00.000Z",
      "checkedAt": "2026-10-01T07:00:00.000Z",
      "title": "Nordhausen - Sanierung Rolandbrunnen, Erneuerung Brunnentechnik",
      "url": "https://www.procuris.eu/notices/nordhausen-sanierung-rolandbrunnen-erneuerung-brunnentechnik-e9da30eb"
    }
  }
}

Request a quote

Tell us what you want to use or connect. Your quote is based on that scope.

Request a quote

On this page