← All posts

What is OCI? SAP's PunchOut interface explained

12 September 2026 / BoreaTech Team

Abstract dark-background diagram of a browser frame returning a column of indexed key-value rows into a procurement system, representing the OCI form post

OCI, the Open Catalog Interface, is SAP’s mechanism for punching out from a buyer’s procurement system into a supplier’s web catalog and bringing the resulting cart back. It achieves the same outcome as cXML PunchOut by considerably simpler technical means: parameters in an HTTP request on the way out, HTML form fields on the way back, and no XML documents anywhere in the exchange.

That simplicity is why OCI persists, and it is also why it is persistently misunderstood. PunchOut tends to get discussed as though it were a single thing, so a supplier who has built a working cXML PunchOut is often assumed to be reachable from any buyer. They are not. These are two different protocols with two different code paths, and a supplier selling into a European buyer base will meet both.

What actually happens during an OCI session

The sequence has four steps, and every one of them runs through the requisitioner’s browser.

  1. The requisitioner selects the supplier’s catalog from inside the buyer’s procurement system.
  2. The buyer’s system opens the supplier’s catalog URL, passing a set of parameters in the HTTP request. These are whatever the supplier has specified for authentication, plus one field the buyer generates for this session: HOOK_URL.
  3. The requisitioner shops on the supplier’s own site, in the supplier’s own session, under the supplier’s own pricing logic.
  4. On transfer, the supplier renders an HTML form whose action is the HOOK_URL, containing one set of hidden fields per cart line, and posts it. The buyer’s system reads those fields and turns them into requisition lines.

There is no server-to-server call at any stage. The browser is the entire transport. That single design decision explains both why OCI is cheap to implement and where its limits sit: there is nowhere to put a structured response, nowhere to negotiate, and no channel for either side to report a problem.

HOOK_URL

HOOK_URL is the return address the buyer supplies, and it is the single most important field to get right. The buyer’s system generates it per session, and it normally carries a session identifier that ties the returning cart to the requisition that opened it.

The supplier’s obligation is narrow and absolute: store the value exactly as received, and use it verbatim as the action of the return form. That sounds trivial and is the most common place implementations break, because the value is a long URL that usually already contains a query string. Appending parameters with ? instead of & breaks it, and so does truncating at the first ampersand, re-encoding it, HTML-escaping it a second time, or passing it through a sanitiser that normalises characters. So does caching it and reusing it in a later session, by which time the session identifier inside it has expired.

The other half is the frame: the buyer’s catalog call often opens inside a frame or named window, and the return post has to land where the buyer’s system is waiting rather than inside the supplier’s own frame. SAP buyer systems conventionally expect a couple of control fields alongside the item data for exactly this: ~OkCode, which tells the receiving transaction to add the returned items, and ~target, which controls where the response renders. Suppliers should ask the buyer which control fields their system expects, because the answer varies by buyer system and release.

The return fields

The cart comes back as a flat list of form fields. Every field name begins with NEW_ITEM-, and an index in square brackets identifies which line it belongs to, starting at 1. A two-line cart is simply two complete sets of fields.

NEW_ITEM-DESCRIPTION[1]=Chopping board, polyethylene, 450mm, blue
NEW_ITEM-QUANTITY[1]=24
NEW_ITEM-UNIT[1]=EA
NEW_ITEM-PRICE[1]=18.50
NEW_ITEM-PRICEUNIT[1]=1
NEW_ITEM-CURRENCY[1]=EUR
NEW_ITEM-VENDORMAT[1]=SKU-99213
NEW_ITEM-MATGROUP[1]=52151500
NEW_ITEM-LEADTIME[1]=3

The fields that carry the weight:

  • DESCRIPTION. The line text that ends up on the requisition and, later, on the purchase order. It is what the approver reads, and it is subject to a length limit on the buyer’s side that the supplier cannot see.
  • QUANTITY and UNIT. The quantity and its unit of measure, which has to be expressed in the buyer’s vocabulary, not the supplier’s.
  • PRICE, PRICEUNIT and CURRENCY. The price, the quantity that price refers to, and the currency. The price unit is the field that quietly ruins requisitions, and it gets its own treatment below.
  • VENDORMAT. The supplier’s own part number. It is what lets the supplier recognise the line when the purchase order arrives, so it should always be populated.
  • MATNR and VENDOR. The buyer’s material number and the buyer’s vendor number respectively, both expressed in the buyer’s master data. A supplier can only populate MATNR if the buyer has given them a mapping, and most have not.
  • MATGROUP. The buyer’s material group or commodity code. Whether it holds a UNSPSC code, an eCl@ss code or a buyer-internal group depends entirely on the buyer, and has to be agreed before go-live.
  • LONGTEXT. The extended item description. Its field name follows a different naming pattern from every other field in the set, which reliably trips implementers who assume the pattern is uniform.
  • CUST_FIELD1 to CUST_FIELD5. Free slots for buyer-specific data. Useful, and by definition not portable between buyers.

Functions beyond the plain catalog call

The specification defines several functions, distinguished by a parameter in the inbound call, not just the one:

  • Validation. The buyer sends an item identifier and the supplier returns the current price and availability for it, without any user interface. This matters when a requisition sits in an approval queue long enough for the price to move.
  • Background search. The buyer sends a search term and the supplier returns matching items directly as fields, again with no user interface, so the requisitioner can search supplier catalogs from inside the buyer’s own screen.
  • Detail display. The buyer opens the supplier’s page for an item bought previously, typically from a requisition or order line.

In practice the plain catalog call is the overwhelmingly common case, and support for the rest varies by buyer system, release and configuration. The useful question for a supplier scoping the work is not which functions OCI defines but which ones this buyer actually calls, and the answer is usually one.

OCI compared with cXML PunchOut

The two protocols solve the same problem, and the trade is legible.

OCI is easier to implement. There is no XML to generate or parse, no schema to validate against, no credential envelope to construct, and no separate server-to-server endpoint to stand up and secure. A supplier with a working web catalog can add OCI support with a parameter reader on the way in and a hidden form on the way out. That low barrier is a genuine advantage for smaller suppliers, and OCI connections often go live in a fraction of the time a cXML integration takes.

OCI is also less expressive. A flat list of key-value pairs cannot carry nested structure, so there is no clean place for multiple classification schemes on one line, no supplier-defined extensions comparable to cXML extrinsics, no cart-level shipping or tax detail, and nothing resembling a structured error response if the buyer’s system rejects what came back. cXML carries more metadata because its document model has room for it, and that extra structure earns its cost exactly when a buyer needs the metadata.

The point that matters commercially: a supplier who has built a cXML PunchOut has not thereby built an OCI one. The inbound parameter handling, the session model, the field names and the return mechanism are all different. Buyers evaluating a supplier should ask specifically which of the two is supported rather than accepting “we support PunchOut” as an answer, and suppliers should not let that phrase stand unqualified in their own marketing. Because SAP’s installed base is concentrated in Europe, a supplier selling into a mixed European buyer base commonly needs both, and should budget for both from the start. The same reasoning behind hosted catalog versus PunchOut applies here: the buyer’s existing stack decides, not the supplier’s preference.

How OCI goes wrong in practice

  • HOOK_URL handling. Truncation at the first ampersand, double encoding, appending parameters with the wrong separator, posting to a cached value from a previous session, or posting into the wrong frame. The symptom is usually a cart that vanishes with no error on either side, which is why this is the first thing to check.
  • Character encoding. The return post carries whatever character set the supplier’s page declares, and buyer systems have their own expectations. Accented characters, degree signs and typographic quotation marks in product descriptions arrive mangled, or truncate the description at the first byte the receiver cannot interpret. Suppliers with German, French, Italian or Nordic product data hit this early.
  • Unit of measure mismatch. The unit field must contain a code the buyer’s system recognises. SAP systems carry their own internal unit keys, which do not always match ISO codes and are sometimes language dependent, so the supplier’s EA may need to arrive as something else entirely. An unrecognised unit is rejected on the buyer’s side, and the rejection message rarely names the field.
  • Price unit convention. PRICE is the price for the quantity given in PRICEUNIT. A price of 18.50 with a price unit of 1 means 18.50 each. The same price with a price unit of 100 means 18.50 per hundred. A supplier whose internal pricing is per thousand, common in packaging and disposables, who sends the per-thousand figure with a price unit of 1, is wrong by three orders of magnitude, and the requisition still looks plausible enough to approve. Omitting the field entirely leaves the buyer’s system to apply a default that the supplier did not choose.
  • Index gaps. Removing a line from the cart without renumbering leaves a gap in the index sequence. Some receivers stop at the gap and silently drop everything after it.

Every one of these fails quietly. OCI has no error channel, so the practical test for an integration is not whether the post succeeds but whether the requisition that results is line for line identical to the cart the requisitioner built.

Where this fits

OCI is one of the formats a supplier has to speak to be reachable, alongside cXML for PunchOut and ordering and EDI for the large-enterprise supply chains that run on it. Each buyer relationship brings its own field conventions, unit vocabulary and test cycle, and none of it carries over to the next buyer.

That repetition is the problem SupplierForge is built around: a supplier configures their catalog and their integration capability once, rather than rebuilding the same connection per buyer. The broader pattern is set out in what is a PunchOut gateway.

punchoutp2p-systemscatalog-management