The API
| Host | https://business-partner-api.retailsvc.com |
| Base path | /api/v1 |
| Writes answer | 202 Accepted, with an empty body |
The authoritative technical reference is the OpenAPI specification. This page covers what the specification cannot tell you.
| Endpoint | Does | Permission |
|---|---|---|
PUT /business-partners/{businessPartnerId} | creates or replaces a partner | bpa.business-partner.write |
DELETE /business-partners/{businessPartnerId} | marks a partner Deleted | bpa.business-partner.write |
GET /business-partners/{businessPartnerId} | reads one partner | bpa.business-partner.read |
GET /business-partners | lists partners, filtered and paged | bpa.business-partner.read |
PUT /warehouse-supply-terms/{businessUnitId} | sets a warehouse's supply terms | bpa.business-partner.write, for that business unit |
DELETE /warehouse-supply-terms/{businessUnitId} | deletes a warehouse's supply terms | bpa.business-partner.write, for that business unit |
GET /warehouse-supply-terms/{businessUnitId} | reads a warehouse's supply terms | bpa.business-partner.read, for that business unit |
The tenant always comes from the caller's token. Every read and write is confined to that tenant, so the same partner id under two tenants is two separate partners.
Permissions
| Role | Permissions | Typical holder |
|---|---|---|
| Business Partner Admin | bpa.business-partner.read, bpa.business-partner.write | your ERP integration |
| Business Partner Reader | bpa.business-partner.read | a system that only looks partners up |
Partners belong to the whole tenant, so the partner endpoints need the permission only. Warehouse supply
terms belong to one business unit, so for those endpoints the permission must also cover the business unit
in the URL. A caller without the permission gets 403 Forbidden.
Sending a partner
PUT creates the partner or replaces it entirely. Send the whole partner every time, as your ERP
holds it now.
PUT /api/v1/business-partners/V-20417
Content-Type: application/json
Correlation-Id: erp-sync-2026-10-20-0001
{
"displayId": "20417",
"status": "Active",
"name": "Fjord Garden",
"description": "Garden tools and outdoor furniture",
"legalName": "Fjord Garden AB",
"vatNumber": "SE556677889901",
"gln": "7350001234564",
"roles": [
{ "role": "SUPPLIER", "isActive": true, "defaultLeadTimeHours": 168, "reliabilityScore": 0.95 },
{ "role": "MANUFACTURER", "isActive": true }
],
"addresses": [
{
"addressType": "Delivery",
"careOf": null,
"street": "Lagervägen 4",
"zipCode": "504 62",
"city": "Borås",
"county": "Västra Götaland",
"country": "Sweden",
"countryCode": "SE",
"phone": "+46 33 123 45 00",
"mobile": null,
"email": "returns@fjordgarden.example",
"contactPerson": "Returns desk"
}
],
"additionalProperties": [
{ "id": "paymentTerms", "name": "Payment terms", "code": "PT30", "description": null,
"dataType": "STRING", "value": "30 days net" }
]
}
The answer is 202 Accepted. The event this produces is shown under
The partner event.
🛑 Leaving something out removes it
A role, an address or an additional property that is not in the body is deleted from the stored partner. There is no partial update. To change one address, send the partner with all its addresses, one of them changed.
What the body must hold
| Field | Required | Rule |
|---|---|---|
name | ✅ | text |
status | ✅ | Active, Passive, Expired, Discontinued, Replaced or Deleted. See Status |
roles | ✅ | at least one; each of SUPPLIER and MANUFACTURER at most once; each with role and isActive |
roles[].defaultLeadTimeHours | SUPPLIER only. A whole number of calendar hours, 0 to 8760, or null | |
roles[].reliabilityScore | SUPPLIER only. 0.0 to 1.0 with at most 9 decimals, or null | |
addresses | ✅ | may be empty; at most one of each addressType; each with zipCode and city; countryCode an ISO 3166-1 alpha-2 code |
additionalProperties | ✅ | may be empty; each with id, name, dataType and value |
gln | 13 digits with a valid GS1 check digit, or null | |
displayId, description, legalName, vatNumber | text, or null |
The id in the URL is 1 to 64 characters, with no spaces and none of /, ?, # or %.
A request that breaks any rule gets 400 Bad Request naming the problem, and nothing is queued. So does
a request with a field that is not listed above, at any level, and a MANUFACTURER role that carries
defaultLeadTimeHours or reliabilityScore, even as null.
Writes are asynchronous
The API checks the request, queues it and answers 202 Accepted straight away. Business Partner then
stores the change and publishes its event, normally within moments.
What that means for your integration:
- A
202is a promise, not a confirmation. The request was valid. The change is not yet readable. - A
GETstraight after aPUTmay return the previous state, or404for a partner that did not exist before. To confirm a write, wait for its event or read again a little later. - Of two
PUTs for the same partner, the one the API accepted last wins, even if the two are stored in the other order. An older change that arrives after a newer one is discarded.
Retrying
A PUT is safe to retry. It replaces the whole partner, so sending the same body twice leaves the same
partner. If a call times out or answers 5xx, send it again. Each accepted PUT publishes an event, even
when nothing changed, so a retry can produce a second event with the same content.
Deleting a partner
DELETE marks the partner Deleted. It is a soft delete: the record, its roles and its addresses are
kept, and an event is published with status: "Deleted".
After a DELETE | |
|---|---|
GET /business-partners/{id} | still 200, with status: "Deleted" |
GET /business-partners | leaves the partner out, unless you ask for status=Deleted |
a later PUT for the same id | restores the partner, with whatever that PUT sends |
DELETE answers 404 Not Found when no partner with that id is stored for your tenant.
⚠ A DELETE sent straight after the PUT that created the partner can answer 404. The DELETE
checks the stored partners, and the PUT may not be stored yet. If you create and remove a partner in quick
succession, for example in a test, wait for the creation's event or retry the DELETE after a moment.
Reading partners
One partner
GET /business-partners/{businessPartnerId} returns the partner as it is stored, in the same shape as the
PUT body plus businessPartnerId and modifiedDatetime, the time the stored state was last written.
It returns 404 Not Found when there is no such partner for your tenant, and a Deleted partner with
200.
A list
GET /business-partners returns { "items": [...], "nextCursor": "..." }, sorted by
businessPartnerId. Each item has the same shape as a single partner.
| Parameter | Meaning |
|---|---|
role | only partners holding this role: SUPPLIER or MANUFACTURER, active or not |
isActive | with role: only partners whose role has this active flag. Without role it answers 400, because the flag belongs to a role |
status | only partners with this status. Without it, every partner except Deleted ones is returned; pass status=Deleted to list those |
gln | only partners with this GLN, 13 digits |
pageSize | 1 to 200; 50 when left out |
cursor | the nextCursor of the previous page |
Filters combine: role=SUPPLIER&isActive=true&gln=7350001234564 returns active suppliers with that GLN.
When there are more partners, the response carries nextCursor; pass it as cursor to get the next page.
The last page has no nextCursor. Treat the cursor as an opaque string.
Warehouse supply terms
PUT /warehouse-supply-terms/{businessUnitId} with { "defaultLeadTimeHours": 48 } sets the lead time
of one of your own warehouses, and GET returns { "businessUnitId": "DC-JKP", "defaultLeadTimeHours": 48 }.
The rules, and the check against Business Unit Management, are on
Partners and your own warehouses.
They behave like partners in the ways that matter: the write is asynchronous, the body replaces what is
stored, a field that is not declared is refused with 400, and the request accepted last wins.
They differ in one way: DELETE answers 202 whether or not any terms were stored for that business
unit, and publishes a deleted event either way. After it, GET answers 404 until the next PUT.
Responses
| Status | Means | What to do |
|---|---|---|
200 OK | the read succeeded | |
202 Accepted | the write is valid and queued | wait for the event if you need confirmation |
400 Bad Request | the request breaks a rule; the message names it. For warehouse supply terms, also: the business unit is not a WAREHOUSE | fix the request; resending it unchanged fails again |
403 Forbidden | the token lacks the permission, or for warehouse supply terms does not cover the business unit | grant the role |
404 Not Found | no such partner, or no such business unit, or no stored supply terms | see Deleting a partner for the one case that resolves itself |
502 Bad Gateway | warehouse supply terms only: Business Unit Management could not be asked | send the request again |
5xx | the request could not be queued | send the request again. Retrying is safe |