Skip to main content
The Emidat API is built so you can drive it with your own identifiers, which are considered external_id in the following. You attach your identifiers when you create writable entities, filter list endpoints by those same codes, and receive them back on every response. Read-only plants and production processes expose the codes configured in the Emidat UI. References between entities in request bodies use the Emidat id (UUID); you obtain each id from the create response or by resolving your code with GET …?external_id=.

Two kinds of identifier

Defining an external_id

external_id is optional. For writable entities, you set it when you create the entity and can change it later through its PUT (see below). It is an arbitrary string you choose — no format rules and no length limit — so your existing ERP codes work as-is. Surrounding whitespace is trimmed, so "ART-1 " and "ART-1" are the same code, and a string that is empty or whitespace-only is treated as no code at all, exactly like null, rather than rejected. Plant and production process codes are managed in the Emidat UI instead. Within your manufacturer an external_id is unique among active entities of a given type. It is descriptive only — not an idempotency key. Creating another entity of the same type with a code that already exists is rejected with 409 (see idempotency below).

Changing an external_id

Every writable entity that carries an external_id lets you change it through its PUT endpoint. Plants and production processes are read-only in API v2, so their external_id must be changed in the Emidat UI. PUT is a full replacement of editable fields, so send external_id on every update, carrying either the code you want or the entity’s current one. Passing null clears the code. Immutable parent and type fields may be omitted or echoed from the current resource; a different value returns 422. Uniqueness is re-checked on update. A code held by another active entity of the same type is rejected with 409 err_external_id_exists; re-sending the entity’s own current code is not a conflict and succeeds unchanged. Three consequences worth planning for:
  • The old code stops resolvingGET …?external_id=OLD-CODE returns an empty page.
  • The freed code becomes available again to another entity of the same type.
  • References are unaffected. Other entities point at this one by its Emidat UUID, never by your code, so no BOM entry or *_id field needs updating.

Addressing an entity

One rule, applied to every entity:
  • A path parameter is always the Emidat UUIDGET /v2/product-instances/{id} returns that one instance, or 404.
  • Your external_id is a filter on the collectionGET /v2/product-instances?external_id=SKU-12345 returns a page whose data holds the single instance carrying that code, or is empty if none does. The filter is optional: omitting it lists every instance you can access, one page at a time. See Pagination.
Because uniqueness makes the filtered result at most one item, a code lookup and a full listing are the same endpoint — you never need a separate call shape for the two.

Idempotent creation

external_id is not an idempotency key — idempotency comes solely from the Idempotency-Key header. Idempotency-Key header. Generate a unique key (e.g. a UUID) per logical create and send it as Idempotency-Key: <key>. A replay carrying the same key returns the original response unchanged (200). Reusing a key with a different request body is rejected with 409. Keys are scoped to your manufacturer and retained for 6 hours; after that a replay is treated as a new create. So the status tells you what happened: 201 = created, 200 = a key replay returned the original entity. The request body is not re-applied on a 200 — to change an entity, use its PUT endpoint. Because external_id is unique per type, a POST carrying an external_id that already exists is rejected with 409 — it is never silently deduplicated.

Referencing other entities

When a request body points at another entity, you reference it by its Emidat id (UUID) — never by your own code. There are two ways to obtain that UUID:
  • For an entity you just created this run, use the id from its create response (the create response always returns it).
  • For an entity you don’t already have the UUID for, resolve it first with GET …?external_id=YOUR-CODE, whose data holds at most one item with its id. This works only for entities that have an external_id; one created without a code can be referenced only via the id returned by its create response, or by walking the unfiltered list.
Then use that id wherever a reference is needed — for example as a BOM entry’s ref: