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.
Generic 997 Functional Acknowledgment
Positive acknowledgment confirming receipt of an 850 PO
Raw EDI (X12)
Human-Readable
Interchange
Functional Group
Transaction 997
Functional AcknowledgmentAcknowledged Group
Transaction Responses (1)
Acknowledgment Summary
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:
| Code | Meaning | Description |
|---|---|---|
| A | Accepted | Transaction is valid and accepted |
| E | Accepted with Errors | Minor errors, but transaction was processed |
| M | Rejected, Message Authentication Code Failed | Security issue |
| P | Partially Accepted | Some parts valid, some rejected |
| R | Rejected | Transaction is invalid and rejected |
| W | Rejected, Assurance Failed | Security/authentication failed |
| X | Rejected, Content After Decryption Could Not Be Analyzed | Encryption 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.
| Code | Meaning | What it usually means in practice |
|---|---|---|
| 1 | Unrecognized segment ID | The segment does not exist in the version you declared in GS08 |
| 2 | Unexpected segment | Valid segment, wrong place in the transaction set |
| 3 | Mandatory segment missing | A required segment was never sent |
| 4 | Loop occurs over maximum times | Too many repeats of a loop, for example more N1 loops than the spec allows |
| 5 | Segment exceeds maximum use | The segment repeated more times than its own max use permits |
| 6 | Segment not in defined transaction set | The segment belongs to X12 but not to this transaction set |
| 7 | Segment not in proper sequence | Correct segment, correct loop, wrong order |
| 8 | Segment has data element errors | The 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
| Code | Meaning | Example |
|---|---|---|
| 1 | Mandatory data element missing | PO102 (quantity) is empty |
| 2 | Conditional required data element missing | If PO103 is EA, then PO102 is required |
| 3 | Too many data elements | Extra elements beyond what's allowed |
| 4 | Data element too short | UPC only has 10 digits instead of 12 |
| 5 | Data element too long | Part number exceeds 30 characters |
| 6 | Invalid character in data element | Letters in a numeric field |
| 7 | Invalid code value | Unit of measure "XX" doesn't exist |
| 8 | Invalid date | DTM00220231132 (no 32nd day) |
| 9 | Invalid time | BSN04*2561 (hour can't be 25) |
| 10 | Exclusion condition violated | Both 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:
- PO1 segment (line item 5) is missing the quantity
- 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.
| Cause | How to confirm | Fix |
|---|---|---|
| Partner never enabled FA return | Their implementation guide lists 997 as optional or inbound only | Ask them to turn on functional acknowledgments for your ISA ID |
| ISA14 set to 0 | Check ISA14 on your outbound file | Set ISA14 to 1 to request an acknowledgment |
| GS08 version mismatch | Your GS08 does not match what the partner has mapped | Align GS08 with their guide, usually 004010 or 005010 |
| They send a 999, not a 997 | Their guide references IK3/IK4 segments | Configure your translator to accept 999 |
| VAN routing gap | The 997 reaches your VAN mailbox but never your translator | Check mailbox routing rules and the VAN audit trail |
| Wrong ISA receiver on the return | Partner is sending to an ISA ID you retired | Confirm 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:
| Column | Definition |
|---|---|
| Total rows | Outbound transaction sets in the period |
| Accepted | AK501 of A or E |
| Rejected | AK501 of R, M, W, or X |
| Partially accepted | AK901 of P at the group level |
| Missing 997 | No acknowledgment received inside the partner's stated window |
| Late acks | Acknowledgment received after the window but before the next cycle |
| Duplicate acks | More 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 Acknowledgment | 999 Implementation Acknowledgment | |
|---|---|---|
| Introduced in | 004010 and earlier | 005010 |
| Syntax error segments | AK3 and AK4 | IK3 and IK4 |
| Verdict segment | AK5 | IK5 |
| Group trailer | AK9 | AK9 |
| Reports guide violations | No, syntax only | Yes, via IK3 and CTX context segments |
| Typical use | Retail, most 004010 partners | Healthcare 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
- 850 Purchase Order - Needs 997 acknowledgment
- 856 Ship Notice - Needs 997 acknowledgment
- 810 Invoice - Needs 997 acknowledgment
- 855 Purchase Order Acknowledgment - Business-level acceptance
Compliance Requirements
Most trading partners require:
| Partner | 997 Timing | Rejection Requirements |
|---|---|---|
| Walmart | Within 4 hours | Must include error details |
| Target | Within 24 hours | AK3/AK4 segments required |
| Amazon | Within 2 hours | Immediate transmission |
| Home Depot | Within 8 hours | Full 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.