Api

API Examples

Curl examples for every Capacitarr API endpoint.

Setup

Set these environment variables before running the examples:

export CAPACITARR_URL="http://localhost:2187/api/v1"
export CAPACITARR_API_KEY="your-api-key-here"

All examples use the X-Api-Key header for authentication unless the endpoint is unauthenticated or requires a Bearer token.


Health

Check server health

curl "$CAPACITARR_URL/health"
{
  "status": "ok",
  "eventsDropped": 0
}

Get version information

curl -s "$CAPACITARR_URL/version" | jq
{
  "version": "2.0.0",
  "commit": "a1b2c3d",
  "buildDate": "2026-03-06T12:00:00Z"
}

Auth

Login

Obtain a JWT token. No authentication required.

curl -s -X POST "$CAPACITARR_URL/auth/login" \
  -H "Content-Type: application/json" \
  -d '{"username":"admin","password":"your-password"}' | jq
{
  "message": "success",
  "token": "eyJhbGciOiJIUzI1NiIs..."
}

The response also sets a jwt cookie for browser-based clients.

Rate limit: 10 attempts per 15 minutes per IP.

Change password

Requires Bearer token authentication.

curl -s -X PUT "$CAPACITARR_URL/auth/password" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"currentPassword":"old-password","newPassword":"new-password"}' | jq

Change username

Requires Bearer token authentication.

curl -s -X PUT "$CAPACITARR_URL/auth/username" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"newUsername":"new-username","currentPassword":"your-current-password"}' | jq

Get API key status

Check whether an API key has been generated.

curl -s -H "X-Api-Key: $CAPACITARR_API_KEY" \
  "$CAPACITARR_URL/auth/apikey" | jq

Generate API key

Creates a new API key, replacing any existing one. Requires Bearer token authentication.

curl -s -X POST "$CAPACITARR_URL/auth/apikey" \
  -H "Authorization: Bearer $TOKEN" | jq
{
  "api_key": "ck_a1b2c3d4e5f6..."
}

Important: Store this key securely — it cannot be retrieved again.


Disk Groups

List all disk groups

curl -s -H "X-Api-Key: $CAPACITARR_API_KEY" \
  "$CAPACITARR_URL/disk-groups" | jq
[
  {
    "id": 1,
    "mountPath": "/mnt/media",
    "totalBytes": 2000000000000,
    "usedBytes": 1800000000000,
    "thresholdPct": 85,
    "targetPct": 75
  }
]

Update a disk group

Set threshold and target percentages for a disk group.

curl -s -X PUT -H "X-Api-Key: $CAPACITARR_API_KEY" \
  -H "Content-Type: application/json" \
  "$CAPACITARR_URL/disk-groups/1" \
  -d '{"thresholdPct":90,"targetPct":80}' | jq

Dashboard

Get dashboard stats

curl -s -H "X-Api-Key: $CAPACITARR_API_KEY" \
  "$CAPACITARR_URL/dashboard-stats" | jq
{
  "totalBytesReclaimed": 524288000000,
  "totalItemsRemoved": 42,
  "totalEngineRuns": 15,
  "protectedCount": 128,
  "growthBytesPerWeek": 10737418240,
  "hasGrowthData": true
}

Get lifetime stats

curl -s -H "X-Api-Key: $CAPACITARR_API_KEY" \
  "$CAPACITARR_URL/lifetime-stats" | jq

Get worker stats

curl -s -H "X-Api-Key: $CAPACITARR_API_KEY" \
  "$CAPACITARR_URL/worker/stats" | jq

Metrics

Get metrics history

Query historical disk usage metrics with configurable resolution and time range.

curl -s -H "X-Api-Key: $CAPACITARR_API_KEY" \
  "$CAPACITARR_URL/metrics/history?resolution=hourly&since=24h" | jq

Query parameters:

ParameterValuesDefaultDescription
resolutionraw, hourly, dailyrawAggregation level
since1h, 24h, 7d, 30dTime range
disk_group_idintegerFilter by disk group

Filter by disk group:

curl -s -H "X-Api-Key: $CAPACITARR_API_KEY" \
  "$CAPACITARR_URL/metrics/history?resolution=daily&since=7d&disk_group_id=1" | jq

Engine

Trigger an engine run

Start the scoring engine manually. Returns immediately — the engine runs asynchronously.

curl -s -X POST -H "X-Api-Key: $CAPACITARR_API_KEY" \
  "$CAPACITARR_URL/engine/run" | jq
{
  "status": "triggered"
}

If an engine run is already in progress or queued:

{
  "status": "already_pending"
}

Get engine run history

curl -s -H "X-Api-Key: $CAPACITARR_API_KEY" \
  "$CAPACITARR_URL/engine/history?range=24h" | jq
{
  "status": "success",
  "data": [
    {
      "id": 42,
      "runAt": "2026-03-06T12:00:00Z",
      "evaluated": 97,
      "flagged": 12,
      "deleted": 3,
      "freedBytes": 15032385536,
      "executionMode": "approval",
      "durationMs": 1234
    }
  ]
}

Integrations

List all integrations

curl -s -H "X-Api-Key: $CAPACITARR_API_KEY" \
  "$CAPACITARR_URL/integrations" | jq
[
  {
    "id": 1,
    "type": "sonarr",
    "name": "Sonarr Main",
    "url": "http://sonarr:8989",
    "apiKey": "abc123...",
    "enabled": true,
    "libraryId": 1,
    "collectionDeletion": false,
    "lastSync": "2026-03-06T12:00:00Z"
  }
]

Create an integration

curl -s -X POST -H "X-Api-Key: $CAPACITARR_API_KEY" \
  -H "Content-Type: application/json" \
  "$CAPACITARR_URL/integrations" \
  -d '{
    "type": "sonarr",
    "name": "Sonarr Main",
    "url": "http://sonarr:8989",
    "apiKey": "your-sonarr-api-key",
    "enabled": true,
    "libraryId": 1
  }' | jq

Get an integration

curl -s -H "X-Api-Key: $CAPACITARR_API_KEY" \
  "$CAPACITARR_URL/integrations/1" | jq

Update an integration

curl -s -X PUT -H "X-Api-Key: $CAPACITARR_API_KEY" \
  -H "Content-Type: application/json" \
  "$CAPACITARR_URL/integrations/1" \
  -d '{
    "type": "sonarr",
    "name": "Sonarr Main (updated)",
    "url": "http://sonarr:8989",
    "apiKey": "your-sonarr-api-key",
    "enabled": true,
    "libraryId": 1
  }' | jq

Delete an integration

curl -s -X DELETE -H "X-Api-Key: $CAPACITARR_API_KEY" \
  "$CAPACITARR_URL/integrations/1" | jq

Test an integration connection

Verify connectivity to an external service without saving the integration.

curl -s -X POST -H "X-Api-Key: $CAPACITARR_API_KEY" \
  -H "Content-Type: application/json" \
  "$CAPACITARR_URL/integrations/test" \
  -d '{
    "type": "sonarr",
    "url": "http://sonarr:8989",
    "apiKey": "your-sonarr-api-key"
  }' | jq

Trigger integration sync

Pull the latest media data from all integrations.

curl -s -X POST -H "X-Api-Key: $CAPACITARR_API_KEY" \
  "$CAPACITARR_URL/integrations/sync" | jq

Get integration health

Check the health and recovery status of all integrations.

curl -s -H "X-Api-Key: $CAPACITARR_API_KEY" \
  "$CAPACITARR_URL/integrations/health" | jq

Rules (Protections)

Get available rule fields

Returns the fields and operators you can use when creating custom rules.

curl -s -H "X-Api-Key: $CAPACITARR_API_KEY" \
  "$CAPACITARR_URL/rule-fields" | jq
[
  {
    "field": "title",
    "type": "string",
    "operators": ["contains", "not_contains", "equals", "not_equals", "regex"]
  },
  {
    "field": "sizeBytes",
    "type": "number",
    "operators": ["gt", "lt", "gte", "lte", "equals"]
  }
]

List all custom rules

curl -s -H "X-Api-Key: $CAPACITARR_API_KEY" \
  "$CAPACITARR_URL/custom-rules" | jq
[
  {
    "id": 1,
    "field": "title",
    "operator": "contains",
    "value": "Firefly",
    "effect": "always_keep",
    "integrationId": 1,
    "enabled": true,
    "sortOrder": 0
  }
]

Create a protection rule

curl -s -X POST -H "X-Api-Key: $CAPACITARR_API_KEY" \
  -H "Content-Type: application/json" \
  "$CAPACITARR_URL/custom-rules" \
  -d '{
    "field": "title",
    "operator": "contains",
    "value": "Firefly",
    "effect": "always_keep",
    "integrationId": 1
  }' | jq

Update a protection rule

curl -s -X PUT -H "X-Api-Key: $CAPACITARR_API_KEY" \
  -H "Content-Type: application/json" \
  "$CAPACITARR_URL/custom-rules/1" \
  -d '{
    "field": "title",
    "operator": "contains",
    "value": "Firefly",
    "effect": "always_keep",
    "integrationId": 1
  }' | jq

Reorder rules

curl -s -X PUT -H "X-Api-Key: $CAPACITARR_API_KEY" \
  -H "Content-Type: application/json" \
  "$CAPACITARR_URL/custom-rules/reorder" \
  -d '{"ids":[3,1,2]}' | jq

Delete a protection rule

curl -s -X DELETE -H "X-Api-Key: $CAPACITARR_API_KEY" \
  "$CAPACITARR_URL/custom-rules/1" | jq

Get rule impact analysis

curl -s -H "X-Api-Key: $CAPACITARR_API_KEY" \
  "$CAPACITARR_URL/custom-rules/1/impact" | jq

Get rule context

curl -s -H "X-Api-Key: $CAPACITARR_API_KEY" \
  "$CAPACITARR_URL/custom-rules/1/context" | jq

Factor Weights

List scoring factor weights

Returns all scoring factors with current weights and metadata.

curl -s -H "X-Api-Key: $CAPACITARR_API_KEY" \
  "$CAPACITARR_URL/scoring-factor-weights" | jq
[
  {
    "key": "watch_history",
    "name": "Watch History",
    "description": "Number of times the media has been watched",
    "weight": 10,
    "defaultWeight": 10
  },
  {
    "key": "file_size",
    "name": "File Size",
    "description": "Total size of media files",
    "weight": 6,
    "defaultWeight": 6
  }
]

Update scoring factor weights

Pass a map of factor keys to weight values (0–10 scale).

curl -s -X PUT -H "X-Api-Key: $CAPACITARR_API_KEY" \
  -H "Content-Type: application/json" \
  "$CAPACITARR_URL/scoring-factor-weights" \
  -d '{
    "watch_history": 10,
    "file_size": 6,
    "rating": 5,
    "time_in_library": 4
  }' | jq

Settings Backup

Export settings

# Export all settings to a JSON file
curl -s -H "X-Api-Key: $CAPACITARR_API_KEY" \
  "$CAPACITARR_URL/settings/export" \
  -o capacitarr-settings.json

# Export only rules and preferences
curl -s -H "X-Api-Key: $CAPACITARR_API_KEY" \
  "$CAPACITARR_URL/settings/export?sections=rules,preferences" \
  -o capacitarr-rules-prefs.json

# View the export without saving
curl -s -H "X-Api-Key: $CAPACITARR_API_KEY" \
  "$CAPACITARR_URL/settings/export" | jq .

Import settings

# Import all sections from a settings export file
curl -s -X POST -H "X-Api-Key: $CAPACITARR_API_KEY" \
  -H "Content-Type: application/json" \
  "$CAPACITARR_URL/settings/import" \
  -d "{
    \"envelope\": $(cat capacitarr-settings.json),
    \"sections\": {
      \"preferences\": true,
      \"rules\": true,
      \"integrations\": true,
      \"diskGroups\": true,
      \"notifications\": true
    }
  }"

# Import only rules from an export file
curl -s -X POST -H "X-Api-Key: $CAPACITARR_API_KEY" \
  -H "Content-Type: application/json" \
  "$CAPACITARR_URL/settings/import" \
  -d "{
    \"envelope\": $(cat capacitarr-settings.json),
    \"sections\": {\"rules\": true}
  }"

Note: Sensitive credentials (API keys, webhook URLs) are stripped from exports. After importing integrations or notification channels, re-enter credentials manually.

Preview import

Preview what an import would change before applying.

curl -s -X POST -H "X-Api-Key: $CAPACITARR_API_KEY" \
  -H "Content-Type: application/json" \
  "$CAPACITARR_URL/settings/import/preview" \
  -d "{
    \"envelope\": $(cat capacitarr-settings.json),
    \"sections\": {
      \"preferences\": true,
      \"rules\": true
    }
  }" | jq

Commit import

Apply a previously previewed import.

curl -s -X POST -H "X-Api-Key: $CAPACITARR_API_KEY" \
  -H "Content-Type: application/json" \
  "$CAPACITARR_URL/settings/import/commit" \
  -d "{
    \"envelope\": $(cat capacitarr-settings.json),
    \"sections\": {
      \"preferences\": true,
      \"rules\": true
    }
  }" | jq

Preview

Preview scored media

Returns all media items ranked by their composite deletion score. Items at the top of the list would be deleted first when the engine runs.

curl -s -H "X-Api-Key: $CAPACITARR_API_KEY" \
  "$CAPACITARR_URL/preview" | jq
[
  {
    "title": "Firefly S01",
    "sizeBytes": 42949672960,
    "score": 87.5,
    "factors": {
      "age": 25.0,
      "size": 30.0,
      "lastWatched": 20.0,
      "popularity": 12.5
    },
    "protected": false,
    "integration": "Sonarr Main"
  }
]

Tip: Pipe through jq '.[:5]' to see only the top 5 deletion candidates.


Preferences

Get current preferences

curl -s -H "X-Api-Key: $CAPACITARR_API_KEY" \
  "$CAPACITARR_URL/preferences" | jq
{
  "id": 1,
  "logLevel": "info",
  "auditLogRetentionDays": 30,
  "pollIntervalSeconds": 300,
  "defaultDiskGroupMode": "dry-run",
  "tiebreakerMethod": "size_desc",
  "deletionsEnabled": true,
  "snoozeDurationHours": 24,
  "checkForUpdates": true,
  "deadContentMinDays": 90,
  "staleContentDays": 180,
  "sunsetDays": 30,
  "sunsetLabel": "capacitarr-sunset",
  "posterOverlayStyle": "countdown",
  "sunsetRescoreEnabled": true,
  "savedDurationDays": 7,
  "savedLabel": "capacitarr-saved",
  "backupRetentionDays": 7,
  "diskGroupGracePeriodDays": 7,
  "deletionQueueDelaySeconds": 30,
  "updatedAt": "2026-03-06T12:00:00Z"
}

Update preferences

curl -s -X PUT -H "X-Api-Key: $CAPACITARR_API_KEY" \
  -H "Content-Type: application/json" \
  "$CAPACITARR_URL/preferences" \
  -d '{
    "logLevel": "info",
    "auditLogRetentionDays": 30,
    "pollIntervalSeconds": 300,
    "defaultDiskGroupMode": "dry-run",
    "tiebreakerMethod": "size_desc",
    "deletionsEnabled": true,
    "snoozeDurationHours": 24,
    "checkForUpdates": true,
    "deletionQueueDelaySeconds": 30,
    "deadContentMinDays": 90,
    "staleContentDays": 180
  }' | jq

Note: Scoring factor weights are managed separately via the /scoring-factor-weights endpoint.

Patch preferences by group

Update a subset of preferences by group without sending the full object.

# Engine settings
curl -s -X PATCH -H "X-Api-Key: $CAPACITARR_API_KEY" \
  -H "Content-Type: application/json" \
  "$CAPACITARR_URL/preferences/engine" \
  -d '{"deletionsEnabled": true, "defaultDiskGroupMode": "approval"}' | jq

# Sunset settings
curl -s -X PATCH -H "X-Api-Key: $CAPACITARR_API_KEY" \
  -H "Content-Type: application/json" \
  "$CAPACITARR_URL/preferences/sunset" \
  -d '{"sunsetDays": 14, "posterOverlayStyle": "simple"}' | jq

# Content analytics settings
curl -s -X PATCH -H "X-Api-Key: $CAPACITARR_API_KEY" \
  -H "Content-Type: application/json" \
  "$CAPACITARR_URL/preferences/content" \
  -d '{"deadContentMinDays": 60, "staleContentDays": 120}' | jq

# Advanced settings
curl -s -X PATCH -H "X-Api-Key: $CAPACITARR_API_KEY" \
  -H "Content-Type: application/json" \
  "$CAPACITARR_URL/preferences/advanced" \
  -d '{"pollIntervalSeconds": 600, "backupRetentionDays": 14}' | jq

Approval Queue

List approval queue items

curl -s -H "X-Api-Key: $CAPACITARR_API_KEY" \
  "$CAPACITARR_URL/approval-queue" | jq
[
  {
    "id": 1,
    "mediaName": "Firefly S01",
    "mediaType": "season",
    "scoreDetails": "[{\"factor\":\"watchHistory\",\"rawScore\":1.0,\"weight\":10}]",
    "sizeBytes": 42949672960,
    "score": 87.5,
    "integrationId": 1,
    "externalId": "12345",
    "status": "pending",
    "trigger": "engine",
    "createdAt": "2026-03-06T12:00:00Z",
    "updatedAt": "2026-03-06T12:00:00Z"
  }
]

Query parameters:

ParameterValuesDefaultDescription
statuspending, approved, rejectedFilter by status

Approve an item

curl -s -X POST -H "X-Api-Key: $CAPACITARR_API_KEY" \
  "$CAPACITARR_URL/approval-queue/1/approve" | jq

Note: Returns 409 Conflict if deletions are disabled in settings. Enable deletions before approving items.

Reject (snooze) an item

curl -s -X POST -H "X-Api-Key: $CAPACITARR_API_KEY" \
  "$CAPACITARR_URL/approval-queue/1/reject" | jq

Unsnooze a rejected item

curl -s -X POST -H "X-Api-Key: $CAPACITARR_API_KEY" \
  "$CAPACITARR_URL/approval-queue/1/unsnooze" | jq

Remove an item from the queue

curl -s -X DELETE -H "X-Api-Key: $CAPACITARR_API_KEY" \
  "$CAPACITARR_URL/approval-queue/1" | jq

Clear all approval queue items

curl -s -X POST -H "X-Api-Key: $CAPACITARR_API_KEY" \
  "$CAPACITARR_URL/approval-queue/clear" | jq

Approve an entire collection group

curl -s -X POST -H "X-Api-Key: $CAPACITARR_API_KEY" \
  -H "Content-Type: application/json" \
  "$CAPACITARR_URL/approval-queue/group/approve" \
  -d '{"collectionGroup":"My Collection"}' | jq

Reject an entire collection group

curl -s -X POST -H "X-Api-Key: $CAPACITARR_API_KEY" \
  -H "Content-Type: application/json" \
  "$CAPACITARR_URL/approval-queue/group/reject" \
  -d '{"collectionGroup":"My Collection"}' | jq

Deletion Queue

List deletion queue items

curl -s -H "X-Api-Key: $CAPACITARR_API_KEY" \
  "$CAPACITARR_URL/deletion-queue" | jq

Cancel a deletion

Remove a specific item from the deletion queue by name and type (passed as query parameters).

curl -s -X DELETE -H "X-Api-Key: $CAPACITARR_API_KEY" \
  "$CAPACITARR_URL/deletion-queue?mediaName=Firefly%20S01&mediaType=season" | jq

Snooze a deletion queue item

curl -s -X POST -H "X-Api-Key: $CAPACITARR_API_KEY" \
  -H "Content-Type: application/json" \
  "$CAPACITARR_URL/deletion-queue/snooze" \
  -d '{"mediaName":"Firefly S01","mediaType":"season"}' | jq

Clear the deletion queue

Cancel all pending deletions.

curl -s -X POST -H "X-Api-Key: $CAPACITARR_API_KEY" \
  "$CAPACITARR_URL/deletion-queue/clear" | jq

Get grace period state

curl -s -H "X-Api-Key: $CAPACITARR_API_KEY" \
  "$CAPACITARR_URL/deletion-queue/grace-period" | jq
{
  "active": true,
  "remainingSeconds": 15,
  "queueSize": 3
}

Manually queue items for deletion

Queue one or more media items for deletion, bypassing the normal engine evaluation.

curl -s -X POST -H "X-Api-Key: $CAPACITARR_API_KEY" \
  -H "Content-Type: application/json" \
  "$CAPACITARR_URL/delete" \
  -d '[{
    "mediaName": "Serenity",
    "mediaType": "movie",
    "integrationId": 1,
    "externalId": "42",
    "sizeBytes": 5069636198,
    "posterUrl": "",
    "score": 85.0,
    "scoreDetails": "[]"
  }]' | jq

Sunset Queue

The sunset queue holds media items that have been scored for deletion but are in a grace period before the actual delete fires. During this window labels and poster overlays may be applied to signal the upcoming removal.

List sunset queue items

curl -s -H "X-Api-Key: $CAPACITARR_API_KEY" \
  "$CAPACITARR_URL/sunset-queue" | jq
[
  {
    "id": 1,
    "mediaName": "Serenity",
    "mediaType": "movie",
    "tmdbId": 16320,
    "integrationId": 2,
    "sizeBytes": 8589934592,
    "score": 0.72,
    "scoreDetails": "[{\"rule\":\"age\",\"score\":0.72}]",
    "posterUrl": "https://image.tmdb.org/t/p/w500/xxx.jpg",
    "diskGroupId": 1,
    "collectionGroup": "",
    "trigger": "engine",
    "deletionDate": "2026-04-15",
    "daysRemaining": 17,
    "labelApplied": true,
    "posterOverlayActive": false,
    "createdAt": "2026-03-29T12:00:00Z"
  }
]

Cancel a sunset item

Remove a specific item from the sunset queue. This also removes any labels or poster overlays that were applied.

curl -s -X DELETE -H "X-Api-Key: $CAPACITARR_API_KEY" \
  "$CAPACITARR_URL/sunset-queue/1" | jq
{
  "status": "cancelled"
}

Reschedule a sunset item

Change the deletion date for a sunset item. The date must be in YYYY-MM-DD format and cannot be in the past.

curl -s -X PATCH -H "X-Api-Key: $CAPACITARR_API_KEY" \
  -H "Content-Type: application/json" \
  "$CAPACITARR_URL/sunset-queue/1" \
  -d '{"deletionDate":"2026-05-01"}' | jq
{
  "id": 1,
  "mediaName": "Serenity",
  "deletionDate": "2026-05-01",
  "daysRemaining": 33
}

Clear sunset queue

Cancel all sunset items at once. Labels and poster overlays are removed for every cancelled item.

curl -s -X POST -H "X-Api-Key: $CAPACITARR_API_KEY" \
  "$CAPACITARR_URL/sunset-queue/clear" | jq
{
  "status": "cleared",
  "cancelled": 5
}

Refresh labels

Re-apply sunset labels to all active sunset queue items. Useful after changing the sunset label name in preferences.

curl -s -X POST -H "X-Api-Key: $CAPACITARR_API_KEY" \
  "$CAPACITARR_URL/sunset-queue/refresh-labels" | jq
{
  "status": "refreshed",
  "refreshed": 4
}

Refresh posters

Re-apply poster overlays to all active sunset queue items. Useful after changing the poster overlay style in preferences.

curl -s -X POST -H "X-Api-Key: $CAPACITARR_API_KEY" \
  "$CAPACITARR_URL/sunset-queue/refresh-posters" | jq
{
  "status": "refreshed",
  "refreshed": 4
}

Restore all posters

Emergency action: restore all original poster images that have been overlaid with sunset countdown artwork.

curl -s -X POST -H "X-Api-Key: $CAPACITARR_API_KEY" \
  "$CAPACITARR_URL/sunset-queue/restore-posters" | jq
{
  "status": "restored",
  "restored": 3
}

Audit Log

The audit log stores a permanent, append-only history of deletions and dry-runs. It does not contain approval queue items — those live in the approval queue.

List audit log entries (paginated)

curl -s -H "X-Api-Key: $CAPACITARR_API_KEY" \
  "$CAPACITARR_URL/audit-log?limit=20&offset=0" | jq
{
  "data": [
    {
      "id": 42,
      "mediaName": "Firefly S01",
      "mediaType": "season",
      "action": "deleted",
      "sizeBytes": 42949672960,
      "score": 87.5,
      "trigger": "engine",
      "integrationId": 1,
      "createdAt": "2026-03-06T12:00:00Z"
    }
  ],
  "total": 150
}

Pagination parameters:

ParameterDefaultDescription
limit20Number of entries to return
offset0Number of entries to skip
actionFilter by action: deleted, dry_run, dry_delete

Get recent audit log entries

curl -s -H "X-Api-Key: $CAPACITARR_API_KEY" \
  "$CAPACITARR_URL/audit-log/recent?limit=10" | jq

Get grouped audit log entries

curl -s -H "X-Api-Key: $CAPACITARR_API_KEY" \
  "$CAPACITARR_URL/audit-log/grouped" | jq

Activity Events

Get recent activity events

curl -s -H "X-Api-Key: $CAPACITARR_API_KEY" \
  "$CAPACITARR_URL/activity/recent?limit=100" | jq
[
  {
    "id": 1,
    "eventType": "engine_complete",
    "message": "Engine run completed: evaluated 97, flagged 12",
    "metadata": "{\"evaluated\":97,\"flagged\":12}",
    "createdAt": "2026-03-06T12:01:00Z"
  }
]

SSE (Server-Sent Events)

Subscribe to real-time events

Connect to the SSE endpoint for real-time event streaming. This is a long-lived HTTP connection.

curl -N -H "X-Api-Key: $CAPACITARR_API_KEY" \
  "$CAPACITARR_URL/events"
id: 1741199820-001
event: engine_start
data: {"message":"Engine run started in approval mode","executionMode":"approval"}

id: 1741199825-002
event: engine_complete
data: {"message":"Engine run completed: evaluated 97, flagged 12","evaluated":97,"flagged":12}

id: 1741199826-003
event: deletion_success
data: {"message":"Deleted: Serenity (4.72 GB freed)","title":"Serenity","sizeBytes":5069636198}

To resume from a specific event after disconnection, pass the Last-Event-ID header:

curl -N -H "X-Api-Key: $CAPACITARR_API_KEY" \
  -H "Last-Event-ID: 1741199825-002" \
  "$CAPACITARR_URL/events"

See the Architecture documentation for the complete list of event types.


Notifications

List notification channels

curl -s -H "X-Api-Key: $CAPACITARR_API_KEY" \
  "$CAPACITARR_URL/notifications/channels" | jq

Create a Discord notification channel

curl -s -X POST -H "X-Api-Key: $CAPACITARR_API_KEY" \
  -H "Content-Type: application/json" \
  "$CAPACITARR_URL/notifications/channels" \
  -d '{
    "type": "discord",
    "name": "My Discord",
    "webhookUrl": "https://discord.com/api/webhooks/...",
    "enabled": true,
    "notificationLevel": "normal"
  }' | jq

Create an Apprise notification channel

curl -s -X POST -H "X-Api-Key: $CAPACITARR_API_KEY" \
  -H "Content-Type: application/json" \
  "$CAPACITARR_URL/notifications/channels" \
  -d '{
    "type": "apprise",
    "name": "Telegram via Apprise",
    "webhookUrl": "http://apprise:8000",
    "appriseTags": "telegram",
    "enabled": true,
    "notificationLevel": "important"
  }' | jq

Update a notification channel (with per-event override)

curl -s -X PUT -H "X-Api-Key: $CAPACITARR_API_KEY" \
  -H "Content-Type: application/json" \
  "$CAPACITARR_URL/notifications/channels/1" \
  -d '{
    "name": "My Discord (updated)",
    "enabled": true,
    "notificationLevel": "normal",
    "overrideCycleDigest": false
  }' | jq

Delete a notification channel

curl -s -X DELETE -H "X-Api-Key: $CAPACITARR_API_KEY" \
  "$CAPACITARR_URL/notifications/channels/1" | jq

Test a notification channel

curl -s -X POST -H "X-Api-Key: $CAPACITARR_API_KEY" \
  "$CAPACITARR_URL/notifications/channels/1/test" | jq

Analytics

Get dead content

Returns media items that have never been watched since being added to the library.

curl -s -H "X-Api-Key: $CAPACITARR_API_KEY" \
  "$CAPACITARR_URL/analytics/dead-content" | jq

# With custom minimum days in library
curl -s -H "X-Api-Key: $CAPACITARR_API_KEY" \
  "$CAPACITARR_URL/analytics/dead-content?minDays=60" | jq

# Filter by disk group
curl -s -H "X-Api-Key: $CAPACITARR_API_KEY" \
  "$CAPACITARR_URL/analytics/dead-content?disk_group_id=1" | jq

Get stale content

Returns media items that haven't been watched in a long time.

curl -s -H "X-Api-Key: $CAPACITARR_API_KEY" \
  "$CAPACITARR_URL/analytics/stale-content" | jq

# With custom stale threshold
curl -s -H "X-Api-Key: $CAPACITARR_API_KEY" \
  "$CAPACITARR_URL/analytics/stale-content?staleDays=120" | jq

Get capacity forecast

Returns a capacity forecast based on linear regression of recent usage history.

curl -s -H "X-Api-Key: $CAPACITARR_API_KEY" \
  "$CAPACITARR_URL/analytics/forecast" | jq

# For a specific disk group
curl -s -H "X-Api-Key: $CAPACITARR_API_KEY" \
  "$CAPACITARR_URL/analytics/forecast?disk_group_id=1" | jq

Migration

Check migration status

Check whether a v1 database migration is available. This endpoint is public (no auth required).

curl -s "$CAPACITARR_URL/migration/status" | jq

Execute migration

Perform the v1-to-v2 database migration.

curl -s -X POST -H "X-Api-Key: $CAPACITARR_API_KEY" \
  "$CAPACITARR_URL/migration/execute" | jq

Dismiss migration

Dismiss the migration prompt without executing.

curl -s -X POST -H "X-Api-Key: $CAPACITARR_API_KEY" \
  "$CAPACITARR_URL/migration/dismiss" | jq

Data

Reset application data

Danger: This deletes all application data including integrations, rules, metrics, approval queue, and audit history. Lifetime stats and disk group thresholds are preserved. This action is irreversible.

curl -s -X DELETE -H "X-Api-Key: $CAPACITARR_API_KEY" \
  "$CAPACITARR_URL/data/reset" | jq

Version Check

Check for updates

curl -s -H "X-Api-Key: $CAPACITARR_API_KEY" \
  "$CAPACITARR_URL/version/check" | jq

Results are cached for 6 hours.

Force a fresh update check

curl -s -X POST -H "X-Api-Key: $CAPACITARR_API_KEY" \
  "$CAPACITARR_URL/version/check" | jq