# SAP Business One connector

Source: /docs/connectors/sap-business-one.md

Use this as an implementation starting point: adapt the worked example to the requested dataset and the source documentation. See [Custom API](/docs/connectors/custom-api) for the shared SDK pattern and document-upload workflow.

## What this connector is for [#what-this-connector-is-for]

ERP for small and midsize companies, with inventory, purchasing, sales, and accounting.

Use this guide to choose the resources and row meanings for a Vortexify source integration. Connection ownership belongs to a connector; each dataset gets its own sync, configuration, and extraction behavior.

## Data and tables you can pull [#data-and-tables-you-can-pull]

The following table families are a starting point for source selection. They describe possible datasets to implement using the [vendor reference](https://help.sap.com/docs/PRODUCT_ID/686100cb1bc34346b2bc6642685bab43/b1bbebd32ff940c786c76315a8dfa270.html?locale=en-US), not a guarantee that the example implements every table. Actual availability depends on the product edition, deployment, account permissions, and API/schema version.

| Suggested table | One row represents |
| --- | --- |
| `business_partners` | a business partner |
| `items` | a item |
| `sales_orders` | a sales order |
| `purchase_orders` | a purchase order |
| `invoices` | a invoice |

### Relationships and extraction considerations [#relationships-and-extraction-considerations]

These are proposed dataset names, not a universal schema guaranteed by the vendor. Preserve source object IDs and relationship references, and split nested child collections into separate tables when appropriate. Choose the concrete endpoint/report and row meaning from the vendor reference before implementing a sync.

## Connecting to SAP Business One [#connecting-to-sap-business-one]

Use the deployed Service Layer version and company database. Establish its authenticated session before resource reads and respect session expiry. S/4HANA communication arrangements are not interchangeable with Business One setup.

For HTTP reads, configure the connector client with the concrete API origin and source-authorized headers or authentication object. Actual credentials belong in platform secret configuration, not in this document or committed source.

### requirements.in [#requirementsin]

Declare these packages in the resource's `requirements.in`. Use the published `vortexify` package for the SDK and the source-specific driver/client shown below. Choose compatible dependency versions for your runtime; the [connector and sync reference](/docs/reference/python/connectors-and-syncs) explains where each file belongs.

```text
vortexify==0.1.1
pandas>=2,<3
httpx
```

This HTTP starting point needs no native database driver. Add the source-specific SDK, signer, or XML parser if the selected interface requires it.

## Worked example: business partners [#worked-example-business-partners]

This read function demonstrates the request and row mapping for one resource. Pass the owning connector's configured `httpx.Client` and dataset settings as `config`. Use the API origin as the client base URL; the function supplies the resource path. Token acquisition, renewal, signing, or session login belongs in the connector. This example reads one response; extend its continuation rule for a full dataset.

### Source read [#source-read]

```python
import pandas as pd


def read_page(client, config):
    response = client.get("/b1s/v2/BusinessPartners", params={"$top": 100})
    response.raise_for_status()
    payload = response.json()
    if isinstance(payload, dict):
        if (
            payload.get("errors")
            or payload.get("success") is False
            or payload.get("ok") is False
            or payload.get("result_ok") is False
        ):
            raise ValueError("Source returned an application error")
    rows = payload["value"]
    if not isinstance(rows, list) or any(not isinstance(row, dict) for row in rows):
        raise ValueError("Expected the documented record array")
    return pd.json_normalize(rows)
```

### What to adapt [#what-to-adapt]

Authenticate the client with the Service Layer Login operation and company database first. Preserve the session cookies and log out when closing the connector. Follow @odata.nextLink for subsequent OData v4 pages.

Use the [custom API SDK starting point](/docs/connectors/custom-api#worked-example-cursor-paginated-json-records) to connect the read operation to `Connector` and `Sync`. For a source with its own driver, retain that client in `Connector.client()` and replace the HTTP request with the driver read. An `extract(*, avg_row_size_bytes=None)` implementation yields bounded DataFrames. An independent `preview()` uses a fresh connector and a small read; it must not call extraction or advance real state.

Choose explicit output columns and stable IDs for the requested table. The examples use `json_normalize` where useful to illustrate row shaping; nested arrays still need deliberate child tables and a stable declared output schema. A first-page sample is useful for development, while a full sync must follow all relevant continuation/parent-resource paths. Design incremental watermarks, update/deletion behavior, and rate-limit handling for the actual source before enabling incremental mode.

The purpose is to give a coding agent a concrete pattern to adapt, including for similar sources. These snippets are examples rather than a claim of complete vendor coverage. Check the [source operation reference](https://help.sap.com/doc/056f69366b5345a386bb8149f1700c19/10.0/en-US/Service%20Layer%20API%20Reference.html) and representative responses before running with a customer's account; live vendor execution has not been verified here.

## Sources and further reading [#sources-and-further-reading]

- [Vendor connection and resource reference](https://help.sap.com/doc/056f69366b5345a386bb8149f1700c19/10.0/en-US/Service%20Layer%20API%20Reference.html) — The interface/access prerequisites underlying this connection path; follow the selected resource's documentation for fields, queries, and pagination.
- [Vortexify connectors and syncs](/docs/reference/python/connectors-and-syncs) — Connector ownership, schemas, preview isolation, extraction, and checkpoint contracts.
- [Vortexify CLI workflow](/docs/reference/cli/overview) — Registering resources, committing source, and providing credential configuration.
