Everything you need to work with EDI X12 files

One compact library that parses, validates, acknowledges, and rebuilds EDI — at native speed.
Native performance

Compiled to native code with zero-copy UTF-8 buffers and streaming split/merge for high-throughput EDI processing.

Zero dependencies

A single self-contained shared library per platform. No .NET runtime, JVM, or install step needed on the target machine.

EDI ↔ JSON conversion

Parse a whole X12 interchange to transaction-set JSON in one call with parse, and build it back to X12 with build.

Streaming split & merge

Process one transaction set or segment at a time with flat, low memory use — ideal for very large interchange files.

Built-in validation

Validate transaction sets with configurable SNIP levels, regex, date/time formats, and error limits, for a detailed report.

Acknowledgments

Automatically generate 999, 997, and TA1 acknowledgments from validated interchanges in a single operation mode.

Parse EDI in a few lines

The same UTF-8 buffer, grow-and-retry, and status-code contract from any FFI-capable language.
import ctypes, json

lib = ctypes.CDLL("./edifabric-x12-tools.so")   # .dll / .dylib on other OSes
lib.parse.restype = ctypes.c_int

def set_map(map_json: str):
    b = map_json.encode("utf-8")
    if lib.set_map(b, len(b)) != 0:
        raise RuntimeError("set_map failed")

def parse(edi: bytes, mode: int = 1) -> str:
    cap = len(edi) * 12
    out_len = ctypes.c_int(0); out_off = ctypes.c_int(0)
    while True:
        out = ctypes.create_string_buffer(cap)
        rc = lib.parse(edi, len(edi), mode, None, 0, out, cap,
                       ctypes.byref(out_len), ctypes.byref(out_off))
        if rc == 1:                     # InsufficientCapacity — grow & retry
            cap = out_len.value; continue
        if rc != 0:
            raise RuntimeError(f"parse failed: {rc}")
        return out.raw[:out_len.value].decode("utf-8")
// P/Invoke into the native library
[DllImport("edifabric-x12-tools", EntryPoint = "parse")]
static extern unsafe int Parse(byte* input, int inputLen, int mode,
                               byte* config, int configLen,
                               byte* output, int outputCap,
                               int* outputLen, int* outputOffset);

static unsafe string Parse(byte[] edi, int mode = 1)
{
    int cap = edi.Length * 12, len, off;
    while (true)
    {
        var outBuf = new byte[cap];
        fixed (byte* pIn = edi, pOut = outBuf)
        {
            int rc = Parse(pIn, edi.Length, mode, null, 0,
                          pOut, cap, &len, &off);
            if (rc == 1) { cap = len; continue; }   // grow & retry
            if (rc != 0) throw new Exception($"parse failed: {rc}");
            return Encoding.UTF8.GetString(outBuf, 0, len);
        }
    }
}
/* Declare the entry points exported by the native library */
extern int  set_map(const unsigned char* map, int len);
extern int  parse(const unsigned char* in, int inLen, int mode,
                  const unsigned char* cfg, int cfgLen,
                  unsigned char* out, int cap, int* outLen, int* outOff);
extern void* get_error(int code);

/* EDI -> JSON, growing the buffer once if it is too small */
int edi_to_json(const unsigned char* edi, int ediLen,
                unsigned char** out, int* outLen) {
    int cap = ediLen * 12, off = 0;
    *out = malloc(cap);
    int rc = parse(edi, ediLen, 1, NULL, 0, *out, cap, outLen, &off);
    if (rc == 1) {                     /* InsufficientCapacity */
        *out = realloc(*out, *outLen);
        rc = parse(edi, ediLen, 1, NULL, 0, *out, *outLen, outLen, &off);
    }
    return rc;                          /* 0 = success */
}
Language-agnostic ABI

A handful of C entry points returning integer status codes — call it from C, C++, Rust, Go, Python, Node.js, or Java/JNA.

Flexible licensing

Choose offline tokens for containers and air-gapped, high-volume workloads, or simple online serial validation.

Configurable models

Map any transaction set (837P, 834, 850, …) to model files with a single JSON map, or fall back to the online spec service.

Start converting EDI X12 today

Drop the native library into your project, authorize with a token or serial, and parse your first interchange in minutes.