This card covers SAP's Business Application Programming Interface (BAPI) and Remote Function Call (RFC) integration layer, applicable to both SAP ECC 6.0 (all EHP levels) and SAP S/4HANA on-premise/private cloud editions. BAPIs are methods of SAP Business Objects defined in the Business Object Repository (BOR, transaction BAPI/SWO1) that wrap RFC-enabled function modules with standardized interfaces, stable naming, and guaranteed backward compatibility. [src1, src5]
RFC is the underlying transport protocol. Five variants exist: synchronous (sRFC), asynchronous (aRFC), transactional (tRFC), queued (qRFC), and background (bgRFC). This card does NOT cover SAP Cloud Integration Suite, SAP BTP destinations, or S/4HANA Cloud public edition APIs (which use OData/REST exclusively).
| Property | Value |
|---|---|
| Vendor | SAP |
| System | SAP S/4HANA 2023/2024 + SAP ECC 6.0 EHP8 |
| API Surface | RFC (sRFC, aRFC, tRFC, qRFC, bgRFC) + BAPIs |
| Current API Version | SAP NetWeaver RFC SDK 7.50+ / JCo 3.1 / NCo 3.1 / PyRFC 3.x |
| Editions Covered | All on-premise and private cloud editions |
| Deployment | On-Premise / Private Cloud / Hybrid |
| API Docs | SAP Help — RFC Variants |
| Status | GA (bgRFC recommended; tRFC/qRFC maintenance-only) |
BAPIs are the application-level API; RFC variants are the transport-level protocol beneath them. Choosing the right RFC variant is critical. [src1, src5]
| RFC Variant | Protocol | Best For | Delivery Guarantee | Ordering | Real-time? | Target Required? |
|---|---|---|---|---|---|---|
| sRFC (Synchronous) | RFC/CPIC or WebSocket | Real-time lookups, immediate-response operations | None (fails if target down) | N/A | Yes | Yes |
| aRFC (Asynchronous) | RFC/CPIC | Parallel processing, non-critical background calls | None (lost if unreachable) | No | Partial | Yes |
| tRFC (Transactional) | RFC/CPIC | Exactly-once delivery (legacy) | Exactly-once via TID | No | No | No |
| qRFC (Queued) | RFC/CPIC | Ordered exactly-once delivery (legacy) | Exactly-once + FIFO | Yes (per queue) | No | No |
| bgRFC (Background) | RFC/CPIC or WebSocket | All new async/transactional work | Exactly-once, optional FIFO | Configurable | No | No |
RFC does not have API call quotas like REST APIs. Instead, limits are defined by system resources — dialog work processes, memory, and RFC connection parameters. [src1]
| Limit Type | Value | Applies To | Notes |
|---|---|---|---|
| Dialog work process time | 600s default | sRFC calls | Parameter rdisp/max_wprun_time; exceeded = TIME_OUT dump |
| Max RFC connections | Configurable per destination | All RFC types | SM59 settings; varies by system sizing |
| Memory per work process | Extended memory allocation | sRFC, aRFC | Large payloads exhaust work process memory |
| tRFC/qRFC payload | Stored in ARFCSSTATE/ARFCSDATA | tRFC, qRFC | Large volumes bloat database; monitor with SM58 |
| bgRFC unit size | Stored in BGRFC* tables | bgRFC | More efficient storage than tRFC tables |
| Limit Type | Value | Window | Configuration |
|---|---|---|---|
| Dialog work processes | Typically 10-40 per app server | Concurrent | rdisp/wp_no_dia; each sRFC occupies one |
| RFC connection pool | Configurable per destination | Concurrent | JCo: jco.destination.pool_capacity (default 1) |
| bgRFC scheduler threads | Configurable per app server | Per scheduler | SBGRFCCONF; multiple schedulers supported |
| SM58 stuck entries | N/A | Rolling | Entries stuck >24h indicate connectivity issues |
| Limit Type | Per-Transaction Value | Notes |
|---|---|---|
| Dialog step timeout | 600s (configurable) | sRFC runs within a dialog step — long-running calls hit this |
| Max internal tables size | Extended memory allocation | Large datasets cause STORAGE_PARAMETERS_WRONG_SET |
| Commit work frequency | 1 per LUW | Multiple BAPIs in one LUW require single BAPI_TRANSACTION_COMMIT |
| RFC callback depth | No hard limit | Recursive RFC calls consume work processes — avoid circular patterns |
RFC authentication is configured at the SAP system level via SM59 (RFC destination maintenance) and is fundamentally different from token-based REST authentication. [src8]
| Method | Use When | Security Level | MFA Support | Notes |
|---|---|---|---|---|
| User/Password | Development, testing | Low | No | Stored in SM59; visible to admins |
| SNC (Secure Network Communication) | Production — all environments | High | Via PKI | X.509 certificates; snc/only_encrypted_rfc=1 |
| Trusted RFC | SAP-to-SAP communication | Medium-High | N/A | S_RFCACL required; avoid wildcard values |
| SSO via Kerberos/SPNEGO | Windows domain environments | High | Via domain | Requires SAP Secure Login Server |
START — User needs to integrate with SAP via BAPI/RFC
|
+-- What's the integration pattern?
| |
| +-- Real-time (individual records, <1s latency)
| | +-- Need immediate response? --> sRFC: call BAPI, get RETURN
| | +-- Fire-and-forget OK? --> bgRFC with high-priority queue
| | +-- Write with confirmation? --> sRFC + check RETURN + COMMIT
| |
| +-- Batch/Bulk (scheduled, high volume)
| | +-- <1,000 records? --> sRFC loop with commit per batch
| | +-- >1,000 records? --> bgRFC with parallel queues (40% faster)
| | +-- Need ordering? --> bgRFC single named queue (FIFO)
| |
| +-- Event-driven
| | +-- SAP triggers? --> bgRFC outbound to registered RFC server
| | +-- Need exactly-once? --> bgRFC (replaces tRFC semantics)
| | +-- Not native RFC --> use SAP Event Mesh or IDoc
| |
| +-- File-based --> Not RFC — use IDoc, FBDI, or BW extractors
|
+-- Which connector?
| +-- Java --> SAP JCo 3.1
| +-- .NET --> SAP NCo 3.1
| +-- Python --> PyRFC 3.x (via SAP NW RFC SDK)
| +-- Node.js --> node-rfc or SAP Cloud SDK
| +-- Other --> SAP NW RFC SDK (C/C++)
|
+-- Error tolerance?
+-- Zero-loss --> bgRFC + SBGRFCMON + dead letter handling
+-- Best-effort --> aRFC (fastest, no persistence)
| BAPI | Module | Operation | Key Parameters | Notes |
|---|---|---|---|---|
| BAPI_SALESORDER_CREATEFROMDAT2 | SD | Create sales order | ORDER_HEADER_IN, ORDER_ITEMS_IN | Most-used SD BAPI; requires COMMIT |
| BAPI_PO_CREATE1 | MM | Create purchase order | POHEADER, POITEM, POSCHEDULE | Supports all item categories |
| BAPI_MATERIAL_SAVEDATA | MM | Create/change material | HEADDATA, CLIENTDATA, PLANTDATA | Set CLIENTDATAX flags for changes |
| BAPI_CUSTOMER_CREATEFROMDATA1 | SD/FI | Create customer | PI_PERSONALDATA, PI_COPYREFERENCE | Returns CUSTOMERNO on success |
| BAPI_GOODSMVT_CREATE | MM | Goods movement | GOODSMVT_HEADER, GOODSMVT_ITEM | GM_CODE determines movement type |
| BAPI_ACC_DOCUMENT_POST | FI | Post accounting doc | DOCUMENTHEADER, ACCOUNTGL | Replaces direct FB01 posting |
| BAPI_EMPLOYEE_GETDATA | HR | Read employee data | EMPLOYEE_ID, TIMEFRAME | Read-only; no commit needed |
| BAPI_TRANSACTION_COMMIT | Cross | Commit transaction | WAIT = 'X' | ALWAYS call after write BAPIs |
| BAPI_TRANSACTION_ROLLBACK | Cross | Rollback transaction | (none) | Only uncommitted changes in LUW |
| Feature | sRFC | aRFC | tRFC | qRFC | bgRFC |
|---|---|---|---|---|---|
| Delivery guarantee | None | None | Exactly-once | Exactly-once + FIFO | Exactly-once, optional FIFO |
| Target must be online | Yes | Yes | No | No | No |
| Caller blocked | Yes | No | No | No | No |
| Data persisted | No | No | Yes (TID) | Yes (queue) | Yes (unit) |
| Ordering | N/A | No | No | Yes | Configurable |
| Recommended for new dev | Yes (reads) | Limited | No | No | Yes (all async) |
| Monitoring txn | SM58 | SM58 | SM58 | SMQ1/SMQ2 | SBGRFCMON |
Create an RFC destination in the SAP system to define connection parameters for external systems. [src1]
Transaction: SM59
1. Create new destination: Type T (TCP/IP) for external, Type 3 for SAP-to-SAP
2. Set Activation Type: "Registered Server Program"
3. Set Program ID (must match external application)
4. For SNC: Technical Settings tab, set SNC partner name and QoP
5. Test connection: green light = success
Verify: SM59 → select destination → "Connection Test" → expected: green status, round-trip time displayed
Use SAP JCo 3.1 to invoke a BAPI synchronously. JCo handles connection pooling, data type conversion, and RFC protocol details. [src2]
// Get destination from properties file
JCoDestination destination = JCoDestinationManager.getDestination("SAP_SYSTEM");
// Get function template from SAP metadata
JCoFunction function = destination.getRepository()
.getFunction("BAPI_COMPANYCODE_GETLIST");
// Execute synchronous RFC call
function.execute(destination);
// Check RETURN for errors
JCoStructure ret = function.getExportParameterList().getStructure("RETURN");
if ("E".equals(ret.getString("TYPE")))
throw new RuntimeException("BAPI error: " + ret.getString("MESSAGE"));
// Process results
JCoTable codes = function.getTableParameterList().getTable("COMPANYCODE_LIST");
for (int i = 0; i < codes.getNumRows(); i++) {
codes.setRow(i);
System.out.println(codes.getString("COMP_CODE") + " - " + codes.getString("COMP_NAME"));
}
Verify: Run application → expected: list of company codes printed; no exceptions
Write BAPIs require explicit BAPI_TRANSACTION_COMMIT. Never call COMMIT WORK directly — it skips BAPI buffer refresh logic. [src3, src4]
// Execute the write BAPI
createSO.execute(dest);
// Check ALL RETURN table entries for errors
JCoTable returnTable = createSO.getTableParameterList().getTable("RETURN");
boolean hasErrors = false;
for (int i = 0; i < returnTable.getNumRows(); i++) {
returnTable.setRow(i);
String msgType = returnTable.getString("TYPE");
if ("E".equals(msgType) || "A".equals(msgType)) {
hasErrors = true;
}
}
// Single commit or rollback for entire LUW
if (!hasErrors) {
JCoFunction commit = dest.getRepository()
.getFunction("BAPI_TRANSACTION_COMMIT");
commit.getImportParameterList().setValue("WAIT", "X"); // Synchronous
commit.execute(dest);
} else {
JCoFunction rollback = dest.getRepository()
.getFunction("BAPI_TRANSACTION_ROLLBACK");
rollback.execute(dest);
}
Verify: SE16 → table VBAK → expected: new sales order with correct header data
bgRFC replaces tRFC and qRFC with better performance and monitoring. [src1, src6]
" Get bgRFC destination (configured in SBGRFCCONF)
DATA(lo_dest) = cl_bgrfc_destination_outbound=>create( 'DESTINATION_NAME' ).
" Create bgRFC unit (use create_qrfc_unit for ordered delivery)
DATA(lo_unit) = lo_dest->create_trfc_unit( ).
" Call function module within bgRFC unit
CALL FUNCTION 'BAPI_SALESORDER_CREATEFROMDAT2'
IN BACKGROUND UNIT lo_unit
EXPORTING order_header_in = ls_header
TABLES order_items_in = lt_items return = lt_return.
" Unit persisted to DB on COMMIT WORK
COMMIT WORK.
" bgRFC scheduler delivers when target is available
Verify: SBGRFCMON → expected: unit ID visible with status "Executed" or "Waiting"
# Input: SAP connection parameters, material number
# Output: Material description and base unit of measure
# Requires: pyrfc>=3.3 + SAP NW RFC SDK installed
from pyrfc import Connection
conn = Connection(
ashost='sap-server.example.com', sysnr='00',
client='100', user='RFC_USER', passwd='secure_password', lang='EN'
)
result = conn.call('BAPI_MATERIAL_GETDETAIL', MATERIAL='MAT-001', PLANT='1000')
ret = result.get('RETURN', {})
if ret.get('TYPE') == 'E':
raise RuntimeError(f"BAPI error: {ret['MESSAGE']}")
mat_desc = result['MATERIAL_GENERAL_DATA']['MATL_DESC']
print(f"Material: {mat_desc}")
conn.close()
// Input: SAP connection parameters
// Output: List of company codes
// Requires: [email protected] + SAP NW RFC SDK
const noderfc = require('node-rfc');
const client = new noderfc.Client({
ashost: 'sap-server.example.com', sysnr: '00',
client: '100', user: 'RFC_USER', passwd: 'secure_password'
});
async function getCompanyCodes() {
await client.open();
const result = await client.call('BAPI_COMPANYCODE_GETLIST', {});
if (result.RETURN?.TYPE === 'E')
throw new Error(`BAPI error: ${result.RETURN.MESSAGE}`);
for (const cc of result.COMPANYCODE_LIST)
console.log(`${cc.COMP_CODE} - ${cc.COMP_NAME}`);
await client.close();
}
getCompanyCodes().catch(console.error);
# RFC is a binary protocol, not HTTP. Cannot use cURL directly.
# For HTTP-based SAP integration, use:
# - SAP API Business Hub (api.sap.com) with OData/REST
# - SAP Cloud Connector + BTP for RFC-over-HTTP tunneling
# - SAP Gateway (SEGW) to expose BAPIs as OData services
| Parameter Type | ABAP Type | Direction | Example | Notes |
|---|---|---|---|---|
| IMPORT | Scalar/Structure | In | ORDER_HEADER_IN | Single values or flat structures |
| EXPORT | Scalar/Structure | Out | SALESDOCUMENT | Return values from BAPI |
| TABLES | Internal Table | In/Out | ORDER_ITEMS_IN, RETURN | Tabular data; RETURN has error messages |
| CHANGING | Structure | In/Out | (rare in BAPIs) | Modified by BAPI and returned |
| Field | Type | Values | Purpose |
|---|---|---|---|
| TYPE | CHAR 1 | S=Success, E=Error, W=Warning, I=Info, A=Abort | Message severity |
| ID | CHAR 20 | Message class (e.g., 'V1') | For lookup in SE91 |
| NUMBER | NUMC 3 | Message number | Combined with ID for unique identification |
| MESSAGE | CHAR 220 | Human-readable text | The actual error/success message |
| LOG_NO | CHAR 20 | Application log number | For detailed investigation via SLG1 |
| MESSAGE_V1-V4 | CHAR 50 | Variable replacements | Dynamic parts of message text |
| Error | Meaning | Cause | Resolution |
|---|---|---|---|
| COMMUNICATION_FAILURE | Cannot reach SAP | Network issue, SAP down | Check SM59 connection test; verify network |
| SYSTEM_FAILURE | ABAP runtime error | Short dump on target | Check ST22 for dump details |
| RFC_ERROR_LOGON_FAILURE | Auth failed | Wrong credentials, locked user | Check SU01 user status; use type B users |
| TABLE_ENTRIES_EXCEED_LIMIT | Too much data | Query returns too many rows | Add filter parameters; paginate |
| RETURN TYPE='E' | Business logic error | Invalid data, missing fields | Read MESSAGE; check SU53 for auths |
| RFC_ERROR_SYSTEM_NOT_AVAILABLE | Target unreachable | System down during tRFC/bgRFC | Entries in queue; auto-retry; check SBGRFCMON |
Always call BAPI_TRANSACTION_COMMIT with WAIT='X' after checking RETURN. [src3, src4]Migrate to bgRFC; parallel schedulers + efficient storage. [src6, src7]Set jco.destination.peak_limit > pool_capacity; set expiration_time. [src2]Monitor with STRUST; set reminders 30 days before expiry. [src8]Call ALL BAPIs first, check ALL RETURNs, then single COMMIT/ROLLBACK. [src3]Use bgRFC for guaranteed delivery; never aRFC for business-critical data. [src1]" BAD — COMMIT WORK skips BAPI buffer refresh logic
CALL FUNCTION 'BAPI_SALESORDER_CREATEFROMDAT2' ...
COMMIT WORK. " Missing BUFFER_REFRESH_ALL, stale buffers
" GOOD — calls BUFFER_REFRESH_ALL internally
CALL FUNCTION 'BAPI_SALESORDER_CREATEFROMDAT2' ...
CALL FUNCTION 'BAPI_TRANSACTION_COMMIT'
EXPORTING WAIT = 'X'. " Synchronous — waits for DB commit
[src4]
// BAD — each iteration is a separate LUW; cannot rollback later
for (Item item : items) {
function.execute(destination);
commitFunction.execute(destination); // COMMIT per item -- WRONG
}
// GOOD — all items in one LUW; single commit/rollback
boolean hasErrors = false;
for (Item item : items) {
function.execute(destination);
if (checkReturnForErrors(function)) { hasErrors = true; break; }
}
if (!hasErrors) commitFunction.execute(destination);
else rollbackFunction.execute(destination);
" BAD — tRFC deprecated; single scheduler, poor performance
CALL FUNCTION 'Z_SEND_ORDER'
IN BACKGROUND TASK DESTINATION 'TARGET_SYSTEM' ...
COMMIT WORK.
" GOOD — multiple schedulers, parallel queues, 40% better throughput
DATA(lo_dest) = cl_bgrfc_destination_outbound=>create( 'TARGET_SYSTEM' ).
DATA(lo_unit) = lo_dest->create_trfc_unit( ).
CALL FUNCTION 'Z_SEND_ORDER'
IN BACKGROUND UNIT lo_unit DESTINATION 'TARGET_SYSTEM' ...
COMMIT WORK.
Always pass WAIT='X' for integrations reading back after writing. [src4]Iterate the RETURN table, not just the export structure. [src3]Use system users (type B) in SU01. [src8]Set pool_capacity to expected concurrency; peak_limit 2-3x pool_capacity. [src2]Periodic monitoring jobs; alert on entries stuck >1h. [src6, src7]Use JCo/NCo metadata APIs for dynamic field lengths. [src2]# SAP transaction codes for RFC diagnostics
# Check RFC destination connectivity
SM59 -> select destination -> "Connection Test"
# Monitor stuck tRFC entries (legacy)
SM58 -> filter by date/destination
# Monitor bgRFC units and queues
SBGRFCMON -> filter by destination/status
# bgRFC history and performance
SBGRFCHIST (history) / SBGRFCPERFMON (throughput)
# Short dumps from failed RFC calls
ST22 -> filter by date/user
# RFC work process usage
SM66 (running processes) / SM04 (active sessions)
# Authorization failure diagnosis
SU53 -> shows last auth failure
# External: Check JCo version
java -cp sapjco3.jar com.sap.conn.jco.JCo
# External: Check PyRFC version
python -c "import pyrfc; print(pyrfc.__version__)"
# External: Test RFC connection from Python
python -c "
from pyrfc import Connection
c = Connection(ashost='host', sysnr='00', client='100', user='USER', passwd='PASS')
print('Connected:', c.get_connection_attributes())
c.close()
"
| Component | Version | Status | Key Changes | Notes |
|---|---|---|---|---|
| bgRFC | NetWeaver 7.0+ | Current, recommended | Replaces tRFC/qRFC | Use for all new async development |
| tRFC | All NW versions | Deprecated (functional) | Original async exactly-once | Migrate to bgRFC |
| qRFC | NetWeaver 6.20+ | Deprecated (functional) | FIFO ordering on tRFC | Migrate to bgRFC create_qrfc_unit() |
| sRFC | All versions | Current | Synchronous — unchanged | Still correct for real-time lookups |
| aRFC | All versions | Current (limited) | No delivery guarantee | Non-critical parallel calls only |
| JCo 3.1 | 3.1.x (2025) | Current | WebSocket RFC, bgRFC | Min Java 8 |
| NCo 3.1 | 3.1.x (2025) | Current | .NET 6+, WebSocket RFC | Replaces NCo 3.0 |
| PyRFC | 3.3+ (2024) | Current | Python 3.8+ required | Archived but functional |
| NW RFC SDK | 7.50+ | Current | Required by all connectors | S-user required for download |
Deprecation policy: SAP does not formally sunset tRFC/qRFC — they remain functional indefinitely. However, all new documentation and features target bgRFC exclusively. SAP Note 1889823 recommends bgRFC migration. [src1, src6]
| Use When | Don't Use When | Use Instead |
|---|---|---|
| Integrating with SAP ECC or S/4HANA on-premise/private cloud | Using S/4HANA Cloud public edition | OData V4 APIs via SAP API Business Hub |
| Calling existing ABAP function modules or BAPIs | Building new APIs from scratch on S/4HANA | RAP (RESTful ABAP Programming) + OData |
| Need exactly-once async delivery (bgRFC) | Need real-time event streaming/webhooks | SAP Event Mesh or ALE/IDocs |
| Using Java, .NET, Python, or C/C++ clients | Browser-based or mobile integration | SAP Gateway OData services |
| Batch processing with guaranteed ordering | High-frequency, low-latency microservices | SAP Cloud SDK + API Management |
| Landscape without SAP BTP | Full cloud-native on SAP BTP | SAP Integration Suite + Cloud Connector |