Integrate Paige with the SAP Business One Service Layer
For developers: the Service Layer calls that turn a Paige invoice into an SAP Business One A/P invoice with the PDF attached — log in, upload the PDF to Attachments2, then POST the PurchaseInvoices document with the attachment entry — fed from Paige's SFTP export files or the Paige API.
Before you begin
- SAP Business One with the Service Layer running, a user for the integration, and the attachments folder configured for the Service Layer
- Somewhere to run code on a schedule
- Either an SFTP server Paige exports to, or a Paige API key
At the end of this guide you'll have the exact Service Layer calls — and the two ways to get Paige's data into them — to create an A/P invoice with the invoice PDF attached for every invoice Paige finishes.
Getting Paige's data
| Source | How | When to prefer it |
|---|---|---|
| SFTP export files | Paige writes <name>.pdf and <name>.json per document; your job polls the folder and reads the JSON (fields, metadata.document_type, metadata.pdf_file) | Simplest; the PDF is already assembled |
| Paige API | GET …/scanJobs/{id}/documentPages, then …/pages/{pageId}/fieldValues; page images by signed URL | You'd rather query than watch a folder. The API returns page images, not one merged PDF — see Integrate your own system with the Paige API. |
The rest assumes you have, per invoice, the field values and the PDF bytes.
Prerequisite: the attachments folder
The Service Layer can only store attachments in the folder configured under Administration > System Initialization > General Settings > Path > Attachments Folder, and the Service Layer process must be able to write there. On a Linux-hosted Service Layer that means the Windows share is mounted; your SAP partner usually sets this up once. Without it, attachment uploads fail.
Log in
POST https://<server>:50000/b1s/v2/Login
Content-Type: application/json
{ "CompanyDB": "<database>", "UserName": "paige-integration", "Password": "…" }Keep the B1SESSION cookie for the calls below; sessions expire after the configured timeout, so re-login on a 401.
The calls
1. Upload the PDF as an attachment
POST https://<server>:50000/b1s/v2/Attachments2
Content-Type: multipart/form-data; boundary=…
--…
Content-Disposition: form-data; name="files"; filename="INV-20441.pdf"
Content-Type: application/pdf
<raw PDF bytes>
--…--What you should see: 201 Created with an AbsoluteEntry — the attachment entry number you'll reference on the invoice.
2. Create the A/P invoice referencing it
POST https://<server>:50000/b1s/v2/PurchaseInvoices
Content-Type: application/json
{
"CardCode": "V00123",
"DocDate": "2026-08-28",
"DocDueDate": "2026-09-27",
"NumAtCard": "INV-20441",
"DocType": "dDocument_Service",
"Comments": "Paige – Vendor Invoice",
"AttachmentEntry": 57,
"DocumentLines": [
{
"AccountCode": "6150",
"LineTotal": 1284.50,
"ItemDescription": "Invoice INV-20441"
}
]
}CardCode is the vendor's business partner code; look it up first with GET …/BusinessPartners?$filter=CardName eq 'Acme Office Supply' if Paige only gives the name. DocType dDocument_Service posts to G/L accounts (AccountCode + LineTotal); for item-based invoices use dDocument_Items with ItemCode, Quantity, and UnitPrice per line, one per row of Paige's line_items table.
What you should see: 201 Created with the new document's DocEntry and DocNum, and the PDF on the invoice's Attachments tab in the SAP client.
Idempotency and errors
- Before creating,
GET …/PurchaseInvoices?$filter=CardCode eq 'V00123' and NumAtCard eq 'INV-20441'and skip if one exists. - Paige's values are strings as printed; format dates as
YYYY-MM-DDand amounts as numbers. - Tax and account errors come back as
400with SAP's message in the body — usually a G/L account not allowed for the vendor's tax group, or a closed posting period. - If you poll SFTP, move processed files to a
processed/subfolder; if you poll the Paige API, record processed page IDs. POST …/Logoutwhen the job finishes.
