Introduction Last updated: 2026-09-29

ediFabric Native is a self-contained, high-performance EDI engine compiled ahead-of-time to a native shared library. It converts EDI to JSON (and back), validates transaction sets, and generates acknowledgments — callable from any language with a C foreign-function interface (C, C++, Rust, Go, Python, Node.js, Java/JNA, .NET, …). The target machine needs only the library file.

This page is the reference for developers integrating ediFabric Native: the package, requirements, a quick start, language bindings, licensing, the C API, configuration, error codes, and threading.

  • Fast — native code, zero-copy UTF‑8 buffers, streaming split/merge.
  • Portable — a single native library per platform, no runtime install.
  • Simple ABI — a handful of C entry points returning integer status codes.

Use of this library requires a valid license (see Licensing).

Package

The distribution contains one native library per platform, per EDI standard. X12, including HIPAA, is available today. EDIFACT, NCPDP, HL7 and the other standards are being released one at a time.

The library files for ediFabric Native X12 are:

Platform File
Windows edifabric-x12-tools.dll
Linux edifabric-x12-tools.so
macOS edifabric-x12-tools.dylib

Download

Plus your model files (per transaction set) and a map file that tells the engine where to find them.

Requirements

  • A supported 64-bit OS (Windows / Linux / macOS).
  • Internet access for the license check. Community (set_serial) checks on each operation. Developer (ensure_token) checks when the one-day cache refreshes. Enterprise (set_token) does not call out after the token is set.
  • No .NET, JVM, or other dependency runtime — the library is fully self-contained.

Quick start

  1. Download the library from here. Drop it to the same folder as your executable (or different folder - configure the path in the bindings).
  2. Load the library with your language's FFI.
  3. Authorize with the call for your plan (see Licensing). On Community that is set_serial.
  4. Load the model map once with set_map.
  5. Parse EDI to JSON with parse (or stream with start_split / split).
set_serial(serial)        // Community. Developer: ensure_token. Enterprise: set_token
set_map(mapJson)          // once
parse(edi, mode=1, …)     // EDI → JSON

All strings and payloads cross the boundary as UTF‑8 byte buffers (pointer + length). Every function returns 0 on success or a non-zero error code.

Language bindings and examples

A comprehensive set of bindings and examples per programming language is available in GitHub:

All bindings conform to the C ABI. Follow the same UTF‑8 buffer + grow-and-retry + get_result contracts from any other FFI-capable language.

Licensing

Sign up free for Community and copy the serial from Your account. The same serial covers ediFabric .NET, Native, and Cloud. Community never expires, needs no credit card, and is limited to 250 operations per day for non-production use. One operation is one parse, generate, validate, or acknowledge call, shared across all three products. Past that quota the call returns error 639.

Call one of these before parse or build. Buffers are UTF-8, pointer + length, same as the rest of the ABI.

Plan What works Call this
Community set_serial only. Online check on each operation. 250 operations per day. Non-production. set_serial
Developer set_serial and ensure_token. ensure_token caches the result in the process for 1 day. get_token is not available (error 628). ensure_token
Enterprise set_serial, get_token, and set_token. Offline tokens last 30 days by default, or 90 or 180 days on request. set_token
set_serial(serial)                    // Community: online check

ensure_token(serial, seconds)        // Developer: 1-day cache; pass seconds to refresh early

get_token(serial) → token             // Enterprise, on a host with internet
set_token(token)                      // Enterprise: per process start, no license call

During an Enterprise trial, use set_token. Query get_token_expiration and refresh with get_token before the token expires. Up to 10,000 token requests per day are allowed across .NET and Native. If you exceed the rate, wait 60 seconds (error 636). A seat is one environment: Community leases 3, Developer leases 3, Enterprise is unlimited.

Use of the product is subject to the EULA. Upgrading is a serial-key swap; then switch to the call in the table.

Entry point Signature Purpose
ensure_token int ensure_token(byte* serial, int len, int seconds) Cache a token for this process.
get_token int get_token(byte* serial, int len, byte* out, int cap, int* outLen) Fetch a signed token (grow-and-retry).
set_token int set_token(byte* token, int len) Cache a token for this process.
validate_token int validate_token(byte* token, int len) Validate a token without caching.
get_token_expiration int get_token_expiration(long* expUtc) Token expiry (UTC ticks; 0 = none).
set_serial int set_serial(byte* serial, int len) Cache a serial for runtime auth.
get_app_version int get_app_version(int* version) Library application version.

API reference

Conventions used by every function:

  • Returns int: 0 = success, non-zero = error code.
  • Inputs are UTF‑8 byte* + int length.
  • Output functions use grow-and-retry: if the buffer is too small the call returns 1 (InsufficientCapacity) and writes the required size into the length out-parameter; reallocate and call again.
  • Exceptions never cross the boundary.

Model

int set_map(byte* map, int mapLength);

Loads the template map that resolves EDI transaction sets to model files. Call once before any parse/split. Cached until replaced.

Parse

int parse(byte* input, int inputLength,
          int mode,
          byte* config, int configLength,
          byte* output, int outputCapacity,
          int* outputLength, int* outputOffset);

Parses a whole interchange in one call.

  • mode — see operation modes.
  • config — optional ParseConfig JSON (null allowed).
  • Output = transaction-set JSON, followed by validation/ACK JSON when mode ≥ 2:
    • *outputOffset = start of the errors/ACK section (0 when mode == 1).
    • *outputLength = total bytes written.

Split (streaming)

int start_split(byte* input, int inputLength, int mode, byte* config, int configLength);
int split(int* resultSize, int* resultOffset, byte* last);

Streams one transaction set at a time (low, flat memory use for large files).

  • config must include a split section with a segment_id.
  • Call split repeatedly; for each step with *resultSize > 0, fetch the payload with get_result. *last == 1 marks the final result.

Build

int build(byte* input, int inputLength,
          void* postfix,
          byte* output, int outputCapacity, int* outputLength);

Builds an X12 EDI string from transaction-set JSON. postfix is an optional null-terminated string appended after each segment terminator (e.g. "\r\n"); pass null for compact output. Grow-and-retry as with parse.

Merge (streaming)

int start_merge(byte* input, int inputLength);
int merge(int* resultSize);

Streams X12 segments from a full interchange JSON document. Each merge returns one segment (fetch with get_result); *resultSize == 0 ends the stream.

Results & errors

int    get_result(byte* buffer, int bufferSize);   // copy the last split/merge result
void*  get_error(int errorCode);                    // null-terminated message string
  • get_result — bufferSize must equal the resultSize returned by the preceding split/merge call. The internal buffer is consumed on success.
  • get_error — returns a human-readable message. The caller must free the returned string (free / Marshal.FreeHGlobal).

Logging & lifecycle

int init_logger(byte* pathUtf8, int pathLen, int minLevel);  // 0=Trace..4=Error
int shutdown_logger();
int clear_cache();   // reset model, split/merge state, results, license, logger

Operation modes

mode Output
1 JSON only
2 JSON + validation error report
3 JSON + validation report + acknowledgment (999/997/TA1)

Any other value returns IncorrectMode (616).

Configuration JSON

All JSON uses snake_case keys and is case-insensitive.

Template map (set_map)

Map keys are message:version. type: 1 loads the model from a local file at location/name. Set default to fall back to the online service for unmapped transaction sets. The value for default must be your serial key.

{
  "default": null,
  "maps": {
    "837:005010X222A1": { "type": 1, "name": "837P.json", "location": "/opt/models" },
    "834:005010X220A1": { "type": 1, "name": "834.json",  "location": "/opt/models" }
  }
}

Models

All X12 transactions, such as 837P, 834, 850, etc. are represented as proprietary JSON. Download a standard model from EdiNation Spec Library, or a custom model from EdiNation Spec Builder. You create/modify models in OpenEDI format, upload them in EdiNation Spec Builder and download them as JSON for use in ediFabric Native.

To download a model in either EdiNation Spec Library or EdiNation Spec Builder, select the model first, then in the JSON view select the Download button in the top right corner:

model

Choose to download as ediFabric Native.

ParseConfig (parse)

{
  "validate": { "regex": null, "date_format": null, "time_format": null,
                "skip_seq_count": false, "skip_hl_seq": false,
                "snip_level": 0, "max_errors": 0 },
  "ack":      { "supress_ta1": false, "ak901p": false,
                "gen_for_valid": false, "gen997": false }
}
  • validate — applied when mode ≥ 2; snip_level is 1–4.
  • ack — applied when mode == 3.

All sections are optional for parse.

SplitConfig (start_split)

{
  "split":    { "segment_id": "ST", "segment_depth": 0, "loop_id": null }
}
  • split — required for start_split; 

Splitting is possible for the following boundaries:

  • ST - splits by transaction for files that contain batches of transactions.
  • Repeating loop - for files that contain batches of loops, such as order lines, claims or benefit enrollments.

The splitter must be configured as follows:

  • segment_id  — the name of the segment to split by. It must be either ST or the first segment in the repeatable loop (Mandatory).
  • segment_depth — the depth of the segment in the model hierarchy (Mandatory).
  • loop_id — the name of the loop for the segment specified in segment_id (Optional).

The values for the splitter can be found in EdiNation by loading a sample file. For example, if you want to split by loop 2000A in 837P, load an 837P file in EdiNation (or use the example one), click on the first segment in that loop, e.g., HL. segment_id is CODE,  loop_id is the last item in PATH, and segment_depth is DEPTH.

The easiest way to get the splitter configuration is to click on the copy button under SPLITTER that has the full splitter JSON pre-configured.

NOTE: If a segment does not show a SPLITTER copy button, than splitting is not possible by that segment.

splitter

Error codes

0 = success. Envelope/segment/element codes originate from the validation engine; the library-level codes are:

Code Meaning
1 Output buffer too small — retry with the returned required size.
501 Unknown.
502 No internet access to the authentication API.
503 Local map file has invalid paths or file names.
611 Incorrect/empty input.
612 Logger initialization error.
613 Map JSON deserialization failed.
614 Incorrect (negative) output capacity.
615 Model map not set (call set_map first).
616 Incorrect mode (must be 1–3).
617 No JSON produced.
618 Validation result unavailable.
619 Validation report serialization failed.
620 Incorrect token.
621 Config JSON deserialization failed.
622 Split segment_id missing/empty.
623 split called before start_split.
624 No result available for get_result.
625 get_result buffer size mismatch.
626 merge called before start_merge.
627 Incorrect/null output pointer.
628 Incorrect serial.
629 License not installed (run install_license).
630 Application maximum version exceeded.
631 Token expired.
632 Token missing.
633 Maximum licenses exceeded.
634 License snapshot not found.
635 License not set (call set_token, ensure_token, or set_serial).
636 Token request rate exceeded. Wait 60 seconds.
638 The operation is not supported by your license.
639 Community daily quota exceeded (250 operations). Upgrade to continue.

Call get_error(code) at runtime for the descriptive message.

Threading model

The library holds process-global state (loaded map, active split reader, active merge writer, last result, license) protected by an internal lock.

  • parse and build are one-shot and independent per call.
  • start_split/split/get_result and start_merge/merge/get_result are stateful sequences: run each sequence to completion without interleaving it with another split/merge on another thread. Serialize these sequences in your application.

Support

Questions, licensing, and model files: support@edifabric.com