List Purchases
const options = {
method: 'GET',
headers: {
'x-api-key': '<x-api-key>',
'x-organization-id': '<x-organization-id>',
'x-user-id': '<x-user-id>'
}
};
fetch('https://api.dcycle.io/api/v1/purchases', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));import requests
url = "https://api.dcycle.io/api/v1/purchases"
headers = {
"x-api-key": "<x-api-key>",
"x-organization-id": "<x-organization-id>",
"x-user-id": "<x-user-id>"
}
response = requests.get(url, headers=headers)
print(response.text)curl --request GET \
--url https://api.dcycle.io/api/v1/purchases \
--header 'x-api-key: <x-api-key>' \
--header 'x-organization-id: <x-organization-id>' \
--header 'x-user-id: <x-user-id>'{
"page": 123,
"size": 123,
"total": 123,
"total2": 123,
"items": [
{
"id": "<string>",
"organization_id": "<string>",
"quantity": 123,
"unit_id": "<string>",
"unit": {},
"sector": "<string>",
"product_name": "<string>",
"purchase_type": "<string>",
"expense_type": "<string>",
"supplier_id": "<string>",
"supplier": {},
"purchase_date": {},
"last_purchase_timestamp": {},
"recycled": 123,
"country": "<string>",
"frequency": "<string>",
"description": "<string>",
"status": "<string>",
"co2e": 123,
"ef": 123,
"displayed_ggss": true,
"custom_emission_factor_id": "<string>",
"file_url": "<string>",
"file_id": "<string>",
"file_name": "<string>"
}
]
}List Purchases
Get a paginated list of purchased goods and services in your organization
GET
/
api
/
v1
/
purchases
List Purchases
const options = {
method: 'GET',
headers: {
'x-api-key': '<x-api-key>',
'x-organization-id': '<x-organization-id>',
'x-user-id': '<x-user-id>'
}
};
fetch('https://api.dcycle.io/api/v1/purchases', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));import requests
url = "https://api.dcycle.io/api/v1/purchases"
headers = {
"x-api-key": "<x-api-key>",
"x-organization-id": "<x-organization-id>",
"x-user-id": "<x-user-id>"
}
response = requests.get(url, headers=headers)
print(response.text)curl --request GET \
--url https://api.dcycle.io/api/v1/purchases \
--header 'x-api-key: <x-api-key>' \
--header 'x-organization-id: <x-organization-id>' \
--header 'x-user-id: <x-user-id>'{
"page": 123,
"size": 123,
"total": 123,
"total2": 123,
"items": [
{
"id": "<string>",
"organization_id": "<string>",
"quantity": 123,
"unit_id": "<string>",
"unit": {},
"sector": "<string>",
"product_name": "<string>",
"purchase_type": "<string>",
"expense_type": "<string>",
"supplier_id": "<string>",
"supplier": {},
"purchase_date": {},
"last_purchase_timestamp": {},
"recycled": 123,
"country": "<string>",
"frequency": "<string>",
"description": "<string>",
"status": "<string>",
"co2e": 123,
"ef": 123,
"displayed_ggss": true,
"custom_emission_factor_id": "<string>",
"file_url": "<string>",
"file_id": "<string>",
"file_name": "<string>"
}
]
}List Purchases
Retrieve all purchases (Scope 3 - Category 1: Purchased Goods and Services) registered in your organization with pagination support and flexible filtering options.Purchases represent Scope 3 emissions from goods and services your organization buys. This is typically one of the largest emission categories for most organizations.
Request
Headers
string
required
Your API key for authenticationExample:
sk_live_1234567890abcdefstring
required
Your organization UUIDExample:
ff4adcc7-8172-45fe-9cf1-e90a6de53aa9string
required
Your user UUIDExample:
a1b2c3d4-e5f6-7890-abcd-ef1234567890Query Parameters
integer
default:"1"
Page number for paginationExample:
1integer
default:"50"
Number of items per page (max: 100)Example:
50string
Advanced filtering criteria (format:
field:operator:value or field:value)Supported operators:eq- Equalsneq- Not equalsin- In listnin- Not in listgt- Greater thangte- Greater than or equallt- Less thanlte- Less than or equal
"status:active" or "sector:eqIT Services"string
Sort criteria (format:
field:asc or field:desc)Sortable fields:purchase_datequantityco2esectorstatus
"co2e:desc"Response
integer
Current page number
integer
Number of items per page
integer
Total count of active purchases
integer
Total count of purchases with errors or in review status
array
Array of purchase objects
Purchase Object Fields:
string
Unique purchase identifier (UUID v4)
string
Organization UUID
float
Purchase quantity
string
Unit UUID for the quantity
object
Unit details object with
id, name, type fieldsstring
Economic sector code (NAICS or similar classification)Examples:
"IT Services", "Manufacturing", "Transportation"string
Product or service nameExamples:
"Laptops", "Cloud Services", "Office Supplies"string
Type of purchase calculation methodValues:
spend_based- Calculated based on monetary spend (most common)supplier_specific- Uses supplier-specific emission factors
string
Expense categoryValues:
"goods", "services", "capital_goods", "other"string
Supplier UUID (for spend_based purchases)
object
Supplier details object with
business_name and country fieldsdatetime
Date of purchase (ISO 8601 format)
datetime
Last update timestamp (ISO 8601 format)
float
Percentage of recycled content (0.0 to 1.0)
string
deprecated
Deprecated. ISO 3166-1 alpha-2 country code. No longer used for emission calculations
(the country is now taken from the supplier); reflects the supplier country.
string
Purchase frequency for recurring purchasesValues:
"once", "weekly", "monthly", "quarterly", "yearly"string
Purchase description or notes
string
Purchase statusValues:
active- Successfully processedsuccess- Successfully processed (legacy)error- Processing failedin_review- Pending review
float
Total CO2 equivalent emissions in kg
float
Emission factor used for calculation (kg CO2e per unit)
boolean
Whether to display GHG sector scope information
string
UUID of custom emission factor (if using supplier-specific method)
string
URL of uploaded file (for bulk uploads)
string
UUID of uploaded file
string
Name of uploaded file
Example
curl -X GET "https://api.dcycle.io/api/v1/purchases?page=1&size=50&sort_by=co2e:desc" \
-H "Authorization: Bearer ${DCYCLE_API_KEY}" \
-H "x-organization-id: ${DCYCLE_ORG_ID}" \
-H "x-user-id: ${DCYCLE_USER_ID}"
import requests
import os
api_key = os.getenv("DCYCLE_API_KEY")
org_id = os.getenv("DCYCLE_ORG_ID")
user_id = os.getenv("DCYCLE_USER_ID")
headers = {
"Authorization": f"Bearer {api_key}",
"x-organization-id": org_id,
"x-user-id": user_id
}
# Get purchases sorted by emissions (highest first)
params = {
"page": 1,
"size": 50,
"sort_by": "co2e:desc"
}
response = requests.get(
"https://api.dcycle.io/api/v1/purchases",
headers=headers,
params=params
)
purchases = response.json()
print(f"Total active purchases: {purchases['total']}")
print(f"Purchases with errors: {purchases['total2']}")
# Display top emissions sources
print("\nTop emission sources:")
for purchase in purchases['items'][:10]:
supplier_name = purchase['supplier'].get('business_name', 'N/A') if purchase['supplier'] else 'N/A'
print(f"- {purchase['product_name']}: {purchase['co2e']:.2f} kg CO2e ({supplier_name})")
const axios = require('axios');
const apiKey = process.env.DCYCLE_API_KEY;
const orgId = process.env.DCYCLE_ORG_ID;
const userId = process.env.DCYCLE_USER_ID;
const headers = {
'Authorization': `Bearer ${apiKey}`,
'x-organization-id': orgId,
'x-user-id': userId
};
// Get purchases sorted by emissions (highest first)
const params = {
page: 1,
size: 50,
sort_by: 'co2e:desc'
};
axios.get('https://api.dcycle.io/api/v1/purchases', { headers, params })
.then(response => {
const purchases = response.data;
console.log(`Total active purchases: ${purchases.total}`);
console.log(`Purchases with errors: ${purchases.total2}`);
// Display top emission sources
console.log('\nTop emission sources:');
purchases.items.slice(0, 10).forEach(purchase => {
const supplierName = purchase.supplier?.business_name || 'N/A';
console.log(`- ${purchase.product_name}: ${purchase.co2e.toFixed(2)} kg CO2e (${supplierName})`);
});
})
.catch(error => console.error(error));
Successful Response
{
"page": 1,
"size": 50,
"total": 245,
"total2": 12,
"items": [
{
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"organization_id": "org-uuid",
"quantity": 25000.0,
"unit_id": "eur-unit-uuid",
"unit": {
"id": "eur-unit-uuid",
"name": "EUR",
"type": "fiat_currency"
},
"sector": "IT Services",
"product_name": "Cloud Computing Services",
"purchase_type": "spend_based",
"expense_type": "services",
"supplier_id": "supplier-uuid",
"supplier": {
"business_name": "AWS EMEA SARL",
"country": "ES"
},
"purchase_date": "2024-01-15T00:00:00Z",
"last_purchase_timestamp": "2024-01-16T10:30:00Z",
"recycled": null,
"country": "ES",
"frequency": "monthly",
"description": "Monthly AWS cloud infrastructure costs",
"status": "active",
"co2e": 2450.75,
"ef": 0.098,
"displayed_ggss": true,
"custom_emission_factor_id": null,
"file_url": null,
"file_id": null,
"file_name": null
},
{
"id": "b2c3d4e5-f6g7-8901-bcde-fg2345678901",
"organization_id": "org-uuid",
"quantity": 15000.0,
"unit_id": "eur-unit-uuid",
"unit": {
"id": "eur-unit-uuid",
"name": "EUR",
"type": "fiat_currency"
},
"sector": "Office Supplies",
"product_name": "Printer Paper",
"purchase_type": "spend_based",
"expense_type": "goods",
"supplier_id": "supplier-uuid-2",
"supplier": {
"business_name": "Office Depot Spain",
"country": "ES"
},
"purchase_date": "2024-01-10T00:00:00Z",
"last_purchase_timestamp": "2024-01-10T14:22:00Z",
"recycled": 0.3,
"country": "ES",
"frequency": "quarterly",
"description": "Q1 2024 office paper supplies",
"status": "active",
"co2e": 1825.50,
"ef": 0.122,
"displayed_ggss": true,
"custom_emission_factor_id": null,
"file_url": null,
"file_id": null,
"file_name": null
}
]
}
Common Errors
400 Bad Request
Cause: Invalid query parameters or filter format{
"detail": "Invalid filter format",
"code": "VALIDATION_ERROR"
}
403 Forbidden
Cause: Organization ID doesn’t match your API key or user doesn’t belong to organization{
"detail": "Not authorized",
"code": "FORBIDDEN"
}
x-organization-id matches your API key’s organization.
Use Cases
Get Purchases Dashboard
Display all active purchases with highest emissions:def get_purchases_dashboard():
"""Get purchases dashboard with top emitters"""
response = requests.get(
"https://api.dcycle.io/api/v1/purchases",
headers=headers,
params={
"page": 1,
"size": 100,
"sort_by": "co2e:desc",
"filter_by": "status:active"
}
)
purchases = response.json()
# Calculate totals
total_emissions = sum(p['co2e'] or 0 for p in purchases['items'])
total_spend = sum(
p['quantity'] for p in purchases['items']
if p['unit']['type'] == 'fiat_currency'
)
return {
'purchases': purchases['items'],
'total_active': purchases['total'],
'total_errors': purchases['total2'],
'total_emissions': total_emissions,
'total_spend': total_spend
}
# Usage
dashboard = get_purchases_dashboard()
print(f"Total emissions: {dashboard['total_emissions']:.2f} kg CO2e")
print(f"Total spend: {dashboard['total_spend']:.2f} EUR")
Filter by Sector
Get all purchases in a specific sector:def get_purchases_by_sector(sector_name):
"""Get purchases filtered by sector"""
response = requests.get(
"https://api.dcycle.io/api/v1/purchases",
headers=headers,
params={
"filter_by": f"sector:eq{sector_name}",
"page": 1,
"size": 100
}
)
purchases = response.json()
print(f"Purchases in {sector_name}: {purchases['total']}")
for purchase in purchases['items']:
print(f" - {purchase['product_name']}: {purchase['co2e']:.2f} kg CO2e")
return purchases
# Example: Get all IT Services purchases
it_purchases = get_purchases_by_sector("IT Services")
Filter by Date Range
Get purchases within a specific time period:from datetime import datetime, timedelta
def get_recent_purchases(days=30):
"""Get purchases from the last N days"""
# Note: Date filtering requires timestamp comparison
# This example shows pagination through all results and client-side filtering
all_purchases = []
page = 1
cutoff_date = datetime.now() - timedelta(days=days)
while True:
response = requests.get(
"https://api.dcycle.io/api/v1/purchases",
headers=headers,
params={"page": page, "size": 100}
)
data = response.json()
# Filter by date client-side
for purchase in data['items']:
purchase_date = datetime.fromisoformat(purchase['purchase_date'].replace('Z', '+00:00'))
if purchase_date >= cutoff_date:
all_purchases.append(purchase)
if len(data['items']) < 100:
break
page += 1
print(f"Purchases in last {days} days: {len(all_purchases)}")
return all_purchases
# Get purchases from last 30 days
recent = get_recent_purchases(30)
Get Purchases with Errors
Identify and review purchases that failed processing:def get_error_purchases():
"""Get purchases with errors for review"""
response = requests.get(
"https://api.dcycle.io/api/v1/purchases",
headers=headers,
params={
"filter_by": "status:eqerror",
"page": 1,
"size": 100
}
)
purchases = response.json()
print(f"⚠️ Purchases with errors: {len(purchases['items'])}")
for purchase in purchases['items']:
print(f"\nPurchase ID: {purchase['id']}")
print(f" Product: {purchase['product_name']}")
print(f" Sector: {purchase['sector']}")
print(f" Date: {purchase['purchase_date']}")
print(f" Status: {purchase['status']}")
return purchases
# Review error purchases
errors = get_error_purchases()
Analyze Emissions by Sector
Group purchases and calculate emissions by sector:def analyze_emissions_by_sector():
"""Analyze total emissions grouped by sector"""
# Get all active purchases
all_purchases = []
page = 1
while True:
response = requests.get(
"https://api.dcycle.io/api/v1/purchases",
headers=headers,
params={
"page": page,
"size": 100,
"filter_by": "status:active"
}
)
data = response.json()
all_purchases.extend(data['items'])
if len(all_purchases) >= data['total']:
break
page += 1
# Group by sector
sectors = {}
for purchase in all_purchases:
sector = purchase['sector']
if sector not in sectors:
sectors[sector] = {
'count': 0,
'total_co2e': 0,
'total_spend': 0
}
sectors[sector]['count'] += 1
sectors[sector]['total_co2e'] += purchase['co2e'] or 0
if purchase['unit']['type'] == 'fiat_currency':
sectors[sector]['total_spend'] += purchase['quantity']
# Sort by emissions
sorted_sectors = sorted(
sectors.items(),
key=lambda x: x[1]['total_co2e'],
reverse=True
)
print("Emissions by Sector:")
print("-" * 70)
for sector, data in sorted_sectors:
print(f"{sector}:")
print(f" Purchases: {data['count']}")
print(f" Emissions: {data['total_co2e']:.2f} kg CO2e")
print(f" Spend: {data['total_spend']:.2f} EUR")
print()
return sorted_sectors
# Analyze emissions
analysis = analyze_emissions_by_sector()
Purchase Types
Spend-Based Purchases
Description: Emissions calculated based on monetary spend using economic input-output emission factors. Characteristics:- Most common method (80-90% of purchases)
- Requires: quantity (in currency), sector, country
- Uses standardized emission factors per EUR/USD spent
- Less accurate but practical for most purchases
Supplier-Specific Purchases
Description: Emissions calculated using supplier-provided product-specific emission factors. Characteristics:- More accurate than spend-based
- Requires: product name, supplier, specific emission factor
- Used when supplier provides LCA data
- Ideal for major suppliers or critical products
Expense Types
| Type | Description | Scope 3 Category |
|---|---|---|
goods | Physical products | Category 1 - Purchased Goods |
services | Professional and technical services | Category 1 - Purchased Services |
capital_goods | Long-lived assets (machinery, buildings) | Category 2 - Capital Goods |
other | Miscellaneous purchases | Category 1 |
Frequency Options
Recurring purchases can be tracked with frequency:| Frequency | Description |
|---|---|
once | One-time purchase |
weekly | Weekly recurring |
monthly | Monthly recurring |
quarterly | Quarterly recurring |
yearly | Annual recurring |
Best Practices
1. Use Pagination Effectively
When you have many purchases, use pagination:# Good - Paginate through results
def get_all_purchases():
all_purchases = []
page = 1
while True:
response = requests.get(
"https://api.dcycle.io/api/v1/purchases",
headers=headers,
params={"page": page, "size": 100}
)
data = response.json()
all_purchases.extend(data['items'])
if len(all_purchases) >= data['total']:
break
page += 1
return all_purchases
2. Filter for Performance
Use server-side filtering instead of loading everything:# Good - Server-side filtering
response = requests.get(
"https://api.dcycle.io/api/v1/purchases",
headers=headers,
params={"filter_by": "sector:eqIT Services"}
)
# Bad - Client-side filtering
response = requests.get("https://api.dcycle.io/api/v1/purchases", headers=headers)
it_purchases = [p for p in response.json()['items'] if p['sector'] == 'IT Services']
3. Monitor Error Status
Regularly check for purchases with errors:# Check error count
response = requests.get(
"https://api.dcycle.io/api/v1/purchases",
headers=headers,
params={"page": 1, "size": 1}
)
error_count = response.json()['total2']
if error_count > 0:
print(f"⚠️ {error_count} purchases need attention")
4. Sort by Emissions
Focus on high-impact purchases first:# Get top 20 emission sources
response = requests.get(
"https://api.dcycle.io/api/v1/purchases",
headers=headers,
params={
"sort_by": "co2e:desc",
"page": 1,
"size": 20
}
)
top_emitters = response.json()['items']
Related Endpoints
Bulk Upload Purchases
Upload multiple purchases via CSV
List Units
Get measurement units for purchases
List Facilities
View your facilities
Authentication
Learn about API authentication
Was this page helpful?