---
title: RFC Console
description: Build, test, and save SAP RFC/BAPI calls. The playground doubles as the library editor — one URL per saved function.
---

The **RFC Console** ([/rfc-console](/rfc-console)) is two things at once:

- A **playground** for testing arbitrary SAP RFC / BAPI calls against your SAP system.
- The **editor** for the workspace's enricher library — each saved function gets its own URL: `/rfc-console/{slug}`.

There is no separate "library page". Bare `/rfc-console` shows the library list below the playground; clicking a row loads it into the form at `/rfc-console/<slug>`.

## Playground

The top of the page is the call form, in three blocks:

1. **Function** — the BAPI / RFC name (e.g. `BAPI_DOCUMENT_GETDETAIL2`) and the parameters / table inputs.
2. **Connection** — host, system number, client, user, password, language. Per-function — each saved row carries its own credentials encrypted at rest.
3. **Output** — the raw SAP response rendered as a collapsible JSON tree, or as raw JSON via the Raw toggle.

### Placeholders

Parameter values may contain placeholders that resolve at run time. The same syntax works on saved enrichers when they auto-fire on ingest.

```
{{DOC_ID}}            FileRelay document id
{{SAP_OBJECT_ID}}     SAP business object key
{{SAP_OBJECT_TYPE}}   SAP object type code
{{ARCHIVE_DATE}}      doc archive date
{{CONT_REP}}          content repository id
{{EXTERNAL_ID}}       external id (if any)
{{TODAY}}             current date — supports {{TODAY:Y}}, {{TODAY:Ymd}}
{{NOW}}               current timestamp
{{USER}}, {{WORKSPACE}}
```

When you run from the playground without a document context, document-scoped placeholders resolve to literal placeholders so you can still preview the call shape. The legacy `{snake_case}` syntax remains supported.

### Test vs Execute

- **Test** — calls SAP but discards the result; useful for verifying credentials + function exists.
- **Execute** — calls SAP and renders the full response in the output panel.

Both run server-side. Whitelist / blacklist rules are also applied server-side before the response is serialized — blacklisted fields never reach the browser.

## Saving as a function

With a BAPI name filled in, the **Save as function** button enables. You don't need to Execute first.

The save modal asks only for a name and tags. The rest (BAPI, params, connection, whitelist, blacklist) is captured from the form. A unique slug is derived from the name; collisions append `-2`, `-3`, etc. The slug is **stable across renames** — once a function has a URL, that URL doesn't change if you rename it later.

If a saved function is already loaded (you arrived via its slug URL), the Save button changes to **Update**.

## The library list

Below the playground is the workspace's library of saved functions — search + grid/list toggle, matching the Destinations page styling.

Per-row actions:

- **Pencil** — rename / re-tag without leaving the page. Sends a partial PATCH that touches only `{name, tags}`.
- **Copy** — duplicate the function. The copy is an **orphan** (not bound to any repo) so it doesn't immediately auto-fire. Credentials carry over so you don't retype them. The copy is **active** by default — bind it from the Data Enrichment page when ready.
- **Trash** — delete. Stored `document_enrichments` rows survive (snapshot fields preserve the function name + module); the document detail page shows them as a strike-through "Deleted" card.

Clicking a row navigates to its dedicated URL (`/rfc-console/<slug>`) with the form filled in.

## Connection details on a loaded function

When you load a saved function:

- The connection form is pre-filled from the saved values.
- The password field is **blank** but shows a "saved" hint — submitting an empty password preserves the existing one.
- Test / Execute reuse the saved password automatically; you only need to re-enter it if you want to change it.

## Binding to a repository

The RFC Console doesn't manage bindings — that lives on the [Data Enrichment](/data-enrichment) page. There you'll see one row per content repository with its currently-bound enrichers, plus an "Add functions" button that opens a binding modal listing the workspace's orphan functions.

Cross-repo poaching is prevented: you can only bind a function that is either an orphan or already bound to the repo you're editing.

## Troubleshooting

| Symptom | Likely cause |
|---|---|
| `Connection refused` from playground | Connector container isn't running, or `FILERELAY_TEMP_STORAGE` paths don't line up between host and container. |
| `BAPI returned RETURN.TYPE=E` | SAP-side error. The playground surfaces `bapiErrors` extracted from the raw response. |
| Saved function fires but no `document_enrichments` row appears | The `enrichment` queue isn't being worked. Run `php artisan queue:work --queue=default,enrichment`. |
| Result is empty on the detail page but populated in the playground | Whitelist is too narrow or blacklist masks the fields. Both are applied server-side. |
| "Inactive" badge on a card | The function is toggled off — visit `/data-enrichment` and re-activate. |

See also: [Data Enrichment Overview](/docs/data-enrichment/overview).
