procuris

Data model

The fields of a record with their type, what missing and estimated values look like and which key identifies a tender permanently.

On request

You receive this service through an individual quote.

One record per tender is the goal, not a guarantee. If a notice appears on several portals, procuris merges it into one record. If procuris detects a duplicate only later, it archives the newer record with archiveReason set to merged and gives in mergedInto the id of the record that remains.

Corrections change the existing record instead of creating a new one. Corrections and change notices keep the id and get a new lastModified. procuris does not delete records, it archives them. Expired, cancelled, awarded or merged tenders get the status archived.

The list, the single request and webhooks deliver the same complete records. The keys are written in camelCase (each word after the first starts with a capital letter, for example lastModified).

Complete example

The example shows the sample record used throughout these docs, as of 1 October 2026. The contracting authority published the notice on 17 September without a contract value. Until 22 September the record therefore held an estimate. On 22 September the contracting authority stated the contract value of 351,000 euros, and on 24 September it moved the submission deadline.

{
  "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-14T08:00:00.000Z",
  "participationDeadline": null,
  "lastModified": "2026-09-24T09:10:00.000Z",
  "checkedAt": "2026-10-01T06:00:00.000Z",
  "contractAmount": {
    "value": 351000,
    "currency": "EUR",
    "estimated": false
  },
  "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"
    }
  ]
}

Title, tender number, dates and CPV codes come from a real notice. Contact, lots, region and source were added for illustration. The contact details are placeholders.

Basic rules

  • Missing values appear as null, not as a missing key. "or null" in the tables means: the key is in the record, without a value. For details from the notice, the contracting authority has usually not published the value. For archiveReason, mergedInto, contractAmount and the fields of the lots, the table says what null means there. An empty list [] means the same for lists.
  • Timestamps are in UTC according to ISO 8601, for example 2026-10-14T08:00:00.000Z.
  • lastModified is the time of the last change in content at procuris. It is not the time at the contracting authority. The value only increases.
  • checkedAt is the data state, meaning when procuris last checked the record. A new checkedAt on its own is not a change in content. It does not change lastModified and does not trigger an event.
  • Skip unknown fields and values. New fields and values can be added, for example a new value for archiveReason. Have your system skip both instead of aborting, because an abort stops the sync until the next adjustment.

Fields of the tender

FieldTypeMeaning
idstring (UUID)fixed key of the tender, stays the same through corrections. Use it for changes and, together with mergedInto, against duplicates.
statusopen or archivedopen: running. archived: ended, see archiveReason.
archiveReasonstring or nullexpired (deadline passed), cancelled (procedure cancelled), awarded (contract awarded), merged (merged with another record). For open the value is null.
mergedIntostring (UUID) or nullfor merged, the id of the record that remains. Otherwise null.
titlestringtitle of the notice
descriptionstring or nulldescription of the work
tenderNumberstring or nulltender number of the contracting authority
urlstringpublic page of the notice at procuris
publicationDatetimestampfirst publication
submissionDatetimestamp or nullsubmission deadline
participationDeadlinetimestamp or nullparticipation deadline in two-stage procedures
lastModifiedtimestamplast change in content at procuris, see above
checkedAttimestampdata state, see above
contractAmountobject or nullcontract value, see below
procedureTypestring or nullprocedure type according to the eForms code list procurement-procedure-type, for example open (open procedure) or restricted (restricted procedure)
contractNaturestring or nullworks (construction work), supplies (deliveries), services (services)
legislationstring or nulllegal basis, where published
organizationslistorganizations involved, see below
cpvClassificationslistCPV codes with cpvCode (string, eight digits) and title (string). CPV is the European vocabulary of types of work. Can be empty.
regionCodeslist of stringsregions according to NUTS, the European division into areas, for example DEG for Thuringia. Can be empty.
realizedLocationstring or nullplace of performance as free text
lotslistlots, see below. Empty if the tender is not divided into lots.
sourceslistoriginal sources, see below. At least one entry.

eForms is the EU format for notices. The code lists are published by the Publications Office of the EU.

Contract value

FieldTypeMeaning
valuenumberamount excluding VAT, for example 351000
currencystringcurrency according to ISO 4217, mostly EUR. procuris does not convert other currencies into euros.
estimatedbooleantrue: estimated, because the contracting authority has not published a value. false: published value.

Only the contract value can be estimated. This applies to the tender and to the lots. If there is neither a published nor an estimated value, contractAmount is null.

Organizations

FieldTypeMeaning
idstring (UUID)fixed key of the organization. If procuris recognizes the same city administration in several tenders, it carries the same id there. Two different id values do not rule out that it is the same body.
namestringname
rolestringcontractingParty (contracting authority), procurementOffice (procurement office, if it is not the contracting authority itself), reviewBody (review body, responsible for review procedures)
contactNamestring or nullcontact person or office
emailstring or nullemail address
phonestring or nullphone number
addressobject or nulladdress, see below

address has these fields:

FieldTypeMeaning
streetstring or nullstreet and house number
postalCodestring or nullpostal code
citystring or nullcity
countryCodestring or nullcountry as a two-letter code according to ISO 3166-1 alpha-2, for example DE

Lots

Lots are parts of a tender that you can bid on separately.

FieldTypeMeaning
lotNumberstringlot number as the contracting authority assigns it, for example 1 or LOT-0002
titlestringtitle of the lot
descriptionstring or nulldescription
contractAmountobject or nullvalue of the lot, same structure as above
submissionDatetimestamp or nullthe lot's own deadline. null: the deadline of the tender applies.
cpvClassificationslistCPV codes of the lot. Empty: the codes of the tender apply.

Sources

If a tender appears on several portals, it has several entries in sources.

FieldTypeMeaning
namestringname of the portal, for example TED
urlstring or nulladdress of the notice on the portal
publishedAttimestamp or nullpublication on this portal

How to process the fields

  • Create records by id and update them by the same id. This gives one entry per id in your system. Duplicates that procuris detects only later are resolved through merged (the point after next).
  • Overwrite a record only if the new lastModified is greater than the stored one. Otherwise a late webhook message overwrites a newer state.
  • If a record arrives with archiveReason set to merged, merge it in your system with the record from mergedInto. If the remaining record is missing in your system, fetch it with API access via GET /v1/tenders/{mergedInto}. Without API access, if your system only receives webhooks (variant B under CRM and ERP), close the old entry and note mergedInto on it. The remaining tender only enters your system when an event for it arrives. In variant B that happens when it is a hit of a selected saved search, or when it gets a change event as an earlier hit.
  • For estimated: true, show the contract value as an estimate, so that nobody calculates with the amount as if it had been published.

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