> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.ada.cx/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.ada.cx/_mcp/server.

# Snapshot API

## Overview

The Snapshot API exports an AI Agent's configuration as one archive file that you keep. It then imports that archive, whole or in parts, into any Agent, including the one it came from. A snapshot is the configuration at that moment; the archive is the file that holds it.

Download full OpenAPI spec

* **Save it.** An export captures the whole Agent exactly as it is right now. There is no partial export.
* **Move it.** An import applies the archive to another Agent, or back to the same one.
* **Move part of it.** An import can take only the sections you name, for example Playbooks. Anything those Playbooks use comes with them.

Three things follow from that design:

1. **A snapshot is a moment in time.** Nothing stays in sync after the export.
2. **An import replaces the sections you import.** In each section you ask for, the target ends up matching the archive. Items the archive does not carry are deleted. Sections pulled in by reference are only added to.
3. **There is no undo on Ada's side.** Ada keeps no copy you can download or import. Export the target Agent first, so you have an archive to import back.

### How it works

Export and import run as background jobs: you start one, get a `job_id`, and poll until it finishes.

|                  | Source Agent          | The archive                | Target Agent                              |
| ---------------- | --------------------- | -------------------------- | ----------------------------------------- |
| **What happens** | Export job            | One `.tar.gz` you download | Import job                                |
| **What you do**  | Start, poll, download | Keep it safe               | Prepare the target, validate, apply, test |

The target Agent must already exist. An import fills an Agent; it does not create one.

An import request runs in `validate` mode unless you ask for `apply`. Validate writes nothing, apart from any secret values you send with it. It reports what an apply would create, update, and delete, by name. Run it with the same archive and the same `include` before every apply.

Three calls do all of this: `GET /v2/config/` starts an export, `PUT /v2/config/` starts an import, and `GET /v2/config/jobs/{job_id}` checks a job. Each call goes to the Agent it concerns, at the host you use to open its dashboard plus `/api`, with that Agent's API key. See [Endpoints](#endpoints) for the details and [Getting started](/reference/snapshot-api/getting-started) for the procedure.

> **Note**
>
> In API paths and error messages this feature appears as `config`, for example `/v2/config/`.

## Limitations

Read this section before the first import. Several limits are silent: the import succeeds and the Agent looks right, but a skipped step only shows up in a conversation.

### Scope of a snapshot

A snapshot carries how the Agent behaves: persona, languages, variable definitions, API tools, Handoffs, Processes, Greetings, Playbooks and Playbooks Classic, Coaching, Custom instructions, and Glossary. It also carries Knowledge sources and articles, CSAT settings, custom redaction patterns, the image redaction setting, the list of enabled integrations, and web chat settings.

It never carries credentials, API keys, secret values, customer login, webhooks, or conversation data. Nor does it carry channels other than web chat settings, tags, code tools, MCP tools, Schedules, built-in PII redaction switches, or change sets. Set those up on the target Agent by hand.

[What a snapshot includes](/reference/snapshot-api/what-a-snapshot-includes) lists every area of the dashboard and how an import treats it.

### Import behavior

* **Replace within the sections you import.** Items the archive does not carry are deleted from those sections. Four exceptions:
  * Persona and the other settings pages are updated field by field.
  * Custom instructions are only added to.
  * Integrations that Ada always keeps on are not disabled.
  * Sections pulled in by reference are only added to.
* **No limit on deletions.** Nothing stops a large deletion, in Knowledge or anywhere else. The `changes` block on a validate is the only advance warning. Read `knowledge.articles.delete` before every apply. Leaving `knowledge` out of `include` stops every article deletion. Articles that your listed sections reference are still added or updated.
* **A failed import can stop halfway.** Items are written one at a time, so the Agent is left partly updated. Whether to re-run depends on the failure reason, see [Failure reasons](#failure-reasons).
* **No undo.** Export the target Agent before importing into it.
* **One import at a time.** A second import request for the same Agent is refused with `409` while one is queued or running.
* **One export at a time.** A second export request returns the export already running instead of starting another.
* **MCP does not travel.** MCP server connections, MCP tools, and the Playbook steps that call them are not in a snapshot. The Playbook imports, but the step points at a tool the target does not have. Reconnect the server and re-select the tool.
* **Primary language is read-only.** A different primary language in the archive is skipped with a warning. Change it in the dashboard.
* **Article limit.** An import cannot take the Agent above its article limit, which is 50,000 articles unless your plan sets a different limit.
* **Search catches up later.** Imported articles are re-indexed after the job completes, so the Agent may not find them for a while. That is not a failed import.
* **Large imports take hours.** Plan for it.

### Limits

| Item                        | Limit                                                                                                                 |
| --------------------------- | --------------------------------------------------------------------------------------------------------------------- |
| Download link for an export | 1 hour. Poll the job again for a fresh link.                                                                          |
| Upload link for an import   | 1 hour from when it is issued. The job waits about 90 minutes for the archive, then fails with `upload_not_received`. |
| Archive size                | 4 GB. A larger archive fails with `upload_too_large`.                                                                 |
| Job record                  | 7 days. Download the archive before then.                                                                             |
| Rate limits                 | The standard [Ada API limits](/reference/introduction/limits) apply.                                                  |

## Use cases

Four ways to use a snapshot, in order of risk. All four are the same calls; what changes is what you include and what you check first.

|   | Use case                                | When                                                                                           | Risk                                                                                                                                                        |
| - | --------------------------------------- | ---------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 1 | **Save a copy before a change**         | Before a large configuration change on the same Agent. Fine on a live Agent.                   | Lowest. Restoring puts the Agent back to the moment of the export, so later changes are lost too.                                                           |
| 2 | **Move part of an Agent**               | Move the Playbooks you built in a sandbox into another Agent that is not live, with `include`. | Low. Only the sections you name are replaced. Everything they use is added to the target, never removed from it. Into a live Agent, treat it as use case 4. |
| 3 | **Copy into an empty Agent**            | A new production Agent, a new region, or a fresh sandbox.                                      | Low. Nothing on the target to lose, but nothing stops an incomplete setup either.                                                                           |
| 4 | **Overwrite an Agent that has content** | Refreshing a sandbox from production, or consolidating two Agents.                             | Highest, and silent. Export the target first. Not recommended on a live Agent; see [Best practices](#best-practices).                                       |

You can keep archives in your own version control as dated files. They are sealed snapshots for restoring or moving, not documents to edit or diff.

### When this is the right tool

| You want to                                      | Use                         |
| ------------------------------------------------ | --------------------------- |
| Set up a whole Agent from another one            | Snapshot API                |
| Move one part of an Agent, such as its Playbooks | Snapshot API with `include` |
| Have a way back before a large change            | Snapshot API                |
| Change one thing on a live Agent                 | The dashboard               |
| Test a change before it goes live                | Change sets                 |
| Keep two Agents in sync over time                | Not available               |

## Capabilities & configuration

Three endpoints and one archive. This section covers each call, the job lifecycle, the archive, the import request, the checks, and what an import changes elsewhere in the dashboard.

### Endpoints

| Method and path                | Purpose                                                                                                                         | Body                                        |
| ------------------------------ | ------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------- |
| `GET /v2/config/`              | Start an export. Returns `job_id` and `status`.                                                                                 | None                                        |
| `PUT /v2/config/`              | Start an import. Returns `job_id`, `status`, and `upload` with a temporary link.                                                | JSON, see [Import request](#import-request) |
| `PUT <upload.url>`             | Send the archive to that link as raw bytes, in one request, with **no Authorization header**. Returns `200` with an empty body. | The `.tar.gz`                               |
| `GET /v2/config/jobs/{job_id}` | Check a job.                                                                                                                    | None                                        |

The base URL is the host you use to open the Agent's dashboard, plus `/api`. Every call except the upload carries that Agent's key:

| Header key    | Header value                             |
| ------------- | ---------------------------------------- |
| Authorization | Bearer `<your_api_key>`                  |
| Content-Type  | `application/json` (import request only) |

Copying between two Agents therefore uses two keys. The source key covers the export and its job checks. The target key covers the import and its job checks.

Every Agent also serves its own API documentation at `https://<handle>.ada.support/api/v2/docs` and its OpenAPI specification at `https://<handle>.ada.support/api/v2/spec`, on the same host. Import the specification into an API client to get every request ready-made; see [Export and import with Postman](/reference/snapshot-api/export-and-import-with-postman).

#### Error responses

| Status | When                                                                                                                                                                                                                                                   |
| ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `400`  | The import request body is malformed, or carries an unknown field. Or `mode` is not `validate` or `apply`, or an `include` entry is not a section name. A typo is refused here, before any upload. Archive problems are reported on the job, not here. |
| `401`  | Missing or invalid API key.                                                                                                                                                                                                                            |
| `404`  | Unknown `job_id`, or a job that belongs to another Agent.                                                                                                                                                                                              |
| `409`  | An import is already queued or running for this Agent. A job still `waiting_for_upload` does not conflict; submitting again replaces it, and the replaced job ends as `failed` with `superseded`.                                                      |
| `429`  | Rate limit exceeded. See [API limits](/reference/introduction/limits).                                                                                                                                                                                 |

### Job lifecycle

Poll `GET /v2/config/jobs/{job_id}` every 5 seconds for the first minute, then every 15 seconds, until the status is `completed` or `failed`.

| Status               | Meaning                                                                                                        |
| -------------------- | -------------------------------------------------------------------------------------------------------------- |
| `waiting_for_upload` | Import only. Waiting for the archive. Allow up to two minutes here after the upload arrives.                   |
| `queued`             | Waiting to start.                                                                                              |
| `in_progress`        | Running.                                                                                                       |
| `completed`          | Done. Read `result`, and for an import `warnings`.                                                             |
| `failed`             | Stopped. `failure_reason` is a short code you can act on. `failure_detail` is a sentence you can show someone. |

Other fields on the job:

| Field                                      | What it holds                                                                                                                                                                                                            |
| ------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `type`                                     | `export` or `import`. Both import modes report `import`.                                                                                                                                                                 |
| `progress`                                 | `0` to `100`, or `null` before counting starts. It measures how far through the Knowledge the job is, not work remaining. `100` can appear while packing, uploading, or final steps still run. Only `status` means done. |
| `result`                                   | Empty until `completed`, or a list of blocking issues when `failure_reason` is `preflight_failed`. Contents depend on the job, see below. Only a validate result carries `result.status`.                                |
| `warnings`                                 | Import only. Findings that did not stop the import, each naming the section and the problem.                                                                                                                             |
| `failure_reason`                           | Set when `failed`. One of the codes in [Failure reasons](#failure-reasons).                                                                                                                                              |
| `failure_detail`                           | A sentence explaining the failure. Empty when the code already says everything.                                                                                                                                          |
| `created_at`, `started_at`, `completed_at` | Timestamps.                                                                                                                                                                                                              |

| Job      | `result` contains                                                                                                                                                                          |
| -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| Export   | `url` (the download link), `expires_at`, and `secrets`: the names of secret values the target must have, each with a `null` value.                                                         |
| Validate | `status` (`valid` or `blocked`), `blockers`, `warnings`, `changes` (see [Change counts](#change-counts)), `articles.found`, and `selection` (see [Choosing sections](#choosing-sections)). |
| Apply    | `articles` (`upserted`, `deleted`), `indexing`, `selection`, and `post_apply_blockers`: anything the checks still flag after the changes. Empty is the healthy answer.                     |

#### Failure reasons

| `failure_reason`         | What happened                                                                                                                                                                           | What to do                                                                                      |
| ------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------- |
| `archive_expired`        | Export only. The archive was removed from storage before you downloaded it. The export itself had succeeded.                                                                            | Export again and download promptly.                                                             |
| `upload_not_received`    | No archive reached the upload link within about 90 minutes.                                                                                                                             | Request the import again and upload within the hour.                                            |
| `upload_too_large`       | The archive is over 4 GB.                                                                                                                                                               | Contact your Ada team.                                                                          |
| `source_unreadable`      | The archive could not be read: missing, damaged, or not a `.tar.gz`.                                                                                                                    | Upload the archive exactly as exported.                                                         |
| `invalid_snapshot`       | The archive was read but cannot be applied: a schema error, an export that wrote fewer articles than the Agent holds, or more articles than this Agent allows. Nothing was written.     | Fix what `failure_detail` names, then export again.                                             |
| `preflight_failed`       | The target cannot serve the snapshot; `result.blockers` lists each blocking issue. Nothing was written, except that integrations the snapshot lists were enabled before the checks ran. | Fix each blocking issue on the target, check **Apps**, then request a new import.               |
| `superseded`             | A later import request replaced this job while it was waiting for its archive.                                                                                                          | Poll the newer job. This is expected, not an error.                                             |
| `partially_applied`      | The apply stopped after part of the configuration was written. The Agent holds part of the snapshot.                                                                                    | Do not simply retry. Check the Agent in the dashboard, then import an archive you know is good. |
| `incomplete_knowledge`   | The import wrote fewer article files than the archive holds, so it refused to delete any articles. The configuration sections were already applied, including their deletions.          | Request the same import again and upload the same archive. It resumes where it stopped.         |
| `ref_key_already_mapped` | An item's stable identifier is already used by a different item on this Agent.                                                                                                          | Contact your Ada team with the `job_id`.                                                        |
| `timeout`                | The job hit its time limit.                                                                                                                                                             | Request it again. An import resumes where it stopped.                                           |
| `stalled`                | The job stopped making progress.                                                                                                                                                        | Request it again. If it happens twice, contact your Ada team with the `job_id`.                 |
| `internal_error`         | An unexpected fault, retried and still failing. `failure_detail` is empty.                                                                                                              | Request it again. If it recurs, contact your Ada team with the `job_id`.                        |
| `agent_not_found`        | The Agent no longer exists.                                                                                                                                                             | Nothing.                                                                                        |

### Archive contents

The export is one timestamped file, for example `config_20260904-145213.tar.gz`, containing:

* `config.json`: the configuration document, everything except article bodies. It also records the export time, the source Agent's handle, and the names of the secrets the snapshot needs. It names the Zendesk or Salesforce accounts the Handoffs were built against.
* `articles/articles_*.jsonl`: the Knowledge articles, one per line, split across files.
* `manifest.json`: an index, including the article count, the archive format version (`1.x`), and whether the export wrote fewer articles than the Agent holds.

Do not edit or repack the archive.

### Import request

The import request body:

| Field                 | Values                             | Default      | Purpose                                                                                                                                                                                                                                                                                                       |
| --------------------- | ---------------------------------- | ------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `mode`                | `validate`, `apply`                | `validate`   | `validate` reports; `apply` writes. Both report the same blocking issues, so an apply fails on exactly what a validate showed.                                                                                                                                                                                |
| `secrets`             | `{ "name": "value" }`              | none         | Values for the secrets the snapshot names. Values never travel in the archive; the names come from `result.secrets` on the export job. A missing secret is a warning, not a failure. The values are stored on the Agent as soon as the request is accepted, in either mode, even if the upload never arrives. |
| `include`             | A list of section names, see below | all sections | Import only these sections. Anything they reference comes with them.                                                                                                                                                                                                                                          |
| `allow_unsafe_import` | `true`, `false`                    | `false`      | Turns the safety checks off. See [Unsafe imports](#unsafe-imports) before you use it.                                                                                                                                                                                                                         |

> **Warning**
>
> `mode` defaults to `validate`, which writes nothing except the secret values in the request. You have to send `mode: "apply"` for an import to make any changes. Send `mode` every time, so the intent is on the request.

Each import request gets its own upload link, so the apply needs a fresh upload of the same archive.

#### Choosing sections

`include` takes one or more of these section names:

`persona`, `variables`, `actions` (API tools), `handoffs`, `processes`, `greetings`, `languages`, `playbooks`, `coaching`, `custom_instructions`, `glossary`, `knowledge`, `csat_settings`, `custom_redactions`, `image_redactions`, `integrations`, `web_chat`

Every section ends up in one of three states:

| Section                                              | What happens                                                         |
| ---------------------------------------------------- | -------------------------------------------------------------------- |
| **Listed** in `include`                              | Replaced. Items of that type the archive does not carry are deleted. |
| **Pulled in** because a listed section references it | Added to, never pruned. Only the referenced items come over.         |
| **Neither**                                          | Untouched. Not read, not written.                                    |

For example, `include: ["playbooks"]` replaces the Agent's Playbooks. The articles, variables, API tools, and Handoffs those Playbooks use come with them and are added to the target. The target's other variables and API tools are not affected.

`result.selection` on the job reports what happened:

| Field        | Meaning                                                                                                                                                                   |
| ------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `requested`  | The sections you listed.                                                                                                                                                  |
| `included`   | Every section that was applied, once references were followed.                                                                                                            |
| `pulled`     | How many items came over per section you did not list. For `knowledge`, `sources` and `articles`.                                                                         |
| `unresolved` | References the import could not follow, each with `kind`, `reference`, `parameter`, and `reason`. Each one is a link that only works if the target already has that item. |

* `include: ["knowledge"]` brings every article and pulls in all variable definitions, so article and source availability rules resolve.
* A whole-snapshot import reports `selection: null`.

#### Unsafe imports

> **Warning**
>
> `allow_unsafe_import: true` applies a snapshot with its safety checks off and leaves the Agent needing repair by hand. Never use it on a live Agent.

With the flag on, three things change:

* **Nothing is pulled in.** Only the sections in `include` are applied. A Playbook arrives without the API tools, variables, Handoffs, or articles it uses, unless the target already has them.
* **Blocking issues become warnings.** A Handoff whose platform is not connected, or a feature the Agent lacks, no longer stops the import. It is reported under `warnings` and the import proceeds.
* **Broken Playbooks are written.** An active Playbook whose references do not resolve is imported as is, and those steps do nothing at runtime.

Nothing repairs the result later. You fix each reference by hand, or import the missing sections afterwards.

Use it for one purpose: rebuilding a scratch or test Agent from one slice of a snapshot, when a half-wired Agent is more useful than a refused import. Always run `mode: "validate"` with the same flag first. `result.selection.unresolved` lists every reference the import will break, and `result.warnings` lists every blocking issue it will ignore.

### Archive checks

These run first and fail the job with a `failure_reason` before anything is written:

* The archive is a readable `.tar.gz` within the size limits. It holds `manifest.json`, `config.json`, and every article file the manifest lists, and nothing else, in format version `1.x`.
* `config.json` matches the configuration schema. Every section is one this API manages. Names and handles are unique, and there is exactly one default Greeting. References between items resolve. Every custom redaction is a valid regular expression, and every language is one Ada supports. A section this API no longer manages is skipped with a warning.
* The Agent's limits are respected: live Custom instructions, Glossary terms, and the article limit. The limit on enabled API tools is checked separately, as a blocking issue.
* The export wrote every article the Agent holds. If it wrote fewer, export again. Or leave `knowledge` out of `include` to apply the rest of the snapshot.

### Pre-import checks

Before an import writes anything, it reads the target Agent and checks that it can serve the snapshot. `validate` reports what it finds; `apply` refuses on any blocking issue and reports the rest as warnings. Each finding has these fields:

| Field       | What it holds                                                 |
| ----------- | ------------------------------------------------------------- |
| `code`      | A code you can act on.                                        |
| `entity`    | The section the finding concerns.                             |
| `parameter` | A path into the archive's `config.json`.                      |
| `message`   | A plain-language explanation.                                 |
| `reference` | Where useful, the integration, variable, or account involved. |

The checks on connections run again right before the import deletes anything, and again after the apply completes. If one fails at the first point, the job stops with `preflight_failed` before anything is deleted; updates already made stay. Anything found after the apply is reported as `post_apply_blockers`. With `allow_unsafe_import`, blocking issues are reported as warnings instead and the import proceeds.

#### Blocking issues

| Code                                   | What it means                                                                                                                                                                                                                                           | What to do on the target                                                                     |
| -------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------- |
| `handoff_connection_missing`           | A Handoff block routes to a live-agent platform or a named handoff integration that is not connected, is disabled, or has no credentials on this Agent. Live-agent platforms are Zendesk Chat, Zendesk Support, Zendesk Messaging, and Salesforce Chat. | Connect it under **Handoffs > Integrations** or **Apps**, then re-run.                       |
| `handoff_integration_label_unresolved` | A block hands off to a custom integration built on the Handoffs API, and that integration is not connected here.                                                                                                                                        | Connect the custom integration.                                                              |
| `handoff_integration_unknown`          | A block names a handoff integration that does not exist in this region.                                                                                                                                                                                 | Rebuild the Handoff against an integration available here.                                   |
| `handoff_tenant_mismatch`              | The snapshot's Handoffs were built against a different Zendesk subdomain or Salesforce org than the one this Agent is connected to. Their routing ids would point at nothing, or at the wrong team.                                                     | Connect this Agent to the same account, or rebuild those Handoffs here.                      |
| `client_feature_missing`               | A Handoff block needs a feature that is not enabled for this Agent.                                                                                                                                                                                     | Ask your Ada team to enable it.                                                              |
| `action_integration_not_enabled`       | A block calls an integration that would not be enabled after the import.                                                                                                                                                                                | Enable it on **Apps**.                                                                       |
| `action_integration_not_connected`     | The integration is enabled but has no credentials, so every call would fail.                                                                                                                                                                            | Connect it on **Apps**.                                                                      |
| `action_limit_exceeded`                | The snapshot would enable more API tools than this Agent's limit allows.                                                                                                                                                                                | Disable some API tools in the source before exporting, or ask your Ada team about the limit. |

#### Warnings

| Code                                  | What it means                                                                                                                                                              | What to do                                                               |
| ------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------ |
| `client_secret_missing`               | The snapshot names a secret that is not defined on this Agent, and no value was supplied. Anything that reads it fails until you set it.                                   | Pass it in `secrets`, or enter it in the dashboard after the import.     |
| `variable_ref_unresolved`             | A field references a variable this Agent does not have. Often a metavariable that exists only when a channel or feature is enabled. The reference is left as literal text. | Enable the channel or feature, or edit the field after the import.       |
| `untranslated_entity_id`              | A Handoff's off-hours response is referenced by an internal id that only resolves on the Agent it came from.                                                               | On a different Agent, re-select the off-hours response after the import. |
| `integration_connectivity_unverified` | Credentials could not be verified: the check could not reach the integration service, or the integration is only being enabled by this import. An apply re-checks it.      | Re-run validate later, or check **Apps** after the apply.                |

These warnings carry no code:

* A section in the archive that this API no longer manages. It is skipped.
* An article's availability rule reads a variable this Agent does not have. The import keeps the rule as written and reports the variable.
* A Knowledge source's availability rule template reads a variable this Agent does not have. The import clears the template on that source. Add the variable, then set the template again.
* On a selective import, the integrations it needs could not be merged with the ones already enabled. The integration service could not be read, so no integration was switched on or off. Enable them on **Apps**, or run the import again.
* The import succeeded, but the enabled integrations could not be read back, so `integrations` is missing from the response. Do not run the import again.

#### Change counts

A validate also returns `changes`. For every section the archive carries, it says how many items the apply would create, update, and delete, and names them. Names are capped at 50 per list. Where a count is higher, a `created_truncated`, `updated_truncated`, or `deleted_truncated` flag says so. The counts are always exact.

* Items are matched by a stable identifier assigned at export. An item renamed on the source therefore still updates the same item on the target. An item the target has not received by import before is matched by its name instead:
  * API tools, variables (within their scope), and Playbooks: by name.
  * Handoffs, Processes, and Greetings: by handle.
  * Glossary terms, Knowledge sources, and articles: by external id.
  * Custom instructions: by title. Custom redactions: by name.
  * Coaching entries have no name, so a snapshot from a different Agent creates new entries instead of updating matching ones.
* `knowledge.articles.delete` is the number to check before applying to an Agent with live Knowledge. It appears on a validate result only; a refused apply does not pre-scan Knowledge.
* Persona, languages, CSAT settings, and web chat are single settings pages. They report `create: 0` and `delete: 0`, and `update` counts the fields that would change.
* Handoffs, Processes, and Greetings share one item type, so their deletions are reported once. Custom instructions never report a deletion. A section pulled in by reference reports `delete: 0`.

### Effects on Reports, Conversations, and the audit log

An import changes configuration, never history. What you see afterward in Reports, in the Conversation View, and in the Audit log:

#### Reports and Conversations

* Items the import updates keep their identity. An API tool, Handoff, Process, Greeting, Playbook, variable, or article matched by its stable identifier is updated in place. Existing filters and past conversations still point at the same item, under its new name if it was renamed.
* Items the import deletes stop appearing in filters for new conversations. Past conversations that used them are unchanged.
* Items the import creates are new, with no history. On an empty Agent everything is new: nothing from the source Agent's Reports or conversations comes with it.

#### Audit log

If the Audit log is not enabled for the Agent, none of these rows are written.

* Requesting an import writes one row immediately: entity **Config Apply** or **Config Validate**, activity **Executed**, Interface **API**. The actor is the API key's owner, with the key's name. A selective import writes the same single row. Secret values supplied in the request are logged at the same time, as variable rows.
* When the apply runs, each item it writes gets its own row: **Created**, **Updated**, or **Deleted**. That covers variables, API tools, Handoffs, Processes, Greetings, Playbooks, Coaching entries, Glossary terms, and Knowledge sources. These rows show **System** as the actor and as the Interface, because the import job made the change rather than a person. Use the Config Apply row's timestamp to find them.
* Persona, languages, Custom instructions, CSAT settings, custom redactions, enabled integrations, and web chat settings get no rows of their own. The Config Apply row is the only record that they changed.
* If the import changes the image redaction setting, it writes one **Updated** row for **Image Redactions**. If the setting does not change, the import writes no row.
* Articles are not logged individually. Their Knowledge source gets one row, including when deleting a source removes its articles.
* Exports are not logged.

## Best practices

Habits that keep imports predictable.

* **Export before every large change**, and put the date in the filename. Those archives are the only version history you have.
* **Validate before every apply**, with the same archive and the same `include`. Read `changes` by name, and `warnings`, even when the result is `valid`.
* **Import the smallest set of sections that does the job.** `include` limits what an import can delete.
* **Run your first import into an Agent that is not live**, even when you are confident.
* **Do not import another Agent's configuration, whole or in part, into a live Agent.** The checks confirm that connections exist, not that they match the source. If you must, complete every prerequisite, then test each flow that uses an integration.
* **Refresh sandboxes from production** with the same procedure. The target is not serving anyone, so it is the safe way to practice.
* **If something is missing after an import, check enabled features first** with your Ada team. A feature mismatch never shows up as an error.
* **Keep secret values in your own secrets manager** and pass them per environment in the apply request. They never belong in the archive or in version control.

## Related features

* [What a snapshot includes](/reference/snapshot-api/what-a-snapshot-includes): every dashboard area, and how an import treats it.
* [Getting started](/reference/snapshot-api/getting-started): the prerequisites checklist and the step-by-step export, validate, and apply procedure.
* [Authentication](/reference/introduction/authentication): generate and manage API keys.
* [API limits](/reference/introduction/limits): rate limits that apply to every call.
* [Audit log](/docs/other/audit-log): where imports and the changes they make are recorded.
* [Playbooks API](/reference/playbooks/overview): edit individual Playbooks instead of moving a whole configuration.
* [Data export](/docs/optimization/conversations/data-export): export conversation data, which a snapshot never carries.

## FAQs

#### Can I edit the archive before importing it?

No. The archive is a sealed snapshot. Edits either fail the archive checks or change what the import deletes. To change configuration, use the dashboard or the individual APIs, then export again.

#### Can I import only part of a snapshot, for example just Playbooks?

Yes. Send `include: ["playbooks"]`. What those Playbooks use comes with them and is only added to the target. See [Choosing sections](#choosing-sections).

#### Can I export only part of an Agent?

No. An export always captures the whole Agent. You choose what to import.

#### Where is the undo?

Your own export of the target Agent, taken before the import. Ada does not keep a copy you can access. Importing that archive puts the Agent back to the moment you exported it.

#### Does an import affect conversations that are in progress?

It can. Items are written one at a time, so a conversation that is running while the import applies can see the configuration change part-way. Import during a quiet period, or into an Agent that is not live.

#### Why does a Playbook step point at nothing after the import?

The step calls a tool connected through an MCP server. MCP servers and their tools do not travel. Reconnect the server on the target and re-select the tool in the Playbook.

#### What is allow_unsafe_import for?

Rebuilding a test Agent from one slice of a snapshot, when a half-wired Agent is more useful than a refused import. It skips the pull-in of referenced items and turns blocking issues into warnings. Never use it on a live Agent.

#### How is this different from change sets?

A snapshot is a copy of a whole Agent at one moment, for moving it or restoring it. Change sets test and promote a set of edits on the same Agent. Use change sets for day-to-day changes, and a snapshot before a large one. An export reads live configuration only, so promote or discard staged changes first.

#### How long does an import take?

An Agent with a handful of articles completes in under a minute. Time scales with the number of articles; tens of thousands can take hours. Poll the job rather than waiting on the request.

#### Why do error messages say Config API?

That is the feature's internal name. `config` in a path or message means the Snapshot API.

#### What happens if I upload the wrong file?

The archive checks fail the job before anything is written, and `failure_reason` says why. Request the import again and upload the right archive.