Now accepting guest editorial from SAP, Oracle, Workday and ServiceNow practitioners.Pitch a guide
The Sign-Off Table

Lesson 1 of 5

Stable dependencies: build only on released contracts

11 min

Listen to this lesson

0:00 / 18:33

Contoso Motor Co. now runs three extensions on SAP BTP next to its converted SAP S/4HANA system: the fleet order status app, the event-driven fleet order notifier, and a warranty app that is still on the drawing board. Each one will outlive several S/4HANA feature pack stacks and at least one upgrade. Whether those upgrades are routine or a crisis is decided long before they happen, by one design question: what exactly does the extension depend on, and has SAP promised that it will stay stable?

LevelSAP's description (2025)Typical techniqueUpgrade risk
AFully compliant: only publicly released, stable SAP interfaces with formal stability contractsSide-by-side on SAP BTP or on-stack ABAP Cloud, using released APIs and eventsLowest
BCompliant: Level A plus SAP's classic APIs, which are documented and generally upgrade-stableClassic APIs where no released successor exists yetLow
CPartially compliant: accesses SAP internal objectsReading internal tables or calling unreleased function modulesNeeds proactive upgrade planning
DNot recommended: modifications, write access to SAP tables, implicit enhancementsAnything that changes or writes into SAP's own objectsHighest; technical debt
SAP's clean core extensibility levels as described on SAP News in August 2025.
The Sign-Off Table · thesignofftable.com/academy/sap-btp-401

What counts as a stable dependency

For a side-by-side extension, the stable surface of SAP S/4HANA is small and well documented: released APIs (OData and SOAP services listed in the SAP Business Accelerator Hub with a released state), released business events, and, for on-stack code, released ABAP objects used through ABAP Cloud. These carry SAP's stability contract: they are versioned, and when SAP replaces one, it deprecates the old version and points to a successor rather than changing it silently. Everything else (a database table read through a custom service, an unreleased function module called by RFC, a screen scraped by a bot) works until the day it does not.

Stability is not only about S/4HANA. The extension also depends on BTP services, on the runtime (a Node.js or Java version on Cloud Foundry), on open-source libraries and on other teams' APIs. An expert design lists all of them, not only the SAP ones.

Business contractReleased S/4HANA APIs and events: Sales Order API, SalesOrder Created and Changed events
Platform servicesDestination, authorization and trust, SAP HANA Cloud, event broker, SAP Cloud Transport Management
RuntimeCloud Foundry buildpack and language version, CAP framework version
LibrariesOpen-source packages pinned in the lock file and scanned in the pipeline
Internal contractsContoso's own APIs and events between extensions, versioned like SAP's
The dependency stack of the fleet order notifier. Each layer changes on its own schedule.
The Sign-Off Table · thesignofftable.com/academy/sap-btp-401

The dependency register

Contoso's architecture rule is short: every extension keeps a dependency register, reviewed at each architecture review and each upgrade. For each dependency it records the exact name and version, its release state, the clean core level it implies, the owner, and the tests that would catch a breaking change. The register turns a vague worry ("will the upgrade break the warranty app?") into a list that Priya's team can test against.

DependencyVersion / stateLevelCovered by
Sales Order OData API (released)Current version, releasedAContract tests in cmc-ext-test against CMQ
SalesOrder Created / Changed eventsv1, releasedAEvent contract tests with the AsyncAPI schema
Core return agreements RAP business object and eventContoso v1, owned by Kenji's teamA (ABAP Cloud)ABAP Unit plus event contract tests
Read of an internal pricing table via custom RFCUnreleasedCFlagged: replace before the next upgrade
Node.js runtimePinned major versionn/aPipeline build; runtime deprecation notices tracked

An extract of Contoso's dependency register (illustrative).

The dependency register as a data model: every dependency an extension has carries a version, release state, clean core level, owner and the tests that would catch a break.
The Sign-Off Table · thesignofftable.com/academy/sap-btp-401
  1. Is there a released API or event that provides what the extension needs?Yes → use it (Level A) · No → continue
  2. Is there a classic, documented API that is generally upgrade-stable?Yes → use it, record it as Level B and watch for a released successor · No → continue
  3. Can the need be met by a custom RAP business object or event in ABAP Cloud?Yes → build the contract yourself on released objects · No → continue
  4. Is internal access truly unavoidable?Yes → Level C: isolate it behind one adapter, register it, plan its replacement · No → redesign
Choosing a dependency, most stable first.
The Sign-Off Table · thesignofftable.com/academy/sap-btp-401

Isolate what you cannot avoid

Sometimes a Level C dependency is the only way to meet a deadline. The expert move is not to pretend otherwise but to contain it: put the access behind one adapter in the code (one module, one service), give it its own contract tests, register it, and set a date to replace it. When the upgrade comes, the blast radius is one adapter, not the whole app. Version your own contracts the same way: Contoso's fleet order notifier publishes a portal update API at v1; a breaking change becomes v2, and v1 stays until the portal has moved.

An unavoidable Level C read is contained behind one adapter with its own contract tests, so an upgrade can only break one place, and the adapter is later swapped for a released contract.
The Sign-Off Table · thesignofftable.com/academy/sap-btp-401

What would you do?

The warranty app needs the standard cost of an alternator at the time of sale. A developer finds an internal table that has it and proposes a custom RFC that reads it directly. No released API is known. What should the architect do?

Key points
  • Upgrade safety is decided by dependencies: released APIs and events, released ABAP objects (Level A) first.
  • Clean core levels run from A (released contracts) to D (modifications and writes to SAP tables).
  • List every dependency: SAP contracts, BTP services, runtime, libraries and internal APIs.
  • Keep a dependency register with version, state, level, owner and covering tests.
  • Contain unavoidable Level C access behind one adapter with tests and a replacement date.

Check your understanding · not graded

Lesson check

  1. 1. Which clean core level uses only publicly released, stable SAP interfaces?

  2. 2. An extension writes directly into an SAP standard table. Which level is that?

  3. 3. What should happen when SAP deprecates a released API the app uses?

  4. 4. How should an unavoidable Level C dependency be handled?