Skip to main content
POST
Upsert a buyer (create or return existing by VAT).

Authorizations

Authorization
string
header
required

OAuth 2.0 client_credentials grant via Keycloak service account. Clients are provisioned per IntegrationOrganization in the nt24-idp realm.

Headers

Idempotency-Key
string
required

Client-generated unique key (UUID recommended) for this write operation. Identical key + identical body within 24h returns the cached response. Identical key + different body returns 422.

Required string length: 1 - 255

Path Parameters

sellerId
string<uuid>
required

UUID of the seller trade partner (must be in caller's authorized list).

Body

application/json
kycMode
enum<string>
required

MARKETPLACE_LED (Mode A), partner provides KYC data; NT24 stores + runs VIES only. Not available yet: a buyer write naming it is refused with 403. NT24_LED (Mode B), NT24 runs full verification (iDenfy + AML) and generates a profile.

Available options:
MARKETPLACE_LED,
NT24_LED
vatNumber
string
required
Example:

"DE123456789"

companyName
string
required
address
object
required
contacts
object[]

Contact people to record on the buyer. Each entry resolves on its email address, compared trimmed and case-insensitively, exactly as POST /contacts does: a person already recorded matches and no second record is created, a new one is recorded, and a different person under a recorded email address resolves to the person on file. So a replayed create body leaves the contact list as it was, and an archived person is reactivated rather than recorded again (one with a platform account whom the company removed answers 409; they return only through the company's re-invite; a reactivated owner stays owner only when the buyer has none and you may name one).

Entries resolve in order, so a second entry under an address an earlier entry already used is matched against what that earlier one left. Where an entry disagrees with the person it resolved to, the response names its fields in notApplied as contacts[1].firstName — the index is the entry's position in the array you sent. Nothing is applied: a stored person is never overwritten here, and no second record is created under an address one person already holds. Two different people on one address is therefore reported rather than silently dropped, on the 201 as well as on the 200.

An entry's role is asked for as on POST /contacts, in order: the first entry asking for OWNER on a new buyer becomes its Admin, and a later one finds the seat taken and is reported as contacts[1].role.

Response

Existing buyer returned, unchanged. notApplied lists the fields of the body the record disagreed with, and is absent when there were none.

uuid
string<uuid>
required
companyNumber
string
required

The Novatrade24-issued partner number. Every partner has one, whatever its type, which is why this — and not vatNumber — is the identifier that resolves any buyer.

Pattern: ^NT-[A-Z0-9]{4}-[A-Z0-9]{4}$
Example:

"NT-4K7M-9XQ2"

type
enum<string>
required

Whether the party is a legal entity or a natural person. Shared by BuyerResponse and ProspectResponse, which describe the same two kinds of party at different points of the onboarding flow.

The webhook contract publishes these same two values as ProspectType in asyncapi-integration-v1.yaml. Two names, one set of values.

Available options:
COMPANY,
CONSUMER
companyName
string
required

The legal company name for a COMPANY buyer, the natural person's full name for a CONSUMER buyer.

address
object
required
kycMode
enum<string>
required

MARKETPLACE_LED (Mode A), partner provides KYC data; NT24 stores + runs VIES only. Not available yet: a buyer write naming it is refused with 403. NT24_LED (Mode B), NT24 runs full verification (iDenfy + AML) and generates a profile.

Available options:
MARKETPLACE_LED,
NT24_LED
status
enum<string>
required
Available options:
ACTIVE,
BLOCKED
version
integer
required

Optimistic-concurrency version.

createdAt
string<date-time>
required
updatedAt
string<date-time>
required
vatNumber
string

The buyer's VAT number, present only when the platform holds one. Its presence does not classify the buyer: no onboarding path gives a natural person a VAT number and a company may never have supplied one, but neither is a guarantee this API makes. Read type for the kind of party.

inactiveSince
string<date-time> | null

When the buyer closed its account on Novatrade24 and became inactive; null while it is active. An inactive buyer takes no new order, KYC request or invitation (409), and its existing orders are read-only.

notApplied
string[]

Fields of an upsert body that named something other than what this record says, and were therefore not written. Two groups, in one list:

  • the buyer's own fields — companyName, address.street, address.postCode, address.city, address.country;
  • a contacts entry that disagreed with the person already recorded under its email address — contacts[0].firstName, contacts[0].lastName, contacts[0].phone, where the index is the entry's position in the array you sent — or that asked for a role the person did not get, contacts[0].role.

Present on POST /buyers only, and only when there was something to report. Absent on every read and on a call that agreed with the record. Absent on a 201 for the buyer's own fields — a buyer this call just created cannot disagree with the body that created it — but a contacts entry can still be reported on a 201, because an array naming two different people on one email address contradicts itself whatever the buyer's age.

Change a buyer field with PATCH under If-Match. A contact person cannot be changed through this API at all; ask Novatrade24 support.

notApplied describes your request, not the resource, so it is not part of the buyer's ETag and two callers reading the same buyer still see the same tag.