Skip to main content

Snapshot API

Usageโ€‹

import { epilot } from '@epilot/sdk'

epilot.authorize(() => '<token>')
const { data } = await epilot.snapshot.createSnapshot(...)

Tree-shakeable importโ€‹

import { getClient, authorize } from '@epilot/sdk/snapshot'

const snapshotClient = getClient()
authorize(snapshotClient, () => '<token>')
const { data } = await snapshotClient.createSnapshot(...)

Operationsโ€‹

Snapshots

ScheduledSnapshots

Schemas

createSnapshotโ€‹

Create a new snapshot of the given resources. Async โ€” returns immediately with a snapshot ID; client polls getSnapshot until create.status moves from in_progress to completed or failed.

POST /v1/snapshots

const { data } = await client.createSnapshot(
null,
{
name: 'string',
description: 'string',
trigger: 'manual',
blueprint_instance_id: 'string',
resources: [
{
type: 'string',
id: 'string'
}
]
},
)

listSnapshotsโ€‹

List snapshots for the caller's organization, newest first.

GET /v1/snapshots

const { data } = await client.listSnapshots({
cursor: 'example',
size: 1,
resource: ['...'],
trigger: 'example',
})
Response
{
"page_size": 0,
"cursor": "string",
"results": [
{
"id": "string",
"org_id": "string",
"name": "string",
"description": "string",
"trigger": "manual",
"blueprint_instance_id": "string",
"resource_counts": {},
"create": {
"type": "create",
"started_at": "1970-01-01T00:00:00.000Z",
"completed_at": "1970-01-01T00:00:00.000Z",
"status": "in_progress",
"error": "string",
"triggered_by": {
"name": "string",
"user_id": "string",
"token_id": "string"
}
},
"restores": [
{
"type": "create",
"started_at": "1970-01-01T00:00:00.000Z",
"completed_at": "1970-01-01T00:00:00.000Z",
"status": "in_progress",
"error": "string",
"triggered_by": {
"name": "string",
"user_id": "string",
"token_id": "string"
}
}
],
"matched_count": 0,
"scope": "selection",
"expires_at": "1970-01-01T00:00:00.000Z",
"capture_summary": {
"total": 0,
"captured": 0,
"skipped": 0,
"failed": 0
}
}
]
}

captureOrgSnapshotโ€‹

Snapshot the caller's whole organization now. Creates a scope: "org" snapshot row and starts a chunked capture Step Function, then returns immediately. The capture asynchronously fetches a fresh inv

POST /v1/snapshots:capture-org

const { data } = await client.captureOrgSnapshot(
null,
{
name: 'string',
retention: {
value: 1,
unit: 'days'
},
excluded_types: ['string']
},
)

getSnapshotโ€‹

Fetch a snapshot's metadata. Poll this endpoint to track create/restore progress.

GET /v1/snapshots/{id}

const { data } = await client.getSnapshot({
id: '123e4567-e89b-12d3-a456-426614174000',
})
Response
{
"id": "string",
"org_id": "string",
"name": "string",
"description": "string",
"trigger": "manual",
"blueprint_instance_id": "string",
"resource_counts": {},
"create": {
"type": "create",
"started_at": "1970-01-01T00:00:00.000Z",
"completed_at": "1970-01-01T00:00:00.000Z",
"status": "in_progress",
"error": "string",
"triggered_by": {
"name": "string",
"user_id": "string",
"token_id": "string"
}
},
"restores": [
{
"type": "create",
"started_at": "1970-01-01T00:00:00.000Z",
"completed_at": "1970-01-01T00:00:00.000Z",
"status": "in_progress",
"error": "string",
"triggered_by": {
"name": "string",
"user_id": "string",
"token_id": "string"
}
}
],
"matched_count": 0,
"scope": "selection",
"expires_at": "1970-01-01T00:00:00.000Z",
"capture_summary": {
"total": 0,
"captured": 0,
"skipped": 0,
"failed": 0
}
}

deleteSnapshotโ€‹

Delete a snapshot's metadata and S3 manifest.

DELETE /v1/snapshots/{id}

const { data } = await client.deleteSnapshot({
id: '123e4567-e89b-12d3-a456-426614174000',
})

restoreSnapshotโ€‹

Restore a snapshot to the org. Async โ€” returns immediately; client polls getSnapshot until the latest entry in restores moves from in_progress to one of completed | partial | failed.

POST /v1/snapshots/{id}:restore

const { data } = await client.restoreSnapshot(
{
id: '123e4567-e89b-12d3-a456-426614174000',
},
{
exclude_target_ids: ['string']
},
)

listSnapshotResourcesโ€‹

List the resources captured in this snapshot. Returns lightweight identity fields per resource โ€” payloads are fetched via the single-resource endpoint when needed.

GET /v1/snapshots/{id}/resources

const { data } = await client.listSnapshotResources({
id: '123e4567-e89b-12d3-a456-426614174000',
})
Response
{
"resources": [
{
"lineage_id": "string",
"target_id": "string",
"type": "string",
"name": "string"
}
]
}

getSnapshotResourceโ€‹

Fetch one captured resource with its full payload. For UI views that diff the captured state against the current destination.

GET /v1/snapshots/{id}/resources/{lineage_id}

const { data } = await client.getSnapshotResource({
id: '123e4567-e89b-12d3-a456-426614174000',
lineage_id: 'example',
})
Response
{
"lineage_id": "string",
"target_id": "string",
"type": "string",
"name": "string",
"captured": {}
}

getOrgSnapshotScheduleโ€‹

Return the scheduled-snapshot enrollment config for the caller's org. Returns 404 when the org has not yet enrolled.

GET /v1/org-snapshot-schedule

const { data } = await client.getOrgSnapshotSchedule()
Response
{
"org_id": "string",
"enabled": true,
"cron_expression": "cron(0 2 * * ? *)",
"timezone": "string",
"retention": {
"value": 1,
"unit": "days"
},
"excluded_types": ["string"],
"schedule_name": "string",
"last_started_at": "1970-01-01T00:00:00.000Z",
"last_completed_at": "1970-01-01T00:00:00.000Z",
"last_status": "completed",
"created_by": "string",
"created_at": "1970-01-01T00:00:00.000Z",
"updated_at": "1970-01-01T00:00:00.000Z"
}

putOrgSnapshotScheduleโ€‹

Create or update the scheduled-snapshot enrollment config for the caller's org (upsert). The cron expression and retention window are validated server-side; invalid values are rejected with 400.

PUT /v1/org-snapshot-schedule

const { data } = await client.putOrgSnapshotSchedule(
null,
{
enabled: true,
cron_expression: 'cron(0 2 * * ? *)',
timezone: 'Europe/Berlin',
retention: {
value: 1,
unit: 'days'
},
excluded_types: ['string']
},
)
Response
{
"org_id": "string",
"enabled": true,
"cron_expression": "cron(0 2 * * ? *)",
"timezone": "string",
"retention": {
"value": 1,
"unit": "days"
},
"excluded_types": ["string"],
"schedule_name": "string",
"last_started_at": "1970-01-01T00:00:00.000Z",
"last_completed_at": "1970-01-01T00:00:00.000Z",
"last_status": "completed",
"created_by": "string",
"created_at": "1970-01-01T00:00:00.000Z",
"updated_at": "1970-01-01T00:00:00.000Z"
}

deleteOrgSnapshotScheduleโ€‹

Remove the scheduled-snapshot enrollment for the caller's org. Returns 404 when no schedule exists. The corresponding EventBridge schedule is removed by a reconcile step (Task 6).

DELETE /v1/org-snapshot-schedule

const { data } = await client.deleteOrgSnapshotSchedule()

listDependenciesโ€‹

Walk the dependency tree for a set of resources and return the full transitive closure, topologically sorted.

POST /v1/snapshots:list-dependencies

const { data } = await client.listDependencies(
null,
{
resources: [
{
type: 'string',
id: 'string'
}
]
},
)
Response
{
"dependencies": [
{
"type": "string",
"id": "string"
}
]
}

Schemasโ€‹

Errorโ€‹

type Error = {
status: number
error: string
}

ResourceRefโ€‹

type ResourceRef = {
type: string
id: string
}

SnapshotResourceSummaryโ€‹

Lightweight identity for a captured resource. Returned by listSnapshotResources; the full payload is fetched separately via getSnapshotResource when needed.

type SnapshotResourceSummary = {
lineage_id: string
target_id: string
type: string
name?: string
}

SnapshotResourceListโ€‹

type SnapshotResourceList = {
resources: Array<{
lineage_id: string
target_id: string
type: string
name?: string
}>
}

SnapshotResourceDetailโ€‹

A single captured resource with its full payload. The identity fields match SnapshotResourceSummary; the captured payload is the pre-install state at snapshot time.

type SnapshotResourceDetail = {
lineage_id: string
target_id: string
type: string
name?: string
captured: Record<string, unknown>
}

CreateSnapshotRequestโ€‹

type CreateSnapshotRequest = {
name: string
description?: string
trigger?: "manual" | "sync" | "blueprint_install" | "scheduled"
blueprint_instance_id?: string
resources: Array<{
type: string
id: string
}>
}

CreateOrgSnapshotRequestโ€‹

Request body for captureOrgSnapshot. All fields optional โ€” an empty body snapshots the whole org with a default name and the 90-day default TTL.

type CreateOrgSnapshotRequest = {
name?: string
retention?: {
value: number
unit: "days" | "weeks" | "months"
}
excluded_types?: string[]
}

CreateSnapshotResponseโ€‹

type CreateSnapshotResponse = {
id: string
name: string
status: "creating"
created_at: string // date-time
}

RestoreSnapshotRequestโ€‹

Apply a captured snapshot to its source org. snapshot-api applies the manifest verbatim minus any target ids the caller pre-decided to skip. Drift detection (skip modified-since-install) is the caller's responsibility โ€” blueprint-manifest-api owns that logic for blueprint restores; Config Hub's manu

type RestoreSnapshotRequest = {
exclude_target_ids?: string[]
}

RestoreSnapshotResponseโ€‹

type RestoreSnapshotResponse = {
id: string
status: "restoring"
}

Snapshotโ€‹

type Snapshot = {
id: string
org_id: string
name: string
description?: string
trigger: "manual" | "sync" | "blueprint_install" | "scheduled"
blueprint_instance_id?: string
resource_counts: Record<string, number>
create: {
type: "create" | "restore"
started_at: string // date-time
completed_at?: string // date-time
status: "in_progress" | "completed" | "partial" | "failed"
error?: string
triggered_by: {
name: { ... }
user_id?: { ... }
token_id?: { ... }
}
}
restores: Array<{
type: "create" | "restore"
started_at: string // date-time
completed_at?: string // date-time
status: "in_progress" | "completed" | "partial" | "failed"
error?: string
triggered_by: {
name: { ... }
user_id?: { ... }
token_id?: { ... }
}
}>
matched_count?: number
scope?: "selection" | "org"
expires_at?: string // date-time
capture_summary?: {
total: number
captured: number
skipped: number
failed: number
}
}

Operationโ€‹

type Operation = {
type: "create" | "restore"
started_at: string // date-time
completed_at?: string // date-time
status: "in_progress" | "completed" | "partial" | "failed"
error?: string
triggered_by: {
name: string
user_id?: string
token_id?: string
}
}

CallerIdentityโ€‹

type CallerIdentity = {
name: string
user_id?: string
token_id?: string
}

RetentionConfigโ€‹

Flat retention window for a scheduled snapshot. Converted to a ttl epoch at capture time. Capped at ~24 months.

type RetentionConfig = {
value: number
unit: "days" | "weeks" | "months"
}

PutOrgSnapshotScheduleRequestโ€‹

Body for putOrgSnapshotSchedule. All fields optional; unset fields receive defaults on first create and are left unchanged on updates (except updated_at).

type PutOrgSnapshotScheduleRequest = {
enabled?: boolean
cron_expression?: string
timezone?: string
retention?: {
value: number
unit: "days" | "weeks" | "months"
}
excluded_types?: string[]
}

OrgSnapshotScheduleโ€‹

Enrollment record for a scheduled org snapshot. One row per org. This table โ€” not EventBridge โ€” is the source of truth; the EventBridge schedule entry is the materialization of this row (reconciled on write by Task 6).

type OrgSnapshotSchedule = {
org_id: string
enabled: boolean
cron_expression: string
timezone: string
retention: {
value: number
unit: "days" | "weeks" | "months"
}
excluded_types?: string[]
schedule_name: string
last_started_at?: string // date-time
last_completed_at?: string // date-time
last_status?: "completed" | "partial" | "failed"
created_by: string
created_at: string // date-time
updated_at: string // date-time
}