I’ve been trying to create a batch transaction using the REST API and I can’t get the transactional part to work, i.e. if I POST 2 entities, the first one succeeds, and the 2nd does not, the 1st is still created.
I’ve tried it with both JSON and multipart requests and got the same result.
As a side note, I’ve also been trying to reference previously-created entities in later ones in a transaction, but one thing at a time.
JSON request:
curl --request POST \
--url 'https://api.businesscentral.dynamics.com/v2.0/xxx/sandbox/api/v2.0/$batch' \
--header 'Authorization: Bearer xxx' \
--header 'Content-Type: application/json' \
--header 'Isolation: snapshot' \
--data '{
"requests": [
{
"method": "POST",
"url": "vendors",
"headers": {
"Company": "TEST company",
"Content-Type": "application/json",
"Content-ID": "1",
"If-Match": "*"
},
"body": {
"number": "15",
"displayName": "Vendor 15"
}
},
{
"method": "POST",
"url": "purchaseOrders",
"headers": {
"Company": "TEST company",
"Content-Type": "application/json",
"Content-ID": "1",
"If-Match": "*"
},
"body": {
"vendorId": "$1"
}
}
]
}'
Multipart request:
curl --request POST \
--url 'https://api.businesscentral.dynamics.com/v2.0/xxx/sandbox/api/v2.0/$batch' \
--header 'Accept: application/json' \
--header 'Authorization: Bearer xxx \
--header 'Content-Type: multipart/mixed; boundary=batch_ABC123' \
--header 'Isolation: snapshot' \
--data '--batch_ABC123
Content-Type: application/http
Content-Transfer-Encoding: binary
Content-ID: 1
POST https://api.businesscentral.dynamics.com/v2.0/xxx/sandbox/api/v2.0/companies(yyy)/vendors HTTP/1.1
Content-Type: application/json;type=entry
{
"number": "27",
"displayName": "Vendor 27"
}
--batch_ABC123
Content-Type: application/http
Content-Transfer-Encoding: binary
Content-ID: 2
POST https://api.businesscentral.dynamics.com/v2.0/xxx/sandbox/api/v2.0/companies(yyy)/purchaseOrders HTTP/1.1
Content-Type: application/json;type=entry
{
"vendorId": "$1"
}
--batch_ABC123--'
Response:
{
"responses": [
{
"id": "1",
"status": 201,
"headers": {
"location": "https://api.businesscentral.dynamics.com/v2.0/xxx/sandbox/api/v2.0/companies(yyy)/vendors(asdf)",
"content-type": "application/json; odata.metadata=minimal; odata.streaming=true",
"odata-version": "4.0"
},
"body": {
"@odata.context": "https://api.businesscentral.dynamics.com/v2.0/xxx/sandbox/api/v2.0/$metadata#companies(yyy)/vendors/$entity",
"@odata.etag": "W/\"asdf=\"",
"id": "asdf",
"number": "27",
"displayName": "Vendor 27",
"addressLine1": "",
"addressLine2": "",
"city": "",
"state": "",
"country": "",
"postalCode": "",
"phoneNumber": "",
"email": "",
"website": "",
"taxRegistrationNumber": "",
"currencyId": "00000000-0000-0000-0000-000000000000",
"currencyCode": "USD",
"irs1099Code": "",
"paymentTermsId": "asdf",
"paymentMethodId": "asdf",
"taxLiable": true,
"blocked": "_x0020_",
"balance": 0,
"lastModifiedDateTime": "2024-07-25T15:18:56.157Z"
}
},
{
"id": "2",
"status": 400,
"headers": {
"content-type": "application/json",
"content-length": "163"
},
"body": {
"error": {
"code": "BadRequest",
"message": "Cannot convert the literal '$1' to the expected type 'Edm.Guid'. CorrelationId: fc3b4859-5a26-451c-ba81-4e6365a535bc."
}
}
}
]
}
If I try either of the 2 requests above again, I get a new error that the vendor with the given ID already exists, so the transacton is obviously not being rolled back when the second entity fails:
{
"responses": [
{
"id": "1",
"atomicityGroup": "3ef07230-5a80-4620-9834-a89c42477bf8",
"status": 400,
"headers": {
"content-type": "application/json",
"content-length": "205"
},
"body": {
"error": {
"code": "Internal_EntityWithSameKeyExists",
"message": "The record in table Vendor already exists. Identification fields and values: No.='27' CorrelationId: 5e756e24-4fb9-41a8-b3ee-16987f4a7dd3."
}
}
}
]
}