What is X12 Passthrough?
X12 Passthrough provides direct access to raw EDI documents. Orderful acts as a network transport layer without modifying your EDI content:
- Full EDI Fidelity: No transformation or mapping by Orderful
- Existing Infrastructure: Connect your current EDI translator
- Complete Control: You manage all EDI formatting and compliance
- Legacy Integration: Bridge legacy systems to modern trading partners
- Translator Independence: Works with Sterling, Gentran, TrustedLink, etc.
When to Use X12 Passthrough
Choose X12 Passthrough when:
- ✅ You have an existing EDI translator or VAN infrastructure
- ✅ You need to maintain exact EDI format control
- ✅ You're integrating legacy systems that only speak X12
- ✅ Your organization has dedicated EDI specialists
- ✅ You need to preserve custom EDI implementations
- ✅ Migration from another VAN or EDI provider
Tip: For new integrations, consider Mosaic or OrderfulJSON which provide easier development experiences.
Prerequisites
Before starting, ensure you have:
- Completed the Quick Start Guide
- Your API key from Settings → API Credentials
- Understanding of X12 EDI format (ISA, GS, ST segments)
- EDI translator or mapping software (optional but recommended)
- A test trading partnership configured
Architecture Overview
┌─────────────────┐ ┌─────────────┐ ┌──────────────────┐
│ Trading Partner │────▶│ Orderful │────▶│ Your System │
│ (Sends X12) │ │ (Pass Thru)│ │ (Gets X12) │
└─────────────────┘ └─────────────┘ └──────────────────┘
│ │ │
│ Raw X12 850 │ │
│─────────────────────▶│ │
│ │ Webhook/Poll │
│ │ Raw X12 │
│ │────────────────────▶│
│ │ │
│ Raw X12 855 │ │
│◀─────────────────────│ POST Raw X12 │
│ │◀────────────────────│
│ │ (No Transform) │
X12 EDI Structure
Raw X12 EDI follows a hierarchical envelope structure:
ISA (Interchange Control Header)
GS (Functional Group Header)
ST (Transaction Set Header)
[Transaction-specific segments]
SE (Transaction Set Trailer)
GE (Functional Group Trailer)
IEA (Interchange Control Trailer)
Key Characteristics
- Segment Terminator:
~(tilde) - Element Separator:
*(asterisk) - Sub-element Separator:
:(colon) or>(greater than) - Line Breaks: Not required (entire file can be one line)
Step 1: Receiving Inbound X12 Transactions
Option A: Webhooks (Recommended)
Configure webhooks in Settings → Webhooks:
Webhook Payload:
{
"event": "transaction.created",
"data": {
"transactionId": 12345,
"transactionType": "850",
"direction": "inbound",
"stream": "live",
"contentUrl": "https://api.orderful.com/v3/transactions/12345/content"
}
}Option B: Polling
Poll for new transactions:
curl -X GET "https://api.orderful.com/v3/transactions?direction=inbound&status=new" \
-H "orderful-api-key: YOUR_API_KEY"Step 2: Get Raw X12 Content
Retrieve the raw X12 document:
curl -X GET "https://api.orderful.com/v3/transactions/12345/content" \
-H "orderful-api-key: YOUR_API_KEY" \
-H "Accept: application/edi-x12"Response (850 Purchase Order):
ISA*00* *00* *ZZ*BUYERISAID *ZZ*SELLERISAID *240115*1200*U*00401*000000001*0*T*>~
GS*PO*BUYERISAID*SELLERISAID*20240115*1200*1*X*004010~
ST*850*0001~
BEG*00*SA*PO-2024-001234**20240115~
REF*DP*DEPT-123~
DTM*010*20240125~
N1*BY*Acme Retail Corp*92*ACME001~
N2*Purchasing Department~
N3*123 Retail Way~
N4*Commerce City*CA*90210*US~
N1*ST*Acme Distribution Center #5*92*DC-001~
N3*456 Warehouse Blvd~
N4*Indianapolis*IN*46201*US~
PO1*1*100*EA*24.99**VP*VPN-98765*BP*SKU-12345~
PID*F****Widget Model A - Blue~
PO1*2*50*EA*35.00**VP*VPN-54321*BP*SKU-67890~
PID*F****Widget Model B - Red~
CTT*2~
SE*18*0001~
GE*1*1~
IEA*1*000000001~
Step 3: Parse and Process X12
Using an EDI Translator
If you have an EDI translator:
- Receive raw X12 from Orderful
- Parse using your translator (Sterling, Gentran, etc.)
- Map to your internal format
- Process in your business system
Parsing X12 Programmatically
If parsing manually, follow these steps:
# Example Python parsing logic
def parse_x12(edi_content):
# Split by segment terminator
segments = edi_content.split('~')
parsed = {
'interchange': {},
'groups': [],
'transactions': []
}
for segment in segments:
# Split by element separator
elements = segment.split('*')
segment_id = elements[0]
if segment_id == 'ISA':
parsed['interchange'] = parse_isa(elements)
elif segment_id == 'GS':
parsed['groups'].append(parse_gs(elements))
elif segment_id == 'ST':
parsed['transactions'].append({
'header': parse_st(elements),
'details': []
})
elif segment_id == 'BEG':
# Parse beginning segment
parsed['transactions'][-1]['details'].append({
'segment': 'BEG',
'purpose': elements[1],
'type': elements[2],
'po_number': elements[3],
'date': elements[5]
})
# Add more segment parsing as needed
return parsedStep 4: Confirm Delivery
After successfully processing, approve the delivery:
curl -X POST "https://api.orderful.com/v3/deliveries/67890/approve" \
-H "orderful-api-key: YOUR_API_KEY"Step 5: Send Outbound X12 Transactions
Sending a Purchase Order Acknowledgment (855)
curl -X POST "https://api.orderful.com/v3/transactions" \
-H "orderful-api-key: YOUR_API_KEY" \
-H "Content-Type: application/edi-x12" \
-d 'ISA*00* *00* *ZZ*SELLERISAID *ZZ*BUYERISAID *240116*1430*U*00401*000000002*0*T*>~GS*PR*SELLERISAID*BUYERISAID*20240116*1430*2*X*004010~ST*855*0001~BAK*00*AC*PO-2024-001234*20240115**20240116~REF*DP*DEPT-123~PO1*1*100*EA*24.99**VP*VPN-98765~ACK*IA*100*EA~PO1*2*50*EA*35.00**VP*VPN-54321~ACK*IA*50*EA~CTT*2~SE*10*0001~GE*1*2~IEA*1*000000002~'Formatted 855 (for readability):
ISA*00* *00* *ZZ*SELLERISAID *ZZ*BUYERISAID *240116*1430*U*00401*000000002*0*T*>~
GS*PR*SELLERISAID*BUYERISAID*20240116*1430*2*X*004010~
ST*855*0001~
BAK*00*AC*PO-2024-001234*20240115**20240116~
REF*DP*DEPT-123~
PO1*1*100*EA*24.99**VP*VPN-98765~
ACK*IA*100*EA~
PO1*2*50*EA*35.00**VP*VPN-54321~
ACK*IA*50*EA~
CTT*2~
SE*10*0001~
GE*1*2~
IEA*1*000000002~
Sending an Advance Ship Notice (856)
curl -X POST "https://api.orderful.com/v3/transactions" \
-H "orderful-api-key: YOUR_API_KEY" \
-H "Content-Type: application/edi-x12" \
--data-binary @shipment.ediSample 856 Content (shipment.edi):
ISA*00* *00* *ZZ*SELLERISAID *ZZ*BUYERISAID *240120*1430*U*00401*000000003*0*T*>~
GS*SH*SELLERISAID*BUYERISAID*20240120*1430*3*X*004010~
ST*856*0001~
BSN*00*SHIP-2024-001*20240120*1430~
DTM*011*20240125~
HL*1**S~
TD5*O*2*FFRT***M~
TD3*TL~
REF*CN*1Z999AA10123456784~
REF*BM*BOL-2024-001~
N1*SF*Your Warehouse~
N3*789 Shipping Lane~
N4*Warehouse City*TX*75001*US~
HL*2*1*O~
PRF*PO-2024-001234~
HL*3*2*P~
MAN*GM*00012345678901234567~
MEA*PD*G*25.5*LB~
HL*4*3*I~
LIN**VP*VPN-98765~
SN1**100*EA~
CTT*1~
SE*22*0001~
GE*1*3~
IEA*1*000000003~
Sending an Invoice (810)
curl -X POST "https://api.orderful.com/v3/transactions" \
-H "orderful-api-key: YOUR_API_KEY" \
-H "Content-Type: application/edi-x12" \
--data-binary @invoice.ediSample 810 Content (invoice.edi):
ISA*00* *00* *ZZ*SELLERISAID *ZZ*BUYERISAID *240120*1430*U*00401*000000004*0*T*>~
GS*IN*SELLERISAID*BUYERISAID*20240120*1430*4*X*004010~
ST*810*0001~
BIG*20240120*INV-2024-001234**PO-2024-001234~
REF*DP*DEPT-123~
N1*ST*Acme Distribution Center #5~
N3*456 Warehouse Blvd~
N4*Indianapolis*IN*46201~
ITD*01*3*****30**NET30~
IT1*1*100*EA*25.00**VP*VPN-98765*BP*SKU-12345~
PID*F****Widget Model A - Blue~
IT1*2*50*EA*35.00**VP*VPN-54321*BP*SKU-67890~
PID*F****Widget Model B - Red~
TDS*425000~
TXI*ST*34000~
CTT*2~
SE*16*0001~
GE*1*4~
IEA*1*000000004~
X12 Segment Reference
Interchange Control Header (ISA)
ISA*00* *00* *ZZ*SENDERISAID *ZZ*RECEIVERISAID *YYMMDD*HHMM*U*00401*000000001*0*T*>~
| Element | Description | Example |
|---|---|---|
| ISA01 | Authorization Info Qualifier | 00 (No Auth) |
| ISA02 | Authorization Info | 10 spaces |
| ISA03 | Security Info Qualifier | 00 (No Security) |
| ISA04 | Security Info | 10 spaces |
| ISA05 | Sender ID Qualifier | ZZ (Mutually Defined) |
| ISA06 | Interchange Sender ID | SENDERISAID (15 chars, padded) |
| ISA07 | Receiver ID Qualifier | ZZ |
| ISA08 | Interchange Receiver ID | RECEIVERISAID (15 chars, padded) |
| ISA09 | Interchange Date | YYMMDD |
| ISA10 | Interchange Time | HHMM |
| ISA11 | Interchange Control Standards | U (US EDI Community) |
| ISA12 | Interchange Control Version | 00401 (4010) |
| ISA13 | Interchange Control Number | 9-digit number |
| ISA14 | Acknowledgment Requested | 0 (No) or 1 (Yes) |
| ISA15 | Usage Indicator | T (Test) or P (Production) |
| ISA16 | Component Element Separator | > |
Functional Group Header (GS)
GS*PO*SENDERISAID*RECEIVERISAID*CCYYMMDD*HHMM*1*X*004010~
| Element | Description | Example |
|---|---|---|
| GS01 | Functional Identifier Code | PO (Purchase Order) |
| GS02 | Application Sender's Code | SENDERISAID |
| GS03 | Application Receiver's Code | RECEIVERISAID |
| GS04 | Date | CCYYMMDD |
| GS05 | Time | HHMM |
| GS06 | Group Control Number | Numeric |
| GS07 | Responsible Agency Code | X (ANSI X12) |
| GS08 | Version/Release/Industry ID | 004010 |
Common Functional Identifier Codes:
PO- Purchase Order (850)PR- Purchase Order Acknowledgment (855)SH- Ship Notice/Manifest (856)IN- Invoice (810)
Transaction Set Header (ST)
ST*850*0001~
| Element | Description |
|---|---|
| ST01 | Transaction Set Identifier Code (850, 855, 856, 810) |
| ST02 | Transaction Set Control Number (must match SE02) |
Control Number Management
ISA Control Numbers (ISA13)
- Must be unique per interchange
- 9 digits, zero-padded (e.g.,
000000001) - Increment for each ISA envelope sent
- IEA02 must match ISA13
GS Control Numbers (GS06)
- Must be unique within an interchange
- Typically numeric (e.g.,
1,2,3) - GE02 must match GS06
ST Control Numbers (ST02)
- Must be unique within a functional group
- Typically 4-digit (e.g.,
0001) - SE02 must match ST02
Example:
ISA*...*000000001*...~ # ISA13 = 000000001
GS*...*1*...~ # GS06 = 1
ST*850*0001~ # ST02 = 0001
...
SE*18*0001~ # SE02 = 0001 (matches ST02)
GE*1*1~ # GE02 = 1 (matches GS06)
IEA*1*000000001~ # IEA02 = 000000001 (matches ISA13)
Best Practices
1. Maintain Proper Enveloping
Every X12 document must have complete envelope structure:
ISA → IEA (Interchange)
└─ GS → GE (Functional Group)
└─ ST → SE (Transaction Set)
2. Use Correct Segment Terminators
- Segment Terminator:
~(ISA16 defines this) - Element Separator:
*(ISA16-1) - Sub-element Separator:
>(ISA16)
Ensure consistency across the entire document.
3. Pad ISA Fields Correctly
ISA fields have fixed lengths and must be space-padded:
ISA*00* *00* *ZZ*SENDERID *ZZ*RECEIVERID *240115*1200*U*00401*000000001*0*T*>~
^^10 spaces^^ ^^10 spaces^^ ^^15 chars^^^ ^^15 chars^^^
4. Handle Test vs Production
Always use correct ISA15 indicator:
T- Test dataP- Production data
Start with test mode (T) and switch to production (P) only after certification.
5. Validate Before Sending
Use EDI validation tools:
- Check segment counts (SE01, GE01, IEA01)
- Verify control numbers match
- Validate required segments are present
- Ensure element data types are correct
6. Store Raw X12
Keep copies of raw X12 for:
- Audit trails
- Partner disputes
- Debugging issues
- Compliance requirements
Testing X12 Transactions
Using Test Mode
Always test with ISA15 = T and stream = test:
curl -X POST "https://api.orderful.com/v3/transactions?stream=test" \
-H "orderful-api-key: YOUR_API_KEY" \
-H "Content-Type: application/edi-x12" \
--data-binary @test-850.ediValidation Tools
Recommended EDI validators:
- Orderful Portal: Built-in X12 validator
- EDI Inspector: Free online validator
- X12 Parser: Open-source validation tools
- Partner Test Environments: Use partner sandbox systems
Common Test Scenarios
- Valid Transaction: Send properly formatted X12
- Missing Required Segment: Omit mandatory segment (e.g., BEG)
- Control Number Mismatch: ST02 ≠ SE02
- Invalid Element: Use wrong data type or length
- Segment Count Error: Incorrect SE01, GE01, or IEA01 values
Error Handling
Transmission Errors
{
"error": {
"code": "INVALID_X12_FORMAT",
"message": "Failed to parse X12 content",
"details": {
"line": 5,
"segment": "BEG",
"issue": "Missing required element BEG05"
}
}
}Common X12 Errors
| Error | Cause | Solution |
|---|---|---|
| Control number mismatch | ST02 ≠ SE02 or GS06 ≠ GE02 | Ensure matching control numbers |
| Invalid segment count | SE01, GE01, or IEA01 incorrect | Count all segments correctly |
| Missing segment terminator | Segments not ending with ~ | Add ~ after each segment |
| ISA padding error | ISA fields not properly padded | Use fixed-length formatting |
| Invalid character | Non-ASCII or special chars | Use only allowed X12 characters |
Functional Acknowledgments (997)
Partners may send 997 acknowledgments confirming receipt:
ISA*00* *00* *ZZ*BUYERISAID *ZZ*SELLERISAID *240116*1500*U*00401*000000005*0*T*>~
GS*FA*BUYERISAID*SELLERISAID*20240116*1500*5*X*004010~
ST*997*0001~
AK1*PO*1~
AK2*850*0001~
AK5*A~
AK9*A*1*1*1~
SE*6*0001~
GE*1*5~
IEA*1*000000005~
AK5 and AK9 Status Codes:
A- AcceptedE- Accepted with errorsR- Rejected
Migration from Other VANs
Transition Strategy
- Parallel Testing: Run both systems simultaneously
- Partner Coordination: Notify partners of migration timeline
- ISA ID Management: May need to update ISA IDs
- Control Number Reset: Start with new control number sequences
- Cutover Plan: Schedule partner-by-partner migration
Data Mapping
If migrating from another VAN:
- Preserve ISA/GS identifiers if possible
- Update Orderful configuration to match partner requirements
- Test thoroughly before cutover
- Keep fallback plan ready
Integration Patterns
Pattern 1: Direct API Integration
import requests
def send_x12_to_orderful(edi_content, api_key):
url = "https://api.orderful.com/v3/transactions"
headers = {
"orderful-api-key": api_key,
"Content-Type": "application/edi-x12"
}
response = requests.post(url, headers=headers, data=edi_content)
return response.json()
# Read X12 from file
with open('outbound-850.edi', 'r') as f:
edi_content = f.read()
# Send to Orderful
result = send_x12_to_orderful(edi_content, "YOUR_API_KEY")
print(f"Transaction ID: {result['id']}")Pattern 2: Batch Processing
#!/bin/bash
# Process all .edi files in outbound directory
API_KEY="YOUR_API_KEY"
OUTBOUND_DIR="/path/to/outbound"
ARCHIVE_DIR="/path/to/archive"
for file in "$OUTBOUND_DIR"/*.edi; do
if [ -f "$file" ]; then
echo "Sending: $file"
response=$(curl -s -X POST "https://api.orderful.com/v3/transactions" \
-H "orderful-api-key: $API_KEY" \
-H "Content-Type: application/edi-x12" \
--data-binary "@$file")
if [ $? -eq 0 ]; then
echo "Success: $response"
mv "$file" "$ARCHIVE_DIR/"
else
echo "Failed: $file"
fi
fi
donePattern 3: Translator Integration
Connect your EDI translator:
- Configure Output: Set translator to output raw X12
- API Integration: Connect translator's API to Orderful
- Inbound Processing: Fetch X12 from Orderful, import to translator
- Monitoring: Set up alerts for failures
Troubleshooting
Debug Mode
Enable verbose logging to see raw X12:
curl -v -X POST "https://api.orderful.com/v3/transactions" \
-H "orderful-api-key: YOUR_API_KEY" \
-H "Content-Type: application/edi-x12" \
--data-binary @debug.edi 2>&1 | tee debug.logValidation Checklist
- ISA envelope complete (ISA → IEA)
- GS envelope complete (GS → GE)
- ST envelope complete (ST → SE)
- Control numbers match (ST02=SE02, GS06=GE02, ISA13=IEA02)
- Segment counts correct (SE01, GE01, IEA01)
- ISA fields properly padded (15 chars for ISA06/08)
- Segment terminator present after each segment
- Element separator consistent (
*) - Required segments present (ST, BEG/BAK/BSN/BIG, SE)
- Test indicator set correctly (ISA15 = T or P)
Security Considerations
Data Protection
- Encryption in Transit: All API calls use HTTPS/TLS
- API Key Security: Never commit API keys to version control
- Access Control: Limit API key permissions
- Audit Logging: Monitor all transaction submissions
Compliance
- PCI DSS: Never include credit card data in X12
- HIPAA: Healthcare data requires Business Associate Agreement
- Data Retention: Follow industry retention requirements
- Partner Agreements: Ensure trading partner agreements are in place
Next Steps
- Integration Patterns - Advanced integration patterns
- Order to Cash Workflow - Complete workflow walkthrough
- Mosaic Integration Guide - Simplified alternative
- OrderfulJSON Guide - JSON with EDI control
- X12 Standards - Official X12 documentation
