Docs

Identify & translate

One capability, four faces, one contract: EPCIS 1.1, 1.2 or 2.0 XML in — EPCIS 2.0 JSON-LD out, with a per-job round-trip fidelity report that names every lossy path or certifies there were none. The hosted door, the CLI verb, the MCP tool and the library function run the same engine; pick the face your integration already speaks.

POST /translate

contractvalue
Method, pathPOST https://epcis.dev/translate
Authnone — this door answers with no key and no account
Price classfree
Requestapplication/xml or text/xml: an EPCIS 1.1, 1.2 or 2.0 XML document
200 responseapplication/json: { document, fidelityReport, meteredEvents, sourceSchemaVersion }
Response headersGS1-EPCIS-Version, GS1-CBV-Version, GS1-Extensions, Spine-Translation-Fidelity, Spine-Translation-Lossy-Paths
CLI twinnpx epcis.dev translate <file.xml> [--out f.json]
MCP twintool translate — answers with no key on the apex POST /mcp door and locally over stdio
Library twinimport { translate, TranslationError } from "epcis.dev"

Typed refusals

Errors are RFC 7807 application/problem+json carrying the standard's own epcisException:* types. Match on type, never on prose.

statustypemeaning
400epcisException:ValidationExceptiontranslation failed; the fidelity report and per-path schema errors ride the problem body
413epcisException:CaptureLimitExceededExceptionpayload exceeds the file-size limit
415epcisException:UnsupportedMediaTypeExceptionthis door accepts application/xml or text/xml; POST JSON to /validate or /hash

Proof — run it against the live door

The fixture is EPCIS 1.1 XML, shipped in the npm tarball (node_modules/epcis.dev/golden-corpus/xml-translation/). Executed against the production door:

$ curl -sS -D - -X POST https://epcis.dev/translate \
    -H 'content-type: application/xml' \
    --data-binary @golden-corpus/xml-translation/aggregation-event-1.1.xml \
    -o out.json
HTTP/2 200
gs1-cbv-version: 2.0.1
gs1-epcis-version: 2.0.1
gs1-extensions: spine=https://epcis.dev/ns/spine/v1
spine-translation-fidelity: round-trip-clean
spine-translation-lossy-paths: 0

And the body's receipt:

{
  "sourceSchemaVersion": "1.1",
  "meteredEvents": 1,
  "fidelityReport": {
    "roundTripClean": true,
    "lossyPaths": [],
    "notes": "Clean round-trip: every source value maps to a standard EPCIS 2.0 field."
  }
}

The fidelity report is the door's own honesty mechanism: when a source construct has no clean 2.0 home, roundTripClean goes false and lossyPaths names each path — the door never silently drops data. The expected-output pair for every shipped XML fixture sits beside it as *.expected.json, so you can diff the door against the corpus yourself.

Where the rest of the family is

The dated launch ledger at /what-ships-today/ is authoritative for every door beyond this page. This reference lists exactly the rows that answer, and nothing else.

We answer in writing. We take at most five conversations a month, only when you ask for one, and only after you already have the written read.