Transports
The same pipeline — dedup → validate → translate → queue → acknowledge — runs behind every transport, so a partner can move between them without any code changes.HTTP API
The direct path.POST /v1/edi/inbound takes X12 or EDIFACT (auto-detected) and returns the
997/CONTRL plus parsed JSON. Outbound endpoints take StateSet-shaped JSON and return wire
format:
File / VAN directory
SetEDI_INBOUND_DIR and EDI_OUTBOUND_DIR to directories served by your SFTP server or
synced from a VAN. The worker picks up .edi, .x12, and .txt files, writes
*.997.edi / *.ta1.edi responses, and moves consumed files to processed/ — or to
failed/ with an .error.txt. Nothing is ever consumed silently.
Files modified within the last EDI_SETTLE_SECONDS (default 2) are skipped, so an upload
still in flight is never read half-written.
A pickup holding several concatenated
ISA..IEA interchanges — the classic VAN batch shape —
is split and each interchange processed independently. Acks get a .N infix
(batch.1.997.edi), and one bad interchange quarantines the file with a note naming it while
its siblings still process. This applies to all three file transports: directory, SFTP, and
VAN mailbox.Native SFTP mailbox
When the partner or VAN hosts the mailbox, the gateway connects out as an SFTP client (pure-Rustrussh, no OpenSSL). It polls the remote inbound directory, processes each file,
writes the 997/TA1 to the remote outbound directory, and moves sources into
processed/ / failed/.
AS2 (EDI over HTTP, with receipts)
AS2 answers what file transport can’t: did the partner receive this document, intact? The gateway computes a MIC (message integrity check) over what it sends; the partner returns an MDN echoing a MIC over what they received. A match is cryptographic proof of intact receipt.Receiving
POST /v1/as2 — partners deliver here. The endpoint processes the EDI and returns a
synchronous MDN. Per the AS2 spec it answers 200 OK even when the EDI is rejected; the
disposition inside the MDN carries the verdict. It is unauthenticated by transport design —
partners are identified by AS2 identity and S/MIME signature.
Set EDI_AS2_REQUIRE_VERIFIED_INBOUND (default true) to fail closed: every inbound message
must be signed and verified against the partner’s configured certificate.
Sending with tracked delivery
Dispatching to an AS2 partner records apending delivery and returns immediately. A
background worker (EDI_DELIVERY_POLL_SECONDS, default 60) sends each due delivery, confirms
its MDN, and on failure retries with exponential backoff (1m → 30m). After the attempt cap
it marks the delivery failed and fires a critical alert.
Inspect deliveries at GET /v1/deliveries; re-drive one with
POST /v1/deliveries/{id}/redeliver or all failures with
POST /v1/deliveries/redeliver-bulk. Delivery state is shared via Postgres, so any replica
can drive a delivery.
Synchronous and asynchronous MDNs
mdn_mode: sync(default) confirms the delivery inline from the HTTP response.mdn_mode: asyncparks the deliveryawaiting_mdnand does not retry it until the partner POSTs its MDN toPOST /v1/as2/mdn. That endpoint matches it to the tracked delivery byOriginal-Message-ID, recomputes the MIC from the delivery’s stored payload to verify integrity, and flips it todelivered— orfailedwith an alert. Anawaiting_mdndelivery older thanEDI_MDN_TIMEOUT_HOURS(default 24) is re-driven by the worker.
S/MIME
Pure-Rust RustCrypto. Detached CMSSignedData (multipart/signed, SHA-256 + RSA) for
signing and verification, and CMS EnvelopedData (AES-256-CBC + RSA key transport) for
encryption. Set EDI_AS2_KEY_FILE and EDI_AS2_CERT_FILE plus a partner’s
as2.partner_cert_pem to sign-then-encrypt outbound and decrypt-then-verify inbound.
The MIC is computed over pre-encryption content on both ends, so receipts verify regardless of
encryption.
Rotate the signing/decryption identity without a restart via POST /v1/as2/identity. By
default a rotation is replica-local; set EDI_AS2_PERSIST_IDENTITY=true to persist it to the
state backend so it survives restarts and reaches all replicas — at the cost of putting key
PEM in the database or data directory.
AS1 (EDI over email)
Partners who exchange EDI by email are served over AS1. Set a partner’sas1.partner_email
and every outbound document is delivered as an application/edi-x12 attachment via the
stateset-mail connector — best-effort, never blocking the API
response. Inbound AS1 arrives at POST /v1/as1/inbound, where the mail service forwards the
message.
Configure the connector with EDI_MAIL_API_URL, EDI_MAIL_API_KEY, and EDI_MAIL_FROM.
Related
- Configuration — the full environment-variable reference
- Operations — deliveries, reconciliation, and alerting