EDI 997 Functional AcknowledgmentPublished Jan 20, 2025 · Updated Aug 4, 2026

EDI 997 Functional Acknowledgment: Complete Guide

Master EDI 997 Functional Acknowledgment transactions. Learn how to send and interpret 997s, error codes, compliance requirements, and automated acknowledgment systems.

The EDI 997 Functional Acknowledgment is the X12 transaction set that confirms receipt of any inbound EDI document and reports whether it passed syntax validation. Every trading partner expects one within hours of transmitting an 850, 810, or 856. A missing 997 is treated as a failed transmission, which can trigger re-sends, duplicate orders, and chargebacks.

What is an EDI 997?

An EDI 997 Functional Acknowledgment (FA) is a structured receipt document defined by the ASC X12 standards body that a trading partner returns to confirm that a received transaction set was syntactically valid or to report specific segment and element errors.

Authoritative sources for 997 implementation:

  • The X12.org Transaction Sets reference defines the 997 functional group acknowledgment structure used across all transaction types
  • The DISA (Data Interchange Standards Association) maintains the X12 secretariat and formal ballot process for 997 error codes
  • Retailer implementation guides (Walmart SupplierOne, Target Partners Online, Amazon Vendor Central) specify timing requirements and mandatory error reporting fields

An EDI 997 is sent to confirm:

  • ✅ The EDI file was successfully received
  • ✅ The structure and syntax are valid
  • ✅ All required segments are present
  • ✅ Data elements are in correct format

Important: A 997 only confirms technical validity, NOT business acceptance. You can receive a positive 997 but still have the business document rejected later.

Interactive Example: Positive 997

Here's a sample 997 acknowledging a received 850 Purchase Order. British-spelling searches for the functional acknowledgement land on the same document; the X12 name uses the American spelling.

Live exampleEDI 997

Generic 997 Functional Acknowledgment

Positive acknowledgment confirming receipt of an 850 PO

Transaction Type
997 Functional Acknowledgment
Trading Partners
BUYER456 → VENDOR123
Segments
10 segments
Validation
All checks passed
/ search navigateesc close

Raw EDI (X12)

1
ISA*00* *00* *ZZ*BUYER456 *ZZ*VENDOR123 *231120*1431*U*00401*000000006*0*P*:~
2
GS*FA*BUYER456*VENDOR123*20231120*1431*6*X*004010~
3
ST*997*0006~
4
AK1*PO*1~
5
AK2*850*0001~
6
AK5*A~
7
AK9*A*1*1*1~
8
SE*6*0006~
9
GE*1*6~
10
IEA*1*000000006~

Human-Readable

Interchange

Sender ID(ZZ)BUYER456
Receiver ID(ZZ)VENDOR123
Date231120
Time1431
Standards IDU
Version00401
Control Number000000006
Acknowledgment RequestedNo
UsageProduction
Included Groups (IEA01)1

Functional Group

Functional IDFAFunctional Acknowledgment
SenderBUYER456
ReceiverVENDOR123
Date20231120
Time1431
Control Number6
Agency CodeX
Version004010
Transactions1
Reported Transaction Count (GE01)1

Transaction 997

Functional Acknowledgment
Transaction Type997
Control Number0006
Segments4
Reported Segment Count (SE01)6

Acknowledged Group

Functional IDPOPurchase Order
Group Control Number1

Transaction Responses (1)

Transaction 850 (Control #0001)
Accepted

Acknowledgment Summary

Group StatusAccepted
Transactions Included1
Transactions Received1
Transactions Accepted1
1 functional group1 transactionControl #000000006Valid

When to Send a 997

The 997 should be sent:

Timing: Within 24 hours of receiving an EDI transaction (many systems send within minutes)

For every transaction received:

  • 850 Purchase Orders → Send 997
  • 810 Invoices → Send 997
  • 856 Ship Notices → Send 997
  • 855 PO Acknowledgments → Send 997
  • Even 997s can receive 997s!

Critical: Not sending a 997 can result in:

  • Trading partner assumes transmission failed
  • Documents may be re-sent (duplicates)
  • Compliance violations
  • Potential chargebacks

Key Segments Explained

AK1 - Functional Group Response Header

AK1*PO*1
  • AK101: Functional Identifier Code from original GS segment
    • PO = Purchase Order (850)
    • SH = Ship Notice (856)
    • IN = Invoice (810)
    • PR = Purchase Order Acknowledgment (855)
  • AK102: Group Control Number (from original GS06)

AK2 - Transaction Set Response Header

AK2*850*0001
  • AK201: Transaction Set Identifier Code (850 = Purchase Order)
  • AK202: Transaction Set Control Number (from original ST02)

AK5 - Transaction Set Response Trailer

This is the verdict on the transaction:

AK5*A

AK501 Status Codes:

CodeMeaningDescription
AAcceptedTransaction is valid and accepted
EAccepted with ErrorsMinor errors, but transaction was processed
MRejected, Message Authentication Code FailedSecurity issue
PPartially AcceptedSome parts valid, some rejected
RRejectedTransaction is invalid and rejected
WRejected, Assurance FailedSecurity/authentication failed
XRejected, Content After Decryption Could Not Be AnalyzedEncryption issue

AK9 - Functional Group Response Trailer

AK9*A*1*1*1
  • AK901: Functional Group Acknowledgment Code
    • A = Accepted
    • E = Accepted with errors
    • P = Partially accepted
    • R = Rejected
  • AK902: Number of transaction sets included
  • AK903: Number of received transaction sets
  • AK904: Number of accepted transaction sets

Acceptance Status Examples

Example 1: Fully Accepted (Best Case)

AK1*PO*1          // Purchase Order group 1
AK2*850*0001      // Transaction 850, control # 0001
AK5*A             // ACCEPTED
AK9*A*1*1*1       // Group accepted, 1 of 1 accepted

Translation: "We received your 850 PO (control #0001), it's perfect, and we accepted it."

Example 2: Rejected with Error

AK1*PO*1
AK2*850*0001
AK3*N1*4          // Error in N1 segment, position 4
AK4*1*5           // Element 1 of N1 is invalid
AK5*R*5           // REJECTED - Invalid segment
AK9*R*1*1*0       // Group rejected, 0 of 1 accepted

Translation: "We received your 850, but the N1 segment (position 4) has an error in element 1. We rejected it."

Example 3: Multiple Transactions

AK1*PO*5
AK2*850*0001      // First PO
AK5*A             // Accepted
AK2*850*0002      // Second PO
AK5*A             // Accepted
AK2*850*0003      // Third PO
AK3*PO1*10        // Error in PO1 segment
AK4*2*7           // Element 2 is invalid
AK5*R*7           // Rejected
AK9*P*3*3*2       // Partially accepted: 2 of 3

Translation: "You sent 3 POs in group 5. We accepted #0001 and #0002, but rejected #0003 due to an error in PO1 segment."

EDI 997 Error Codes (AK304 and AK403)

When a transaction is rejected, the 997 should explain why. Two elements carry the actual error codes. AK304 says what is wrong with a segment. AK403 says what is wrong with an element inside that segment.

AK3 - Data Segment Note

Points to the specific segment with an error:

AK3*PO1*5*7
  • AK301: Segment ID (e.g., PO1, N1, REF)
  • AK302: Segment position in transaction set
  • AK303: Loop identifier (optional)
  • AK304: Segment syntax error code

AK304 Segment Error Codes

AK304 is the element most people are looking for when a 997 comes back rejected and the AK3 segment names a segment they thought was fine. It reports what is wrong with the segment itself, as opposed to AK403, which reports what is wrong with an element inside it.

CodeMeaningWhat it usually means in practice
1Unrecognized segment IDThe segment does not exist in the version you declared in GS08
2Unexpected segmentValid segment, wrong place in the transaction set
3Mandatory segment missingA required segment was never sent
4Loop occurs over maximum timesToo many repeats of a loop, for example more N1 loops than the spec allows
5Segment exceeds maximum useThe segment repeated more times than its own max use permits
6Segment not in defined transaction setThe segment belongs to X12 but not to this transaction set
7Segment not in proper sequenceCorrect segment, correct loop, wrong order
8Segment has data element errorsThe segment is positioned correctly but one or more elements failed

Code 8 is the one that pairs with AK4. If you see AK3 ending in 8, read the AK4 segments that follow it to find the specific element.

AK4 - Data Element Note

Points to the specific data element with an error:

AK4*2*7*8
  • AK401: Position in segment (element number)
  • AK402: Element reference number
  • AK403: Error code

AK403 Data Element Error Codes

CodeMeaningExample
1Mandatory data element missingPO102 (quantity) is empty
2Conditional required data element missingIf PO103 is EA, then PO102 is required
3Too many data elementsExtra elements beyond what's allowed
4Data element too shortUPC only has 10 digits instead of 12
5Data element too longPart number exceeds 30 characters
6Invalid character in data elementLetters in a numeric field
7Invalid code valueUnit of measure "XX" doesn't exist
8Invalid dateDTM00220231132 (no 32nd day)
9Invalid timeBSN04*2561 (hour can't be 25)
10Exclusion condition violatedBoth mutually exclusive elements present

Complete Error Example

ISA*00*          *00*          *ZZ*BUYER456       *ZZ*VENDOR123      *231120*1432*U*00401*000000007*0*P*:~
GS*FA*BUYER456*VENDOR123*20231120*1432*7*X*004010~
ST*997*0007~
AK1*PO*1~
AK2*850*0001~
AK3*PO1*5~              // Error in PO1 segment at position 5
AK4*2**1~               // Element 2 (quantity) is missing
AK3*N4*8~               // Error in N4 segment at position 8
AK4*3**8~               // Element 3 (zip code) has invalid format
AK5*R*1~                // REJECTED - segment error
AK9*R*1*1*0~            // Group rejected
SE*9*0007~
GE*1*7~
IEA*1*000000007~

Translation: "Your 850 was rejected because:

  1. PO1 segment (line item 5) is missing the quantity
  2. N4 segment (address 8) has an invalid zip code format"

How to Read a 997 Rejection: Worked Example

If someone hands you a rejection fragment with no context, read it left to right. Every AK3 and AK4 segment is positional, so each element position has a fixed meaning.

Decoding AK3*N2*48

AK3*N2*48
     |   |
     |   +-- AK302: segment position 48 in the transaction set
     +------ AK301: segment ID N2 (Additional Name Information)

Read it as: "the N2 segment at position 48 failed." There is no AK303 loop identifier and no AK304 error code here, so the partner told you where the problem is but not what kind of problem it is. That is common and it is legal. When AK304 is omitted, look at the AK4 segments that follow, and if there are none, check the segment against the partner's implementation guide for the version in GS08.

Position 48 counts every segment in the transaction set starting at ST, not the line number in the file and not the position within the loop. Off by one errors here usually mean you are counting from ISA instead of ST.

Decoding AK4*2*7*8

AK4*2*7*8
     | | |
     | | +-- AK403: error code 8, Invalid Date
     | +---- AK402: data element reference number 7
     +------ AK401: element position 2 within the segment

Read it as: "element 2 of the segment named in the preceding AK3 holds an invalid date." Pair it with the AK3 above it to get the full picture. If the AK3 said AK3*DTM*12*8, the failing value is DTM02 and it is a malformed date.

Mapper errors that point at a loop path

Some translators report the same failure as a document path rather than an AK3. A string like edi_004010_204/loop/s5_loop/n1_loop/n1, segment counter = 48 is the mapper's version of AK3*N1*48. Read the path right to left: the failing segment is N1, it sits inside the N1 loop, which sits inside the S5 loop, in a 204 using version 004010. The segment counter is the same position number AK302 would carry.

Paste the raw file into the EDI Inspector and jump to that segment position to see the actual values rather than guessing from the path.

Why Am I Not Getting a 997?

A missing acknowledgment is more often a configuration problem than a transmission problem. Work through these in order.

CauseHow to confirmFix
Partner never enabled FA returnTheir implementation guide lists 997 as optional or inbound onlyAsk them to turn on functional acknowledgments for your ISA ID
ISA14 set to 0Check ISA14 on your outbound fileSet ISA14 to 1 to request an acknowledgment
GS08 version mismatchYour GS08 does not match what the partner has mappedAlign GS08 with their guide, usually 004010 or 005010
They send a 999, not a 997Their guide references IK3/IK4 segmentsConfigure your translator to accept 999
VAN routing gapThe 997 reaches your VAN mailbox but never your translatorCheck mailbox routing rules and the VAN audit trail
Wrong ISA receiver on the returnPartner is sending to an ISA ID you retiredConfirm the qualifier and ID pair they have on file

The most common single cause is ISA14. If you never set it to 1, many partners treat the acknowledgment as not requested and will not send one.

997 Reconciliation: Missing, Late, and Duplicate Acknowledgments

Once volume is above a few hundred documents a month, the useful question stops being "did this file get a 997" and becomes "which files did not." A reconciliation report answers that by joining every outbound interchange against the acknowledgments received.

A working report tracks these columns:

ColumnDefinition
Total rowsOutbound transaction sets in the period
AcceptedAK501 of A or E
RejectedAK501 of R, M, W, or X
Partially acceptedAK901 of P at the group level
Missing 997No acknowledgment received inside the partner's stated window
Late acksAcknowledgment received after the window but before the next cycle
Duplicate acksMore than one 997 matched to the same GS06 and ST02 pair

Match on the pair of GS06 (group control number) and ST02 (transaction set control number). Matching on control number alone produces false duplicates as soon as your counter rolls over.

Duplicate acknowledgments are usually harmless and come from a partner re-running a batch. Treat them as informational. Missing acknowledgments are the only column worth alerting on, and the alert should fire at the partner's stated window rather than a fixed 24 hours, since Walmart's window is 4 hours and Target's is 24.

Implementation Approaches

Option 1: Manual 997 Generation

Suitable for low-volume EDI:

1. Receive inbound EDI
2. Parse and validate
3. Log any errors
4. Generate 997 based on validation results
5. Send 997 via VAN/AS2

Pros: Full control, can customize validation Cons: Time-consuming, error-prone

Option 2: Automated 997 Generation

Recommended for most implementations:

1. EDI software receives transaction
2. Real-time syntax validation
3. 997 auto-generated instantly
4. 997 transmitted automatically
5. Log for audit trail

Pros: Fast, reliable, no manual work Cons: Need EDI software/middleware

Option 3: VAN-Generated 997s

Many VANs (Value-Added Networks) can generate 997s:

1. Send EDI to VAN
2. VAN validates syntax
3. VAN generates 997
4. VAN sends 997 to partner
5. You receive confirmation

Pros: Zero effort, VAN handles it Cons: Limited customization, VAN fees, may not catch business logic errors

Best Practices for 997 Error Handling

1. Send 997s Promptly

❌ Wait 24 hours to batch 997s
✅ Send within minutes of receiving transaction

Prompt 997s help partners know their transmission succeeded and allows faster error correction.

2. Always Send a 997

❌ Only send 997 if there's an error
✅ Send 997 for every transaction (accepted or rejected)

Silence = uncertainty. Partners need to know you received their transmission.

3. Provide Detailed Error Information

❌ AK5*R (rejected with no explanation)
✅ AK5*R + AK3/AK4 segments explaining what's wrong

Help your partner fix issues faster with specific error details.

4. Log All 997s

Keep an audit trail:

  • ✅ 997 sent timestamp
  • ✅ Original transaction details
  • ✅ Accept/reject status
  • ✅ Error details if rejected

Useful for troubleshooting and compliance audits.

5. Monitor 997 Receipt

After you send EDI to a partner:

  • ✅ Expect a 997 within 24 hours
  • ✅ Alert if no 997 received
  • ✅ Check if 997 shows rejection
  • ✅ Investigate and resubmit if needed

997 vs. Business Acceptance

Critical Distinction:

997 FA = Technical acceptance only
855/856/810 = Business acceptance

Example Flow:

1. You send 850 PO
2. Partner sends 997*A (✅ received and valid)
3. Partner sends 855*04 (❌ cannot fulfill - out of stock)

The 997*A means "your EDI syntax is correct," but the 855 rejection means they can't actually fulfill your order.

997 vs 999: Which One Does My Partner Want?

Both documents acknowledge receipt. The 999 Implementation Acknowledgment adds a reporting level the 997 does not have.

997 Functional Acknowledgment999 Implementation Acknowledgment
Introduced in004010 and earlier005010
Syntax error segmentsAK3 and AK4IK3 and IK4
Verdict segmentAK5IK5
Group trailerAK9AK9
Reports guide violationsNo, syntax onlyYes, via IK3 and CTX context segments
Typical useRetail, most 004010 partnersHealthcare HIPAA, some 005010 supply chain

The practical rule: check GS08 on the inbound file. A 004010 partner expects a 997. A 005010 partner may expect either, and their implementation guide is the only reliable answer. Healthcare partners running HIPAA 5010 almost always require the 999.

Sending a 997 where a 999 is expected usually results in silence rather than an error, which is why this specific mismatch tends to surface as "we are not getting acknowledgments" rather than a rejection.

Common 997 Mistakes

1. Not Sending 997s at All

❌ Assume partner knows you received the file
✅ Always send 997 confirmation

2. Incorrect Control Numbers

❌ AK2*850*9999 (wrong control number)
✅ AK2*850*0001 (matches original ST02)

3. Wrong Functional Identifier

❌ AK1*SH*1 (for an 850 PO)
✅ AK1*PO*1 (matches original GS01)

4. Accepting Invalid Data

❌ AK5*A (but data has business logic errors)
✅ AK5*R + detailed error codes

Don't accept bad data just because it parses correctly!

Testing Your 997 Implementation

Use our EDI Inspector to:

  • Validate 997 structure
  • Check control number matching
  • Verify error code accuracy
  • Test against partner specs

Integration Tips

Automated 997 Response

def on_edi_received(edi_file):
    try:
        # Parse and validate
        parsed = parse_edi(edi_file)
        validate_syntax(parsed)
        validate_business_rules(parsed)

        # Generate positive 997
        fa = generate_997(
            status='A',  # Accepted
            original_control=parsed.control_number
        )

        # Send 997
        send_edi(fa)

        # Process transaction
        process_transaction(parsed)

    except SyntaxError as e:
        # Generate negative 997
        fa = generate_997(
            status='R',  # Rejected
            errors=e.details,
            original_control=parsed.control_number
        )
        send_edi(fa)

    except BusinessError as e:
        # Send positive 997 (syntax OK)
        fa = generate_997(status='A')
        send_edi(fa)

        # But send business rejection (855/810/etc)
        rejection = generate_business_rejection(e)
        send_edi(rejection)

Related Transaction Sets

Compliance Requirements

Most trading partners require:

Partner997 TimingRejection Requirements
WalmartWithin 4 hoursMust include error details
TargetWithin 24 hoursAK3/AK4 segments required
AmazonWithin 2 hoursImmediate transmission
Home DepotWithin 8 hoursFull error reporting

Late or missing 997s may result in compliance violations or chargebacks.

Frequently Asked Questions

What does AK5 = "A" vs. AK5 = "R" mean?

AK5 is the transaction set response trailer and its first element (AK501) is the verdict on the transaction. "A" means Accepted: the transaction parsed correctly and passed all syntax checks. "R" means Rejected: the transaction had one or more errors that prevented processing. When you see "R," look for AK3 and AK4 segments immediately before it in the same AK2 block. Those segments point to the exact segment position and element number that failed.

What is the difference between a 997 and a 999?

The 997 is the original X12 Functional Acknowledgment used in version 004010 and earlier. The 999 is the updated Implementation Acknowledgment introduced in version 005010 and later. The 999 adds a fourth reporting level for implementation-level errors (IK3/IK4) on top of the basic AK3/AK4 syntax errors. Most retail trading partners still use 004010 and 997. If your partner requires 005010, check their implementation guide to see whether they expect a 997 or a 999.

How quickly do I have to send a 997 after receiving a transaction?

Timing varies by trading partner. Walmart requires a 997 within 4 hours. Amazon Vendor Central expects one within 2 hours. Target allows up to 24 hours. In practice, modern EDI translators generate and return a 997 within seconds of parsing an inbound file. If your system cannot do that, batching 997s every 30 minutes is generally safe. Anything slower risks the partner assuming the transmission failed.

Can a 997 acknowledge multiple transactions in one document?

Yes. A single 997 can contain multiple AK1/AK2/AK5 blocks, one for each functional group received. Each AK2 block corresponds to one transaction set (one 850, one 810, etc.). The AK9 segment at the end of each AK1 block summarizes how many transactions were in the group and how many were accepted.

What is error "invalid request (m997)"?

This is not an X12 code. There is no AK403 or AK304 value that produces "m997," and the 997 standard has no concept of an "invalid request" status. It is a vendor-specific application error, and the string appears in a few different EDI portals and middleware products where "m" prefixes a message number. Check the error catalog for the specific product raising it. In most cases it means the request envelope reached the application layer but failed an authentication or entitlement check before any EDI parsing happened, so the file itself is usually fine.

Why am I not getting a 997 back for my 850?

Check ISA14 on your outbound interchange first. If it is set to 0, you did not request an acknowledgment and many partners will not send one. After that, confirm the partner has functional acknowledgments enabled for your ISA qualifier and ID pair, confirm your GS08 version matches what they mapped, and check whether they return a 999 rather than a 997. VAN mailbox routing is the last place to look, since the acknowledgment can arrive at the mailbox and never reach your translator.

What counts as a duplicate 997?

Two acknowledgments that match the same GS06 group control number and ST02 transaction set control number. Matching on the transaction set control number alone will report false duplicates as soon as your partner's counter rolls over, which on a four digit counter happens every 9,999 transactions. Duplicates are normally harmless and come from a partner re-running a batch.

Should I send a 997 for a 997 I receive?

Technically yes, though most implementations do not bother. The X12 spec treats a 997 like any other inbound transaction, meaning it should get its own acknowledgment. In practice, most trading partners disable 997-of-997 to avoid infinite loops. Check your partner's implementation guide. If they do not mention it, skip it.

Need Help?

Try our free EDI inspector to validate your 997 functional acknowledgments or contact our team for automated 997 implementation support.

James Darby
Last updated: 8/4/2026

How to Answer "Are You EDI Capable?"

A buyer asked, and you need to answer this week. The four things they are checking, what you can say yes to today, and a realistic date for the rest.

  • What a buyer is really asking when they ask this
  • The minimum set-up that makes the answer yes
  • What you can answer today versus what needs building
  • Rough timelines, so you can give a date rather than a maybe

One email with the download. Unsubscribe any time.

Related Resources