API reference
Reference for the ErgOps Embedded API v1, generated from the authoritative OpenAPI specification.
New to the API? Start with Send your first API calculation, then read Create and manage API keys, Idempotency and Error handling.
Base URL#
https://api.ergops.com/v1Test and Live are selected by the API key, not by the hostname. The API is server-to-server; browser cross-origin requests are not enabled.
Authentication#
Send your API key as an HTTP bearer token: Authorization: Bearer <API key>. Key format: ergops_test_* or ergops_live_*. See Authentication and API keys.
POST /emissions/logistics#
Calculate customer-attributed logistics emissions
- Authentication
- API key (Bearer)
- Required scope
emissions:calculate- Operation ID
calculateLogisticsEmissions
Parameters#
| Name | In | Type | Required | Description |
|---|---|---|---|---|
Idempotency-Key | header | string | Yes | Stable retry key for one logical write. Reuse with a different material payload returns 409. At least 1 characters. Up to 200 characters. |
Request body#
application/json · LogisticsRequest
| Field | Type | Required | Description |
|---|---|---|---|
customer_reference | string | Yes | Up to 120 characters. |
external_reference | string | Yes | Up to 120 characters. |
mode | string | Yes | One of: ROAD, SEA, AIR. |
origin | Place | Yes | Provide at least one of: code or label. Unknown fields are rejected. |
origin.code | string | No | Up to 20 characters. |
origin.label | string | No | Up to 200 characters. |
origin.country | string | No | Exactly 2 characters. |
destination | Place | Yes | Provide at least one of: code or label. Unknown fields are rejected. |
destination.code | string | No | Up to 20 characters. |
destination.label | string | No | Up to 200 characters. |
destination.country | string | No | Exactly 2 characters. |
cargo | object | Yes | Unknown fields are rejected. |
cargo.value | number | Yes | Greater than 0. |
cargo.unit | string | Yes | Always tonne. |
distance | object | Yes | Unknown fields are rejected. |
distance.value | number | Yes | Greater than 0. |
distance.unit | string | Yes | Always km. |
activity_date | string (date) | Yes | |
business_context | string | No | One of: upstream, downstream. Default upstream. |
factor_reference | string | Yes | Existing governed factor key; direct factor values are not accepted. |
Example request#
curl -X POST "https://api.ergops.com/v1/emissions/logistics" \
-H "Authorization: Bearer $ERGOPS_API_KEY" \
-H "Idempotency-Key: YOUR_IDEMPOTENCY_KEY" \
-H "Content-Type: application/json" \
-d '{"customer_reference":"CUSTOMER_REFERENCE","external_reference":"EXTERNAL_REFERENCE","mode":"ROAD","origin":{"code":"CODE","label":"LABEL","country":"GB"},"destination":{"code":"CODE","label":"LABEL","country":"GB"},"cargo":{"value":1,"unit":"tonne"},"distance":{"value":1,"unit":"km"},"activity_date":"2026-01-31","factor_reference":"FACTOR_REFERENCE"}'Responses#
| Status | Meaning | Body |
|---|---|---|
200 | The same logical calculation was replayed idempotently Headers: X-Request-Id, Idempotent-Replayed | — |
201 | A new canonical calculation was created Headers: X-Request-Id | Calculation |
400 | Invalid request | Error |
401 | Invalid | Error |
403 | Entitlement | Error |
404 | Tenant-safe not found | Error |
409 | Idempotency conflict | Error |
422 | Validation | Error |
429 | Technical throughput or hard contract capacity limit Headers: Retry-After | Error |
201 response fields · Calculation
| Field | Type | Required | Description |
|---|---|---|---|
id | string (uuid) | Yes | |
external_reference | string | Yes | |
status | string | Yes | Always succeeded. |
environment | string | Yes | One of: test, live. |
customer | object | Yes | |
customer.reference | string | Yes | |
activity | object | Yes | |
activity.value | number | Yes | |
activity.unit | string | Yes | Always tkm. |
emissions | object | Yes | |
emissions.value | number | Yes | |
emissions.unit | string | Yes | Always kgCO2e. |
methodology | object | Yes | |
factor | object | Yes | |
created_at | string (date-time) | Yes |
Example shape, generated from the schema:
{
"id": "00000000-0000-4000-8000-000000000000",
"external_reference": "EXTERNAL_REFERENCE",
"status": "succeeded",
"environment": "test",
"customer": {
"reference": "REFERENCE"
},
"activity": {
"value": 0,
"unit": "tkm"
},
"emissions": {
"value": 0,
"unit": "kgCO2e"
},
"methodology": {},
"factor": {},
"created_at": "2026-01-31T12:00:00Z"
}GET /calculations/{id}#
Read a calculation from the credential's organization and environment
- Authentication
- API key (Bearer)
- Required scope
emissions:readoremissions:calculate- Operation ID
getCalculation
Parameters#
| Name | In | Type | Required | Description |
|---|---|---|---|---|
id | path | string (uuid) | Yes |
Example request#
curl "https://api.ergops.com/v1/calculations/CALCULATION_ID" \
-H "Authorization: Bearer $ERGOPS_API_KEY"Responses#
| Status | Meaning | Body |
|---|---|---|
200 | Calculation | Calculation |
401 | Invalid | Error |
403 | Entitlement | Error |
404 | Tenant-safe not found | Error |
429 | Technical throughput or hard contract capacity limit Headers: Retry-After | Error |
200 response fields · Calculation
| Field | Type | Required | Description |
|---|---|---|---|
id | string (uuid) | Yes | |
external_reference | string | Yes | |
status | string | Yes | Always succeeded. |
environment | string | Yes | One of: test, live. |
customer | object | Yes | |
customer.reference | string | Yes | |
activity | object | Yes | |
activity.value | number | Yes | |
activity.unit | string | Yes | Always tkm. |
emissions | object | Yes | |
emissions.value | number | Yes | |
emissions.unit | string | Yes | Always kgCO2e. |
methodology | object | Yes | |
factor | object | Yes | |
created_at | string (date-time) | Yes |
Example shape, generated from the schema:
{
"id": "00000000-0000-4000-8000-000000000000",
"external_reference": "EXTERNAL_REFERENCE",
"status": "succeeded",
"environment": "test",
"customer": {
"reference": "REFERENCE"
},
"activity": {
"value": 0,
"unit": "tkm"
},
"emissions": {
"value": 0,
"unit": "kgCO2e"
},
"methodology": {},
"factor": {},
"created_at": "2026-01-31T12:00:00Z"
}GET /customers/{customerReference}#
Read a customer using its organization-scoped external reference
- Authentication
- API key (Bearer)
- Required scope
customers:read- Operation ID
getCustomer
Parameters#
| Name | In | Type | Required | Description |
|---|---|---|---|---|
customerReference | path | string | Yes | Up to 120 characters. Pattern ^[A-Za-z0-9][A-Za-z0-9._:/-]*$. |
Example request#
curl "https://api.ergops.com/v1/customers/CUSTOMER_REFERENCE" \
-H "Authorization: Bearer $ERGOPS_API_KEY"Responses#
| Status | Meaning | Body |
|---|---|---|
200 | Customer-safe metadata | Customer |
401 | Invalid | Error |
403 | Entitlement | Error |
404 | Tenant-safe not found | Error |
429 | Technical throughput or hard contract capacity limit Headers: Retry-After | Error |
200 response fields · Customer
| Field | Type | Required | Description |
|---|---|---|---|
reference | string | Yes | |
name | string | Yes | |
status | string | Yes | |
country_code | string | null | No | |
analytics | object | null | No |
Example shape, generated from the schema:
{
"reference": "REFERENCE",
"name": "NAME",
"status": "STATUS"
}GET /customers/{customerReference}/emissions#
Read environment-isolated customer calculation aggregates
- Authentication
- API key (Bearer)
- Required scope
customers:read+customer-analytics:read- Operation ID
getCustomerEmissions
Parameters#
| Name | In | Type | Required | Description |
|---|---|---|---|---|
customerReference | path | string | Yes | Up to 120 characters. Pattern ^[A-Za-z0-9][A-Za-z0-9._:/-]*$. |
Example request#
curl "https://api.ergops.com/v1/customers/CUSTOMER_REFERENCE/emissions" \
-H "Authorization: Bearer $ERGOPS_API_KEY"Responses#
| Status | Meaning | Body |
|---|---|---|
200 | Customer analytics | Customer |
401 | Invalid | Error |
403 | Entitlement | Error |
404 | Tenant-safe not found | Error |
429 | Technical throughput or hard contract capacity limit Headers: Retry-After | Error |
200 response fields · Customer
| Field | Type | Required | Description |
|---|---|---|---|
reference | string | Yes | |
name | string | Yes | |
status | string | Yes | |
country_code | string | null | No | |
analytics | object | null | No |
Example shape, generated from the schema:
{
"reference": "REFERENCE",
"name": "NAME",
"status": "STATUS"
}POST Webhook: calculationEvent#
Signed calculation lifecycle event delivered to a configured endpoint
ErgOps sends this request to your endpoint. Verify it before processing — see Verify webhook signatures.
Headers#
| Header | Type | Description |
|---|---|---|
X-ErgOps-Webhook-Id | string (uuid) | |
X-ErgOps-Webhook-Timestamp | string | |
X-ErgOps-Webhook-Signature | string | Pattern ^v1=[a-f0-9]{64}$. |
Body#
| Field | Type | Required | Description |
|---|---|---|---|
id | string (uuid) | Yes | |
type | string | Yes | One of: calculation.succeeded, calculation.failed. |
created_at | string (date-time) | Yes | |
environment | string | Yes | One of: test, live. |
data | object | Yes | Customer-safe calculation result or stable error reference. |
Errors#
Every error uses the same envelope. Always log request_id when contacting support.
{
"error": {
"code": "INVALID_API_KEY",
"message": "MESSAGE",
"request_id": "00000000-0000-4000-8000-000000000000"
}
}Error codes defined in the contract:
INVALID_API_KEYAPI_KEY_REVOKEDAPI_KEY_EXPIREDINSUFFICIENT_SCOPEFEATURE_NOT_ENTITLEDORGANIZATION_NOT_ACTIVECUSTOMER_NOT_FOUNDCUSTOMER_ACCESS_DENIEDINVALID_REQUESTIDEMPOTENCY_KEY_REQUIREDIDEMPOTENCY_KEY_REUSEDFACTOR_NOT_FOUNDCALCULATION_FAILEDUSAGE_LIMIT_REACHEDRATE_LIMITEDINTERNAL_ERROR
See Error handling for guidance.
Download the specification#
openapi.yaml (OpenAPI 3.1.0) is the authoritative contract. Use it to generate clients or import into API tools.