curl --request POST \
--url https://api.emidat.com/v2/product-instances \
--header 'Content-Type: application/json' \
--header 'X-API-Key: <api-key>' \
--data '
{
"external_id": "CEM-42.5R-25KG-MUNICH",
"plant_id": "11111111-1111-1111-1111-111111111111",
"name": "CEM 42.5 R, 25 kg bag (Munich)",
"elementary_id": "22222222-2222-2222-2222-222222222222",
"production_process_id": "77777777-7777-7777-7777-777777777777",
"unit": "KG",
"produced_from": 2025,
"produced_to": null,
"tech_specs": {
"compressive_strength": 42.5,
"density": 3100
},
"annual_data": [
{
"year": 2025,
"production_output": 120000,
"economic_value_per_unit": 0.35
}
]
}
'import requests
url = "https://api.emidat.com/v2/product-instances"
payload = {
"external_id": "CEM-42.5R-25KG-MUNICH",
"plant_id": "11111111-1111-1111-1111-111111111111",
"name": "CEM 42.5 R, 25 kg bag (Munich)",
"elementary_id": "22222222-2222-2222-2222-222222222222",
"production_process_id": "77777777-7777-7777-7777-777777777777",
"unit": "KG",
"produced_from": 2025,
"produced_to": None,
"tech_specs": {
"compressive_strength": 42.5,
"density": 3100
},
"annual_data": [
{
"year": 2025,
"production_output": 120000,
"economic_value_per_unit": 0.35
}
]
}
headers = {
"X-API-Key": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'X-API-Key': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
external_id: 'CEM-42.5R-25KG-MUNICH',
plant_id: '11111111-1111-1111-1111-111111111111',
name: 'CEM 42.5 R, 25 kg bag (Munich)',
elementary_id: '22222222-2222-2222-2222-222222222222',
production_process_id: '77777777-7777-7777-7777-777777777777',
unit: 'KG',
produced_from: 2025,
produced_to: null,
tech_specs: {compressive_strength: 42.5, density: 3100},
annual_data: [{year: 2025, production_output: 120000, economic_value_per_unit: 0.35}]
})
};
fetch('https://api.emidat.com/v2/product-instances', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.emidat.com/v2/product-instances",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'external_id' => 'CEM-42.5R-25KG-MUNICH',
'plant_id' => '11111111-1111-1111-1111-111111111111',
'name' => 'CEM 42.5 R, 25 kg bag (Munich)',
'elementary_id' => '22222222-2222-2222-2222-222222222222',
'production_process_id' => '77777777-7777-7777-7777-777777777777',
'unit' => 'KG',
'produced_from' => 2025,
'produced_to' => null,
'tech_specs' => [
'compressive_strength' => 42.5,
'density' => 3100
],
'annual_data' => [
[
'year' => 2025,
'production_output' => 120000,
'economic_value_per_unit' => 0.35
]
]
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"X-API-Key: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.emidat.com/v2/product-instances"
payload := strings.NewReader("{\n \"external_id\": \"CEM-42.5R-25KG-MUNICH\",\n \"plant_id\": \"11111111-1111-1111-1111-111111111111\",\n \"name\": \"CEM 42.5 R, 25 kg bag (Munich)\",\n \"elementary_id\": \"22222222-2222-2222-2222-222222222222\",\n \"production_process_id\": \"77777777-7777-7777-7777-777777777777\",\n \"unit\": \"KG\",\n \"produced_from\": 2025,\n \"produced_to\": null,\n \"tech_specs\": {\n \"compressive_strength\": 42.5,\n \"density\": 3100\n },\n \"annual_data\": [\n {\n \"year\": 2025,\n \"production_output\": 120000,\n \"economic_value_per_unit\": 0.35\n }\n ]\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("X-API-Key", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.emidat.com/v2/product-instances")
.header("X-API-Key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"external_id\": \"CEM-42.5R-25KG-MUNICH\",\n \"plant_id\": \"11111111-1111-1111-1111-111111111111\",\n \"name\": \"CEM 42.5 R, 25 kg bag (Munich)\",\n \"elementary_id\": \"22222222-2222-2222-2222-222222222222\",\n \"production_process_id\": \"77777777-7777-7777-7777-777777777777\",\n \"unit\": \"KG\",\n \"produced_from\": 2025,\n \"produced_to\": null,\n \"tech_specs\": {\n \"compressive_strength\": 42.5,\n \"density\": 3100\n },\n \"annual_data\": [\n {\n \"year\": 2025,\n \"production_output\": 120000,\n \"economic_value_per_unit\": 0.35\n }\n ]\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.emidat.com/v2/product-instances")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["X-API-Key"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"external_id\": \"CEM-42.5R-25KG-MUNICH\",\n \"plant_id\": \"11111111-1111-1111-1111-111111111111\",\n \"name\": \"CEM 42.5 R, 25 kg bag (Munich)\",\n \"elementary_id\": \"22222222-2222-2222-2222-222222222222\",\n \"production_process_id\": \"77777777-7777-7777-7777-777777777777\",\n \"unit\": \"KG\",\n \"produced_from\": 2025,\n \"produced_to\": null,\n \"tech_specs\": {\n \"compressive_strength\": 42.5,\n \"density\": 3100\n },\n \"annual_data\": [\n {\n \"year\": 2025,\n \"production_output\": 120000,\n \"economic_value_per_unit\": 0.35\n }\n ]\n}"
response = http.request(request)
puts response.read_body{
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"external_id": "<string>",
"plant_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"name": "<string>",
"elementary_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"production_process_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"unit": "KG",
"produced_from": 2025,
"produced_to": 123,
"tech_specs": {
"compressive_strength": 42.5,
"density": 3100
},
"annual_data": [
{
"year": 2025,
"production_output": 120000,
"economic_value_per_unit": 1
}
],
"status": "draft",
"created_at": "2023-11-07T05:31:56Z"
}{
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"external_id": "<string>",
"plant_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"name": "<string>",
"elementary_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"production_process_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"unit": "KG",
"produced_from": 2025,
"produced_to": 123,
"tech_specs": {
"compressive_strength": 42.5,
"density": 3100
},
"annual_data": [
{
"year": 2025,
"production_output": 120000,
"economic_value_per_unit": 1
}
],
"status": "draft",
"created_at": "2023-11-07T05:31:56Z"
}{
"msg": "supplier product requires a supplier plant",
"err_code": "err_supplier_product_missing_supplier_plant",
"entitlement_limit": {
"dimension": "users",
"usage": 123,
"limit": 123
}
}{
"msg": "supplier product requires a supplier plant",
"err_code": "err_supplier_product_missing_supplier_plant",
"entitlement_limit": {
"dimension": "users",
"usage": 123,
"limit": 123
}
}{
"msg": "supplier product requires a supplier plant",
"err_code": "err_supplier_product_missing_supplier_plant",
"entitlement_limit": {
"dimension": "users",
"usage": 123,
"limit": 123
}
}{
"msg": "supplier product requires a supplier plant",
"err_code": "err_supplier_product_missing_supplier_plant",
"entitlement_limit": {
"dimension": "users",
"usage": 123,
"limit": 123
}
}{
"msg": "supplier product requires a supplier plant",
"err_code": "err_supplier_product_missing_supplier_plant",
"entitlement_limit": {
"dimension": "users",
"usage": 123,
"limit": 123
}
}Create product instance
Idempotent create — a replay of the same Idempotency-Key returns the
original response (200); otherwise a new product instance is created
(201). Your external_id must be unique: reusing one returns 409. See
External IDs.
annual_data[].production_output and
annual_data[].economic_value_per_unit are
production data: without edit:processes they are ignored rather than
rejected, and the instance is created without them.
curl --request POST \
--url https://api.emidat.com/v2/product-instances \
--header 'Content-Type: application/json' \
--header 'X-API-Key: <api-key>' \
--data '
{
"external_id": "CEM-42.5R-25KG-MUNICH",
"plant_id": "11111111-1111-1111-1111-111111111111",
"name": "CEM 42.5 R, 25 kg bag (Munich)",
"elementary_id": "22222222-2222-2222-2222-222222222222",
"production_process_id": "77777777-7777-7777-7777-777777777777",
"unit": "KG",
"produced_from": 2025,
"produced_to": null,
"tech_specs": {
"compressive_strength": 42.5,
"density": 3100
},
"annual_data": [
{
"year": 2025,
"production_output": 120000,
"economic_value_per_unit": 0.35
}
]
}
'import requests
url = "https://api.emidat.com/v2/product-instances"
payload = {
"external_id": "CEM-42.5R-25KG-MUNICH",
"plant_id": "11111111-1111-1111-1111-111111111111",
"name": "CEM 42.5 R, 25 kg bag (Munich)",
"elementary_id": "22222222-2222-2222-2222-222222222222",
"production_process_id": "77777777-7777-7777-7777-777777777777",
"unit": "KG",
"produced_from": 2025,
"produced_to": None,
"tech_specs": {
"compressive_strength": 42.5,
"density": 3100
},
"annual_data": [
{
"year": 2025,
"production_output": 120000,
"economic_value_per_unit": 0.35
}
]
}
headers = {
"X-API-Key": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'X-API-Key': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
external_id: 'CEM-42.5R-25KG-MUNICH',
plant_id: '11111111-1111-1111-1111-111111111111',
name: 'CEM 42.5 R, 25 kg bag (Munich)',
elementary_id: '22222222-2222-2222-2222-222222222222',
production_process_id: '77777777-7777-7777-7777-777777777777',
unit: 'KG',
produced_from: 2025,
produced_to: null,
tech_specs: {compressive_strength: 42.5, density: 3100},
annual_data: [{year: 2025, production_output: 120000, economic_value_per_unit: 0.35}]
})
};
fetch('https://api.emidat.com/v2/product-instances', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.emidat.com/v2/product-instances",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'external_id' => 'CEM-42.5R-25KG-MUNICH',
'plant_id' => '11111111-1111-1111-1111-111111111111',
'name' => 'CEM 42.5 R, 25 kg bag (Munich)',
'elementary_id' => '22222222-2222-2222-2222-222222222222',
'production_process_id' => '77777777-7777-7777-7777-777777777777',
'unit' => 'KG',
'produced_from' => 2025,
'produced_to' => null,
'tech_specs' => [
'compressive_strength' => 42.5,
'density' => 3100
],
'annual_data' => [
[
'year' => 2025,
'production_output' => 120000,
'economic_value_per_unit' => 0.35
]
]
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"X-API-Key: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.emidat.com/v2/product-instances"
payload := strings.NewReader("{\n \"external_id\": \"CEM-42.5R-25KG-MUNICH\",\n \"plant_id\": \"11111111-1111-1111-1111-111111111111\",\n \"name\": \"CEM 42.5 R, 25 kg bag (Munich)\",\n \"elementary_id\": \"22222222-2222-2222-2222-222222222222\",\n \"production_process_id\": \"77777777-7777-7777-7777-777777777777\",\n \"unit\": \"KG\",\n \"produced_from\": 2025,\n \"produced_to\": null,\n \"tech_specs\": {\n \"compressive_strength\": 42.5,\n \"density\": 3100\n },\n \"annual_data\": [\n {\n \"year\": 2025,\n \"production_output\": 120000,\n \"economic_value_per_unit\": 0.35\n }\n ]\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("X-API-Key", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.emidat.com/v2/product-instances")
.header("X-API-Key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"external_id\": \"CEM-42.5R-25KG-MUNICH\",\n \"plant_id\": \"11111111-1111-1111-1111-111111111111\",\n \"name\": \"CEM 42.5 R, 25 kg bag (Munich)\",\n \"elementary_id\": \"22222222-2222-2222-2222-222222222222\",\n \"production_process_id\": \"77777777-7777-7777-7777-777777777777\",\n \"unit\": \"KG\",\n \"produced_from\": 2025,\n \"produced_to\": null,\n \"tech_specs\": {\n \"compressive_strength\": 42.5,\n \"density\": 3100\n },\n \"annual_data\": [\n {\n \"year\": 2025,\n \"production_output\": 120000,\n \"economic_value_per_unit\": 0.35\n }\n ]\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.emidat.com/v2/product-instances")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["X-API-Key"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"external_id\": \"CEM-42.5R-25KG-MUNICH\",\n \"plant_id\": \"11111111-1111-1111-1111-111111111111\",\n \"name\": \"CEM 42.5 R, 25 kg bag (Munich)\",\n \"elementary_id\": \"22222222-2222-2222-2222-222222222222\",\n \"production_process_id\": \"77777777-7777-7777-7777-777777777777\",\n \"unit\": \"KG\",\n \"produced_from\": 2025,\n \"produced_to\": null,\n \"tech_specs\": {\n \"compressive_strength\": 42.5,\n \"density\": 3100\n },\n \"annual_data\": [\n {\n \"year\": 2025,\n \"production_output\": 120000,\n \"economic_value_per_unit\": 0.35\n }\n ]\n}"
response = http.request(request)
puts response.read_body{
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"external_id": "<string>",
"plant_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"name": "<string>",
"elementary_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"production_process_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"unit": "KG",
"produced_from": 2025,
"produced_to": 123,
"tech_specs": {
"compressive_strength": 42.5,
"density": 3100
},
"annual_data": [
{
"year": 2025,
"production_output": 120000,
"economic_value_per_unit": 1
}
],
"status": "draft",
"created_at": "2023-11-07T05:31:56Z"
}{
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"external_id": "<string>",
"plant_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"name": "<string>",
"elementary_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"production_process_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"unit": "KG",
"produced_from": 2025,
"produced_to": 123,
"tech_specs": {
"compressive_strength": 42.5,
"density": 3100
},
"annual_data": [
{
"year": 2025,
"production_output": 120000,
"economic_value_per_unit": 1
}
],
"status": "draft",
"created_at": "2023-11-07T05:31:56Z"
}{
"msg": "supplier product requires a supplier plant",
"err_code": "err_supplier_product_missing_supplier_plant",
"entitlement_limit": {
"dimension": "users",
"usage": 123,
"limit": 123
}
}{
"msg": "supplier product requires a supplier plant",
"err_code": "err_supplier_product_missing_supplier_plant",
"entitlement_limit": {
"dimension": "users",
"usage": 123,
"limit": 123
}
}{
"msg": "supplier product requires a supplier plant",
"err_code": "err_supplier_product_missing_supplier_plant",
"entitlement_limit": {
"dimension": "users",
"usage": 123,
"limit": 123
}
}{
"msg": "supplier product requires a supplier plant",
"err_code": "err_supplier_product_missing_supplier_plant",
"entitlement_limit": {
"dimension": "users",
"usage": 123,
"limit": 123
}
}{
"msg": "supplier product requires a supplier plant",
"err_code": "err_supplier_product_missing_supplier_plant",
"entitlement_limit": {
"dimension": "users",
"usage": 123,
"limit": 123
}
}Authorizations
Per-manufacturer API key in the X-API-Key header, format
emidat-{key_id}-{secret} where key_id is a random public handle.
Issued by an owner in the Emidat
dashboard; carries its own permission scopes, optional plant
restrictions, and optional expiry. A revoked, expired, or unknown key
returns 401. See the Authentication guide for details.
Headers
Optional client-generated key (e.g. a UUID) that makes a create
idempotent — the only mechanism that does so. 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 6h. See External IDs.
Body
The plant's Emidat UUID.
"CEM 42.5 R, 25 kg bag (Munich)"
Emidat material-type UUID — determines the product type.
M, M2, M3, UG, KG, T, L, KWH, MJ, UNIT, METRIC TON*KM "KG"
First year this instance is valid.
2020 <= x <= 21002025
Your own code for this instance (its SKU / BOM node id). Optional. When
provided it is unique among your active instances — creating another
with the same code returns 409 (see External IDs).
"CEM-42.5R-25KG-MUNICH"
The production process's Emidat UUID. Optional.
Last valid year, or null if open-ended.
2020 <= x <= 2100Technical specifications as key/value pairs. Which keys apply depends
on the instance's elementary_id — cement, for example, takes
compressive_strength and density.
{ "compressive_strength": 42.5, "density": 3100 }
Production output and economic value per year. Include both
values for each year, using null when one is unknown. Each year
must fall inside the instance's production period.
Show child attributes
Show child attributes
Response
Returned unchanged — an Idempotency-Key replay.
Your own code for this instance, as provided on creation.
The plant's Emidat UUID. Always present — set at creation and immutable.
Emidat material-type UUID — determines the product type.
The production process's Emidat UUID, or null if none.
M, M2, M3, UG, KG, T, L, KWH, MJ, UNIT, METRIC TON*KM "KG"
First year this instance is valid.
2025
Last valid year, or null if open-ended.
Technical specifications as key/value pairs. Which keys apply depends
on the instance's elementary_id — cement, for example, takes
compressive_strength and density.
{ "compressive_strength": 42.5, "density": 3100 }
Production output and economic value per year.
Show child attributes
Show child attributes
Whether the instance is modelled far enough to run an LCA. Derived on every read, never set directly.
incomplete — something structural is still missing: tech_specs is
empty, production_process_id is null, or the material type needs a
BOM (PUT …/bom) and none is set. draft — all of that is present.
draft is about structure only. It does not mean any year is
computable: per-year gaps such as missing production data surface as
blocked_by entries on the LCA results, not here.
incomplete, draft "draft"