Skip to main content

SAP S/4HANA — overview

This section explains which connector actions to use and how, so you (or an AI agent) can drive SAP S/4HANA correctly the first time. SAP exposes thousands of OData services with several interaction styles; the connector wraps all of them behind a consistent set of actions. Knowing which style a task needs is the whole game — start here, then jump to the worked example you need:

Where actions run

You call actions from the Smart Chat (natural language) or the Web Editor with run_connection_action(...). Both go through the same connector. Set up the connection in the Abstra Console first.

All identifiers in these pages (purchase orders, company codes, suppliers, bank keys…) are placeholders — replace them with your own values.


Connection modes

Decided by the base URL you configure:

  • Host mode — base URL is the SAP host (e.g. https://my-sap-host:44300). Every activated OData service is reachable, resolved on demand. Action names are prefixed with the service: odata/api_business_partner_list_a_business_partner.
  • Single-service mode — base URL points at one service (e.g. .../sap/opu/odata/sap/API_BUSINESS_PARTNER). Actions are not service-prefixed.

Authentication is Basic or OAuth2, configured on the connection.

sap-client

If your SAP system needs a specific client (mandante), set it on the connection. A wrong/absent client is a common cause of 401 even with correct credentials.


The action namespaces

Actions are grouped by interaction style. Pick the namespace that matches the task:

NamespaceUse it forStyle
odata/*Reading and simple stateless writes on any entity setStateless CRUD
softstate/*Transactional BOPF documents (e.g. supplier invoice)Soft-state session
draft/*Fiori Draft documents (e.g. bank statement, “Manage…” apps)Draft session
invoice/*Curated supplier-invoice-from-PO helper (MIRO)One-call helper
statement/*Curated bank-statement helperOne-call helper

Action naming

Action-name suffixes are snake_case, derived from the SAP $metadata names:

  • odata/api_..._list_a_business_partner, get_a_business_partner, create_*, update_*, delete_*
  • softstate/open_headers, update_headers, do_assignment, post, read
  • draft/open_c_arbankstatement, update_c_arbankstatement, add_c_arbankstatement_item, activate, discard, read

Discovering actions and their fields

The catalog can be large:

  1. List actions to find candidates by name.
  2. Get an action to see its exact field schema before calling it — per-entity fields are loaded on demand, so getAction is how you learn the parameters.
from abstra.connectors import list_connection_actions, get_connection_action

actions = list_connection_actions(connection_name="my_sap")
schema = get_connection_action(
connection_name="my_sap",
action_name="odata/api_business_partner_get_a_business_partner",
)
print(schema) # payloadSchema + returnSchema
For agents

Prefer the curated actions (invoice/*, statement/*) when they fit — they do the whole transaction in one call and avoid the pitfalls below. Drop to softstate/* / draft/* only for documents without a curated helper.


The transactional model (read before writing documents)

Creating real business documents (invoices, bank statements, …) is not a single POST. SAP drives these through a stateful session you open, fill incrementally, then effectivate. Two flavors:

  • Soft-state / BOPF (e.g. MM_SUPPLIER_INVOICE_MANAGE): keys like NodeKey + State; ended with a post action.
  • Fiori Draft (e.g. FAR_MANAGE_BS_SRV): keys like DraftUUID + IsActiveEntity; ended with an activate action.

Both follow the same shape:

open  →  set header fields  →  set / derive line items  →  post | activate
└──────────── you hold an opaque sessionId throughout ────────────┘
  • open_* returns a sessionId and the draft keys. Every subsequent action takes that sessionId. You never build guid'…' URLs and never touch CSRF tokens or cookies — the connector manages the session.
  • post / activate effectivate and end the session. discard rolls back.
The #1 gotcha: don't create/add what the draft already made

When you open a transactional document, SAP frequently auto-creates the first line-item row (empty). You fill it with update (a MERGE), not with create/add. A plain POST to a line-item entity set on these services raises a RAISE_SHORTDUMP. To add more lines, POST through the parent’s navigation (the connector’s add_* / curated helpers do this for you) — never the flat item entity set.


Quick decision guide

  • Read / list / get one recordodata/list_*, odata/get_*.
  • Create/update a simple, non-transactional entityodata/create_* / update_*.
  • Supplier invoice from a PO (MIRO)invoice/create_supplier_invoice_from_po (after invoice/lookup_purchase_order_for_invoice).
  • Bank statementstatement/create_bank_statement (pass lines).
  • Any other transactional documentsoftstate/* or draft/*: open → update → (derive) → post / activate, holding the sessionId; fill auto-created rows with update, add extra rows with add.
Golden rule

If a curated action exists for your document, use it. Otherwise open a session and MERGE fields after opening — never rely on a single create/POST to carry a whole transactional document.