Ignite Procurement Export API (2.0.0)

Download OpenAPI specification:

Exporting data from Ignite Procurement. Note: Legacy JSON Web Tokens (JWTs) are no longer supported. Generate a new API token and pass it using Bearer authorization.

Migrating from /export/ and /datatables/: these endpoints were removed on 2026-10-01. The replacements are GET /tables/ for the table registry, POST /tables/{entity}/rows for paginated reads and POST /tables/{entity}/exports for full extracts. What changes:

  • Your spend, supplier and contract tables are addressed as spend, suppliers and contracts instead of by UUID. Other tables you have defined are addressed as datatable__<table id>, and each custom classification structure as classification_custom__<structure id>.
  • The row identifier id on spend and suppliers is the same value /export/ returned as rowId.
  • Supplier attributes are no longer inlined on each transaction. spend carries supplier_id, supplier_name and supplier_headquarters_country; everything else about a supplier, including its registration number (vat), is read from suppliers.
  • Rows are keyed by column name unless you request keyBy: label. Columns you have defined yourself are named custom__<field id> and carry your display name as label.
  • Classification is pre-joined onto spend as sc_level_N_id / sc_level_N_name and bu_level_N_id / bu_level_N_name; the classification tables hold the same rows.
  • Spend amount is delivered in your display currency, converted with the daily rate for transaction_date.
  • Spend-based emissions and GHGP scope/category are served by the separate emissions table; join its spend_id to spend.id. Columns of type group structure, emissions and aggregation on your own tables, and the /export/ metadata fields lastModified and importId, are not part of the new API.

List available export tables and columns

Lists the available export tables and the columns available for filtering and projection. Classification result tables expose spend_id plus the available level_N_id / level_N_name columns from the tenant's classification tree; the schema supports levels 1 through 10, with deeper levels nullable when not used.

Table ids: Your spend, supplier and contract data are served under the fixed ids spend, suppliers and contracts, classification results under classification_business_units and classification_spend_categories, and spend-based emissions under emissions. Each other classification structure (every structure except business units, spend categories and the emission structures) is its own table with the id classification_custom__<structure id>, named after the structure. It has one row per spend line classified into the structure, with spend_id and level_1_id/level_1_name through level_10_id/level_10_name. A spend line that is not in the table is not classified in that structure. The id stays the same when the structure is renamed; the table name follows the structure name, so key on the id. A rows request that would read more than 10 GB is rejected; on large structures, request only the fields you need or use an async export. Any other table you have defined in Ignite appears with the id datatable__<table id>, where the table id is the table's UUID with hyphens replaced by underscores. Your spend, supplier and contract tables are never listed under a datatable__ id, even though they have a UUID in Ignite; use the fixed ids.

Column names: name is the stable identifier and the only value accepted in fields, filters and sort. Standard columns (for example id, amount, transaction_date, supplier_id) are part of this API's contract and are not renamed. Columns you have defined yourself appear as custom__<field id>; the field id is assigned when the column is created and never changes or gets reused, so these names are safe to hard-code. Deleting a column and creating a new one with the same label produces a new field id. label is the display name you have given the column and changes whenever you rename it, so never key on label unless you have chosen keyBy: label deliberately. The row id on spend and suppliers is the same identifier the removed /export/ endpoint returned as rowId.

Every scalar column supports is_null and is_not_null. STRING columns additionally support literal substring search with contains and blank-value checks with is_blank / is_not_blank. Columns whose dataType is STRING_ARRAY (repeated string values) support only the array operators contains_any, contains_all, is_empty, and is_not_empty. Array columns are not part of the default response fields, so request them explicitly via fields to include their values in a rows response.

updated_at semantics: The updated_at column on suppliers and contracts reflects when the core record was last modified in Ignite. It does not advance when enrichment data is refreshed or when custom fields are edited. Consumers relying on updated_at for incremental sync will miss those changes; use the async export endpoint (POST /tables/{entity}/exports) for a complete point-in-time snapshot instead.

emissions columns: One row per spend transaction. emission_factor_category is the EXIOBASE product category and emission_factor_region the EXIOBASE region assigned to the transaction by classification rules, by default from the supplier's NACE code and country. Together with the transaction year they select the spend-based emission factor. emissions_kg_co2e is the transaction's spend multiplied by factor, with the spend valued in the currency given in unit (for example kgCO2e/NOK). emission_factor_source is spend_factor when a factor matched and customer_average when your average factor was used for an unmatched Scope 3 transaction, in which case customer_average_factor holds the value. emissions_kg_co2e is null when no factor applies, for example when the transaction has no category. ghgp_scope and ghgp_category give the GHG Protocol scope and category. Rows with excluded = true have 0 emissions, and excluded_reason says why: ACTIVITY_OVERRIDE (covered by activity-based data), EXEMPT (category in the Exempt group, such as taxes or internal transactions) or NON_SCOPE_3 (Scope 1 or 2, where spend-based factors do not apply). Filter excluded = false for emission totals.

Authorizations:
bearerAuth

Responses

Response samples

Content type
application/json
[
  • {
    },
  • {
    },
  • {
    },
  • {
    }
]

Fetch rows from an export table

Fetches scalar rows from an export table using optional field projection, typed filters, and opaque cursor pagination. Use GET /tables/ first to discover valid table ids, column names, data types, and supported filter operators. Classification result rows are identified by spend_id and contain the available level_N_id / level_N_name columns, with deeper levels nullable when not used. When fields is omitted, the endpoint returns every scalar column of the table; array (STRING_ARRAY) columns are excluded unless you request them explicitly in fields. For stable pagination, repeat the same request body and pass the previous response's nextPageToken as pageToken. Spend amount values and the currency column are in the tenant display currency (EUR when the tenant has none configured) unless the request sets currency; either way they are converted with the daily rate on or before transaction_date.

Authorizations:
bearerAuth
path Parameters
entity
required
string
Example: spend

The export table to read, given as the id returned by GET /tables/.

Request Body schema: application/json
optional
fields
Array of strings

Column names to include. When omitted, all scalar columns of the table are returned.

object

Conjunctive filters keyed by column name (all conditions must match). Supported operators depend on the column metadata returned by GET /tables/. Every scalar type supports is_null and is_not_null. STRING additionally supports eq, in, contains, is_blank, and is_not_blank; NUMBER / MONETARY_AMOUNT support eq, in, gte, lte, and between; DATE / TIMESTAMP support eq, gte, lte, and between; BOOL supports eq. STRING_ARRAY columns instead support contains_any / contains_all (an array of up to 100 strings) and is_empty / is_not_empty.

The unary operators is_null, is_not_null, is_blank, is_not_blank, is_empty, and is_not_empty take the boolean true. is_blank matches null, empty, and whitespace-only strings; is_not_blank excludes all three. contains takes a non-empty string and performs a normalized, case-insensitive literal substring search, so % and _ are ordinary characters rather than wildcards. in takes a non-empty array and between takes a two-item inclusive range.

Scalar value formats: STRING values are JSON strings; NUMBER and MONETARY_AMOUNT are JSON numbers; BOOL is a JSON boolean; DATE is a YYYY-MM-DD string; TIMESTAMP is an RFC 3339 UTC string (e.g. 2026-01-15T00:00:00Z).

Array of objects

Order results by one or more columns. Keys apply in order: the first is primary, each subsequent key breaks ties. Sort by any scalar column (STRING_ARRAY columns are not sortable); columns need not be part of fields. When omitted, rows come back in the table's default order. The table's default order columns are always appended as final tie-breakers, keeping pagination stable and deterministic.

pageSize
integer [ 1 .. 100000 ]
Default: 1000

Maximum number of rows to return. The service may return fewer rows and provides nextPageToken when more rows are available.

pageToken
string

Opaque cursor returned as nextPageToken from the previous response. Send the same request body as the previous page except for pageToken; do not change fields, filters, sort, pageSize, keyBy, or currency. Cursors are valid for 24 hours from the first page. An expired cursor is rejected with code: page_token_expired; the HTTP status is 400 when the cursor itself has expired and 410 when the underlying query can no longer be resumed. Treat both the same: check code, not the status, and restart pagination from the first page. Cursors cannot be resumed after expiry.

keyBy
string
Default: "name"
Enum: "name" "label"

Selects the key used in each returned row object. name (the default) keys by the column name (column.name from GET /tables/); label keys by the human-readable label (column.label). The fields projection and filters always reference column names regardless of keyBy.

Under keyBy: label, keys are made unique across the table in GET /tables/ column order: (1) the first column with a given label keeps that label as its key; (2) subsequent columns with the same label get "<label> (<name>)"; (3) any remaining collision gets an integer suffix #2, #3, … appended until unique. The response key for a given column does not depend on the fields projection.

currency
string^[A-Za-z]{3}$

ISO 4217 code for spend amount values and the currency column. Defaults to the tenant display currency. Amounts are converted with the daily exchange rate on or before transaction_date; amount is null when no such rate exists. Only the spend table accepts this field; other tables, or a code with no exchange rates, return 400 invalid_request with param: currency. The value is part of the pagination cursor, so keep it unchanged across pages.

Responses

Request samples

Content type
application/json
Example
{
  • "pageSize": 1000
}

Response samples

Content type
application/json
Example
{
  • "data": [
    ],
  • "nextPageToken": "AoF3kZ9vQ2tBxLmN7rPwYc1dHs5gJ0eU4iT6bWx"
}

Start an asynchronous table export

Starts an asynchronous export for a table. The returned export id can be used to poll status until the export is ready for download. Spend amount values and the currency column are in the tenant display currency (EUR when the tenant has none configured) unless the request sets currency; either way they are converted with the daily rate on or before transaction_date.

Authorizations:
bearerAuth
path Parameters
entity
required
string
Example: spend

The export table to read, given as the id returned by GET /tables/.

Request Body schema: application/json
optional
fields
Array of strings

Column names to include. When omitted, all scalar columns of the table are exported.

object

Conjunctive filters keyed by column name, with the same operator and value semantics as POST /tables/{entity}/rows. In particular, every scalar type supports is_null / is_not_null, and STRING additionally supports contains, is_blank, and is_not_blank. STRING_ARRAY columns support contains_any, contains_all, is_empty, and is_not_empty.

format
string
Enum: "json" "parquet"

Output file format. Send the lowercase value json or parquet (other casings are also accepted). Defaults to json when omitted. A large export may be split into several files; each file's extension matches the chosen format (.json or .parquet).

currency
string^[A-Za-z]{3}$

ISO 4217 code for spend amount values and the currency column in the exported files. Defaults to the tenant display currency. Amounts are converted with the daily exchange rate on or before transaction_date; amount is null when no such rate exists. Only the spend table accepts this field; other tables, or a code with no exchange rates, return 400 invalid_request with param: currency.

Responses

Request samples

Content type
application/json
Example
{ }

Response samples

Content type
application/json
{
  • "id": "95e90b56-5cd0-4d9a-a07b-52f5205731ac",
  • "entity": "spend",
  • "status": "queued",
  • "format": "json",
  • "estimatedBytesProcessed": 123456789,
  • "createdAt": "2026-05-06T07:20:00Z",
  • "updatedAt": "2026-05-06T07:20:00Z"
}

Get asynchronous export status

Polls the current status of an asynchronous export. When status is succeeded, the response includes time-limited download URLs. Three retention windows apply: the export status is available for 24 hours after the export was started, after which this endpoint returns 404; each download URL is valid for 1 hour and is re-issued on every poll; the exported files are deleted 7 days after the export. Start the export and download the files within the same 24-hour window.

Authorizations:
bearerAuth
path Parameters
id
required
string <uuid>
Example: 95e90b56-5cd0-4d9a-a07b-52f5205731ac

Responses

Response samples

Content type
application/json
Example
{
  • "id": "95e90b56-5cd0-4d9a-a07b-52f5205731ac",
  • "entity": "spend",
  • "status": "running",
  • "format": "json",
  • "estimatedBytesProcessed": 123456789,
  • "createdAt": "2026-05-06T07:20:00Z",
  • "updatedAt": "2026-05-06T07:20:03Z"
}