List Purchases
const options = {
method: 'GET',
headers: {'x-api-key': '<x-api-key>', 'x-organization-id': '<x-organization-id>'}
};
fetch('https://api.dcycle.io/v1/purchases', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));import requests
url = "https://api.dcycle.io/v1/purchases"
headers = {
"x-api-key": "<x-api-key>",
"x-organization-id": "<x-organization-id>"
}
response = requests.get(url, headers=headers)
print(response.text)curl --request GET \
--url https://api.dcycle.io/v1/purchases \
--header 'x-api-key: <x-api-key>' \
--header 'x-organization-id: <x-organization-id>'{
"items": {
"id": "<string>",
"organization_id": "<string>",
"product_name": {},
"description": {},
"sector": {},
"quantity": {},
"unit_id": {},
"purchase_date": {},
"purchase_type": {},
"expense_type": "<string>",
"status": {},
"recycled": {},
"supplier_id": {},
"custom_emission_factor_id": {},
"file_id": {},
"file_name": {},
"file_url": {},
"co2e": {},
"frequency": {},
"exchange_rate_to_eur": {},
"exchange_rate_date": {},
"custom_emission_group": {},
"last_purchase_timestamp": {},
"supplier": {},
"unit": {},
"uploaded_by": {},
"uploaded_by_user": {},
"created_at": {},
"updated_at": {}
},
"total": 123,
"page": 123,
"size": 123,
"filter_hash": "<string>"
}List Purchases
Retrieve all purchases with filtering and pagination support
GET
/
v1
/
purchases
List Purchases
const options = {
method: 'GET',
headers: {'x-api-key': '<x-api-key>', 'x-organization-id': '<x-organization-id>'}
};
fetch('https://api.dcycle.io/v1/purchases', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));import requests
url = "https://api.dcycle.io/v1/purchases"
headers = {
"x-api-key": "<x-api-key>",
"x-organization-id": "<x-organization-id>"
}
response = requests.get(url, headers=headers)
print(response.text)curl --request GET \
--url https://api.dcycle.io/v1/purchases \
--header 'x-api-key: <x-api-key>' \
--header 'x-organization-id: <x-organization-id>'{
"items": {
"id": "<string>",
"organization_id": "<string>",
"product_name": {},
"description": {},
"sector": {},
"quantity": {},
"unit_id": {},
"purchase_date": {},
"purchase_type": {},
"expense_type": "<string>",
"status": {},
"recycled": {},
"supplier_id": {},
"custom_emission_factor_id": {},
"file_id": {},
"file_name": {},
"file_url": {},
"co2e": {},
"frequency": {},
"exchange_rate_to_eur": {},
"exchange_rate_date": {},
"custom_emission_group": {},
"last_purchase_timestamp": {},
"supplier": {},
"unit": {},
"uploaded_by": {},
"uploaded_by_user": {},
"created_at": {},
"updated_at": {}
},
"total": 123,
"page": 123,
"size": 123,
"filter_hash": "<string>"
}List Purchases
Retrieve a paginated list of purchases in your organization with support for filtering by status, type, expense type, date range, supplier, CO2e calculation status, and more.Request
Headers
string
required
Your API key for authenticationExample:
sk_live_1234567890abcdefstring
required
Your organization UUIDExample:
a8315ef3-dd50-43f8-b7ce-d839e68d51faQuery Parameters
array[string]
Filter by purchase statusAvailable values:
active, pending, in_progress, in_review, inactive, errorExample: status[]=active&status[]=pendingarray[string]
Filter by purchase calculation typeAvailable values:
spend_based, supplier_specificExample: purchase_type[]=spend_basedarray[string]
Filter by expense classificationAvailable values:
capex, opexExample: expense_type[]=opexarray[string]
Filter by linked file ID (UUID)Example:
file_id[]=550e8400-e29b-41d4-a716-446655440000string
Search by description or supplier name (case-insensitive substring match)Example:
office suppliesstring
Filter by purchase description (substring match)
array[string]
Filter by supplier UUIDExample:
supplier_id[]=550e8400-e29b-41d4-a716-446655440000array[string]
Filter by currency/unit UUIDExample:
unit_id[]=eur-unit-uuiddate
Filter purchases with
purchase_date on or after this date (inclusive)Example: 2024-01-01date
Filter purchases with
purchase_date on or before this date (inclusive)Example: 2024-12-31date
Filter purchases created on or after this date (inclusive)Example:
2024-01-01date
Filter purchases created on or before this date (inclusive)Example:
2024-12-31string
Filter by CO2e calculation statusAvailable values:
calculated, not_calculatedstring
Sort field. Prefix with
- for descending order.Available values: purchase_date, created_at, description, quantity, expense_type, status, product_name, sector, recycled, file_name, co2eExamples: co2e, -quantity, -purchase_datestring
Advanced per-column filter expression. Each clause is
field:operatorValue, and multiple clauses are separated by $.Operators: gt (greater than), lt (less than), gte (≥), lte (≤), bt[min,max] (between), eq (equals), neq (not equals), contains (substring match)Example: quantity:gt100$co2e:bt[10,500] — quantity > 100 AND CO2e between 10 and 500string
How to combine
filter_by clauses across different fields. Default combines with AND.Available values: any (OR — matches if any clause is true), all (AND — all clauses must match)Example: anystring
Comma-separated list of field names whose same-field
filter_by clauses should combine with OR instead of AND.Example: status,expense_type — multiple status or expense_type filters use OR logicinteger
default:"1"
Page number for paginationExample:
2integer
default:"50"
Number of items per page (max 100)Example:
50Response
array[object]
Array of purchase objects
Show Purchase Object
Show Purchase Object
string
Unique identifier (UUID)
string
Organization UUID
string | null
Name of the product or service
string | null
Optional description
string | null
Economic sector
number | null
Purchase amount
string | null
Unit of measurement
date | null
Date of purchase
string | null
Calculation method:
spend_based or supplier_specificstring
Classification:
capex or opexstring | null
Purchase status
number | null
Recycled content percentage (0-1)
string | null
Supplier identifier
string | null
Custom emission factor UUID
string | null
Linked file UUID
string | null
Linked file name
string | null
Linked file download URL
number | null
Calculated CO2 equivalent emissions (kg)
string | null
Purchase frequency
number | null
Exchange rate used to convert the purchase amount to EUR
date | null
Date used for the exchange rate lookup
object | null
Custom emission group applied to this purchase
datetime | null
Timestamp of the most recent purchase in a recurring series
object | null
Supplier details (id, business_name, country, enabled)
object | null
Unit of measurement details
string | null
UUID of the user who created this record
object | null
User who created this record (id, first_name, last_name, email, profile_img_url)
datetime
Timestamp when the purchase was created
datetime | null
Timestamp when the purchase was last updated
integer
Total number of purchases matching the filter
integer
Current page number
integer
Number of items per page
string
16-character hex hash of the applied filters. Pass this to the bulk delete by filters endpoint to ensure consistency.
Example
curl -X GET "https://api.dcycle.io/v1/purchases?page=1&size=50&status[]=active" \
-H "x-api-key: ${DCYCLE_API_KEY}" \
-H "x-organization-id: ${DCYCLE_ORG_ID}"
import requests
import os
api_key = os.getenv("DCYCLE_API_KEY")
org_id = os.getenv("DCYCLE_ORG_ID")
headers = {
"x-api-key": api_key,
"x-organization-id": org_id
}
params = {
"page": 1,
"size": 50,
"status[]": ["active"]
}
response = requests.get(
"https://api.dcycle.io/v1/purchases",
headers=headers,
params=params
)
result = response.json()
for purchase in result["items"]:
print(f"{purchase['product_name']}: {purchase['co2e']} kg CO2e")
const axios = require('axios');
const apiKey = process.env.DCYCLE_API_KEY;
const orgId = process.env.DCYCLE_ORG_ID;
const headers = {
'x-api-key': apiKey,
'x-organization-id': orgId
};
const params = {
page: 1,
size: 50,
'status[]': ['active']
};
axios.get(
'https://api.dcycle.io/v1/purchases',
{ headers, params }
)
.then(response => {
response.data.items.forEach(purchase => {
console.log(`${purchase.product_name}: ${purchase.co2e} kg CO2e`);
});
})
.catch(error => console.error(error));
Successful Response
{
"items": [
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"organization_id": "a8315ef3-dd50-43f8-b7ce-d839e68d51fa",
"product_name": "Office Supplies",
"description": "Q1 2024 office supplies order",
"sector": "Manufacturing",
"quantity": 1500.00,
"unit_id": "EUR",
"purchase_date": "2024-03-15",
"purchase_type": "spend_based",
"expense_type": "opex",
"status": "active",
"recycled": 0.25,
"supplier_id": "supplier-123",
"custom_emission_factor_id": null,
"file_id": "660e8400-e29b-41d4-a716-446655440000",
"file_name": "invoice_q1_2024.pdf",
"file_url": "https://storage.dcycle.io/...",
"co2e": 245.5,
"frequency": "once",
"exchange_rate_to_eur": 1.0,
"exchange_rate_date": "2024-03-15",
"custom_emission_group": null,
"last_purchase_timestamp": null,
"supplier": {
"id": "supplier-123",
"business_name": "Office Depot",
"country": "ES",
"enabled": true
},
"unit": { "id": "unit-uuid", "name": "EUR", "type": "currency" },
"uploaded_by": null,
"uploaded_by_user": null,
"created_at": "2024-03-15T10:30:00Z",
"updated_at": "2024-03-15T10:30:00Z"
},
{
"id": "550e8400-e29b-41d4-a716-446655440001",
"organization_id": "a8315ef3-dd50-43f8-b7ce-d839e68d51fa",
"product_name": "Cloud Services",
"description": "AWS hosting services",
"sector": "Information and communication",
"quantity": 5000.00,
"unit_id": "USD",
"purchase_date": "2024-03-01",
"purchase_type": "spend_based",
"expense_type": "opex",
"status": "active",
"recycled": null,
"supplier_id": "aws-123",
"custom_emission_factor_id": null,
"file_id": null,
"file_name": null,
"file_url": null,
"co2e": 892.3,
"frequency": "once",
"exchange_rate_to_eur": 0.92,
"exchange_rate_date": "2024-03-01",
"custom_emission_group": null,
"last_purchase_timestamp": null,
"supplier": null,
"unit": { "id": "unit-uuid", "name": "USD", "type": "currency" },
"uploaded_by": null,
"uploaded_by_user": null,
"created_at": "2024-03-01T09:00:00Z",
"updated_at": "2024-03-01T09:00:00Z"
}
],
"total": 156,
"page": 1,
"size": 50,
"filter_hash": "a1b2c3d4e5f67890"
}
Common Errors
401 Unauthorized
Cause: Missing or invalid API key{
"detail": "Invalid API key",
"code": "INVALID_API_KEY"
}
404 Not Found
Cause: Organization not found{
"code": "ORGANIZATION_NOT_FOUND",
"detail": "Organization with id=UUID('...') not found"
}
x-organization-id header contains a valid organization UUID.
422 Validation Error
Cause: Invalid query parameters{
"detail": [
{
"loc": ["query", "size"],
"msg": "ensure this value is less than or equal to 100",
"type": "value_error.number.not_le"
}
]
}
Use Cases
Get All Active Purchases
Retrieve only active purchases:def get_active_purchases():
"""Get all active purchases in the organization"""
response = requests.get(
"https://api.dcycle.io/v1/purchases",
headers=headers,
params={"status[]": ["active"], "size": 100}
)
return response.json()["items"]
active_purchases = get_active_purchases()
print(f"Active purchases: {len(active_purchases)}")
Filter by Expense Type
Get only operational expenditures:def get_opex_purchases():
"""Get all OPEX purchases (Scope 3 Category 1)"""
response = requests.get(
"https://api.dcycle.io/v1/purchases",
headers=headers,
params={
"expense_type[]": ["opex"],
"status[]": ["active"],
"size": 100
}
)
return response.json()["items"]
opex = get_opex_purchases()
total_opex_co2e = sum(p.get("co2e", 0) for p in opex)
print(f"OPEX emissions: {total_opex_co2e} kg CO2e")
Calculate Category 1 Totals
Sum up all purchased goods and services emissions:def get_category_1_total():
"""Calculate total Scope 3 Category 1 emissions"""
total_co2e = 0
page = 1
while True:
response = requests.get(
"https://api.dcycle.io/v1/purchases",
headers=headers,
params={
"page": page,
"size": 100,
"status[]": ["active"],
"expense_type[]": ["opex"]
}
)
data = response.json()
for purchase in data["items"]:
total_co2e += purchase.get("co2e", 0) or 0
if len(data["items"]) < 100:
break
page += 1
return total_co2e
total = get_category_1_total()
print(f"Scope 3 Category 1: {total:,.0f} kg CO2e ({total/1000:.1f} tonnes)")
Group by Sector
Analyze purchases by economic sector:from collections import defaultdict
def get_purchases_by_sector():
"""Group purchases by sector"""
sector_totals = defaultdict(float)
page = 1
while True:
response = requests.get(
"https://api.dcycle.io/v1/purchases",
headers=headers,
params={"page": page, "size": 100, "status[]": ["active"]}
)
data = response.json()
for purchase in data["items"]:
sector = purchase.get("sector") or "Unknown"
sector_totals[sector] += purchase.get("co2e", 0) or 0
if len(data["items"]) < 100:
break
page += 1
return dict(sector_totals)
by_sector = get_purchases_by_sector()
for sector, co2e in sorted(by_sector.items(), key=lambda x: -x[1]):
print(f"{sector}: {co2e:,.0f} kg CO2e")
Pagination Guide
Navigate through large purchase lists efficiently:def iterate_all_purchases(batch_size=50):
"""Iterate through all purchases in organization"""
page = 1
while True:
response = requests.get(
"https://api.dcycle.io/v1/purchases",
headers=headers,
params={"page": page, "size": batch_size}
)
data = response.json()
for purchase in data["items"]:
yield purchase
if len(data["items"]) < batch_size:
break
page += 1
# Process all purchases
for purchase in iterate_all_purchases():
print(f"Processing {purchase['product_name']}")
Related Endpoints
Get Purchase
Get a specific purchase by ID
Create Purchase
Add a new purchase to your organization
Update Purchase
Modify purchase details
Delete Purchase
Remove a purchase
Was this page helpful?