Overview
Complete REST API for programmatic access to Preamp backup, restore, and device management.
Base URL
https://api.preamp.ai
Authentication
Most endpoints require a Bearer token. Get one by signing up with your email via /signup and verifying with /verify. Then pass it in the Authorization header:
Authorization: Bearer YOUR_DEVICE_TOKEN
Errors
All errors return a consistent JSON envelope:
{
"error": "VALIDATION_ERROR",
"message": "Invalid request body"
}
| Status | Meaning |
|---|---|
400 | Validation error — check the message field for details |
401 | Missing or invalid Bearer token |
404 | Resource not found |
429 | Rate limit exceeded — back off and retry |
500 | Internal server error |
Rate Limits
Global rate limit of 20 requests/second (burst 50). Auth endpoints have stricter per-IP and per-email limits. A 429 response means you’ve exceeded the limit.
Authentication
Sign up and verify your email to get a device token. These endpoints do not require a Bearer token.
POST /signup
Send a six-digit verification code to an email address. The response is identical for new and existing users to prevent email enumeration.
No authentication required
Request body
| Field | Type | Required | Description |
|---|---|---|---|
email | string | Yes | Email address (max 254 chars) |
curl -X POST https://api.preamp.ai/signup \
-H "Content-Type: application/json" \
-d '{"email": "dev@example.com"}'
{
"message": "Verification code sent"
}
POST /verify
Verify the six-digit code and register a device. Returns a Bearer token for all subsequent requests.
No authentication required
Request body
| Field | Type | Required | Description |
|---|---|---|---|
email | string | Yes | Email used during signup |
code | string | Yes | Six-digit verification code |
deviceName | string | Yes | Name for this device (max 100 chars) |
inviteToken | string | No | Organization invite token |
replaceDevice | boolean | No | Revoke existing device with the same name |
curl -X POST https://api.preamp.ai/verify \
-H "Content-Type: application/json" \
-d '{"email": "dev@example.com", "code": "123456", "deviceName": "my-laptop"}'
{
"userId": "usr_abc123",
"deviceToken": "tok_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"deviceId": "dev_xyz789",
"deviceName": "my-laptop",
"isNewUser": true
}
Save the deviceToken — it is your Bearer token for all authenticated endpoints.
Backup
Upload backup archives and check account status.
POST /backup
Upload a zip archive of agent configuration files. The server deduplicates unchanged files using HMAC hashes. Supports incremental backups via headers.
Headers
| Header | Required | Description |
|---|---|---|
Content-Type | Yes | Must be application/zip |
X-Unchanged-Files | No | JSON array of {path, hmacHash} for unchanged files (incremental backup) |
X-Deleted-Files | No | JSON array of file paths deleted since last backup |
X-Health-Warnings | No | JSON array of client-detected health warnings |
X-Client-Encryption | No | Set to “true” if archive is client-side encrypted |
curl -X POST https://api.preamp.ai/backup \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/zip" \
--data-binary @backup.zip
{
"snapshotId": "2026-04-09T10:30:00.000Z#snap_abc123",
"filesChanged": 5,
"filesUnchanged": 37,
"filesSkipped": 0,
"filesCarriedForward": 0,
"filesDeleted": 1,
"totalFiles": 42,
"totalSize": 1048576,
"healthWarnings": 0,
"fileHashes": {
".claude/settings.json": "a1b2c3...",
".cursor/rules": "d4e5f6..."
}
}
The fileHashes map enables incremental backups — send unchanged hashes via X-Unchanged-Files on the next backup to skip re-uploading them.
GET /status
Get comprehensive account and backup status including health, devices, tags, and pending suggestions.
curl https://api.preamp.ai/status \
-H "Authorization: Bearer YOUR_TOKEN"
{
"userId": "usr_abc123",
"email": "dev@example.com",
"plan": "free",
"backup": {
"health": "healthy",
"lastBackupAt": "2026-04-09T10:30:00.000Z",
"hoursSinceLastBackup": 1.5,
"lastSnapshotId": "2026-04-09T10:30:00.000Z#snap_abc123",
"lastSnapshotFiles": 42,
"lastSnapshotSize": 1048576,
"recentSnapshots": [...]
},
"devices": {
"total": 2,
"active": 2,
"current": "dev_xyz789"
},
"organization": null,
"tags": [],
"health": {
"status": "healthy",
"warningCount": 0,
"errorCount": 0
},
"pendingSuggestions": 0,
"lastVerifiedAt": "2026-04-08T15:00:00.000Z",
"lastVerifyResult": null
} Snapshots
List snapshots, view file changes, and manage tags.
GET /snapshots
List snapshots with optional filtering by device, date range, or tag.
Query parameters
| Parameter | Type | Description |
|---|---|---|
since | datetime | ISO 8601 lower bound (exclusive) |
limit | integer | Max results (1-100, default 20) |
deviceId | string | Filter to a specific device |
tag | string | Return only the snapshot with this tag |
curl "https://api.preamp.ai/snapshots?limit=5" \
-H "Authorization: Bearer YOUR_TOKEN"
{
"snapshots": [
{
"snapshotId": "2026-04-09T10:30:00.000Z#snap_abc123",
"timestamp": "2026-04-09T10:30:00.000Z",
"fileCount": 42,
"totalSize": 1048576,
"deviceId": "dev_xyz789",
"tags": ["pre-migration"]
}
]
}
GET /changes
List files that have changed since a given timestamp, sorted by most recently changed.
Query parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
since | datetime | Yes | ISO 8601 lower bound |
limit | integer | No | Max results (1-100, default 20) |
curl "https://api.preamp.ai/changes?since=2026-04-01T00:00:00Z" \
-H "Authorization: Bearer YOUR_TOKEN"
{
"since": "2026-04-01T00:00:00.000Z",
"files": [
{
"path": ".claude/CLAUDE.md",
"latestHmacHash": "a1b2c3...",
"latestSnapshotId": "2026-04-09T10:30:00.000Z#snap_abc123",
"latestTimestamp": "2026-04-09T10:30:00.000Z",
"changeCount": 3
}
],
"totalChanged": 1
}
POST /tags
Create a named tag for a snapshot. Tag names must be unique per user.
Request body
| Field | Type | Required | Description |
|---|---|---|---|
snapshotId | string | Yes | Snapshot ID to tag |
tagName | string | Yes | Tag name (max 100 chars, alphanumeric + spaces/hyphens/dots) |
description | string | No | Optional description (max 500 chars) |
curl -X POST https://api.preamp.ai/tags \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"snapshotId": "2026-04-09T10:30:00.000Z#snap_abc123", "tagName": "pre-migration"}'
{
"message": "Tag created",
"tagName": "pre-migration"
}
GET /tags
List all tags for the authenticated user.
curl https://api.preamp.ai/tags \
-H "Authorization: Bearer YOUR_TOKEN"
{
"tags": [
{
"tagName": "pre-migration",
"snapshotId": "2026-04-09T10:30:00.000Z#snap_abc123",
"timestamp": "2026-04-09T10:30:00.000Z",
"description": null,
"createdAt": "2026-04-09T11:00:00.000Z"
}
]
}
DELETE /tags/{tagName}
Delete a tag by name. The underlying snapshot is not affected.
curl -X DELETE "https://api.preamp.ai/tags/pre-migration" \
-H "Authorization: Bearer YOUR_TOKEN"
{
"message": "Tag deleted",
"tagName": "pre-migration"
} Restore
Restore files from a snapshot. Uses a two-step email verification flow for security.
POST /restore/{snapshotId}
Initiate or complete a snapshot restore. The snapshot ID must be URL-encoded.
Two-step flow
- Initiate: Call with an empty body. A verification code is emailed to your account.
- Complete: Call again with
{"code": "123456"}. Returns pre-signed download URLs for every file.
Step 1 — Initiate
curl -X POST "https://api.preamp.ai/restore/2026-04-09T10%3A30%3A00.000Z%23snap_abc123" \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json"
{
"status": "verification_required",
"message": "Verification code sent to d**@example.com"
}
Step 2 — Complete
curl -X POST "https://api.preamp.ai/restore/2026-04-09T10%3A30%3A00.000Z%23snap_abc123" \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"code": "123456"}'
{
"snapshotId": "2026-04-09T10:30:00.000Z#snap_abc123",
"timestamp": "2026-04-09T10:30:00.000Z",
"files": [
{
"path": ".claude/CLAUDE.md",
"downloadUrl": "https://s3.amazonaws.com/...",
"hmacHash": "a1b2c3...",
"size": 2048
}
]
}
Download URLs are pre-signed and expire after a short period. Download all files promptly.
Devices
List, rename, revoke, and delete registered devices.
GET /devices
List all devices for the authenticated user, including last backup info per device.
curl https://api.preamp.ai/devices \
-H "Authorization: Bearer YOUR_TOKEN"
{
"devices": [
{
"deviceId": "dev_xyz789",
"deviceName": "my-laptop",
"createdAt": "2026-03-01T12:00:00.000Z",
"lastUsedAt": "2026-04-09T10:30:00.000Z",
"lastIP": "203.0.113.1",
"status": "active",
"isCurrent": true,
"lastBackupAt": "2026-04-09T10:30:00.000Z",
"lastBackupFileCount": 42
}
]
}
POST /devices/{id}/revoke
Revoke a device, preventing it from authenticating. You cannot revoke the device making the request.
curl -X POST https://api.preamp.ai/devices/dev_abc123/revoke \
-H "Authorization: Bearer YOUR_TOKEN"
{
"message": "Device revoked",
"deviceId": "dev_abc123"
}
POST /devices/{id}/rename
Change the display name of a device.
Request body
| Field | Type | Required | Description |
|---|---|---|---|
deviceName | string | Yes | New name (1-100 chars) |
curl -X POST https://api.preamp.ai/devices/dev_xyz789/rename \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"deviceName": "work-macbook"}'
{
"message": "Device renamed",
"deviceId": "dev_xyz789",
"deviceName": "work-macbook"
}
DELETE /devices/{id}
Permanently delete a device. You cannot delete the device making the request.
curl -X DELETE https://api.preamp.ai/devices/dev_abc123 \
-H "Authorization: Bearer YOUR_TOKEN"
{
"message": "Device deleted",
"deviceId": "dev_abc123"
} Health
Monitor backup health, get smart restore suggestions, verify integrity, and view usage insights.
GET /health
Get health warnings from the latest snapshot — JSON syntax errors, disappeared files, emptied files, size anomalies, broken MCP configs, and secret detections.
curl https://api.preamp.ai/health \
-H "Authorization: Bearer YOUR_TOKEN"
{
"status": "warnings",
"warningCount": 1,
"errorCount": 0,
"warnings": [
{
"level": "warning",
"category": "size-anomaly",
"path": ".cursor/rules",
"message": "File size decreased by 80%"
}
],
"lastCheckedAt": "2026-04-09T10:30:00.000Z"
}
GET /suggestions
List active smart restore suggestions generated by regression analysis during backups.
curl https://api.preamp.ai/suggestions \
-H "Authorization: Bearer YOUR_TOKEN"
{
"suggestions": [
{
"userId": "usr_abc123",
"suggestionId": "sug_def456",
"type": "files-disappeared",
"severity": "high",
"message": "3 files disappeared from your Claude Code config",
"affectedPaths": [".claude/CLAUDE.md", ".claude/settings.json", ".claude/memory/MEMORY.md"],
"suggestedSnapshotId": "2026-04-08T10:00:00.000Z#snap_prev",
"createdAt": "2026-04-09T10:30:00.000Z",
"dismissedAt": null,
"expiresAt": 1744300000
}
]
}
POST /suggestions/{suggestionId}/dismiss
Dismiss a suggestion so it no longer appears as pending.
curl -X POST https://api.preamp.ai/suggestions/sug_def456/dismiss \
-H "Authorization: Bearer YOUR_TOKEN"
{
"dismissed": true,
"suggestionId": "sug_def456"
}
POST /verify-backup
Verify backup integrity. Samples up to 10 random files from the latest snapshot, re-downloads them from S3, and verifies their HMAC hashes.
curl -X POST https://api.preamp.ai/verify-backup \
-H "Authorization: Bearer YOUR_TOKEN"
{
"status": "passed",
"filesChecked": 10,
"filesValid": 10,
"filesFailed": 0,
"checkedAt": "2026-04-09T12:00:00.000Z"
}
GET /insights
Get 30-day usage analysis including stale files, bloated configs, duplicate content, and config sprawl.
curl https://api.preamp.ai/insights \
-H "Authorization: Bearer YOUR_TOKEN"
{
"insights": [
{
"type": "stale-files",
"severity": "low",
"message": "2 files haven't changed in 30 days",
"paths": [".aider/config.yml", ".continue/config.json"]
}
]
} Webhooks
Subscribe to events and receive HTTP POST notifications. See the webhook guide for event types, payload format, and signature verification.
POST /webhooks
Create a new webhook endpoint. The HMAC signing secret is only returned at creation — save it immediately.
Request body
| Field | Type | Required | Description |
|---|---|---|---|
url | string | Yes | HTTPS URL to receive deliveries (max 2000 chars) |
events | string[] | Yes | 1-10 event types to subscribe to |
curl -X POST https://api.preamp.ai/webhooks \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"url": "https://example.com/hooks/preamp", "events": ["backup-complete", "backup-failed"]}'
{
"webhookId": "wh_abc123",
"secret": "whsec_YOUR_WEBHOOK_SECRET",
"url": "https://example.com/hooks/preamp",
"events": ["backup-complete", "backup-failed"]
}
The secret is only returned once. Use it to verify webhook signatures.
GET /webhooks
List all registered webhook subscriptions.
curl https://api.preamp.ai/webhooks \
-H "Authorization: Bearer YOUR_TOKEN"
{
"webhooks": [
{
"webhookId": "wh_abc123",
"url": "https://example.com/hooks/preamp",
"events": ["backup-complete", "backup-failed"],
"enabled": true,
"createdAt": "2026-04-01T12:00:00.000Z",
"lastDeliveryAt": "2026-04-09T10:30:00.000Z",
"lastDeliveryStatus": 200
}
]
}
DELETE /webhooks/{webhookId}
Permanently delete a webhook subscription.
curl -X DELETE https://api.preamp.ai/webhooks/wh_abc123 \
-H "Authorization: Bearer YOUR_TOKEN"
{
"message": "Webhook deleted",
"webhookId": "wh_abc123"
}
POST /webhooks/{webhookId}/test
Send a test payload to the webhook URL. Returns the HTTP status code from the target. Slack-compatible formatting is used when the URL contains hooks.slack.com.
curl -X POST https://api.preamp.ai/webhooks/wh_abc123/test \
-H "Authorization: Bearer YOUR_TOKEN"
{
"message": "Test delivery sent",
"webhookId": "wh_abc123",
"deliveryStatus": 200
} Feedback
POST /feedback
Submit product feedback or bug reports.
Request body
| Field | Type | Required | Description |
|---|---|---|---|
message | string | Yes | Feedback message (1-2000 chars) |
category | string | No | One of: feature-request, bug, question, other (default: feature-request) |
curl -X POST https://api.preamp.ai/feedback \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"message": "Would love to see backup diffs in the dashboard", "category": "feature-request"}'
{
"message": "Feedback received — thank you!",
"feedbackId": "fb_abc123"
}