Integrations / SAP S/4HANA Cloud (Public Edition)
SAP S/4HANA Cloud (Public Edition)
SAP S/4HANA Cloud Public Edition over its released OData APIs with a communication user: business partners, customers, suppliers, sales orders, purchase orders, products, billing documents, material documents, deliveries, supplier invoices and ledger line items, plus guarded OData reads and a few approved writes. Each API needs its communication scenario in a communication arrangement (business partner SAP_COM_0008, sales order SAP_COM_0109, product SAP_COM_0009, purchase order SAP_COM_0053, billing SAP_COM_0120, material document SAP_COM_0108, delivery SAP_COM_0106, supplier invoice SAP_COM_0057). Not verified against a live SAP system.
Connect
const conn = await setu.connections.initiate({ userId: "user_1", toolkit: "sap_s4hana_cloud" });
console.log(conn.connectUrl); // show this to your user
await conn.waitUntilActive();Permissions requested
This toolkit uses a single credential and requests no scopes.
Actions
Cancel billing documentdestructivesap_s4hana_cloud.cancel_billing_documentCancel a billing document (function import Cancel, POST, parameter BillingDocument). SAP creates a cancellation document that reverses the invoice, with accounting consequences for the customer. Destructive: needs explicit confirmation. Setu fetches the CSRF token for you. Function name and parameter are confirmed in SAP's generated client for this service. Needs the communication scenario SAP_COM_0120 in a communication arrangement (Public Edition: Fiori app Communication Arrangements) or the service API_BILLING_DOCUMENT_SRV activated in /IWFND/MAINT_SERVICE (on-premise).
| Input | Type | Description | |
|---|---|---|---|
billing_document | string | Required | BillingDocument number to cancel, e.g. 90000001 |
await setu.execute({
userId: "user_1",
action: "sap_s4hana_cloud.cancel_billing_document",
input: {
"billing_document": "<billing_document>"
},
confirm: true,
});Cancel material documentdestructivesap_s4hana_cloud.cancel_material_documentCancel (reverse) a whole material document, i.e. a goods movement (function import Cancel, POST, parameters MaterialDocumentYear, MaterialDocument, PostingDate). SAP posts a reversal movement that changes stock and valuation. Destructive: needs explicit confirmation. posting_date is an OData literal, e.g. datetime'2026-10-01T00:00:00'. Setu fetches the CSRF token for you. Function name and parameters are confirmed in SAP's generated client for this service. Needs the communication scenario SAP_COM_0108 in a communication arrangement (Public Edition: Fiori app Communication Arrangements) or the service API_MATERIAL_DOCUMENT_SRV activated in /IWFND/MAINT_SERVICE (on-premise).
| Input | Type | Description | |
|---|---|---|---|
material_document_year | string | Required | MaterialDocumentYear, e.g. 2026 |
material_document | string | Required | MaterialDocument number, e.g. 4900000001 |
posting_date | string | Optional | PostingDate of the reversal as an OData literal, e.g. datetime'2026-10-01T00:00:00'; optional |
await setu.execute({
userId: "user_1",
action: "sap_s4hana_cloud.cancel_material_document",
input: {
"material_document_year": "<material_document_year>",
"material_document": "<material_document>"
},
confirm: true,
});Create business partnerwritesap_s4hana_cloud.create_business_partnerCreate a business partner (POST A_BusinessPartner). BusinessPartnerCategory is 1 (person: FirstName and LastName) or 2 (organization: OrganizationBPName1). BusinessPartnerGrouping selects the number range (system specific; ask the user). Optional addresses is the OData v2 collection wrapper {"results":[{"Country":"US","CityName":"New York","PostalCode":"10001","StreetName":"Main Street","HouseNumber":"1"}]} for a deep insert (the address fields are from SAP's metadata; the wrapper is the OData v2 standard form). Setu fetches the CSRF token for you. Creates real master data: ask first. Needs the communication scenario SAP_COM_0008 in a communication arrangement (Public Edition: Fiori app Communication Arrangements) or the service API_BUSINESS_PARTNER activated in /IWFND/MAINT_SERVICE (on-premise).
| Input | Type | Description | |
|---|---|---|---|
category | string | Required | BusinessPartnerCategory: 1 person, 2 organization |
grouping | string | Optional | BusinessPartnerGrouping (number range key, e.g. BP02); system specific |
first_name | string | Optional | FirstName (category 1) |
last_name | string | Optional | LastName (category 1) |
organization_name | string | Optional | OrganizationBPName1 (category 2) |
search_term | string | Optional | SearchTerm1 |
addresses | object | Optional | Deep insert: {"results":[{address fields}]} for to_BusinessPartnerAddress |
await setu.execute({
userId: "user_1",
action: "sap_s4hana_cloud.create_business_partner",
input: {
"category": "<category>"
},
});Create sales orderwritesap_s4hana_cloud.create_sales_orderCreate a sales order (POST A_SalesOrder). Header fields are SalesOrderType (e.g. OR), SalesOrganization, DistributionChannel, OrganizationDivision and SoldToParty (the customer number). items is the OData v2 collection wrapper for a deep insert: {"results":[{"Material":"TG11","RequestedQuantity":"10"}]} (Material and RequestedQuantity are from SAP's metadata; numbers are strings). Setu fetches the CSRF token for you. This commits the company to a sale: always confirm with the user first. Needs the communication scenario SAP_COM_0109 in a communication arrangement (Public Edition: Fiori app Communication Arrangements) or the service API_SALES_ORDER_SRV activated in /IWFND/MAINT_SERVICE (on-premise).
| Input | Type | Description | |
|---|---|---|---|
sales_order_type | string | Required | SalesOrderType, e.g. OR (standard order) |
sales_organization | string | Required | SalesOrganization, e.g. 1710 |
distribution_channel | string | Required | DistributionChannel, e.g. 10 |
organization_division | string | Required | OrganizationDivision, e.g. 00 |
sold_to_party | string | Required | SoldToParty: the customer number |
purchase_order_by_customer | string | Optional | PurchaseOrderByCustomer: the customer's own reference |
transaction_currency | string | Optional | TransactionCurrency, e.g. USD |
items | object | Optional | Deep insert: {"results":[{"Material":"TG11","RequestedQuantity":"10"}]} for to_Item |
await setu.execute({
userId: "user_1",
action: "sap_s4hana_cloud.create_sales_order",
input: {
"sales_order_type": "<sales_order_type>",
"sales_organization": "<sales_organization>",
"distribution_channel": "<distribution_channel>",
"organization_division": "<organization_division>",
"sold_to_party": "<sold_to_party>"
},
});Get business partnerreadsap_s4hana_cloud.get_business_partnerGet one business partner by its number, including all its addresses (street, city, postal code, country) via $expand=to_BusinessPartnerAddress. The number is the BusinessPartner key (10 characters, often with leading zeros on some systems). Needs the communication scenario SAP_COM_0008 in a communication arrangement (Public Edition: Fiori app Communication Arrangements) or the service API_BUSINESS_PARTNER activated in /IWFND/MAINT_SERVICE (on-premise).
| Input | Type | Description | |
|---|---|---|---|
business_partner | string | Required | BusinessPartner number, e.g. 1000010 |
select | string | Optional | Comma-separated fields to return ($select); leave out for everything |
await setu.execute({
userId: "user_1",
action: "sap_s4hana_cloud.get_business_partner",
input: {
"business_partner": "<business_partner>"
},
});Get sales order with itemsreadsap_s4hana_cloud.get_sales_orderGet one sales order by number including its line items (to_Item: Material, RequestedQuantity, NetAmount, SalesOrderItemText). Needs the communication scenario SAP_COM_0109 in a communication arrangement (Public Edition: Fiori app Communication Arrangements) or the service API_SALES_ORDER_SRV activated in /IWFND/MAINT_SERVICE (on-premise).
| Input | Type | Description | |
|---|---|---|---|
sales_order | string | Required | SalesOrder number, e.g. 1 |
select | string | Optional | Comma-separated header fields to return ($select); leave out for everything |
await setu.execute({
userId: "user_1",
action: "sap_s4hana_cloud.get_sales_order",
input: {
"sales_order": "<sales_order>"
},
});List billing documentsreadsap_s4hana_cloud.list_billing_documentsList billing documents / invoices (entity A_BillingDocument, key BillingDocument). Fields include BillingDocumentType, BillingDocumentDate, SoldToParty, TotalNetAmount, TransactionCurrency, BillingDocumentIsCancelled. Dates in filters use datetime'2026-01-01T00:00:00'. Needs the communication scenario SAP_COM_0120 in a communication arrangement (Public Edition: Fiori app Communication Arrangements) or the service API_BILLING_DOCUMENT_SRV activated in /IWFND/MAINT_SERVICE (on-premise).
| Input | Type | Description | |
|---|---|---|---|
filter | string | Optional | OData $filter, e.g. "SoldToParty eq '10100001'" (string values in single quotes) |
top | integer | Optional | Maximum rows ($top); always set it, many SAP services do not page by themselves |
skip | integer | Optional | Rows to skip ($skip), for paging |
select | string | Optional | Comma-separated fields to return ($select) |
orderby | string | Optional | OData $orderby, e.g. 'CreationDate desc' |
expand | string | Optional | Navigation to include ($expand), e.g. to_Item |
await setu.execute({
userId: "user_1",
action: "sap_s4hana_cloud.list_billing_documents",
input: {},
});List business partnersreadsap_s4hana_cloud.list_business_partnersList business partners (customers, suppliers, contacts) with OData filtering and paging. Useful fields: BusinessPartner, BusinessPartnerFullName, BusinessPartnerCategory (1 person, 2 organization), Customer, Supplier. Use get_business_partner for one partner with addresses. Needs the communication scenario SAP_COM_0008 in a communication arrangement (Public Edition: Fiori app Communication Arrangements) or the service API_BUSINESS_PARTNER activated in /IWFND/MAINT_SERVICE (on-premise).
| Input | Type | Description | |
|---|---|---|---|
filter | string | Optional | OData $filter, e.g. "SoldToParty eq '10100001'" (string values in single quotes) |
top | integer | Optional | Maximum rows ($top); always set it, many SAP services do not page by themselves |
skip | integer | Optional | Rows to skip ($skip), for paging |
select | string | Optional | Comma-separated fields to return ($select) |
orderby | string | Optional | OData $orderby, e.g. 'CreationDate desc' |
await setu.execute({
userId: "user_1",
action: "sap_s4hana_cloud.list_business_partners",
input: {},
});List customersreadsap_s4hana_cloud.list_customersList customer master records (entity A_Customer, key Customer) with OData filtering and paging. Fields include Customer, CustomerName, CustomerFullName, CustomerAccountGroup, PostingIsBlocked. Needs the communication scenario SAP_COM_0008 in a communication arrangement (Public Edition: Fiori app Communication Arrangements) or the service API_BUSINESS_PARTNER activated in /IWFND/MAINT_SERVICE (on-premise).
| Input | Type | Description | |
|---|---|---|---|
filter | string | Optional | OData $filter, e.g. "SoldToParty eq '10100001'" (string values in single quotes) |
top | integer | Optional | Maximum rows ($top); always set it, many SAP services do not page by themselves |
skip | integer | Optional | Rows to skip ($skip), for paging |
select | string | Optional | Comma-separated fields to return ($select) |
orderby | string | Optional | OData $orderby, e.g. 'CreationDate desc' |
await setu.execute({
userId: "user_1",
action: "sap_s4hana_cloud.list_customers",
input: {},
});List G/L account line itemsreadsap_s4hana_cloud.list_gl_account_line_itemsList general ledger journal entry line items (read only). UNVERIFIED: the service API_GLACCOUNTLINEITEM and its scenarios are confirmed in SAP's API catalog, but the entity set name A_GLAccountLineItem and its field names were not confirmed against SAP's metadata. Always filter (e.g. by CompanyCode and FiscalYear) and set top: the ledger is huge. If SAP answers 404, read $metadata with odata_get. Needs the communication scenario SAP_COM_0241 or SAP_COM_0303 in a communication arrangement (Public Edition: Fiori app Communication Arrangements) or the service API_GLACCOUNTLINEITEM activated in /IWFND/MAINT_SERVICE (on-premise).
| Input | Type | Description | |
|---|---|---|---|
filter | string | Optional | OData $filter, e.g. "SoldToParty eq '10100001'" (string values in single quotes) |
top | integer | Optional | Maximum rows ($top); always set it, many SAP services do not page by themselves |
skip | integer | Optional | Rows to skip ($skip), for paging |
select | string | Optional | Comma-separated fields to return ($select) |
orderby | string | Optional | OData $orderby, e.g. 'CreationDate desc' |
await setu.execute({
userId: "user_1",
action: "sap_s4hana_cloud.list_gl_account_line_items",
input: {},
});List material documentsreadsap_s4hana_cloud.list_material_documentsList material document headers (goods movements; entity A_MaterialDocumentHeader, composite key MaterialDocumentYear + MaterialDocument). Fields include PostingDate, DocumentDate, GoodsMovementCode, ReferenceDocument; $expand=to_MaterialDocumentItem adds the items (Material, Plant, GoodsMovementType, QuantityInBaseUnit). Needs the communication scenario SAP_COM_0108 in a communication arrangement (Public Edition: Fiori app Communication Arrangements) or the service API_MATERIAL_DOCUMENT_SRV activated in /IWFND/MAINT_SERVICE (on-premise).
| Input | Type | Description | |
|---|---|---|---|
filter | string | Optional | OData $filter, e.g. "SoldToParty eq '10100001'" (string values in single quotes) |
top | integer | Optional | Maximum rows ($top); always set it, many SAP services do not page by themselves |
skip | integer | Optional | Rows to skip ($skip), for paging |
select | string | Optional | Comma-separated fields to return ($select) |
orderby | string | Optional | OData $orderby, e.g. 'CreationDate desc' |
expand | string | Optional | Navigation to include ($expand), e.g. to_MaterialDocumentItem |
await setu.execute({
userId: "user_1",
action: "sap_s4hana_cloud.list_material_documents",
input: {},
});List outbound deliveriesreadsap_s4hana_cloud.list_outbound_deliveriesList outbound delivery headers (entity A_OutbDeliveryHeader, key DeliveryDocument) from the service version API_OUTBOUND_DELIVERY_SRV;v=0002. Fields include ShipToParty, SoldToParty, ShippingPoint, PlannedGoodsIssueDate, OverallGoodsMovementStatus (C when goods are issued); $expand=to_DeliveryDocumentItem adds the items. Needs the communication scenario SAP_COM_0106 in a communication arrangement (Public Edition: Fiori app Communication Arrangements) or the service API_OUTBOUND_DELIVERY_SRV;v=0002 activated in /IWFND/MAINT_SERVICE (on-premise).
| Input | Type | Description | |
|---|---|---|---|
filter | string | Optional | OData $filter, e.g. "SoldToParty eq '10100001'" (string values in single quotes) |
top | integer | Optional | Maximum rows ($top); always set it, many SAP services do not page by themselves |
skip | integer | Optional | Rows to skip ($skip), for paging |
select | string | Optional | Comma-separated fields to return ($select) |
orderby | string | Optional | OData $orderby, e.g. 'CreationDate desc' |
expand | string | Optional | Navigation to include ($expand), e.g. to_DeliveryDocumentItem |
await setu.execute({
userId: "user_1",
action: "sap_s4hana_cloud.list_outbound_deliveries",
input: {},
});List productsreadsap_s4hana_cloud.list_productsList product (material) master records (entity A_Product, key Product). Fields include ProductType (e.g. FERT finished product), ProductGroup, BaseUnit, GrossWeight, IsMarkedForDeletion; $expand=to_Description adds the texts. Needs the communication scenario SAP_COM_0009 in a communication arrangement (Public Edition: Fiori app Communication Arrangements) or the service API_PRODUCT_SRV activated in /IWFND/MAINT_SERVICE (on-premise).
| Input | Type | Description | |
|---|---|---|---|
filter | string | Optional | OData $filter, e.g. "SoldToParty eq '10100001'" (string values in single quotes) |
top | integer | Optional | Maximum rows ($top); always set it, many SAP services do not page by themselves |
skip | integer | Optional | Rows to skip ($skip), for paging |
select | string | Optional | Comma-separated fields to return ($select) |
orderby | string | Optional | OData $orderby, e.g. 'CreationDate desc' |
expand | string | Optional | Navigation to include ($expand), e.g. to_Description |
await setu.execute({
userId: "user_1",
action: "sap_s4hana_cloud.list_products",
input: {},
});List purchase ordersreadsap_s4hana_cloud.list_purchase_ordersList purchase order headers (entity A_PurchaseOrder, key PurchaseOrder). Fields include Supplier, CompanyCode, PurchaseOrderType, PurchasingOrganization, PurchaseOrderDate, DocumentCurrency; $expand=to_PurchaseOrderItem adds the items. SAP marks this v2 service deprecated on the Public Edition (successor CE_PURCHASEORDER_0001 on OData v4, whose entity names are not curated here: use odata_get) but still serves it. Needs the communication scenario SAP_COM_0053 in a communication arrangement (Public Edition: Fiori app Communication Arrangements) or the service API_PURCHASEORDER_PROCESS_SRV activated in /IWFND/MAINT_SERVICE (on-premise).
| Input | Type | Description | |
|---|---|---|---|
filter | string | Optional | OData $filter, e.g. "SoldToParty eq '10100001'" (string values in single quotes) |
top | integer | Optional | Maximum rows ($top); always set it, many SAP services do not page by themselves |
skip | integer | Optional | Rows to skip ($skip), for paging |
select | string | Optional | Comma-separated fields to return ($select) |
orderby | string | Optional | OData $orderby, e.g. 'CreationDate desc' |
expand | string | Optional | Navigation to include ($expand), e.g. to_PurchaseOrderItem |
await setu.execute({
userId: "user_1",
action: "sap_s4hana_cloud.list_purchase_orders",
input: {},
});List sales ordersreadsap_s4hana_cloud.list_sales_ordersList sales order headers (entity A_SalesOrder, key SalesOrder). Filterable fields include SoldToParty, SalesOrderType, SalesOrganization, CreationDate, OverallSDProcessStatus; TotalNetAmount and TransactionCurrency give the value. Use get_sales_order for items. Needs the communication scenario SAP_COM_0109 in a communication arrangement (Public Edition: Fiori app Communication Arrangements) or the service API_SALES_ORDER_SRV activated in /IWFND/MAINT_SERVICE (on-premise).
| Input | Type | Description | |
|---|---|---|---|
filter | string | Optional | OData $filter, e.g. "SoldToParty eq '10100001'" (string values in single quotes) |
top | integer | Optional | Maximum rows ($top); always set it, many SAP services do not page by themselves |
skip | integer | Optional | Rows to skip ($skip), for paging |
select | string | Optional | Comma-separated fields to return ($select) |
orderby | string | Optional | OData $orderby, e.g. 'CreationDate desc' |
await setu.execute({
userId: "user_1",
action: "sap_s4hana_cloud.list_sales_orders",
input: {},
});List supplier invoicesreadsap_s4hana_cloud.list_supplier_invoicesList supplier invoices (accounts payable). UNVERIFIED: the service API_SUPPLIERINVOICE_PROCESS_SRV and its scenario are confirmed in SAP's API catalog, but the entity set name A_SupplierInvoice and its field names were not confirmed against SAP's metadata. If SAP answers 404, read the service's $metadata with odata_get and use odata_get instead. Needs the communication scenario SAP_COM_0057 in a communication arrangement (Public Edition: Fiori app Communication Arrangements) or the service API_SUPPLIERINVOICE_PROCESS_SRV activated in /IWFND/MAINT_SERVICE (on-premise).
| Input | Type | Description | |
|---|---|---|---|
filter | string | Optional | OData $filter, e.g. "SoldToParty eq '10100001'" (string values in single quotes) |
top | integer | Optional | Maximum rows ($top); always set it, many SAP services do not page by themselves |
skip | integer | Optional | Rows to skip ($skip), for paging |
select | string | Optional | Comma-separated fields to return ($select) |
orderby | string | Optional | OData $orderby, e.g. 'CreationDate desc' |
await setu.execute({
userId: "user_1",
action: "sap_s4hana_cloud.list_supplier_invoices",
input: {},
});List suppliersreadsap_s4hana_cloud.list_suppliersList supplier master records (entity A_Supplier, key Supplier) with OData filtering and paging. Fields include Supplier, SupplierName, SupplierFullName, SupplierAccountGroup, PostingIsBlocked. Needs the communication scenario SAP_COM_0008 in a communication arrangement (Public Edition: Fiori app Communication Arrangements) or the service API_BUSINESS_PARTNER activated in /IWFND/MAINT_SERVICE (on-premise).
| Input | Type | Description | |
|---|---|---|---|
filter | string | Optional | OData $filter, e.g. "SoldToParty eq '10100001'" (string values in single quotes) |
top | integer | Optional | Maximum rows ($top); always set it, many SAP services do not page by themselves |
skip | integer | Optional | Rows to skip ($skip), for paging |
select | string | Optional | Comma-separated fields to return ($select) |
orderby | string | Optional | OData $orderby, e.g. 'CreationDate desc' |
await setu.execute({
userId: "user_1",
action: "sap_s4hana_cloud.list_suppliers",
input: {},
});OData read (any service)readsap_s4hana_cloud.odata_getGeneric guarded read of any OData service the system exposes (custom Z services, other API_* services, OData v4). The path must start with /sap/opu/odata/ (v2) or /sap/opu/odata4/ (v4), e.g. /sap/opu/odata/sap/API_MATERIAL_STOCK_SRV/A_MatlStkInAcctMod, or the service root plus $metadata to discover entity sets. Pass OData options in query ($filter, $top, $select, $expand, $skip, $orderby; v4 also $count). Returns the raw reply: v2 wraps rows in d.results, v4 in value. Always set $top. Every API needs its communication scenario or active service.
| Input | Type | Description | |
|---|---|---|---|
path | string | Required | Path starting with /sap/opu/odata/ or /sap/opu/odata4/, e.g. /sap/opu/odata/sap/API_PRODUCT_SRV/A_ProductDescription |
query | object | Optional | OData query options as plain parameters, e.g. {"$top": 5, "$filter": "Product eq 'TG11'"} |
await setu.execute({
userId: "user_1",
action: "sap_s4hana_cloud.odata_get",
input: {
"path": "<path>"
},
});Post goods issue for a deliverywritesap_s4hana_cloud.post_goods_issuePost the goods issue for an outbound delivery (function import PostGoodsIssue, POST, parameter DeliveryDocument). This books the stock out and cannot simply be undone (ReverseGoodsIssue exists but is not curated). Optional posting_date is an OData literal for ActualGoodsMovementDate, e.g. datetime'2026-10-01T00:00:00'. Setu fetches the CSRF token for you. The function name and parameters are confirmed in SAP's generated client for API_OUTBOUND_DELIVERY_SRV; the service path with ;v=0002 is from SAP's API catalog; that this version exposes the same function import is inferred. Needs the communication scenario SAP_COM_0106 in a communication arrangement (Public Edition: Fiori app Communication Arrangements) or the service API_OUTBOUND_DELIVERY_SRV;v=0002 activated in /IWFND/MAINT_SERVICE (on-premise).
| Input | Type | Description | |
|---|---|---|---|
delivery_document | string | Required | DeliveryDocument number, e.g. 80000001 |
posting_date | string | Optional | ActualGoodsMovementDate as an OData literal, e.g. datetime'2026-10-01T00:00:00'; optional |
await setu.execute({
userId: "user_1",
action: "sap_s4hana_cloud.post_goods_issue",
input: {
"delivery_document": "<delivery_document>"
},
});Update sales orderwritesap_s4hana_cloud.update_sales_orderChange header fields of a sales order (PATCH A_SalesOrder('<number>')). fields is an object of header fields to change, e.g. {"PurchaseOrderByCustomer":"PO-4712"}. SAP usually requires If-Match: pass if_match as "*" (accepted by many services, not confirmed for every system) or the entity's ETag (read it from __metadata.etag in get_sales_order). SAP normally answers 204 with no body. Setu fetches the CSRF token for you. Needs the communication scenario SAP_COM_0109 in a communication arrangement (Public Edition: Fiori app Communication Arrangements) or the service API_SALES_ORDER_SRV activated in /IWFND/MAINT_SERVICE (on-premise).
| Input | Type | Description | |
|---|---|---|---|
sales_order | string | Required | SalesOrder number to change |
fields | object | Required | Header fields to change, e.g. {"PurchaseOrderByCustomer":"PO-4712"} |
if_match | string | Optional | If-Match header: '*' or the ETag from the entity's __metadata.etag; omitted when not given |
await setu.execute({
userId: "user_1",
action: "sap_s4hana_cloud.update_sales_order",
input: {
"sales_order": "<sales_order>",
"fields": {}
},
});