EKKO and EKPO: SAP Purchase Order Tables and Joins

Aug 13, 2026

Convert a purchase order to Excel, CSV, or JSON

PDF, JPG, PNG, BMP, HEIC, TIFF

Submit your purchase orders

EKKO and EKPO are the two SAP tables that hold a purchase order. EKKO stores one row per purchasing document header, keyed on EBELN. EKPO stores one row per line item, keyed on EBELN plus EBELP. You join them on EBELN, and you almost always want to add EKKO-BSTYP = 'F' so contracts and scheduling agreements do not come back with your purchase orders.

Last updated August 2026.

That is the short version. The longer version is where the reports go wrong: EKPO does not carry a currency, the quantity you see there is not always the quantity that was scheduled, the price fields do not multiply the way people expect, and half the data a buyer would call part of the order lives in a child table with its own key. This is the reference for all of that, written for the person who has to produce a number somebody will act on.

What are EKKO and EKPO in SAP?

EKKO is the purchasing document header table and EKPO is the purchasing document item table. Both are real, transparent database tables in SAP MM, and both survived the move to S/4HANA unchanged in that respect. A purchase order created in ME21N writes one EKKO row and one EKPO row per line. Display it later in ME23N and you are looking at those two tables plus a handful of children.

The naming is worth decoding once. The E-K prefix comes from the German Einkauf, meaning purchasing. EKKO is the Kopf, the head. EKPO is the Position, the item. Every sibling table in the family follows the same pattern, which is why EKET, EKKN, EKBE and EKPA all start the same way.

EKKO key fields and the ones you will actually use

EKKO is keyed on MANDT and EBELN. In practice EBELN is the purchasing document number, a ten-character field, and MANDT is the client, which your query tool usually supplies for you. These are the header fields worth knowing by name.

FieldWhat it holdsWhy it matters
EBELNPurchasing document numberThe key. Joins to every child table
BSTYPPurchasing document categoryF is a purchase order. Filter on it or you get contracts too
BSARTDocument typeNB, UB, FO and your own Z types. Configured in T161
BUKRSCompany codeThe usual reporting boundary
LIFNRVendor account numberJoins to LFA1 for the vendor name
EKORG / EKGRPPurchasing organization and groupHow most procurement reports are sliced
WAERSDocument currencyLives here, not on the item. See the currency trap below
WKURSExchange rateFixed at the document, so restatement is not automatic
BEDATPurchasing document dateThe order date a buyer means when they say order date
AEDAT / ERNAMCreated on, created byRecord creation, not the business order date
FRGKE / FRGZURelease indicator and release statusThe approval state under a release strategy, decoded in the release strategy tables
LOEKZDeletion indicatorSet to L on a deleted document, which is not removed
KNUMVCondition record numberThe way into pricing conditions, taxes and freight
ZTERMPayment terms keyA code, not a phrase. Text lives in configuration

EKPO key fields and the ones you will actually use

EKPO is keyed on MANDT, EBELN and EBELP. EBELP is the five-character item number, so line 10 is stored as 00010 and sorts correctly as text. A single EKPO row is one line of one order.

FieldWhat it holdsWhy it matters
EBELN / EBELPDocument number and item numberTogether they identify a line uniquely
MATNRMaterial numberBlank on free-text and service lines, which is normal
TXZ01Short textThe description a supplier would recognize
WERKS / LGORTPlant and storage locationPlant is the receiving unit, not the ship-to address
MENGE / MEINSOrder quantity and unitThe line total, which schedule lines then split up
NETPRNet pricePer price unit, not per one. Read PEINH before using it
PEINHPrice unitA price of 250 with PEINH 100 means 2.50 each
BPRMEOrder price unitCan differ from MEINS, which is how unit bugs start
NETWRNet order valueThe line value in document currency. Use this, not MENGE times NETPR
PSTYPItem categoryStandard, consignment, subcontracting, third party, service
KNTTPAccount assignment categoryBlank means stock. K, F, P and A send cost elsewhere, via EKKN
ELIKZDelivery completed indicatorThe flag that closes a line for receiving
EREKZFinal invoice indicatorThe invoicing equivalent of ELIKZ
LOEKZDeletion indicatorSet per line. A live order can contain deleted lines
RETPOReturns itemFlips the direction of the movement. Easy to double count

How do you join EKKO and EKPO?

On EBELN. The header has one row per document and the item table has one row per line, so an inner join on EBELN gives you one row per line with the header repeated. In ABAP or in an external SQL tool it looks the same.

SELECT k~ebeln, k~bsart, k~lifnr, k~bedat, k~waers,
       p~ebelp, p~matnr, p~txz01, p~werks,
       p~menge, p~meins, p~netpr, p~peinh, p~netwr
  FROM ekko AS k
  INNER JOIN ekpo AS p
     ON p~ebeln = k~ebeln
 WHERE k~bstyp  = 'F'          "purchase orders only
   AND k~bukrs  = @lv_bukrs
   AND k~bedat  BETWEEN @lv_from AND @lv_to
   AND k~loekz  = @space        "header not deleted
   AND p~loekz  = @space        "line not deleted
 INTO TABLE @DATA(lt_po).

Two details in that statement do most of the work. The BSTYP filter is explained below. The two LOEKZ checks matter because SAP does not delete purchasing documents, it flags them, and a report that omits those checks will quietly include cancelled lines in a spend total.

The BSTYP trap: EKKO holds more than purchase orders

This is the single most common mistake in a first EKKO query. EKKO is not the purchase order table, it is the purchasing document header table, and several document categories share it. The category sits in BSTYP, and the domain has a fixed set of values.

BSTYPDocument category
FPurchase order
KContract
LScheduling agreement
ARequest for quotation
BPurchase requisition
IInfo record
QService entry sheet
WSource list

SAP sets these values and they cannot be changed in configuration, which is what makes BSTYP safe to filter on. BSART, the document type, is configurable in T161 and varies by client, so filtering on BSART alone is how one system's report stops working after a rollout to another. Filter the category first, then narrow by type if you need to.

A related point that catches people: a contract has a header in EKKO and its items in EKPO, exactly like a purchase order. Nothing about the row shape tells you which is which. Only BSTYP does.

The child tables around EKKO and EKPO

Roughly half of what a buyer thinks of as the purchase order is not in EKPO at all. These are the tables that hold the rest, and the keys that reach them.

TableHoldsKey beyond EBELN and EBELP
EKETSchedule lines: quantity and delivery date per shipmentETENR
EKKNAccount assignment: cost center, order, project, assetZEKKN
EKBEPurchase order history: goods and invoice receiptsZEKKN, VGABE, GJAHR, BELNR, BUZEI
EKBZHistory for delivery costs, kept apart from EKBESame shape as EKBE
EKPAPartner functions: ordering address, invoicing party, carrierPARVW
EKESVendor confirmations: order acknowledgments and shipping noticesETENS
EKPBComponents to be provided on subcontracting linesComponent counter
EBANPurchase requisitions, the document before the orderBANFN, BNFPO
EINA / EINEPurchasing info records, general and per purchasing orgINFNR
LFA1Vendor master, for the name behind LIFNRLIFNR

EKBE is the one people underestimate, because it is where received and invoiced quantities really live. It has its own transaction codes, its own movement-type semantics, and its own way of hiding itself in ME23N. Since it deserves more room than a row in a table, it has a reference of its own: purchase order history in SAP covers EKBE, the VGABE and BEWTP codes, and why the PO History tab sometimes vanishes.

Why the quantity in EKPO does not match the delivery schedule

EKPO-MENGE is the total quantity ordered on that line. EKET holds how that total is split across delivery dates, one row per schedule line, each with its own quantity in EKET-MENGE and delivery date in EKET-EINDT. For a simple order there is one schedule line and the two agree. For anything with staged deliveries they do not, and a report that joins EKPO to EKET without expecting several rows per line will multiply the value of the order by the number of shipments.

The rule of thumb: use EKPO for what was ordered, EKET for when it is due, and EKBE for what actually arrived. Three different questions, three different tables, and no single field answers all three.

The price fields, and why NETWR is not MENGE times NETPR

NETPR is a net price expressed per price unit, and PEINH is that price unit. A line priced at 250.00 with PEINH of 100 costs 2.50 each. Multiply quantity by NETPR and ignore PEINH and you overstate that line by a factor of a hundred. There is a second wrinkle: BPRME, the order price unit, can differ from MEINS, the order unit, so quantity may need converting before it is comparable to the price at all.

The practical answer is to use NETWR, the net order value, which SAP has already calculated in document currency. And that currency is the next trap, because EKPO does not carry one. Currency lives on the header in EKKO-WAERS, with the exchange rate in EKKO-WKURS fixed at the time of the order. Summing NETWR across a multi-currency vendor base without carrying WAERS through the join produces a number that looks reasonable and means nothing.

Taxes, freight and discounts are not in EKPO either. They are pricing conditions, reached through EKKO-KNUMV. In ECC those conditions sit in KONV. In S/4HANA that table was replaced by PRCD_ELEMENTS, so a query written before a conversion will fail after it, and this is one of the more common things to fix in an upgrade. The condition layer has its own set of tables and traps, covered in the reference on the purchase order pricing condition tables in SAP.

Do EKKO and EKPO still exist in S/4HANA?

Yes. Unlike several status tables in sales that became compatibility views, EKKO and EKPO remain real tables in S/4HANA and continue to store purchasing documents directly. What changed around them is worth knowing.

  • MATNR is 40 characters. The material number field was extended, so any interface, custom table, or downstream extract sized at 18 characters needs checking.
  • KONV became PRCD_ELEMENTS. Pricing condition reads have to be repointed.
  • CDS views are the recommended read path. SAP models purchase orders through views such as I_PurchaseOrderAPI01 and I_PurchaseOrderItemAPI01, with C_PurchaseOrderTP as the consumption view behind the Fiori purchase order apps. New reporting and extensions are expected to go through the view layer rather than straight to the tables.
  • The tables are still there for the old reports. Which is exactly why so many sites run both patterns at once and why knowing the underlying fields still pays.

How to look at EKKO and EKPO without writing code

You do not need a developer to read these tables. SE16N is the general table browser and takes EKKO or EKPO directly, which is the fastest way to confirm what a field really contains on a document you can see on screen. ME23N displays a single purchase order in business terms, with the item overview showing EKPO and the tabs underneath showing the child tables. For lists rather than single documents, the ME2 family does the work: ME2N by document number, ME2L by vendor, ME2M by material, each with selection parameters that filter on open, delivered, or invoiced state without you having to reason about ELIKZ and EREKZ yourself.

If you need the data outside SAP, the usual routes are a query in SQVI or SQ01, an extract from an ME2 report to spreadsheet, or an ABAP program that writes a file. Which one you pick usually comes down to how often you need it and whether anyone will notice if it stops running.

EKKO and EKPO compared with the other major ERPs

If you work across systems, the shapes are more alike than the names suggest. Every one of these splits a purchase order into a header and a set of lines. What differs is where history goes and how much of the order sits in child tables.

SystemHeaderLinesWhere history lives
SAP ECC and S/4HANAEKKOEKPOEKBE, a separate history table
Oracle EBS and FusionPO_HEADERS_ALLPO_LINES_ALLShipments and distributions carry it
Dynamics 365 F&OPurchTablePurchLineNowhere. Status fields do the job
Dynamics GPPOP10100POP10110Closed orders move to POP30100
JD EdwardsF4301F4311F43121 receipts, F43199 ledger

The per-system detail is in Oracle purchase order tables, PurchTable and PurchLine in Dynamics 365, Dynamics GP purchase order tables, and the JD Edwards F4311 and F4301 tables.

Getting purchase order data into EKKO and EKPO in the first place

Everything above is about reading. The harder problem at most sites is writing, because the orders that need to reach SAP frequently arrive as documents rather than as data. A supplier sends an order confirmation as a PDF. An acquired division hands over a year of open orders as scans. A category manager forwards an emailed order that has to be recorded against a contract. None of those can be loaded by the Migration Cockpit, BAPI_PO_CREATE1, or an IDoc, all of which want structured fields, so somebody reads one window and types into another.

That is the step we remove. Converting a purchase order to SAP-ready data means reading the PDF, scan, or photo with AI and returning the header fields and the full line grid as CSV, Excel, or JSON, shaped so it can be mapped to EKKO and EKPO fields and loaded with the tools SAP already gives you. To be clear about the boundary: we extract data from documents. We do not write to your tables, we are not an SAP connector, and nothing installs in your system.

Once that extract exists it tends to earn its keep more than once. The same line-level purchase data is what category analysis runs on, and it is increasingly what sustainability reporting runs on too, since Scope 3 category 1 covers purchased goods and services and is calculated from exactly this spend. Teams that already have clean line data can turn purchased goods and services spend into an audit-ready emissions footprint without a second data-gathering exercise.

Frequently asked questions

What is the difference between EKKO and EKPO?

EKKO holds the purchase order header, one row per document, keyed on EBELN. EKPO holds the line items, one row per line, keyed on EBELN and EBELP. Header-level facts such as vendor, currency, purchasing organization and payment terms are in EKKO. Item-level facts such as material, plant, quantity and price are in EKPO.

How do I find a purchase order in table EKKO?

Open SE16N, enter EKKO, and put the ten-character document number in EBELN. If you are searching rather than looking up a known order, filter on BSTYP equal to F for purchase orders, then narrow by LIFNR for a vendor, BUKRS for a company code, or BEDAT for an order date range. Leave BSTYP out and contracts and scheduling agreements come back with your results.

Which table stores purchase order line items in SAP?

EKPO. Each row is one line of one purchase order, identified by EBELN plus EBELP, where EBELP is a five-character item number so line 10 appears as 00010. Delivery dates for those lines are in EKET, account assignments in EKKN, and received or invoiced quantities in EKBE.

Is there one table with the complete purchase order?

No, and any tool that shows you one has joined several. A complete order spans EKKO for the header, EKPO for the lines, EKET for the delivery schedule, EKKN for account assignment, EKPA for partner functions, EKES for vendor confirmations, and EKBE for receipt and invoice history. Pricing conditions sit outside all of them, reached through EKKO-KNUMV.

What does EKPO-LOEKZ mean?

It is the deletion indicator, set to L when a line is deleted. SAP does not physically remove purchasing documents, so the row remains in the table with the flag set. Any spend or open-order report has to exclude flagged rows at both header and item level, because a live order can contain deleted lines.

How do I get EKKO and EKPO data into Excel?

The simplest route is an ME2 list report, ME2N, ME2L or ME2M, exported to spreadsheet from the list. For repeatable extracts a SQVI or SQ01 query over the EKKO and EKPO join gives you control over the fields. For a one-off investigation, SE16N will export directly. All three assume the data is already in SAP, which is a separate problem if your orders arrive as PDFs.

Related reading

The receipt and invoice side of these tables is covered in purchase order history in SAP. If you are loading orders rather than reading them, purchase order to SAP covers turning documents into loadable data, and the IDoc purchase order reference covers the message route. For the fields a purchase order carries regardless of system, see purchase order fields. The status indicators on these tables, EKKO-PROCSTAT and the EKPO flags ELIKZ, EREKZ and LOEKZ, are mapped in the SAP purchase order status tables reference.

Stop retyping purchase orders

Upload a PDF, scan, or photo of any PO and get clean Excel, CSV, or JSON line items in seconds.

Try it free

25 pages free. No credit card required.