Skip to main content
GET
https://api.dcycle.io
/
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));
{
  "items": {
    "id": "<string>",
    "organization_id": "<string>",
    "product_name": {},
    "description": {},
    "sector": {},
    "country": {},
    "quantity": {},
    "unit_id": {},
    "purchase_date": {},
    "purchase_type": {},
    "expense_type": {},
    "status": {},
    "recycled": {},
    "supplier_id": {},
    "custom_emission_factor_id": {},
    "file_id": {},
    "file_name": {},
    "file_url": {},
    "co2e": {},
    "frequency": {},
    "created_at": {},
    "updated_at": {}
  },
  "total": 123,
  "page": 123,
  "size": 123,
  "pages": 123
}

List Purchases

Retrieve a paginated list of purchases in your organization with support for filtering by status, type, expense type, and file.

Request

Headers

x-api-key
string
required
Your API key for authenticationExample: sk_live_1234567890abcdef
x-organization-id
string
required
Your organization UUIDExample: a8315ef3-dd50-43f8-b7ce-d839e68d51fa

Query Parameters

status[]
array[string]
Filter by purchase statusAvailable values: active, pending, in_progress, in_review, inactive, errorExample: status[]=active&status[]=pending
purchase_type[]
array[string]
Filter by purchase calculation typeAvailable values: spend_based, supplier_specificExample: purchase_type[]=spend_based
expense_type[]
array[string]
Filter by expense classificationAvailable values: capex, opexExample: expense_type[]=opex
file_id[]
array[string]
Filter by linked file ID (UUID)Example: file_id[]=550e8400-e29b-41d4-a716-446655440000
file_name[]
array[string]
Filter by linked file nameExample: file_name[]=invoice_2024.pdf
page
integer
default:"1"
Page number for paginationExample: 2
size
integer
default:"50"
Number of items per page (max 100)Example: 50

Response

items
array[object]
Array of purchase objects
total
integer
Total number of purchases matching the filter
page
integer
Current page number
size
integer
Number of items per page
pages
integer
Total number of pages

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}"

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",
      "country": "ES",
      "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",
      "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",
      "country": "US",
      "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",
      "created_at": "2024-03-01T09:00:00Z",
      "updated_at": "2024-03-01T09:00:00Z"
    }
  ],
  "total": 156,
  "page": 1,
  "size": 50,
  "pages": 4
}

Common Errors

401 Unauthorized

Cause: Missing or invalid API key
{
  "detail": "Invalid API key",
  "code": "INVALID_API_KEY"
}
Solution: Verify your API key is valid and active. Get a new one from Settings -> API.

404 Not Found

Cause: Organization not found
{
  "code": "ORGANIZATION_NOT_FOUND",
  "detail": "Organization with id=UUID('...') not found"
}
Solution: Verify that the 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"
    }
  ]
}
Solution: Check that page size is between 1 and 100, and that filter values are valid enums.

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 page >= data["pages"]:
            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 page >= data["pages"]:
            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 page >= data["pages"]:
            break
        page += 1

# Process all purchases
for purchase in iterate_all_purchases():
    print(f"Processing {purchase['product_name']}")