Skip to main content
POST
← Sold Products API Say how a sold product is used during one of its periods of sales (Scope 3 category 11): how long one unit lasts and what it consumes, in up to four blocks: electricity, fuel it burns, water and refrigerant it leaks. The periods are the ones Create Sold Products (v2) answers (periods[].id). The request checks every record and writes them all at once, then answers 202 Accepted with an ingest job that calculates their emissions (see how bulk ingestion works). Follow it with GET /v2/ingest-jobs/{id} or, for a job submitted with an API key, the ingest_job.finished webhook. This route replaces POST /v1/sold-products/{sold_product_id}/use-of-product and PATCH /v1/sold-products/{sold_product_id}/use-of-product/{use_of_product_data_id}.
Beta. Part of the bulk ingest API, in beta. The contract may still change before general availability.

How it works

  1. Every record is checked: its schema, its period (it must exist in your organization’s perimeter), the units, fuel and gas of its blocks, and the fuel and gas against the other periods of the product (see step 3). If any record is invalid the whole request is rejected with 422 and nothing is written (all or nothing): rejected is the number of invalid records and errors lists them (up to 100).
  2. A period has one use. A record for a period that has none creates it; a record for a period that already has one replaces it whole (a block you leave out is removed), keeps its id and calculates its emissions again. Two records for the same period reject the second (DUPLICATE_PERIOD).
  3. Periods of a product that share a calendar year burn the same fuel and leak the same gas, or none: a period of 2025 that burns natural gas and another of 2025 that burns diesel, or burns nothing, are USE_OF_PRODUCT_INCONSISTENT. The rule is checked on the state after the request, against the uses the product already has and the other records of the request; a period with no use is not compared. error_params.field says which block disagrees (combustion or fugitive) and error_params.period_id with which period.
  4. The uses are written at once, in the organization of their product, and the job calculates them in the background, 50 per chunk. For each block, one unit of the product consumes quantity per frequency over its lifespan (all_life: quantity is already the whole life), and that is multiplied by the quantity sold in each country of the period. A use whose calculation fails for some sale has its job item failed with CALCULATION_FAILED.
  5. When every chunk is done the job is completed (or completed_with_errors). For a job submitted with an API key, ingest_job.finished is sent to the webhook endpoints of the x-organization-id organization.

Units

Each unit is checked against its block; any other is UNIT_NOT_SUPPORTED, with error_params.field naming it. GET /v2/units lists them with ?type=use_of_product_electricity, use_of_product_combustion and use_of_product_water. The lifespan units have no type: they are in the whole catalog (GET /v2/units without type). fugitive has no unit: its quantity is in kilograms.

Request

Headers

string
required
Your API key (see Authentication).
string
required
The organization you act as. A record can name a period of its products or of the organizations under it (its perimeter); each use belongs to the organization of its product. The job and its ingest_job.finished webhook belong to the x-organization-id organization.
string
required
1 to 255 characters, one per batch, looked up per organization across every v2 bulk route. Within 24 hours, the same key with the same route and body returns the original job (with Idempotent-Replayed: true) instead of writing the uses again; the same key with another body or on another route is 422 IDEMPOTENCY_KEY_REUSED, and while the first request is still being processed 409 IDEMPOTENCY_KEY_IN_PROGRESS. After 24 hours the key is free, and a request with it is a new one. See The Idempotency-Key.

Query Parameters

boolean
default:"false"
Check only: the same 422 for invalid records, nothing written, no job; 200 with {"dry_run": true, "submitted": n, "valid": n} when every record is valid. It does not check or store the Idempotency-Key.

Body Parameters

array[object]
required
The uses to write, 1 to 5,000, one per period. A field not listed here is rejected (SCHEMA_INVALID), in the record and in its blocks.

Response

202 Accepted with the job (entity_type: use_of_product, operation: create) and a Location header to it. To read the result:
If chunks_done stops moving, see A job that does not finish. Resending the batch with a new Idempotency-Key replaces the same uses and calculates them again.

Errors

Problem details. Per-record codes in errors[].error_code of a 422 BULK_RECORDS_REJECTED: Request-level errors: 401 for a missing or invalid API key, 403 LOGGED_USER_NOT_MEMBER when the key’s user is not a member of the organization, 422 REQUEST_VALIDATION_FAILED for a malformed body (no records, more than 5,000, no Idempotency-Key), 422 IDEMPOTENCY_KEY_REUSED, 409 IDEMPOTENCY_KEY_IN_PROGRESS, and 429 beyond the rate limits.

Limits

Delete Use of Sold Products (v2)

Delete uses by id

Create Sold Products (v2)

The products and periods a use is for

Period Emissions

The emissions of a period

Get Ingest Job

Follow the calculation