> ## Documentation Index
> Fetch the complete documentation index at: https://code.dcycle.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Update Purchase

> Modify an existing purchase's details

# Update Purchase

Update an existing purchase's information. You can modify any combination of the purchase's fields.

<Note>
  **Partial Updates**: Only include the fields you want to update. Fields not included in the request body will remain unchanged.
</Note>

## Request

### Headers

<ParamField header="x-api-key" type="string" required>
  Your API key for authentication

  **Example:** `sk_live_1234567890abcdef`
</ParamField>

<ParamField header="x-organization-id" type="string" required>
  Your organization UUID

  **Example:** `a8315ef3-dd50-43f8-b7ce-d839e68d51fa`
</ParamField>

<ParamField header="Content-Type" type="string" required>
  Must be `application/json`
</ParamField>

### Path Parameters

<ParamField path="purchase_id" type="string" required>
  The unique identifier (UUID) of the purchase to update

  **Example:** `550e8400-e29b-41d4-a716-446655440000`
</ParamField>

### Body Parameters

<ParamField body="product_name" type="string">
  Name of the product or service purchased (max 255 characters)

  **Example:** `"Office Supplies - Updated"`
</ParamField>

<ParamField body="sector" type="string">
  Economic sector for emission factor lookup (max 255 characters)

  **Example:** `"Retail trade"`
</ParamField>

<ParamField body="country" type="string">
  2-letter ISO country code where the purchase was made

  **Example:** `"DE"`
</ParamField>

<ParamField body="quantity" type="number">
  Purchase amount (must be >= 0). For spend-based, this is the monetary value.

  **Example:** `2000.00`
</ParamField>

<ParamField body="unit_id" type="string">
  Unit of measurement (e.g., EUR, USD, kg)

  **Example:** `"EUR"`
</ParamField>

<ParamField body="purchase_date" type="string">
  Date of purchase in YYYY-MM-DD format

  **Example:** `"2024-03-20"`
</ParamField>

<ParamField body="expense_type" type="string">
  Expense classification

  **Available values:** `capex`, `opex`

  **Example:** `"capex"`
</ParamField>

<ParamField body="description" type="string">
  Optional description of the purchase (max 500 characters)

  **Example:** `"Updated Q1 2024 order with additional items"`
</ParamField>

<ParamField body="purchase_type" type="string">
  Calculation method for emissions

  **Available values:** `spend_based`, `supplier_specific`

  **Example:** `"supplier_specific"`
</ParamField>

<ParamField body="status" type="string">
  Purchase status

  **Available values:** `active`, `pending`, `in_progress`, `in_review`, `inactive`

  **Example:** `"in_review"`
</ParamField>

<ParamField body="recycled" type="number">
  Recycled content percentage (0 to 1). Reduces calculated emissions.

  **Example:** `0.5` (50% recycled content)
</ParamField>

<ParamField body="supplier_id" type="string">
  Optional supplier identifier for reference

  **Example:** `"supplier-456"`
</ParamField>

<ParamField body="custom_emission_factor_id" type="string">
  UUID of custom emission factor for supplier-specific calculations

  **Example:** `"770e8400-e29b-41d4-a716-446655440000"`
</ParamField>

<ParamField body="frequency" type="string">
  Purchase frequency

  **Available values:** `once`

  **Example:** `"once"`
</ParamField>

<ParamField body="file_id" type="string">
  UUID of linked file/document

  **Example:** `"660e8400-e29b-41d4-a716-446655440000"`
</ParamField>

<ParamField body="file_name" type="string">
  Name of linked file (max 255 characters)

  **Example:** `"invoice_q1_2024_updated.pdf"`
</ParamField>

<ParamField body="file_url" type="string">
  URL of linked file

  **Example:** `"https://storage.dcycle.io/..."`
</ParamField>

## Response

Returns the updated purchase object with recalculated emissions.

<ResponseField name="id" type="string">
  Unique identifier (UUID)
</ResponseField>

<ResponseField name="organization_id" type="string">
  Organization UUID
</ResponseField>

<ResponseField name="product_name" type="string | null">
  Name of the product or service
</ResponseField>

<ResponseField name="description" type="string | null">
  Optional description
</ResponseField>

<ResponseField name="sector" type="string | null">
  Economic sector
</ResponseField>

<ResponseField name="country" type="string | null">
  2-letter ISO country code
</ResponseField>

<ResponseField name="quantity" type="number | null">
  Purchase amount
</ResponseField>

<ResponseField name="unit_id" type="string | null">
  Unit of measurement
</ResponseField>

<ResponseField name="purchase_date" type="date | null">
  Date of purchase
</ResponseField>

<ResponseField name="purchase_type" type="string | null">
  Calculation method: `spend_based` or `supplier_specific`
</ResponseField>

<ResponseField name="expense_type" type="string">
  Classification: `capex` or `opex`
</ResponseField>

<ResponseField name="status" type="string | null">
  Purchase status
</ResponseField>

<ResponseField name="recycled" type="number | null">
  Recycled content percentage (0-1)
</ResponseField>

<ResponseField name="supplier_id" type="string | null">
  Supplier identifier
</ResponseField>

<ResponseField name="custom_emission_factor_id" type="string | null">
  Custom emission factor UUID
</ResponseField>

<ResponseField name="file_id" type="string | null">
  Linked file UUID
</ResponseField>

<ResponseField name="file_name" type="string | null">
  Linked file name
</ResponseField>

<ResponseField name="file_url" type="string | null">
  Linked file download URL
</ResponseField>

<ResponseField name="co2e" type="number | null">
  Recalculated CO2 equivalent emissions (kg)
</ResponseField>

<ResponseField name="frequency" type="string | null">
  Purchase frequency
</ResponseField>

<ResponseField name="exchange_rate_to_eur" type="number | null">
  Exchange rate used to convert the purchase amount to EUR
</ResponseField>

<ResponseField name="exchange_rate_date" type="date | null">
  Date used for the exchange rate lookup
</ResponseField>

<ResponseField name="custom_emission_group" type="object | null">
  Custom emission group applied to this purchase

  | Field         | Type           | Description       |
  | ------------- | -------------- | ----------------- |
  | `id`          | string         | Group UUID        |
  | `name`        | string \| null | Group name        |
  | `category`    | string \| null | Group category    |
  | `description` | string \| null | Group description |
</ResponseField>

<ResponseField name="last_purchase_timestamp" type="datetime | null">
  Timestamp of the most recent purchase in a recurring series
</ResponseField>

<ResponseField name="supplier" type="object | null">
  Supplier details

  | Field           | Type            | Description                     |
  | --------------- | --------------- | ------------------------------- |
  | `id`            | string          | Supplier UUID                   |
  | `business_name` | string \| null  | Supplier business name          |
  | `country`       | string \| null  | Supplier country code           |
  | `enabled`       | boolean \| null | Whether the supplier is enabled |
</ResponseField>

<ResponseField name="unit" type="object | null">
  Unit of measurement details

  <Expandable title="Unit Object">
    <ResponseField name="id" type="string">Unit UUID</ResponseField>
    <ResponseField name="name" type="string">Unit name (e.g. `euro_(€)`, `kilogram_(kg)`)</ResponseField>
    <ResponseField name="type" type="string">Unit category (e.g. `currency`, `weight`)</ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="uploaded_by" type="string | null">
  UUID of the user who created this record
</ResponseField>

<ResponseField name="uploaded_by_user" type="object | null">
  User who created this record

  | Field             | Type           | Description       |
  | ----------------- | -------------- | ----------------- |
  | `id`              | string         | User UUID         |
  | `first_name`      | string         | First name        |
  | `last_name`       | string         | Last name         |
  | `email`           | string         | Email address     |
  | `profile_img_url` | string \| null | Profile image URL |
</ResponseField>

<ResponseField name="created_at" type="datetime">
  Timestamp when the purchase was created
</ResponseField>

<ResponseField name="updated_at" type="datetime | null">
  Timestamp when the purchase was last updated
</ResponseField>

## Example

<CodeGroup>
  ```bash cURL theme={"theme":{"light":"github-light","dark":"github-dark"}}
  curl -X PATCH "https://api.dcycle.io/v1/purchases/550e8400-e29b-41d4-a716-446655440000" \
    -H "x-api-key: ${DCYCLE_API_KEY}" \
    -H "x-organization-id: ${DCYCLE_ORG_ID}" \
    -H "Content-Type: application/json" \
    -d '{
      "quantity": 2000.00,
      "recycled": 0.5,
      "description": "Updated order with additional items"
    }'
  ```

  ```python Python theme={"theme":{"light":"github-light","dark":"github-dark"}}
  import requests
  import os

  api_key = os.getenv("DCYCLE_API_KEY")
  org_id = os.getenv("DCYCLE_ORG_ID")
  purchase_id = "550e8400-e29b-41d4-a716-446655440000"

  headers = {
      "x-api-key": api_key,
      "x-organization-id": org_id,
      "Content-Type": "application/json"
  }

  # Only include fields to update
  payload = {
      "quantity": 2000.00,
      "recycled": 0.5,
      "description": "Updated order with additional items"
  }

  response = requests.patch(
      f"https://api.dcycle.io/v1/purchases/{purchase_id}",
      headers=headers,
      json=payload
  )

  purchase = response.json()
  print(f"Updated: {purchase['product_name']}")
  print(f"New CO2e: {purchase['co2e']} kg")
  ```

  ```javascript JavaScript theme={"theme":{"light":"github-light","dark":"github-dark"}}
  const axios = require('axios');

  const apiKey = process.env.DCYCLE_API_KEY;
  const orgId = process.env.DCYCLE_ORG_ID;
  const purchaseId = '550e8400-e29b-41d4-a716-446655440000';

  const headers = {
    'x-api-key': apiKey,
    'x-organization-id': orgId,
    'Content-Type': 'application/json'
  };

  // Only include fields to update
  const payload = {
    quantity: 2000.00,
    recycled: 0.5,
    description: 'Updated order with additional items'
  };

  axios.patch(
    `https://api.dcycle.io/v1/purchases/${purchaseId}`,
    payload,
    { headers }
  )
  .then(response => {
    const purchase = response.data;
    console.log(`Updated: ${purchase.product_name}`);
    console.log(`New CO2e: ${purchase.co2e} kg`);
  })
  .catch(error => console.error(error));
  ```
</CodeGroup>

### Successful Response

**Status Code:** `200 OK`

```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "organization_id": "a8315ef3-dd50-43f8-b7ce-d839e68d51fa",
  "product_name": "Office Supplies",
  "description": "Updated order with additional items",
  "sector": "Manufacturing",
  "country": "ES",
  "quantity": 2000.00,
  "unit_id": "EUR",
  "purchase_date": "2024-03-15",
  "purchase_type": "spend_based",
  "expense_type": "opex",
  "status": "active",
  "recycled": 0.5,
  "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": 163.7,
  "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" },
  "uploaded_by": null,
  "uploaded_by_user": null,
  "created_at": "2024-03-15T10:30:00Z",
  "updated_at": "2024-03-20T14:45:00Z"
}
```

## Common Errors

### 401 Unauthorized

**Cause:** Missing or invalid API key

```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
{
  "detail": "Invalid API key",
  "code": "INVALID_API_KEY"
}
```

**Solution:** Verify your API key is valid and active.

### 404 Not Found

**Cause:** Purchase not found or doesn't belong to your organization

```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
{
  "detail": "Purchase not found",
  "code": "PURCHASE_NOT_FOUND"
}
```

**Solution:** Verify the purchase ID exists and belongs to the organization specified in the header.

### 422 Validation Error

**Cause:** Invalid field values

```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
{
  "detail": [
    {
      "loc": ["body", "recycled"],
      "msg": "ensure this value is less than or equal to 1",
      "type": "value_error.number.not_le"
    }
  ]
}
```

**Solution:** Check that:

* `recycled` is between 0 and 1
* `quantity` is >= 0
* `country` is a valid 2-letter ISO code
* `expense_type` is either `capex` or `opex`
* `purchase_type` is either `spend_based` or `supplier_specific`

## Use Cases

### Update Quantity and Recalculate Emissions

Modify the purchase amount to update the calculated CO2e:

```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
def update_purchase_quantity(purchase_id, new_quantity):
    """Update purchase quantity and recalculate emissions"""
    response = requests.patch(
        f"https://api.dcycle.io/v1/purchases/{purchase_id}",
        headers=headers,
        json={"quantity": new_quantity}
    )
    purchase = response.json()
    print(f"New quantity: {purchase['quantity']} {purchase['unit_id']}")
    print(f"New CO2e: {purchase['co2e']} kg")
    return purchase

# Update purchase amount
purchase = update_purchase_quantity(
    "550e8400-e29b-41d4-a716-446655440000",
    3500.00
)
```

### Change Calculation Method

Switch from spend-based to supplier-specific calculation:

```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
def switch_to_supplier_specific(purchase_id, custom_factor_id):
    """Change purchase to use supplier-specific emission factor"""
    response = requests.patch(
        f"https://api.dcycle.io/v1/purchases/{purchase_id}",
        headers=headers,
        json={
            "purchase_type": "supplier_specific",
            "custom_emission_factor_id": custom_factor_id
        }
    )
    return response.json()

# Switch to supplier-specific calculation
purchase = switch_to_supplier_specific(
    "550e8400-e29b-41d4-a716-446655440000",
    "770e8400-e29b-41d4-a716-446655440000"
)
print(f"New CO2e with supplier factor: {purchase['co2e']} kg")
```

### Update Recycled Content

Adjust the recycled percentage for more accurate emissions:

```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
def update_recycled_percentage(purchase_id, recycled_pct):
    """Update recycled content percentage (0 to 1)"""
    response = requests.patch(
        f"https://api.dcycle.io/v1/purchases/{purchase_id}",
        headers=headers,
        json={"recycled": recycled_pct}
    )
    return response.json()

# Set 30% recycled content
purchase = update_recycled_percentage(
    "550e8400-e29b-41d4-a716-446655440000",
    0.3
)
print(f"CO2e with recycled content: {purchase['co2e']} kg")
```

### Mark Purchase as Inactive

Exclude a purchase from calculations:

```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
def deactivate_purchase(purchase_id):
    """Mark purchase as inactive"""
    response = requests.patch(
        f"https://api.dcycle.io/v1/purchases/{purchase_id}",
        headers=headers,
        json={"status": "inactive"}
    )
    return response.json()

# Deactivate purchase
purchase = deactivate_purchase("550e8400-e29b-41d4-a716-446655440000")
print(f"{purchase['product_name']} is now {purchase['status']}")
```

### Link Supporting Documentation

Attach an invoice or receipt to the purchase:

```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
def link_document(purchase_id, file_id, file_name, file_url):
    """Link a document to a purchase"""
    response = requests.patch(
        f"https://api.dcycle.io/v1/purchases/{purchase_id}",
        headers=headers,
        json={
            "file_id": file_id,
            "file_name": file_name,
            "file_url": file_url
        }
    )
    return response.json()

# Link invoice
purchase = link_document(
    "550e8400-e29b-41d4-a716-446655440000",
    "660e8400-e29b-41d4-a716-446655440000",
    "invoice_updated.pdf",
    "https://storage.dcycle.io/..."
)
print(f"Linked document: {purchase['file_name']}")
```

### Bulk Update Purchases

Update multiple purchases' status:

```python theme={"theme":{"light":"github-light","dark":"github-dark"}}
def bulk_update_status(purchase_ids, new_status):
    """Update status for multiple purchases"""
    results = {"success": [], "failed": []}

    for purchase_id in purchase_ids:
        try:
            response = requests.patch(
                f"https://api.dcycle.io/v1/purchases/{purchase_id}",
                headers=headers,
                json={"status": new_status}
            )
            if response.status_code == 200:
                results["success"].append(purchase_id)
            else:
                results["failed"].append({"id": purchase_id, "error": response.text})
        except Exception as e:
            results["failed"].append({"id": purchase_id, "error": str(e)})

    return results

# Mark purchases as reviewed
purchase_ids = [
    "550e8400-e29b-41d4-a716-446655440000",
    "550e8400-e29b-41d4-a716-446655440001"
]

results = bulk_update_status(purchase_ids, "active")
print(f"Updated: {len(results['success'])}")
print(f"Failed: {len(results['failed'])}")
```

## Related Endpoints

<CardGroup cols={2}>
  <Card title="Get Purchase" icon="receipt" href="/api-reference/purchases/get">
    View purchase details
  </Card>

  <Card title="Delete Purchase" icon="trash" href="/api-reference/purchases/delete">
    Remove a purchase
  </Card>

  <Card title="List Purchases" icon="list" href="/api-reference/purchases/list">
    View all purchases
  </Card>

  <Card title="Custom Emission Factors" icon="chart-line" href="/api-reference/legacy/custom-emission-factors/overview">
    Create supplier-specific factors
  </Card>
</CardGroup>
