---
title: RFC Remote Execution API
description: "API endpoints for invoking SAP BAPIs and remote-enabled function modules through the FileRelay JCo bridge."
---

# RFC Remote Execution API

The RFC API lets you invoke SAP **remote-enabled function modules** (BAPIs) through FileRelay's JCo bridge. This is the same channel FileRelay uses internally to enrich documents with SAP business-object metadata.

Each workspace's on-prem connector hosts a JCo connection pool to the configured SAP system. The cloud API authenticates the caller, forwards the call over the connector tunnel, captures the result and the JCo trace, and returns both.

> **Connector requirement.** RFC endpoints require a running connector with JCo enabled. See [SAP Connection](/docs/workspaces/sap-connection) for setup.

## Authorization

RFC calls execute under the SAP service account configured in the connector (`sap.jco.user`). The API key only governs whether a workspace member is allowed to *trigger* a call; SAP authorisations (S_RFC, transaction codes, table reads) are enforced by SAP for that service user.

| API Key Role | Can do                                                          |
|--------------|-----------------------------------------------------------------|
| Admin        | All RFC actions, including `custom` BAPIs                       |
| Member       | Predefined actions (`metadata`, `audits`, `claim`) only         |
| Viewer       | `GET /api/{userSlug}/{workspaceSlug}/rfc/status` and `.../rfc/logs` only |

## JCo Connection Status

Check whether the workspace's connector has an active JCo session before issuing calls.

```
GET /api/{userSlug}/{workspaceSlug}/rfc/status
```

### Example Request

```bash
curl -X GET "https://filerelay.dev/api/acme/production/rfc/status" \
  -H "Authorization: Bearer fr_live_abc123def456" \
  -H "Accept: application/json"
```

### Example Response

```json
{
  "data": {
    "enabled": true,
    "connected": true,
    "ashost": "sap-prd.acme.internal",
    "sysnr": "00",
    "client": "100",
    "user": "FILERELAY_RFC",
    "lang": "EN",
    "pool": {
      "capacity": 5,
      "peak_limit": 10,
      "in_use": 1,
      "idle": 4
    },
    "last_call_at": "2026-04-04T10:29:00Z"
  }
}
```

If `enabled` is `false`, JCo is not configured on this connector and all calls to `POST .../rfc/call` will return `409 Conflict`.

## Invoke an RFC

Execute a predefined or custom BAPI.

```
POST /api/{userSlug}/{workspaceSlug}/rfc/call
```

### Request Body

| Field           | Type   | Required | Description                                                                 |
|-----------------|--------|----------|-----------------------------------------------------------------------------|
| `action`        | string | Yes      | One of `metadata`, `audits`, `claim`, or `custom`                           |
| `doc_id`        | string | Cond.    | SAP `doc_id` (required for `metadata`, `audits`, `claim`)                   |
| `function_name` | string | Cond.    | ABAP function module name (required when `action: "custom"`)                |
| `parameters`    | object | No       | Input parameters passed to the function module                              |
| `tables`        | object | No       | Table parameters (each value is an array of rows)                           |
| `timeout_ms`    | integer| No       | Per-call timeout in milliseconds (default 15000, max 120000)                |

### Predefined Actions

| Action     | Function Module                | Purpose                                                |
|------------|--------------------------------|--------------------------------------------------------|
| `metadata` | `BAPI_DOCUMENT_GETDETAIL2`     | Read business-object metadata for a `doc_id`           |
| `audits`   | `BAPI_DOCUMENT_GETCHANGES`     | List change events recorded by ArchiveLink             |
| `claim`    | `BAPI_DOCUMENT_GETCLAIM`       | Read claim/retention info for a document               |

For these actions, only `doc_id` (and optionally `parameters`) is required.

### Example Request -- Predefined

```bash
curl -X POST "https://filerelay.dev/api/acme/production/rfc/call" \
  -H "Authorization: Bearer fr_live_abc123def456" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json" \
  -d '{
    "action": "metadata",
    "doc_id": "4A3F8B2C1D7E9F0A"
  }'
```

### Example Request -- Custom BAPI

```bash
curl -X POST "https://filerelay.dev/api/acme/production/rfc/call" \
  -H "Authorization: Bearer fr_live_abc123def456" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json" \
  -d '{
    "action": "custom",
    "function_name": "BAPI_USER_GET_DETAIL",
    "parameters": {
      "USERNAME": "JOHN_DOE"
    }
  }'
```

### Example Response (Success)

```json
{
  "data": {
    "id": "rfc_01J8...",
    "type": "rfc_call",
    "attributes": {
      "action": "metadata",
      "function_name": "BAPI_DOCUMENT_GETDETAIL2",
      "doc_id": "4A3F8B2C1D7E9F0A",
      "success": true,
      "result": {
        "DOCUMENTCLASS": "PDF",
        "DOCUMENTTYPE": "FIINVOICE",
        "CREATED_BY": "MMUSTER",
        "CREATED_AT": "2026-04-04T10:30:00Z",
        "OBJECT_TYPE": "BKPF",
        "OBJECT_ID": "1000012345672026"
      },
      "tables": {
        "RETURN": [
          { "TYPE": "S", "ID": "DOCUMENT", "NUMBER": "001", "MESSAGE": "OK" }
        ]
      },
      "duration_ms": 87,
      "called_at": "2026-04-04T10:30:01Z"
    }
  }
}
```

### Example Response (Failure)

```json
{
  "error": {
    "code": "rfc_error",
    "message": "BAPI returned message type E: Document 4A3F8B2C1D7E9F0A not found.",
    "details": {
      "duration_ms": 42,
      "tables": {
        "RETURN": [
          { "TYPE": "E", "ID": "OAGN", "NUMBER": "104", "MESSAGE": "Document not found" }
        ]
      }
    }
  }
}
```

Returns `200 OK` on a successful call (HTTP-level success), `422` for client-side validation errors, `502` for transport errors to the connector, and `504` if the call exceeds `timeout_ms`.

## JCo Trace Logs

Tail the most recent JCo trace lines from the connector. Useful when a call returns an opaque error and you need to see the raw RFC trace.

```
GET /api/{userSlug}/{workspaceSlug}/rfc/logs
```

### Query Parameters

| Parameter | Type    | Description                                | Default |
|-----------|---------|--------------------------------------------|---------|
| `limit`   | integer | Number of trailing lines to return (max 500) | 200     |
| `since`   | string  | ISO 8601 timestamp -- return lines after this | --      |

### Example Request

```bash
curl -X GET "https://filerelay.dev/api/acme/production/rfc/logs?limit=50" \
  -H "Authorization: Bearer fr_live_abc123def456" \
  -H "Accept: application/json"
```

### Example Response

```json
{
  "data": {
    "lines": [
      "2026-04-04 10:30:01.087 [pool-1-thread-3] DEBUG JCo  >> BAPI_DOCUMENT_GETDETAIL2 DOC_ID=4A3F...",
      "2026-04-04 10:30:01.174 [pool-1-thread-3] DEBUG JCo  << RETURN.TYPE=S MESSAGE=OK"
    ],
    "truncated": false
  }
}
```

## List Recent RFC Calls

All RFC calls made through this API are persisted as `captured_requests` with `channel: "jco"`. Query them through the [Request Viewer API](/docs/api/request-viewer) with `?channel=jco`:

```bash
curl "https://filerelay.dev/api/acme/production/requests?channel=jco&per_page=20" \
  -H "Authorization: Bearer fr_live_abc123def456"
```

This gives you the same response/trace context as the dashboard's Request Viewer.

## Safety Notes

- Custom BAPIs run with the connector's SAP authorisations. Treat `custom` like an admin-level operation: anyone with an Admin API key can read anything the service user can read.
- Calls are rate-limited at **30 per minute per workspace** in addition to the workspace's plan-level API limits. Bursts above 30/minute receive `429`.
- Sensitive parameter values (anything matching `*PASS*`, `*SECRET*`, `*TOKEN*` keys) are **redacted** in the persisted `captured_requests` body before storage. They are still sent to SAP at call time.

## Next Steps

- [SAP Connection](/docs/workspaces/sap-connection) -- Configure the connector and JCo pool
- [Request Viewer API](/docs/api/request-viewer) -- Inspect persisted RFC call payloads
- [Documents API](/docs/api/documents) -- Documents enriched by the `metadata` action
