EDI 997 Functional AcknowledgmentPublished Jan 20, 2025 · Updated May 9, 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 997 acknowledging a received 850 Purchase Order:

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
Control Number000000006
Acknowledgment RequestedNo

Functional Group

Functional IDFAFunctional Acknowledgment
SenderBUYER456
ReceiverVENDOR123
Date20231120
Time1431
Control Number6
Transactions1

Transaction 997

Functional Acknowledgment
Transaction Type997
Control Number0006
Segments4
AK1Functional Group Response Header
AK2Transaction Set Response Header
AK5Transaction Set Response Trailer
AK9Functional Group Response Trailer
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."

Error Reporting (AK3 and AK4)

When a transaction is rejected, the 997 should explain why:

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)

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

Common AK403 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"

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

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.

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.

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: 5/9/2026

Related Resources