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

# Apply log retention policies across all projects via API

export const plans_0 = "Plans: Any"

export const deployments_0 = "Deployments: Any"

export const data_plane_version_0 = undefined

export const use_case_0 = "Use case - Enforcing a consistent log retention policy (e.g., 30 days) across all projects in an organization"

<Note>
  **Applies to:**

  * Plan - {plans_0}
  * Deployment - {deployments_0}
  * {data_plane_version_0}
  * {use_case_0}
</Note>

## Summary

**Goal:** Enforce a 30-day log retention policy across all projects in an organization.

**Features:** Project automation API, project listing API, retention policy management functions.

## Configuration steps

### Step 1: Understand scope limitations

Retention policies are scoped to individual projects. There is no org-wide setting. Each project requires its own retention automation.

New projects created after running this script will need the policy applied separately.

### Step 2: Set up the script

Save this script with your API key:

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

api_key = 'sk-your-api-key'
project_id = "your project id"

# Retrieves the current retention policy configuration for a specific project
# This function queries the Braintrust API to get all project automations and filters
# for the retention policy automation specifically
# Args:
#   api_key (str): The API key for authentication with Braintrust API
#   project_id (str): The unique identifier of the project to query
# Returns:
#   dict: The retention policy automation configuration, or empty string if none exists
def get_retention_policy(api_key, project_id):
    url = "https://api.braintrust.dev/api/project_automation/get"

    headers = {
        "Authorization": "Bearer " + api_key,
        "Content-Type": "application/json"
    }

    data = {
        "project_id": project_id
    }

    response = requests.post(url, json=data, headers=headers)

    retention_config = ""
    for automation in response.json():
        if (automation['config']['event_type'] == 'retention'):
            retention_config = automation

    return(retention_config)

# Creates a new retention policy or updates an existing one for a project
# This function first checks if a retention policy already exists for the project.
# If no policy exists, it creates a new one with the specified parameters.
# If a policy exists, it updates the retention period while preserving other settings.
# Args:
#   api_key (str): The API key for authentication with Braintrust API
#   project_id (str): The unique identifier of the project
#   retention_period (int): Number of days to retain logs before deletion
#   retention_target (str): Type of objects to apply retention to (e.g., 'project_logs')
# Returns:
#   dict: The API response containing the created or updated policy information
def create_or_update_retention_policy(api_key, project_id, retention_period, retention_target):
    url = "https://api.braintrust.dev/api/project_automation/register"

    headers = {
        "Authorization": "Bearer " + api_key,
        "Content-Type": "application/json"
    }
    policy = get_retention_policy(api_key, project_id)
    if policy == "":
        data = {
            "project_automation_name": str(retention_period) + "-Day Log Retention Policy",
            "description": "Automatically delete project logs older than + str(retention_period) + days",
            "project_id": project_id,
            "config": {
                "event_type": "retention",
                "object_type": retention_target,
                "retention_days": retention_period
            }
        }
        print("Retention policy for project ID " + project_id + " does not exist, creating")
    else:
        data = {
            "project_automation_name": policy['name'],
            "description": policy['description'],
            "project_id": project_id,
            "config": {
                "event_type": "retention",
                "object_type": policy['config']['object_type'],
                "retention_days": retention_period
            },
            "update": True
        }
        print("Retention policy for project ID " + project_id + " exist, updating")

    response = requests.post(url, json=data, headers=headers)
    return response.json()

# Retrieves a complete list of all projects accessible with the given API key
# This function handles pagination automatically to ensure all projects are returned,
# even if there are more than 500 projects (the API limit per request).
# It continues making requests until all projects have been retrieved.
# Args:
#   api_key (str): The API key for authentication with Braintrust API
# Returns:
#   list: A list of all project objects, each containing project details like id, name, etc.
def get_project_list(api_key):
    url = "https://api.braintrust.dev/v1/project"
    params = {
        "limit": 500
    }

    headers = {
        "Authorization": "Bearer " + api_key
    }

    response = requests.get(url, headers=headers, params=params)
    project_list = response.json()['objects']
    while len(response.json()['objects']) == 500:
        params = {
            "limit": 500,
            "starting_after": response.json()['objects'][499]['id']
        }
        response = requests.get(url, headers=headers, params=params)
        project_list.extend(response.json()['objects'])
    return project_list

# retention_config = get_retention_policy(api_key, project_id)
# print(retention_config)

# retention_config = create_or_update_retention_policy(api_key, project_id, 93, 'project_logs')
# print(retention_config)

# project_list = get_project_list(api_key)
# print(str(project_list))
```

### Step 3: Apply retention policy to all projects

Uncomment and modify the example usage at the bottom of the script to apply 30-day retention across all projects:

```python theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
# Get all projects
project_list = get_project_list(api_key)

# Apply 30-day retention to each project
for project in project_list:
    retention_config = create_or_update_retention_policy(api_key, project['id'], 30, 'project_logs')
    print(f"Project {project['name']}: {retention_config}")
```

### Step 4: Verify configuration

Check a specific project's policy:

```python theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
retention_config = get_retention_policy(api_key, "your-project-id")
print(retention_config)
```

## Notes

* Existing data older than 30 days is **permanently deleted** once a policy is applied.
* The script checks for existing policies and updates them instead of creating duplicates.
* Re-run the script for new projects created after initial setup.
* Retention automations run on a system schedule — no separate cron step is required.

## References

* [Configure data retention — Braintrust docs](https://www.braintrust.dev/docs/admin/automations/configure-data-retention)
* [Plans and limits](https://www.braintrust.dev/docs/plans-and-limits)
