# Retention

> Tracon documentation. Tracon is a .NET package family that adds a control
> plane on Microsoft Agent Framework, published as NuGet packages that run
> inside your own ASP.NET Core application.
>
> Page: https://tracon.dev/http-api/retention/
> Summary: The retention endpoints of the Tracon HTTP API — 7 operations.

7 operations. `{prefix}` is the route prefix passed to
`MapTracon`; the template uses `/tracon`.

## GET {prefix}/api/retention

**Operation ID:** `TraconListRetentionPolicies`

**Lists a tenant's retention policies.**

Only targets that have an explicit policy appear here. A target missing from the list is not cleaned up at all — absence means 'keep forever', not 'use a default'. A policy is also kept while switched off, so 'enabled: false' is a configured-but-paused policy and is different from having none.

**Authorization:** bearer authentication; `Admin` role policy when that policy is registered; `PlatformRead` API-key scope.

| Response | Body | Headers |
|---|---|---|
| **200** OK | `application/json` → array of [`RetentionPolicy`](/http-api/schemas/retentionpolicy/) | — |

## GET {prefix}/api/retention/{target}

**Operation ID:** `TraconGetRetentionPolicy`

**Gets the retention policy for a single target.**

Two different failures are reported differently: an unrecognized target name returns 400 and lists the valid targets, while a valid target with no policy configured returns 404. Read that 404 as 'this data is never cleaned up'.

**Authorization:** bearer authentication; `Admin` role policy when that policy is registered; `PlatformRead` API-key scope.

| Parameter | In | Required | Type | Description and rules |
|---|---|---|---|---|
| `target` | path | yes | `string` | — |

| Response | Body | Headers |
|---|---|---|
| **200** OK | `application/json` → [`RetentionPolicy`](/http-api/schemas/retentionpolicy/) | — |

## PUT {prefix}/api/retention/{target}

**Operation ID:** `TraconSaveRetentionPolicy`

**Creates or updates the retention policy for a target.**

'maxAgeDays' and 'maxRows' are independent limits and both may be set; each must be at least 1 when given, and leaving both unset means the policy removes nothing. Saving does not delete anything by itself — the cleanup runs from the queue, so preview first. Every save is written to the audit trail with the previous and the new values. An unrecognized target returns 400.

**Authorization:** bearer authentication; `Admin` role policy when that policy is registered; `PlatformAdmin` API-key scope.

| Parameter | In | Required | Type | Description and rules |
|---|---|---|---|---|
| `target` | path | yes | `string` | — |

**Request body** (required):

- `application/json` → [`RetentionPolicySaveRequest`](/http-api/schemas/retentionpolicysaverequest/)

| Response | Body | Headers |
|---|---|---|
| **200** OK | `application/json` → [`RetentionPolicy`](/http-api/schemas/retentionpolicy/) | — |

## DELETE {prefix}/api/retention/{target}

**Operation ID:** `TraconDeleteRetentionPolicy`

**Deletes the retention policy for a target.**

Removing a policy stops the cleanup for that target; it deletes no data and restores none that was already deleted. To pause a cleanup while keeping the limits, save the policy with 'enabled: false' instead. The removal is written to the audit trail. An unrecognized target returns 400, a target with no policy returns 404.

**Authorization:** bearer authentication; `Admin` role policy when that policy is registered; `PlatformAdmin` API-key scope.

| Parameter | In | Required | Type | Description and rules |
|---|---|---|---|---|
| `target` | path | yes | `string` | — |

| Response | Body | Headers |
|---|---|---|
| **204** No Content | — | — |

## GET {prefix}/api/retention/history

**Operation ID:** `TraconRetentionHistory`

**Lists past cleanup runs.**

Each entry records one executed cleanup — the target, when it ran, and how many rows it removed — which is how a deletion is accounted for after the fact. Filter to one target with '?target='. Paging is offset based: 'skip' defaults to 0, 'take' to 50, and 'take' is clamped to 1..200 instead of being rejected. This history is not itself cleaned up by any policy — it is the permanent record of what was deleted.

**Authorization:** bearer authentication; `Admin` role policy when that policy is registered; `PlatformRead` API-key scope.

| Parameter | In | Required | Type | Description and rules |
|---|---|---|---|---|
| `target` | query | no | `string` | — |
| `skip` | query | no | `integer (int32)` | pattern `^-?(?:0\\|[1-9]\d*)$` |
| `take` | query | no | `integer (int32)` | pattern `^-?(?:0\\|[1-9]\d*)$` |

| Response | Body | Headers |
|---|---|---|
| **200** OK | `application/json` → array of [`RetentionRun`](/http-api/schemas/retentionrun/) | — |

## GET {prefix}/api/retention/preview

**Operation ID:** `TraconPreviewRetention`

**Shows how many rows would be deleted if run now. Does NOT delete.**

Run this before every cleanup: it is the only way to see the size of a deletion before it happens. The counts are computed against the data as it is right now, so they are an estimate — rows written between the preview and the run are included by the run. Without '?target=' every configured target is previewed; an unknown target name returns 400. Nothing is written and no job is queued.

**Authorization:** bearer authentication; `Admin` role policy when that policy is registered; `PlatformRead` API-key scope.

| Parameter | In | Required | Type | Description and rules |
|---|---|---|---|---|
| `target` | query | no | `string` | — |

| Response | Body | Headers |
|---|---|---|
| **200** OK | `application/json` → array of [`RetentionPreview`](/http-api/schemas/retentionpreview/) | — |

## POST {prefix}/api/retention/run

**Operation ID:** `TraconRunRetention`

**Runs the cleanup now.**

Does not run synchronously: an tracon.retention job is enqueued and processed from the queue.

**Authorization:** bearer authentication; `Admin` role policy when that policy is registered; `PlatformAdmin` API-key scope.

| Parameter | In | Required | Type | Description and rules |
|---|---|---|---|---|
| `target` | query | no | `string` | — |

| Response | Body | Headers |
|---|---|---|
| **200** OK | `application/json` → [`RetentionRunTriggerResponse`](/http-api/schemas/retentionruntriggerresponse/) | — |
