Cet article n'est pas encore disponible en français ; il est affiché ci-dessous en anglais.
A battery model holds the data every battery of one design shares — the model-level data points of Annex VI and Annex XIII. Values live in fields, keyed by the names in the field catalogue; category, capacityKwh and chemistry are properties of the model itself.
A model must be complete for its category before its passports can be published. GET /models/{id}/completeness tells you what is missing; POST /models/validate asks the same question about a draft before anything is stored.
Personalise the samples. Paste a test key and every snippet uses it — and your own model and passport ids.
/v1/modelsList models
Your battery models, newest first, a page at a time — each with its completeness for its category and how many batteries it has and how many are published. Filter by category, completeness, or updated_since to sync only what changed.
Parameters5
limitintegerqueryoptionalPage size, 1–200. Default 50.
cursorstringqueryoptionalThe
next_cursorof the previous page. Omit for the first page.category"EV" | "LMT" | "INDUSTRIAL"queryoptionalOnly models of this category.
updated_sinceISO 8601 date or date-timequeryoptionalOnly models changed at or after this instant.
complete"true" | "false"queryoptionalOnly complete, or only incomplete, models.
Responses
- 200OK — A page of models.
Errors2
- 400
Validation faileddetailsnames each invalid field. - 401
unauthorizedThe key is missing, unknown or revoked.
Response fields · 200
object- idstring
- namestring
- categorystring
One of
EVLMTINDUSTRIAL - capacityKwhnumber
- chemistrystring
- fieldsobject
Template field values keyed by field name — see GET /v1/field-catalog.
- createdAtstring · date-time
- updatedAtstring · date-time
- requiredFilledinteger
- requiredTotalinteger
- completeboolean
Every field, attribute and document this category owes is present.
- itemCountinteger
- publishedCountinteger
- has_morebooleanrequired
- next_cursorstring | nullrequired
Pass as
cursorto get the next page.
curl "https://dppapi-production.up.railway.app/v1/models?category=LMT&complete=false" \-H "Authorization: Bearer $DPP_API_KEY"{"data": [{"id": "cm1q8x2k40003l70f9a8s7d6e","name": "Cargo 48V 15Ah","category": "LMT","capacityKwh": 0.72,"chemistry": "Lithium-ion NMC","templateKey": "battery","industrialExternalStorage": false,"createdAt": "2027-01-15T09:12:44.120Z","updatedAt": "2027-01-15T11:40:02.019Z","requiredFilled": 39,"requiredTotal": 41,"complete": false,"itemCount": 100,"publishedCount": 0}],"has_more": true,"next_cursor": "eyJpZCI6ImNtMXE4eTBicTAwMDZsNzBmeDl5OHo3dzYifQ"}/v1/modelsCreate a model
Creates a battery model. Industrial batteries are in passport scope only above 2 kWh (Art. 77(1)), so an INDUSTRIAL model with capacityKwh of 2 or less is refused.
Request body7
category"EV" | "LMT" | "INDUSTRIAL"requiredBattery category. Decides which data points are required.
namestring, 1–200requiredYour name for the model.
capacityKwhnumber > 0requiredEnergy capacity in kWh. Must exceed 2 for
INDUSTRIAL.chemistrystring, 1–120requiredBattery chemistry (Annex VI A(7)), e.g. "Lithium-ion NMC".
industrialExternalStoragebooleanoptionalIndustrial battery with exclusively external storage. Default
false.templateKeystringoptionalCategory template. Default
"battery".fieldsobjectoptionalModel-level data points keyed by API field name.
Headers2
Idempotency-KeystringheaderoptionalOptional. A unique string per logical operation (a UUID is ideal). The first response is stored for 24 hours and replayed for retries; see Idempotency.
X-DPP-Dry-Run"true"headeroptionalOptional, live keys. Validate the write in full and store nothing. Test keys always dry-run; see Test keys.
Responses
- 201Created — The new model.
Errors6
- 400
Validation faileddetailsnames each invalid field. - 401
unauthorizedThe key is missing, unknown or revoked. - 402
plan_upgrade_requiredYour plan does not allow another model, or it is paused on Maintenance. - 403
insufficient_scopeThe key has nowritescope. - 409
organisation_frozenThe organisation is frozen and read-only. - 422
idempotency_key_reusedTheIdempotency-Keywas already used with a different body.
Webhooks fired
Response fields · 201
object- idstring
- namestring
- categorystring
One of
EVLMTINDUSTRIAL - capacityKwhnumber
- chemistrystring
- fieldsobject
Template field values keyed by field name — see GET /v1/field-catalog.
- createdAtstring · date-time
- updatedAtstring · date-time
curl -X POST "https://dppapi-production.up.railway.app/v1/models" \-H "Authorization: Bearer $DPP_API_KEY" \-H "Content-Type: application/json" \-H "Idempotency-Key: 7b3e0c52-1f7d-4b8a-9a52-2f0e6d1c9a44" \-d '{"category": "LMT","name": "Cargo 48V 15Ah","capacityKwh": 0.72,"chemistry": "Lithium-ion NMC","fields": {"manufacturerName": "Example Batteries GmbH","ratedCapacity": 15,"nominalVoltage": 48}}'{"id": "cm1q8x2k40003l70f9a8s7d6e","templateKey": "battery","category": "LMT","industrialExternalStorage": false,"name": "Cargo 48V 15Ah","capacityKwh": 0.72,"chemistry": "Lithium-ion NMC","fields": {"manufacturerName": "Example Batteries GmbH","ratedCapacity": 15,"nominalVoltage": 48},"createdAt": "2027-01-15T09:12:44.120Z","updatedAt": "2027-01-15T09:12:44.120Z"}/v1/models/{id}Get a model
One model with its conformity record, documents, carbon-footprint and recycled-content declarations, and _count.items, the number of batteries created for it.
Parameters1
idstringpathrequiredThe model id.
Responses
- 200OK — The model (abridged).
Errors2
- 401
unauthorizedThe key is missing, unknown or revoked. - 404
Not foundNo model with this id in your organisation.
Response fields · 200
object- idstring
- namestring
- categorystring
One of
EVLMTINDUSTRIAL - capacityKwhnumber
- chemistrystring
- fieldsobject
Template field values keyed by field name — see GET /v1/field-catalog.
- createdAtstring · date-time
- updatedAtstring · date-time
curl "https://dppapi-production.up.railway.app/v1/models/cm1q8x2k40003l70f9a8s7d6e" \-H "Authorization: Bearer $DPP_API_KEY"{"id": "cm1q8x2k40003l70f9a8s7d6e","templateKey": "battery","category": "LMT","industrialExternalStorage": false,"name": "Cargo 48V 15Ah","capacityKwh": 0.72,"chemistry": "Lithium-ion NMC","fields": {"manufacturerName": "Example Batteries GmbH","ratedCapacity": 15,"nominalVoltage": 48},"createdAt": "2027-01-15T09:12:44.120Z","updatedAt": "2027-01-15T09:12:44.120Z"}/v1/models/{id}Update a model
Changes the name, chemistry or field values. fields is merged into what is stored: send only what changes, and a partial update never blanks the rest. Category and capacity cannot change — create a new model instead.
Every change is written to the audit trail.
Parameters1
idstringpathrequiredThe model id.
Request body3
namestring, 1–200optionalNew name.
chemistrystring, 1–120optionalNew chemistry.
fieldsobjectoptionalField values to add or replace, merged into the stored ones.
Headers2
Idempotency-KeystringheaderoptionalOptional. A unique string per logical operation (a UUID is ideal). The first response is stored for 24 hours and replayed for retries; see Idempotency.
X-DPP-Dry-Run"true"headeroptionalOptional, live keys. Validate the write in full and store nothing. Test keys always dry-run; see Test keys.
Responses
- 200OK — The updated model.
Errors6
- 400
Validation faileddetailsnames each invalid field. - 401
unauthorizedThe key is missing, unknown or revoked. - 403
insufficient_scopeThe key has nowritescope. - 404
Not foundNo model with this id in your organisation. - 409
organisation_frozenThe organisation is frozen and read-only. - 422
idempotency_key_reusedTheIdempotency-Keywas already used with a different body.
Webhooks fired
Response fields · 200
object- idstring
- namestring
- categorystring
One of
EVLMTINDUSTRIAL - capacityKwhnumber
- chemistrystring
- fieldsobject
Template field values keyed by field name — see GET /v1/field-catalog.
- createdAtstring · date-time
- updatedAtstring · date-time
curl -X PATCH "https://dppapi-production.up.railway.app/v1/models/cm1q8x2k40003l70f9a8s7d6e" \-H "Authorization: Bearer $DPP_API_KEY" \-H "Content-Type: application/json" \-d '{"fields": {"hazardousSubstances": "None above reporting thresholds","extinguishingAgent": "Water, foam"}}'{"id": "cm1q8x2k40003l70f9a8s7d6e","templateKey": "battery","category": "LMT","industrialExternalStorage": false,"name": "Cargo 48V 15Ah","capacityKwh": 0.72,"chemistry": "Lithium-ion NMC","fields": {"manufacturerName": "Example Batteries GmbH","ratedCapacity": 15,"nominalVoltage": 48},"createdAt": "2027-01-15T09:12:44.120Z","updatedAt": "2027-01-15T09:12:44.120Z"}/v1/models/{id}/completenessMissing-field analysis
Compares the model with the obligations of its category. missing holds required data points still empty — they block publishing. conditionalUnset holds "if applicable" ones, as prompts. Required documents (the EU Declaration of Conformity) and model properties (chemistry) are included.
Battery-level fields are answered per battery; the newest battery stands in as the sample, and with no batteries yet those fields read as unanswered.
Parameters1
idstringpathrequiredThe model id.
Responses
- 200OK — The report (abridged).
Errors2
- 401
unauthorizedThe key is missing, unknown or revoked. - 404
Not foundNo model with this id in your organisation.
Response fields · 200
object- categorystring
- requiredTotalinteger
- requiredFilledinteger
- completeboolean
- namestring
- labelstring
- pointinteger
Annex XIII point (1 public … 4 dynamic).
- annexRefstring
- granularitystring
One of
modelitem
- namestring
- labelstring
- pointinteger
Annex XIII point (1 public … 4 dynamic).
- annexRefstring
- granularitystring
One of
modelitem
curl "https://dppapi-production.up.railway.app/v1/models/cm1q8x2k40003l70f9a8s7d6e/completeness" \-H "Authorization: Bearer $DPP_API_KEY"{"category": "LMT","requiredTotal": 41,"requiredFilled": 39,"complete": false,"missing": [{"name": "EU Declaration of Conformity","label": "EU Declaration of Conformity","point": 1,"annexRef": "Annex XIII 1(r) / Art. 18","granularity": "model"}],"conditionalUnset": [],"missingByPoint": { "1": 2 }}/v1/models/validateValidate a draft model
A stateless completeness check: send the body you would send to POST /models and get the model-level analysis back, without creating anything. unknownFields names field keys the template does not recognise — usually a typo in your mapping. Use it in an ERP form or a CI job to know whether a product record is passport-ready before it is pushed.
It changes nothing, so it needs only the read scope, and a test key gets the real analysis — not a dry-run envelope.
Request body2
…objectrequiredThe same body as Create a model.
documentTypesstring[]optionalDocuments you will upload, e.g.
["EU Declaration of Conformity"], so they count as present.
Responses
- 200OK — The analysis (abridged).
Errors2
- 400
Validation faileddetailsnames each invalid field. - 401
unauthorizedThe key is missing, unknown or revoked.
Response fields · 200
object- validboolean
- completeboolean
- requiredTotalinteger
- requiredFilledinteger
- namestring
- labelstring
- pointinteger
Annex XIII point (1 public … 4 dynamic).
- annexRefstring
- granularitystring
One of
modelitem
- namestring
- labelstring
- pointinteger
Annex XIII point (1 public … 4 dynamic).
- annexRefstring
- granularitystring
One of
modelitem
- unknownFieldsarray of string
curl -X POST "https://dppapi-production.up.railway.app/v1/models/validate" \-H "Authorization: Bearer $DPP_API_KEY" \-H "Content-Type: application/json" \-d '{"category": "EV","name": "Pack 400V 82kWh","capacityKwh": 82,"chemistry": "Lithium-ion NMC 811","fields": {"manufacturerName": "Example Batteries GmbH","ratedCapacity": 205,"nominalVoltag": 400},"documentTypes": ["EU Declaration of Conformity"]}'{"valid": true,"complete": false,"requiredTotal": 38,"requiredFilled": 4,"missing": [{"name": "nominalVoltage","label": "Nominal voltage","point": 1,"annexRef": "Annex XIII 1(h)","granularity": "model"}],"conditionalUnset": [],"unknownFields": ["nominalVoltag"]}