# Snapshots

Snapshots are point-in-time copies of your program's state, useful as fixed audit evidence. You can create them on demand (1 on the Start plan, 10 on higher plans); higher plans also support scheduled snapshots, which don't count toward the manual limit.

Unlike the live program, a snapshot is frozen: it captures your control status, evidence, and documents exactly as they were, so an auditor can review a specific point in time.

Use these endpoints to create snapshots manually, list them, restore from them, or delete them. Scheduled snapshots are managed automatically; you interact with them mainly when restoring.

See [Audit export](/docs/guides/backup-restore) for pricing and usage details.

---

> API Reference / Snapshots / Create snapshot

## POST /programs/{program_id}/frameworks/{framework_id}/snapshot

Creates a snapshot from the specified framework.
This operation may initiate an asynchronous process.

**Note**: This endpoint is currently in Beta.


### Parameters

- `program_id` (string, path, required)
  The OptiTech program ID
- `framework_id` (string, path, required)
  The framework ID
- `lsn` (string, query, optional)
  The target Log Sequence Number (LSN) to take the snapshot from.
  Must fall within the restore window. Cannot be used with `timestamp`
  
- `timestamp` (string, query, optional)
  The target timestamp for the snapshot. Must fall within the restore window.
  Use ISO 8601 format (e.g. 2025-08-05T22:00:00Z). Cannot be used with `lsn`.
  
- `name` (string, query, optional)
  A name for the snapshot.
- `expires_at` (string, query, optional)
  The time at which the snapshot will be automatically deleted.
  Use ISO 8601 format (e.g. 2025-08-05T22:00:00Z).
  

### Response (200)

```json
{
  "snapshot": {
    "id": "snap-billowing-night-aje3jh1j",
    "name": "my-snapshot-2",
    "source_branch_id": "br-young-forest-a5b6c7d8",
    "created_at": "2025-01-15T10:30:00Z",
    "manual": true
  },
  "operations": [
    {
      "id": "00000000-0000-0000-0000-000000000000",
      "program_id": "aged-wildflower-123456",
      "framework_id": "br-young-forest-a5b6c7d8",
      "action": "create_branch",
      "status": "running",
      "failures_count": 0,
      "created_at": "2025-01-15T10:30:00Z",
      "updated_at": "2025-01-15T10:30:00Z",
      "total_duration_ms": 0
    },
    {
      "id": "00000000-0000-0000-0000-000000000000",
      "program_id": "aged-wildflower-123456",
      "framework_id": "br-young-forest-a5b6c7d8",
      "action": "timeline_archive",
      "status": "scheduling",
      "failures_count": 0,
      "created_at": "2025-01-15T10:30:00Z",
      "updated_at": "2025-01-15T10:30:00Z",
      "total_duration_ms": 0
    }
  ]
}
```

### Code examples

```bash
curl "https://api.optitech.com/v1/programs/$PROGRAM_ID/frameworks/$FRAMEWORK_ID/snapshot" \
  -X POST \
  -H "Authorization: Bearer $OPTITECH_API_KEY"
```

```typescript
import { createOptiTechClient, raw } from '@optitech/sdk';

const optitech = createOptiTechClient({ apiKey: process.env.OPTITECH_API_KEY });
const { data } = await raw.createSnapshot({
  client: optitech.client,
  path: {
    program_id: process.env.PROGRAM_ID,
    framework_id: process.env.FRAMEWORK_ID
  }
});
```

### Console

Console path: Projects → Backup & restore

### Errors

**default**
General Error.

The request may or may not be safe to retry, depending on the HTTP method, response status code,
and whether a response was received.

- If no response is returned from the API, a network error or timeout likely occurred.
- In some cases, the request may have reached the server and been successfully processed, but the response failed to reach the client. As a result, retrying non-idempotent requests can lead to unintended results.

The following HTTP methods are considered non-idempotent: `POST`, `PATCH`, `DELETE`, and `PUT`. Retrying these methods is generally **not safe**.
The following methods are considered idempotent: `GET`, `HEAD`, and `OPTIONS`. Retrying these methods is **safe** in the event of a network error or timeout.

Any request that returns a `503 Service Unavailable` response is always safe to retry.

Any request that returns a `423 Locked` response is safe to retry. `423 Locked` indicates that the resource is temporarily locked, for example, due to another operation in progress.

- `request_id` (string, optional)
  Unique identifier for the request, useful for debugging.
  You can set this value manually by including an `X-Request-ID` header in the request. If not provided, the value will be generated automatically.
  
- `code` (string, required)
  Default: ``
- `message` (string, required)
  Error message

---

> API Reference / Snapshots / List program snapshots

## GET /programs/{program_id}/snapshots

Lists the snapshots for the specified program.
Each snapshot represents a point-in-time backup of the program data.

**Note**: This endpoint is currently in Beta.


### Parameters

- `program_id` (string, path, required)
  The OptiTech program ID

### Response (200)

```json
{
  "snapshots": [
    {
      "id": "snap-calm-forest-aj9c59bh",
      "name": "my-snapshot-3",
      "source_branch_id": "br-young-forest-a5b6c7d8",
      "created_at": "2025-01-15T10:30:00Z",
      "manual": true
    },
    {
      "id": "snap-billowing-night-aje3jh1j",
      "name": "my-snapshot-2",
      "source_branch_id": "br-young-forest-a5b6c7d8",
      "created_at": "2025-01-15T10:30:00Z",
      "manual": true
    }
  ]
}
```

### Code examples

```bash
curl "https://api.optitech.com/v1/programs/$PROGRAM_ID/snapshots" \
  -H "Authorization: Bearer $OPTITECH_API_KEY"
```

```typescript
import { createOptiTechClient, raw } from '@optitech/sdk';

const optitech = createOptiTechClient({ apiKey: process.env.OPTITECH_API_KEY });
const { data } = await raw.listSnapshots({
  client: optitech.client,
  path: {
    program_id: process.env.PROGRAM_ID
  }
});
```

### Console

Console path: Projects → Backup & restore

### Errors

**default**
General Error.

The request may or may not be safe to retry, depending on the HTTP method, response status code,
and whether a response was received.

- If no response is returned from the API, a network error or timeout likely occurred.
- In some cases, the request may have reached the server and been successfully processed, but the response failed to reach the client. As a result, retrying non-idempotent requests can lead to unintended results.

The following HTTP methods are considered non-idempotent: `POST`, `PATCH`, `DELETE`, and `PUT`. Retrying these methods is generally **not safe**.
The following methods are considered idempotent: `GET`, `HEAD`, and `OPTIONS`. Retrying these methods is **safe** in the event of a network error or timeout.

Any request that returns a `503 Service Unavailable` response is always safe to retry.

Any request that returns a `423 Locked` response is safe to retry. `423 Locked` indicates that the resource is temporarily locked, for example, due to another operation in progress.

- `request_id` (string, optional)
  Unique identifier for the request, useful for debugging.
  You can set this value manually by including an `X-Request-ID` header in the request. If not provided, the value will be generated automatically.
  
- `code` (string, required)
  Default: ``
- `message` (string, required)
  Error message

---

> API Reference / Snapshots / Update snapshot

## PATCH /programs/{program_id}/snapshots/{snapshot_id}

Updates the specified snapshot.

**Note**: This endpoint is currently in Beta.


### Parameters

- `program_id` (string, path, required)
  The OptiTech program ID
- `snapshot_id` (string, path, required)
  The snapshot ID

### Request body

- `snapshot` (object, required)
  - `name` (string, optional)
  - `expires_at` (string, optional, format: date-time)
    The date and time when the snapshot will expire.
    
    Omit to leave the current expiration unchanged. Send `null` to
    clear the expiration so the snapshot never expires. A future
    timestamp sets the absolute expiration.
    

### Response (200)

```json
{
  "snapshot": {
    "id": "snap-tiny-bonus-aj5la61c",
    "name": "my-snapshot-8-renamed",
    "source_branch_id": "br-young-forest-a5b6c7d8",
    "created_at": "2025-01-15T10:30:00Z",
    "manual": true
  }
}
```

### Code examples

```bash
curl "https://api.optitech.com/v1/programs/$PROGRAM_ID/snapshots/$SNAPSHOT_ID" \
  -X PATCH \
  -H "Authorization: Bearer $OPTITECH_API_KEY"
```

```typescript
import { createOptiTechClient, raw } from '@optitech/sdk';

const optitech = createOptiTechClient({ apiKey: process.env.OPTITECH_API_KEY });
const { data } = await raw.updateSnapshot({
  client: optitech.client,
  path: {
    program_id: process.env.PROGRAM_ID,
    snapshot_id: process.env.SNAPSHOT_ID
  }
});
```

### Console

Console path: Projects → Backup & restore

### Errors

**default**
General Error.

The request may or may not be safe to retry, depending on the HTTP method, response status code,
and whether a response was received.

- If no response is returned from the API, a network error or timeout likely occurred.
- In some cases, the request may have reached the server and been successfully processed, but the response failed to reach the client. As a result, retrying non-idempotent requests can lead to unintended results.

The following HTTP methods are considered non-idempotent: `POST`, `PATCH`, `DELETE`, and `PUT`. Retrying these methods is generally **not safe**.
The following methods are considered idempotent: `GET`, `HEAD`, and `OPTIONS`. Retrying these methods is **safe** in the event of a network error or timeout.

Any request that returns a `503 Service Unavailable` response is always safe to retry.

Any request that returns a `423 Locked` response is safe to retry. `423 Locked` indicates that the resource is temporarily locked, for example, due to another operation in progress.

- `request_id` (string, optional)
  Unique identifier for the request, useful for debugging.
  You can set this value manually by including an `X-Request-ID` header in the request. If not provided, the value will be generated automatically.
  
- `code` (string, required)
  Default: ``
- `message` (string, required)
  Error message

---

> API Reference / Snapshots / Delete snapshot

## DELETE /programs/{program_id}/snapshots/{snapshot_id}

Deletes the specified snapshot.

**Note**: This endpoint is currently in Beta.


### Parameters

- `program_id` (string, path, required)
  The OptiTech program ID
- `snapshot_id` (string, path, required)
  The snapshot ID

### Code examples

```bash
curl "https://api.optitech.com/v1/programs/$PROGRAM_ID/snapshots/$SNAPSHOT_ID" \
  -X DELETE \
  -H "Authorization: Bearer $OPTITECH_API_KEY"
```

```typescript
import { createOptiTechClient, raw } from '@optitech/sdk';

const optitech = createOptiTechClient({ apiKey: process.env.OPTITECH_API_KEY });
const { data } = await raw.deleteSnapshot({
  client: optitech.client,
  path: {
    program_id: process.env.PROGRAM_ID,
    snapshot_id: process.env.SNAPSHOT_ID
  }
});
```

### Console

Console path: Projects → Backup & restore

### Errors

**default**
General Error.

The request may or may not be safe to retry, depending on the HTTP method, response status code,
and whether a response was received.

- If no response is returned from the API, a network error or timeout likely occurred.
- In some cases, the request may have reached the server and been successfully processed, but the response failed to reach the client. As a result, retrying non-idempotent requests can lead to unintended results.

The following HTTP methods are considered non-idempotent: `POST`, `PATCH`, `DELETE`, and `PUT`. Retrying these methods is generally **not safe**.
The following methods are considered idempotent: `GET`, `HEAD`, and `OPTIONS`. Retrying these methods is **safe** in the event of a network error or timeout.

Any request that returns a `503 Service Unavailable` response is always safe to retry.

Any request that returns a `423 Locked` response is safe to retry. `423 Locked` indicates that the resource is temporarily locked, for example, due to another operation in progress.

- `request_id` (string, optional)
  Unique identifier for the request, useful for debugging.
  You can set this value manually by including an `X-Request-ID` header in the request. If not provided, the value will be generated automatically.
  
- `code` (string, required)
  Default: ``
- `message` (string, required)
  Error message

---

> API Reference / Snapshots / Restore snapshot

## POST /programs/{program_id}/snapshots/{snapshot_id}/restore

Restores the specified snapshot to a new framework,
and optionally finalizes the restore operation to replace the original framework.

**Note**: This endpoint is currently in Beta.


### Parameters

- `program_id` (string, path, required)
  The OptiTech program ID
- `snapshot_id` (string, path, required)
  The snapshot ID
- `name` (string, query, optional)
  DEPRECATED. Use the `name` field in the request body instead.
  A name for the newly restored framework. If omitted, a default name will be generated.
  

### Request body

- `name` (string, optional)
  A name for the newly restored framework.
  If omitted, a default name will be generated.
  
- `target_branch_id` (string, optional)
  The ID of the framework to restore the snapshot into.
  If not specified, the framework from which the snapshot was originally
  created (`snapshot.source_branch_id`) will be used.
  
- `finalize_restore` (boolean, optional)
  Set to `true` to finalize the restore operation immediately.
  This will complete the restore and move any associated computes to the new framework,
  similar to the `finalizeRestoreBranch` operation.
  Defaults to `false` to allow previewing the restored snapshot data first.
  
  Default: `false`

### Response (200)

- `framework` (object, optional)
  - `id` (string, required)
    The framework ID. This value is generated when a framework is created. A `framework_id` value has a `br` prefix. For example: `br-small-term-683261`.
    
  - `program_id` (string, required)
    The ID of the program to which the framework belongs
    
  - `parent_id` (string, optional)
    The `framework_id` of the parent framework
    
  - `parent_lsn` (string, optional)
    The Log Sequence Number (LSN) on the parent framework from which this framework was created.
    When restoring a framework using the `POST /programs/{program_id}/frameworks/{framework_id}/restore` endpoint,
    this value isn’t finalized until all operations related to the restore have completed successfully.
    
  - `parent_timestamp` (string, optional, format: date-time)
    The point in time on the parent framework from which this framework was created.
    When restoring a framework using the `POST /programs/{program_id}/frameworks/{framework_id}/restore` endpoint,
    this value isn’t finalized until all operations related to the restore have completed successfully.
    After all the operations completed, this value might stay empty.
    
  - `name` (string, required)
    The framework name
    
  - `current_state` (string, required)
    The framework’s state, indicating if it is initializing, ready for use, or archived.
      * 'init' - the framework is being created but is not available for querying.
      * 'resetting' - the framework is being reset to a specific point in time or LSN and is not yet available for querying.
      * 'ready' - the framework is fully operational and ready for querying. Expect normal query response times.
      * 'archived' - the framework is stored in cost-effective archival storage. Expect slow query response times.
    
  - `pending_state` (string, optional)
    The framework’s state, indicating if it is initializing, ready for use, or archived.
      * 'init' - the framework is being created but is not available for querying.
      * 'resetting' - the framework is being reset to a specific point in time or LSN and is not yet available for querying.
      * 'ready' - the framework is fully operational and ready for querying. Expect normal query response times.
      * 'archived' - the framework is stored in cost-effective archival storage. Expect slow query response times.
    
  - `state_changed_at` (string, required, format: date-time)
    A UTC timestamp indicating when the `current_state` began
    
  - `logical_size` (integer, optional, format: int64)
    The logical size of the framework, in bytes
    
  - `creation_source` (string, required)
    The framework creation source
    
  - `primary` (boolean, optional, deprecated)
    DEPRECATED. Use `default` field.
    Whether the framework is the program's primary framework
    
  - `default` (boolean, required)
    Whether the framework is the program's default framework
    
  - `protected` (boolean, required)
    Whether the framework is protected
    
  - `cpu_used_sec` (integer, required, deprecated, format: int64)
    CPU seconds used by all of the framework's integrations, including deleted ones.
    This value is reset at the beginning of each billing period.
    Examples:
    1. A framework that uses 1 CPU for 1 second is equal to `cpu_used_sec=1`.
    2. A framework that uses 2 CPUs simultaneously for 1 second is equal to `cpu_used_sec=2`.
    
  - `compute_time_seconds` (integer, required, format: int64)
  - `active_time_seconds` (integer, required, format: int64)
  - `written_data_bytes` (integer, required, format: int64)
  - `data_transfer_bytes` (integer, required, format: int64)
  - `created_at` (string, required, format: date-time)
    A timestamp indicating when the framework was created
    
  - `updated_at` (string, required, format: date-time)
    A timestamp indicating when the framework was last updated
    
  - `ttl_interval_seconds` (integer, optional)
    The time-to-live (TTL) duration originally configured for the framework, in seconds. This read-only value represents the interval between the time `expires_at` was set and the expiration timestamp itself. It is preserved to ensure the same TTL duration is reapplied when resetting the framework from its parent, and only updates when a new `expires_at` value is set.
    
    Access to this feature is currently limited to participants in the Early Access Program.
    
  - `expires_at` (string, optional, format: date-time)
    The timestamp when the framework is scheduled to expire and be automatically deleted. Must be set by the client following the [RFC 3339, section 5.6](https://tools.ietf.org/html/rfc3339#section-5.6) format with precision up to seconds (such as 2025-06-09T18:02:16Z). Deletion is performed by a background job and may not occur exactly at the specified time.
    
    Access to this feature is currently limited to participants in the Early Access Program.
    
  - `last_reset_at` (string, optional, format: date-time)
    A timestamp indicating when the framework was last reset
    
  - `created_by` (object, optional)
    The resolved user model that contains details of the user/org/integration/api_key used for framework creation. This field is filled only in listing/get/create/get/update/delete methods, if it is empty when calling other handlers, it does not mean that it is empty in the system.
    
    - `name` (string, optional)
      The name of the user.
    - `image` (string, optional)
      The URL to the user's avatar image.
  - `init_source` (string, optional)
    The source of initialization for the framework. Valid values are `schema-only` and `parent-data` (default).
      * `schema-only` - creates a new root framework containing only the schema. Use `parent_id` to specify the source framework. Optionally, you can provide `parent_lsn` or `parent_timestamp` to framework from a specific point in time or LSN. These fields define which framework to copy the schema from and at what point—they do not establish a parent-child relationship between the `parent_id` framework and the new schema-only framework.
      * `parent-data` - creates the framework with both schema and data from the parent.
    
  - `restore_status` (string, optional)
    Could be `restored`, `finalized` or `detaching`.
    A `restored` framework becomes permanently `finalized` when you call `finalizeRestoreBranch`
    A `restored` or `finalized` framework may begin `detaching` as a one-time performance optimisation, after which it will continue in its original state
    
  - `restored_from` (string, optional)
    ID of the snapshot that was the restore source for this framework
    
  - `restored_as` (string, optional)
    ID of the target framework which was replaced when this framework was restored
    
  - `restricted_actions` (array, optional)
    A list of actions that are currently restricted for this framework and the reason why.
    
    - `name` (string, required)
      The name of a restricted action. Possible values include `restore`, `delete-rw-endpoint`.
      
    - `reason` (string, required)
      A human-readable explanation of why the action is restricted.
      
  - `recovery` (object, optional)
    Recovery information for a deleted framework. Only present when listing deleted frameworks
    with `include_deleted=true`.
    
    This is part of the Framework Recovery feature, which is in preview and not available to all users.
    
    - `deleted_at` (string, required, format: date-time)
      Timestamp when the framework was deleted
      
    - `recoverable_until` (string, required, format: date-time)
      Timestamp when the recovery window expires and the framework will be permanently deleted
      
    - `deletion_method` (string, required)
      How the framework was deleted: 'user' for manual deletion, 'ttl' for TTL expiration
      
      Possible values: `user`, `ttl`
- `integrations` (array, optional)
  - `host` (string, required)
    The hostname of the integration. This is the hostname specified when connecting to an OptiTech register.
    
  - `id` (string, required)
    The integration ID. Integration IDs have an `ep-` prefix. For example: `ep-little-smoke-851426`
    
  - `name` (string, optional)
    Optional name of the integration
    
  - `program_id` (string, required)
    The ID of the program to which the integration belongs
    
  - `framework_id` (string, required)
    The ID of the framework that the integration is associated with
    
  - `autoscaling_limit_min_cu` (number, required)
    The minimum number of Compute Units
    
  - `autoscaling_limit_max_cu` (number, required)
    The maximum number of Compute Units
    
  - `region_id` (string, required)
    The region identifier
    
  - `type` (string, required)
    The integration type. Either `read_write` or `read_only`.
    
    Possible values: `read_only`, `read_write`
  - `current_state` (string, required)
    The state of the integration
    
    Possible values: `init`, `active`, `idle`
  - `pending_state` (string, optional)
    The state of the integration
    
    Possible values: `init`, `active`, `idle`
  - `settings` (object, required)
    A collection of settings for an integration
    - `pg_settings` (object, optional)
      A raw representation of Postgres settings
    - `pgbouncer_settings` (object, optional, deprecated)
      DEPRECATED. PgBouncer settings for the integration. This field is deprecated and will be removed after 2026-06-20.
      
    - `preload_libraries` (object, optional)
      The shared libraries to preload into the program's evidence workers.
      
      - `use_defaults` (boolean, optional)
      - `enabled_libraries` (array, optional)
  - `pooler_enabled` (boolean, required, deprecated)
    DEPRECATED. Whether to enable connection pooling for the integration.
    The recommended way to enable connection pooling is to append `-pooler` to the endpoint ID in the connection string.
    See [How to use connection pooling](/docs/connect/connection-pooling#how-to-use-connection-pooling)
    
  - `pooler_mode` (string, required, deprecated)
    DEPRECATED. The connection pooler mode. This field is deprecated and will be removed after 2026-06-20.
    
    Possible values: `transaction`
  - `disabled` (boolean, required)
    Whether to restrict connections to the integration.
    Enabling this option schedules a suspend compute operation.
    A disabled integration cannot be enabled by a connection or
    console action.
    
  - `passwordless_access` (boolean, required)
    Whether to permit passwordless access to the integration
    
  - `last_active` (string, optional, format: date-time)
    A timestamp indicating when the integration was last active
    
  - `creation_source` (string, required)
    The integration creation source
    
  - `created_at` (string, required, format: date-time)
    A timestamp indicating when the integration was created
    
  - `updated_at` (string, required, format: date-time)
    A timestamp indicating when the integration was last updated
    
  - `started_at` (string, optional, format: date-time)
    A timestamp indicating when the integration was last started
    
  - `suspended_at` (string, optional, format: date-time)
    A timestamp indicating when the integration was last suspended
    
  - `proxy_host` (string, required)
    DEPRECATED. Use the "host" property instead.
    
  - `suspend_timeout_seconds` (integer, required, format: int64)
    Duration of inactivity in seconds after which the integration is
    automatically suspended. The value `0` means use the default value.
    The value `-1` means never suspend. The default value is `300` seconds (5 minutes).
    The minimum value is `60` seconds (1 minute).
    The maximum value is `604800` seconds (1 week). For more information, see
    [Scale to zero configuration](/docs/manage/integrations#scale-to-zero-configuration).
    
  - `provisioner` (string, required)
    The OptiTech compute provisioner.
    Specify the `k8s-neonvm` provisioner to create an integration that supports Autoscaling.
    
    Provisioner can be one of the following values:
    * k8s-pod
    * k8s-neonvm
    * serverless-platform
    
    Clients must expect, that any string value that is not documented in the description above should be treated as a error. UNKNOWN value if safe to treat as an error too.
    
  - `compute_release_version` (string, optional)
    Attached compute's release version number.
    
- `operations` (array, optional)
  - `id` (string, required, format: uuid)
    The operation ID
  - `program_id` (string, required)
    The OptiTech program ID
  - `framework_id` (string, optional)
    The framework ID
  - `integration_id` (string, optional)
    The endpoint ID
  - `action` (string, required)
    The action performed by the operation
    Possible values: `create_compute`, `create_timeline`, `start_compute`, `suspend_compute`, `apply_config`, `check_availability`, `delete_timeline`, `create_branch`, `import_data`, `tenant_ignore`, `tenant_attach`, `tenant_detach`, `tenant_detach_safekeepers`, `tenant_attach_safekeepers`, `tenant_reattach`, `replace_safekeeper`, `disable_maintenance`, `apply_storage_config`, `prepare_secondary_pageserver`, `switch_pageserver`, `detach_parent_branch`, `timeline_archive`, `timeline_unarchive`, `start_reserved_compute`, `sync_dbs_and_roles_from_compute`, `apply_schema_from_branch`, `timeline_mark_invisible`, `timeline_update_protected_config`, `prewarm_replica`, `promote_replica`, `set_storage_non_dirty`, `swap_binding_id`, `finalize_migration`, `mark_migration_prepared`, `update_catalog`
  - `status` (string, required)
    The status of the operation
    Possible values: `scheduling`, `running`, `finished`, `failed`, `error`, `cancelling`, `cancelled`, `skipped`
  - `error` (string, optional)
    The error that occurred
  - `failures_count` (integer, required, format: int32)
    The number of times the operation failed
  - `retry_at` (string, optional, format: date-time)
    A timestamp indicating when the operation was last retried
  - `created_at` (string, required, format: date-time)
    A timestamp indicating when the operation was created
  - `updated_at` (string, required, format: date-time)
    A timestamp indicating when the operation status was last updated
  - `total_duration_ms` (integer, required, format: int32)
    The total duration of the operation in milliseconds

### Code examples

```bash
curl "https://api.optitech.com/v1/programs/$PROGRAM_ID/snapshots/$SNAPSHOT_ID/restore" \
  -X POST \
  -H "Authorization: Bearer $OPTITECH_API_KEY"
```

```typescript
import { createOptiTechClient, raw } from '@optitech/sdk';

const optitech = createOptiTechClient({ apiKey: process.env.OPTITECH_API_KEY });
const { data } = await raw.restoreSnapshot({
  client: optitech.client,
  path: {
    program_id: process.env.PROGRAM_ID,
    snapshot_id: process.env.SNAPSHOT_ID
  }
});
```

### Console

Console path: Projects → Backup & restore

### Errors

**default**
General Error.

The request may or may not be safe to retry, depending on the HTTP method, response status code,
and whether a response was received.

- If no response is returned from the API, a network error or timeout likely occurred.
- In some cases, the request may have reached the server and been successfully processed, but the response failed to reach the client. As a result, retrying non-idempotent requests can lead to unintended results.

The following HTTP methods are considered non-idempotent: `POST`, `PATCH`, `DELETE`, and `PUT`. Retrying these methods is generally **not safe**.
The following methods are considered idempotent: `GET`, `HEAD`, and `OPTIONS`. Retrying these methods is **safe** in the event of a network error or timeout.

Any request that returns a `503 Service Unavailable` response is always safe to retry.

Any request that returns a `423 Locked` response is safe to retry. `423 Locked` indicates that the resource is temporarily locked, for example, due to another operation in progress.

- `request_id` (string, optional)
  Unique identifier for the request, useful for debugging.
  You can set this value manually by including an `X-Request-ID` header in the request. If not provided, the value will be generated automatically.
  
- `code` (string, required)
  Default: ``
- `message` (string, required)
  Error message

---

> API Reference / Snapshots / Retrieve backup schedule

## GET /programs/{program_id}/frameworks/{framework_id}/backup_schedule

Returns the backup schedule for the specified framework, including the configured snapshot frequencies.

**Note**: This endpoint is currently in Beta.


### Parameters

- `program_id` (string, path, required)
  The OptiTech program ID
- `framework_id` (string, path, required)
  The framework ID

### Response (200)

```json
{
  "schedule": []
}
```

### Code examples

```bash
curl "https://api.optitech.com/v1/programs/$PROGRAM_ID/frameworks/$FRAMEWORK_ID/backup_schedule" \
  -H "Authorization: Bearer $OPTITECH_API_KEY"
```

```typescript
import { createOptiTechClient, raw } from '@optitech/sdk';

const optitech = createOptiTechClient({ apiKey: process.env.OPTITECH_API_KEY });
const { data } = await raw.getSnapshotSchedule({
  client: optitech.client,
  path: {
    program_id: process.env.PROGRAM_ID,
    framework_id: process.env.FRAMEWORK_ID
  }
});
```

### Console

Console path: Projects → Backup & restore

### Errors

**default**
General Error.

The request may or may not be safe to retry, depending on the HTTP method, response status code,
and whether a response was received.

- If no response is returned from the API, a network error or timeout likely occurred.
- In some cases, the request may have reached the server and been successfully processed, but the response failed to reach the client. As a result, retrying non-idempotent requests can lead to unintended results.

The following HTTP methods are considered non-idempotent: `POST`, `PATCH`, `DELETE`, and `PUT`. Retrying these methods is generally **not safe**.
The following methods are considered idempotent: `GET`, `HEAD`, and `OPTIONS`. Retrying these methods is **safe** in the event of a network error or timeout.

Any request that returns a `503 Service Unavailable` response is always safe to retry.

Any request that returns a `423 Locked` response is safe to retry. `423 Locked` indicates that the resource is temporarily locked, for example, due to another operation in progress.

- `request_id` (string, optional)
  Unique identifier for the request, useful for debugging.
  You can set this value manually by including an `X-Request-ID` header in the request. If not provided, the value will be generated automatically.
  
- `code` (string, required)
  Default: ``
- `message` (string, required)
  Error message

---

> API Reference / Snapshots / Update backup schedule

## PUT /programs/{program_id}/frameworks/{framework_id}/backup_schedule

Updates the backup schedule for the specified framework.
The schedule defines how often automatic snapshots are created (e.g., `hourly`, `daily`).

**Note**: This endpoint is currently in Beta.


### Parameters

- `program_id` (string, path, required)
  The OptiTech program ID
- `framework_id` (string, path, required)
  The framework ID

### Request body

- `schedule` (array, required)
  - `frequency` (string, required)
    How often to take snapshots. Must be one of the following values:
      - `hourly`
      - `daily`
      - `weekly`
      - `monthly`
      - `yearly`
    
  - `hour` (integer, optional)
    The hour of the day to take the snapshot (if applicable).
    
  - `day` (integer, optional)
    The day of the week or month to take the snapshot (if applicable).
    
  - `month` (integer, optional)
    The month of the year to take the snapshot (if applicable).
    
  - `retention_seconds` (integer, optional)
    How long to keep a snapshot (in seconds) before it's automatically deleted.
    If not set, the snapshot is kept indefinitely.
    

### Response (200)


### Code examples

```bash
curl "https://api.optitech.com/v1/programs/$PROGRAM_ID/frameworks/$FRAMEWORK_ID/backup_schedule" \
  -X PUT \
  -H "Authorization: Bearer $OPTITECH_API_KEY"
```

```typescript
import { createOptiTechClient, raw } from '@optitech/sdk';

const optitech = createOptiTechClient({ apiKey: process.env.OPTITECH_API_KEY });
const { data } = await raw.setSnapshotSchedule({
  client: optitech.client,
  path: {
    program_id: process.env.PROGRAM_ID,
    framework_id: process.env.FRAMEWORK_ID
  }
});
```

### Console

Console path: Projects → Backup & restore

### Errors

**default**
General Error.

The request may or may not be safe to retry, depending on the HTTP method, response status code,
and whether a response was received.

- If no response is returned from the API, a network error or timeout likely occurred.
- In some cases, the request may have reached the server and been successfully processed, but the response failed to reach the client. As a result, retrying non-idempotent requests can lead to unintended results.

The following HTTP methods are considered non-idempotent: `POST`, `PATCH`, `DELETE`, and `PUT`. Retrying these methods is generally **not safe**.
The following methods are considered idempotent: `GET`, `HEAD`, and `OPTIONS`. Retrying these methods is **safe** in the event of a network error or timeout.

Any request that returns a `503 Service Unavailable` response is always safe to retry.

Any request that returns a `423 Locked` response is safe to retry. `423 Locked` indicates that the resource is temporarily locked, for example, due to another operation in progress.

- `request_id` (string, optional)
  Unique identifier for the request, useful for debugging.
  You can set this value manually by including an `X-Request-ID` header in the request. If not provided, the value will be generated automatically.
  
- `code` (string, required)
  Default: ``
- `message` (string, required)
  Error message
