SAP S/4HANA Connector Guide

The SAP S/4HANA connector helps Tealfabric workflows interact with business data in SAP through API-driven operations. It is best suited for scenarios such as customer synchronization, order updates, and master-data retrieval where SAP remains the system of record.

Document information
FieldValue
Canonical URL/docs/04_connecting-systems/connectors/s/sap-s4hana
Version (published date)2026-05-08
Tagsconnectors, reference, sap-s4hana
Connector IDsap-s4hana-1.0.0

SAP S/4HANA connector flow showing secure client-scoped authentication, business partner write operations, and OData retrieval for downstream workflow automation.

Configuration and access

Before creating the integration, confirm your SAP base URL, client number, and API user credentials with the required authorizations. For most modern implementations, use odata as the API type to simplify entity operations and filtering. Keep credentials scoped to least privilege and rotate them under your standard ERP security policy.

  • base_url (required): SAP S/4HANA endpoint, such as https://sap.example.com:44300 (trailing slashes are trimmed).
  • username (required): SAP API user.
  • password (required): Password for the SAP API user.
  • client (required): SAP client number, for example 100.
  • api_type (optional): odata (default), soap, or rest. Selects the test probe path only; HTTP requests always use JSON Content-Type.
  • timeout_seconds (optional): Request timeout in seconds, default 60.

The connector uses Basic Authentication plus the X-SAP-Client header. Only test validates required configuration fields; send, receive, and execute follow legacy behavior and do not pre-validate configuration.

Create or update entities with send

Use send when your workflow needs to write business data such as customers or sales entities in SAP. Paths are relative to base_url (no leading slash). The default HTTP method is POST. Provide data for the JSON body, or omit data to send the full call payload as the body, matching legacy behavior. Empty bodies are omitted on POST/PUT/PATCH, matching PHP !empty($body) semantics.

const baseUrl = "https://api.example.com/api/v1";
const tenantId = "<TENANT_ID>";
const apiKey = "<API_KEY>";

async function createBusinessPartner(integrationId: string) {
  const response = await fetch(`${baseUrl}/integrations/${encodeURIComponent(integrationId)}/execute`, {
    method: "POST",
    headers: {
      "X-API-Key": apiKey,
      "X-Tenant-ID": tenantId,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      operation: "send",
      endpoint: "sap/opu/odata/sap/API_BUSINESS_PARTNER/A_BusinessPartner",
      method: "POST",
      data: {
        BusinessPartner: "BP900123",
        BusinessPartnerName: "Acme Distribution GmbH",
        BusinessPartnerCategory: "2",
      },
    }),
  });
  if (!response.ok) throw new Error(`Request failed: ${response.status}`);
  const payload = await response.json();
  return payload.data?.result;
}
curl -X POST "https://api.example.com/api/v1/integrations/<ENTITY_ID>/execute" \
  -H "X-API-Key: <API_KEY>" \
  -H "X-Tenant-ID: <TENANT_ID>" \
  -H "Content-Type: application/json" \
  -d '{
    "operation": "send",
    "endpoint": "sap/opu/odata/sap/API_BUSINESS_PARTNER/A_BusinessPartner",
    "method": "POST",
    "data": {
      "BusinessPartner": "BP900123",
      "BusinessPartnerName": "Acme Distribution GmbH",
      "BusinessPartnerCategory": "2"
    }
  }'
{
  "success": true,
  "data": {
    "message": "SAP S/4HANA operation completed successfully",
    "result": {
      "d": {
        "BusinessPartner": "BP900123"
      }
    }
  }
}

Retrieve SAP records with receive

Use receive to fetch OData entity sets or filtered lists. Provide endpoint and optional query as flat OData parameters ($filter, $top, $skip, etc.). List responses prefer d.results[] or results[]; otherwise the full payload is returned as a single-item array.

async function listUsBusinessPartners(integrationId: string) {
  const response = await fetch(`${baseUrl}/integrations/${encodeURIComponent(integrationId)}/execute`, {
    method: "POST",
    headers: {
      "X-API-Key": apiKey,
      "X-Tenant-ID": tenantId,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      operation: "receive",
      endpoint: "sap/opu/odata/sap/API_BUSINESS_PARTNER/A_BusinessPartner",
      query: {
        "$filter": "Country eq 'US'",
        "$select": "BusinessPartner,BusinessPartnerName,Country",
        "$top": "25",
        "$skip": "0",
      },
    }),
  });
  if (!response.ok) throw new Error(`Request failed: ${response.status}`);
  const payload = await response.json();
  return payload.data?.items ?? [];
}
{
  "success": true,
  "data": {
    "message": "SAP S/4HANA data retrieved successfully",
    "record_count": 1,
    "items": [
      {
        "BusinessPartner": "BP900123",
        "BusinessPartnerName": "Acme Distribution GmbH",
        "Country": "US"
      }
    ]
  }
}

Execute arbitrary SAP API calls with execute

Use execute for custom HTTP methods and endpoints. Provide body or data for the JSON request body; when both are omitted the connector sends no body on mutable methods (legacy default []).

{
  "operation": "execute",
  "endpoint": "sap/opu/odata/sap/API_BUSINESS_PARTNER/A_BusinessPartner('BP900123')",
  "method": "PATCH",
  "body": {
    "BusinessPartnerName": "Acme Distribution LLC"
  }
}

Test connectivity with test

test validates required configuration (base_url, username, password, client) and probes SAP:

  • api_type odata (default): GET sap/opu/odata/sap/API_BUSINESS_PARTNER/$metadata
  • soap or rest: GET sap/bc/rest
{
  "success": true,
  "data": {
    "message": "SAP S/4HANA connection test successful",
    "details": {
      "base_url": "https://sap.example.com:44300",
      "client": "100",
      "api_type": "odata"
    }
  }
}

When configuration is incomplete, test returns success: false with error.message of Configuration validation failed.

Reliability guidance

Most production failures are caused by authorization gaps, invalid entity mappings, or heavy unbounded queries. Test connectivity and permissions before go-live, apply pagination for large datasets, and add retry/backoff logic for transient API failures. XML/SOAP responses are returned as { "xml_response": "..." } when JSON parsing fails and the body contains <?xml.

Additional resources