Developer ToolsFree generatorPDF, Excel, Word exportSAP Business OneAll SAP Business One tools

SAP Business One Service Layer $batch Request Generator

This generator writes the raw HTTP for an SAP Business One Service Layer session: Login, a $batch request whose changeset deletes, updates or creates several records in one transaction, and Logout. Use it to test in Postman or a REST client before you code the same request in your integration.

Fill in

Generated code
Download:

1. Login

POST https://b1server:50000/b1s/v1/Login
Content-Type: application/json

{"CompanyDB": "SBODEMOUS", "UserName": "manager", "Password": "<password>"}

# Response returns SessionId and SessionTimeout and sets cookies:
#   B1SESSION=<SessionId>; ROUTEID=<node>
# Send both cookies on every following request.

2a. $batch: delete two records in one changeset

POST https://b1server:50000/b1s/v1/$batch
Cookie: B1SESSION=<SessionId>; ROUTEID=<node>
Content-Type: multipart/mixed;boundary=batch_1

--batch_1
Content-Type: multipart/mixed;boundary=changeset_1

--changeset_1
Content-Type: application/http
Content-Transfer-Encoding: binary
Content-ID: 1

DELETE /b1s/v1/Items('A0001') HTTP/1.1

--changeset_1
Content-Type: application/http
Content-Transfer-Encoding: binary
Content-ID: 2

DELETE /b1s/v1/Items('A0002') HTTP/1.1

--changeset_1--
--batch_1--

2b. $batch: PATCH two records in one changeset

POST https://b1server:50000/b1s/v1/$batch
Cookie: B1SESSION=<SessionId>; ROUTEID=<node>
Content-Type: multipart/mixed;boundary=batch_1

--batch_1
Content-Type: multipart/mixed;boundary=changeset_1

--changeset_1
Content-Type: application/http
Content-Transfer-Encoding: binary
Content-ID: 1

PATCH /b1s/v1/Items('A0001') HTTP/1.1
Content-Type: application/json

{"Frozen": "tYES"}

--changeset_1
Content-Type: application/http
Content-Transfer-Encoding: binary
Content-ID: 2

PATCH /b1s/v1/Items('A0002') HTTP/1.1
Content-Type: application/json

{"Frozen": "tYES"}

--changeset_1--
--batch_1--

2c. $batch: a GET outside and a POST inside a changeset

POST https://b1server:50000/b1s/v1/$batch
Cookie: B1SESSION=<SessionId>; ROUTEID=<node>
Content-Type: multipart/mixed;boundary=batch_1

--batch_1
Content-Type: application/http
Content-Transfer-Encoding: binary

GET /b1s/v1/Items('A0001') HTTP/1.1

--batch_1
Content-Type: multipart/mixed;boundary=changeset_1

--changeset_1
Content-Type: application/http
Content-Transfer-Encoding: binary
Content-ID: 1

POST /b1s/v1/Items HTTP/1.1
Content-Type: application/json

{"ItemCode": "A0003", "ItemName": "New item"}

--changeset_1--
--batch_1--

3. Logout

POST https://b1server:50000/b1s/v1/Logout
Cookie: B1SESSION=<SessionId>; ROUTEID=<node>

Lines in a multipart body must end with CRLF and the blank lines shown are required; most HTTP clients convert line endings for you, plain curl with a file does not. The POST body in 2c is written for Items; replace it with valid fields for other entity sets. Check the batch section of the Service Layer user manual for your version (10.0 FP) before using v2, where some entity names and behaviours differ.

Get your Service Layer integration reviewed

Send us your batch requests and error responses and we will help you fix transaction handling and session use.

Optional. The tool and every export work without this. No spam.

Was this tool useful?

How to use it

Enter the Service Layer host and port (50000 is the usual HTTPS port), the version path, the company database, the user, the entity set, two keys and the PATCH body. Send block 1 first and copy the B1SESSION and ROUTEID cookies from the response. Then send block 2a, 2b or 2c with those cookies, and finish with block 3. String keys need single quotes inside the parentheses, numeric keys such as DocEntry for Orders do not. Add more parts by repeating a --changeset_1 section with the next Content-ID.

  • The boundary in the Content-Type header must match the --batch_1 lines exactly.
  • Each part needs Content-Type: application/http and Content-Transfer-Encoding: binary.
  • Close the changeset with --changeset_1-- before closing the batch with --batch_1--.

How $batch and changesets behave

Service Layer follows the OData batch format. A $batch request contains parts; GET requests go directly in the batch, and write requests go inside a changeset. All requests inside one changeset run as one database transaction: if one fails, Service Layer rolls back the whole changeset and returns the error for the failing part, which is what you want for a set of records that must change together. Separate changesets in the same batch are independent. The response is itself multipart, with one HTTP status per part, so your code must parse it rather than only checking the outer 200 or 202 status.

Batch delete in practice

Deleting master data through Service Layer is subject to the same rules as in the client: an item or business partner that has transactions cannot be removed, and the delete returns an error naming the dependency. Inside a changeset that error rolls back every other delete in it, so for clean-up jobs put records you expect to fail in separate changesets, or check usage first. For records that are in use, the supported path is to deactivate them instead, for example a PATCH setting Frozen to tYES on Items or BusinessPartners, which is why that is the default PATCH body here.

Sessions and limits

The Login response contains a SessionId and a SessionTimeout, 30 minutes by default; each request extends the session. ROUTEID matters when Service Layer runs behind its load balancer with several nodes, because it pins your session to one node. Always log out from integrations, since every open session holds a license and memory until it times out. Keep batches to a reasonable size: very large changesets hold locks for the whole transaction and are harder to diagnose when one part fails.

Frequently Asked Questions

How do I log in to SAP Business One Service Layer?

POST to https://<host>:50000/b1s/v1/Login with JSON containing CompanyDB, UserName and Password. The response returns a SessionId and sets B1SESSION and ROUTEID cookies, which you send on every later call. POST to /Logout when finished.

How do I batch delete records with Service Layer?

POST to /b1s/v1/$batch with Content-Type multipart/mixed and a boundary, put one DELETE request per record inside a changeset, and close the changeset and batch boundaries. All deletes in the changeset succeed or fail together.

What is the difference between Service Layer v1 and v2?

v1 follows OData version 3 conventions and v2 follows OData version 4, with differences in some entity names, metadata and response formats. Both live on the same server under /b1s/v1 and /b1s/v2. Pick one per integration and check the manual for your feature pack.

Why does my $batch return 400 Bad Request?

The usual causes are a boundary mismatch between the header and the body, missing blank lines between part headers and the request line, LF instead of CRLF line endings, or a GET placed inside a changeset. Compare your body line by line with the generated one.

If you want an assistant that reads and, with approval, updates Business One through Service Layer on your own server, we can build that with these same calls.

ArchRay builder
Design the on-prem AI stack for SAP Business One: model, GPUs, RAG pipeline, guardrails
See memory, speed and cost as you swap parts, then export the diagram. Free, in your browser.
Open the builder

Keep exploring

Free tools

ERP fixes and how-tos

Runs with your ERP

AI on your ERP

Integrations

Comparisons

Software