# Backup file format

See how a Link Manager Pro backup file is built, what each item holds and how a restore treats ids and secrets. Check what a backup leaves out.
Page: https://docs.linkmanagerpro.com/developers/data/backup-format
Use when someone asks: link manager pro backup file format; link manager pro backup json; restore link manager pro backup file
Intent: Reference

A Link Manager Pro backup is one JSON file with six top-level keys. It holds the items you ticked, each as a list of rows.

The file is named `link-manager-pro-backup-{YYYYMMDD-HHMMSS}.json`, with the time in UTC. For the screen that makes and restores it, see [Back up and restore](https://docs.linkmanagerpro.com/guides/backup-restore).

## Structure

| Key | Type | What it holds |
|---|---|---|
| `schema_version` | integer | The file format. The current format is `1` |
| `plugin_version` | string | The value of the option `link_manager_pro_version` when the file was made |
| `exported_at` | string | When the file was made, `Y-m-d H:i:s` in UTC |
| `site_url` | string | The site's `home_url()` |
| `items` | object | One list of rows per item |
| `silent` | object | The setup state, under `onboarding` |

A short example, with values shortened:

```json
{
  "schema_version": 1,
  "plugin_version": "...",
  "exported_at": "2026-10-23 09:30:00",
  "site_url": "https://example.com",
  "items": {
    "categories": [
      { "term_id": 4, "name": "Tools", "slug": "tools", "description": "", "color": "#6B7280", "link_ids": [12] }
    ],
    "links": [
      { "id": "12", "slug": "abc123", "target_url": "https://example.org/...", "redirect_type": "302" }
    ],
    "link_meta": [
      { "entity_id": "12", "meta_key": "address:...", "meta_value": "..." }
    ],
    "settings": [
      { "general": { "link_prefix": "go" }, "ai": { "api_key": "..." } }
    ]
  },
  "silent": { "onboarding": { "status": "complete" } }
}
```

## Items

The twelve items a backup can hold, in the order a restore applies them:

| Item | Rows |
|---|---|
| `categories` | One per category: `term_id`, `name`, `slug`, `description`, `color` and `link_ids` |
| `tags` | The same as categories, without `color` |
| `links` | One per row of the `links` table, with every column |
| `link_rules` | One per row of the `link_rules` table |
| `clicks` | One per row of the `clicks` table, including `ip_address`, `cookie_id` and `user_id` |
| `affiliates` | One per row of the `affiliates` table |
| `campaigns` | Meta rows of the types `campaign` and `utm_template`: managed campaigns and UTM templates |
| `link_health` | One per row of the `link_health` table |
| `redirects` | One per row of the `redirects` table |
| `settings` | One object that maps each settings group to its stored values |
| `webhooks` | One per webhook, with its settings. The signing secret and custom headers (`headers_encrypted`) are stored encrypted |
| `posts` | Full rows of the WordPress posts table, for the post types the plugin scans |

Column names are the ones in [Database tables](https://docs.linkmanagerpro.com/developers/data/tables).

`link_meta` is added to the file whenever `links` is in it. Its rows are the meta table rows with `entity_type` `link`: other addresses and import bookkeeping. Each row holds `entity_id`, `meta_key`, `meta_value`, `created_at` and `updated_at`, and no row `id`. You can't choose it on its own. Older files without it still restore.

Some items bring sections you can't choose on their own: `deleted_slugs` (with `links`), `click_meta` (with `clicks`), `affiliate_meta` (with `affiliates`) and `coverage_history` (with `link_health`). A file made before `campaigns` and `webhooks` existed has no such section. Ticking them still restores the file, and the notes say yours were kept.

## Secrets

The `settings` item holds each value as the database stores it, so `ai.api_key` stays encrypted in the file. Encryption is AES-256-CBC with a key derived from the site's `AUTH_KEY`.

- On the same site, a restore decrypts the key and saves it again.
- From another site, a restore keeps this site's own key. The file's key couldn't be read here anyway.
- A key that is empty, masked or can't be decrypted isn't restored, and the restore result counts it.

Webhooks are in a backup. Their signing secrets and custom headers are stored encrypted with the site's key, so another site can't read them. After a restore there, the notes say which webhooks need a new secret or custom headers.

## Restore rules

- A file with a `schema_version` above `1` is refused before anything changes. A file without the key counts as `1`. The plugin version that made the file isn't checked.
- `webhooks` and `posts` are opt-in: they start unticked in the restore dialog, and the CLI restores them only when `--items` names them. Webhooks from another site come back paused.
- Ticked items replace the current rows. The exceptions are `settings`, which merges, and `posts`, which only rewrites the content of posts that exist.
- Restored rows keep their ids from the file. After the restore, new ids start above both the file's highest id and the live table's highest id.
- Posts restore only on the site they were backed up from. The restore compares the file's `site_url` with this site's address.
- A restore from another site is refused when a ticked item would leave unticked rows that point at the wrong ids. For example, restoring `links` but not `clicks` on a site that already has clicks.
- Before each item is replaced, the plugin copies it to a `__lmpsnap` table, and puts it back if the restore fails. See [Database tables](https://docs.linkmanagerpro.com/developers/data/tables#restore-safety-copies).

## Import limits

- Only a `.json` file is accepted.
- The browser uploads a large file in parts. Each part can be as large as the site's upload limit, `wp_max_upload_size()`, and the whole file up to 1 GB.
- A larger file restores with WP-CLI, which has no size limit. See [WP-CLI for developers](https://docs.linkmanagerpro.com/developers/cli).

```bash
wp link-manager-pro backup export --items=links,clicks --file=/tmp/links.json
wp link-manager-pro backup restore /tmp/links.json --items=links,clicks --yes
```

## Links-only CSV export

A separate route exports short links as a CSV file, named `link-manager-pro-links-{YYYY-MM-DD}.csv`.

`GET /wp-json/link-manager-pro/v1/settings/backup/export/csv`

**Permission:** a user with the `manage_options` capability.

The columns are `ID`, `Slug`, `Target URL`, `Redirect Type`, `Source`, `Click Count`, `Autolink`, `Keywords` and `Created At`. It is not a backup: you can't restore from it.

## What a backup doesn't include

The code exports only the twelve items above plus the sections they bring. These are never in a backup file:

- The webhook delivery log
- The Link Audit table
- Post types the plugin doesn't scan, post meta, media and your theme

## Related

- [Back up and restore](https://docs.linkmanagerpro.com/guides/backup-restore)
- [WP-CLI for developers](https://docs.linkmanagerpro.com/developers/cli)
- [Database tables](https://docs.linkmanagerpro.com/developers/data/tables)
- [Where Link Manager Pro stores data](https://docs.linkmanagerpro.com/developers/data/)
