856 in Python
Receive and parse an EDI 856 ASN in Python
Quick answer
Can I poll instead of webhooks?
Inbound ASN flow
When a partner sends an 856, SignalEDI validates structure against the partner profile and emits a webhook with normalized JSON. Your Python handler verifies the signature, idempotently processes the payload, and updates inventory or fulfillment state.
- document.received for new ASNs
- document.partner_ack when retailers return 997 status on your outbound traffic
- HL hierarchy already flattened to lines and carton context where applicable
Webhook verification in Python
Always verify X-SignalEDI-Signature and X-SignalEDI-Delivery-ID before side effects. Replay protection belongs in your handler, not in ad-hoc scripts.
import os
import hmac
import hashlib
def verify_signaledi_webhook(raw_body: str, signature: str, timestamp: str, secret: str) -> bool:
provided = signature.removeprefix("sha256=").lower()
expected = hmac.new(
secret.encode(),
f"{timestamp}.{raw_body}".encode(),
hashlib.sha256,
).hexdigest()
return hmac.compare_digest(provided, expected)
# Example document.received payload (abbreviated)
# {
# "event": "document.received",
# "documentTypeCode": "856",
# "payload": {
# "shipmentId": "SHIP-4421",
# "shipDate": "2025-06-09",
# "lines": [{"sku": "SKU-100", "quantityShipped": 24}]
# }
# }Retailer timing matters more than syntax
Major retailers score ASN latency and hierarchy accuracy — read retailer requirement guides alongside this tutorial. A valid 856 sent after the carrier window still triggers chargebacks.
- BSN ship date and shipment ID anchor retailer reconciliation
- SSCC and HL nesting must match physical cartons
- See /blog/walmart-edi-requirements and /blog/target-edi-requirements
FAQ
Common questions
Webhooks are recommended for production. The developer dashboard shows document status if you need manual inspection during certification.
See /documents/856, /edi/x12/segment/BSN, and /edi/x12/segment/HL for X12 context.