created_items and failed_items and re-send only what failed; repeating the whole call duplicates the lines that already committed.
Authentication and enablement
Requires a workspace SAP integration.base_url and authorization are injected. Enable the tool and bind the integration.
Calling off a contract into multiple order lines
items_to_add accepts reference_sd_document and reference_sd_document_item, and the same contract item may be referenced by several lines in one call.
This is the tool’s main reason to exist for contract work. A single POST /A_SalesOrder deep create rejects a payload that references one contract item twice, with:
material and production_plant — SAP copies both from the referenced document, and sending material explicitly makes SAP reject the line with SLS_LORD/025 "field is not an input field".
Inputs
sales_order (required), plus at least one of items_to_update, items_to_add, items_to_delete.
items_to_add — full parity with create
Accepts exactly the fields sap_create_sales_order accepts for a line item: material,
material_by_customer, requested_quantity, requested_quantity_unit, production_plant,
reference_sd_document, reference_sd_document_item, incoterms_location1, pricing_date,
shipping_point, shipping_type, sales_order_item_category, item_billing_block_reason,
delivery_date_quantity_is_fixed, schedule_line, pricing_elements, texts.
requested_quantity is always required. material is required unless a reference is supplied. Do not set an item number — SAP assigns it.
Limit: 200 items per call. At roughly 2.5–5 s per item a larger batch would hold a worker step for many minutes and monopolise the document’s lock. Split the work across calls.
items_to_update — a narrower set
A PATCH cannot set every field. A_SalesOrderItem’s CDS view marks the quantity, weight, amount and status fields read-only, and SAP additionally decides editability per item, per document state — a line created by copy-with-reference accepts less than a manually entered one. Exposed fields:
sales_order_item (required), requested_quantity, requested_quantity_unit, production_plant, material_by_customer, incoterms_location1, delivery_date_quantity_is_fixed, pricing_elements.
material and the reference pair are not updatable here. Changing either is a delete-and-re-add, not an update. Anything SAP refuses appears in failed_items rather than being silently dropped.
pricing_elements is an upsert, keyed on condition_type: a condition the item already carries
is changed in place, one it does not carry is added. Supply condition_currency when adding — a
rate alone does not define a condition. SAP decides which condition types may be entered manually,
so a type its pricing procedure determines automatically is refused with SAP’s own reason.
items_to_delete — disabled by default
Deleting a line from a live order is destructive and cannot be undone through this API, so it is opt-in per configured tool. With allow_item_delete unset, a call containing items_to_delete is rejected in full before anything is sent to SAP — including a mixed payload, so adds cannot half-apply ahead of a refused delete.
Operator settings
Not agent-visible; set per configured tool.
On pacing: adding items to one order serialises on SAP’s lock for the order and — for copy-with-reference items — for the source contract too. Measured on a fresh order, 500 ms between calls produced zero lock errors across 100 items, while 100 ms lost 9 of 100 even with three retries each. Lower it only with evidence from the target system.
Output
sap_messages carries SAP’s own business messages from every request the call made — credit
blocks, incompleteness, SLS_LORD/025 field refusals — plus one error entry per operation the
tool could not apply and one leading success entry summarising what was applied. Repeats are
de-duplicated (SAP sends the document-level warnings on every item response) and the list is capped
at 50 with a trailing note when anything was dropped. This is what the feed card renders, exactly as
sap_create_sales_order does.
retryable: true marks a transient document lock that used up its retry budget — those items can be re-sent as-is. retryable: false is a real rejection and will fail again unchanged.
The call ends by reading the order back, which is where full_details, total_net_amount and
line_item_count come from. If that read fails, the call is reported as an error but still
returns created_items, failed_items and sap_messages — those items are already committed in
SAP, and the order-derived fields are left empty rather than guessed. Re-send only what is listed in
failed_items; re-sending the whole payload duplicates every line that succeeded.
Limits and side effects
- Writes to SAP. Adds, changes and deletes are immediate and not transactional across items.
- Re-running the same call after a partial failure duplicates the items that already succeeded.
- Concurrent call-offs from the same contract cannot be parallelised: SAP locks the source document during each copy, so two agents working the same contract will collide regardless of pacing.
- Lock retries use exponential backoff (1 s, 2 s, 4 s). Retrying at the pacing interval does not work — it lands inside the same lock window.
Expected errors
Notes
Customer-specific extension fields (ZZ1_* / YY1_*) are not supported. An earlier version
exposed one such field; it was removed because it exists on only one tenant and made the request
fail everywhere else.