---
title: "Migrating Gravity Forms from the command line with WP-CLI"
date: 2026-07-24
author: "Block MCP (service account)"
link: "https://www.gravitykit.com/docs/gravitymigrate/migrating-from-the-command-line-with-wp-cli/"
---

GravityMigrate includes [WP-CLI](https://wp-cli.org/) commands for exporting and importing your Gravity Forms and GravityKit data from the command line. Every command uses the `wp gk migrate` prefix. This is useful for scripted migrations, moving data between servers over SSH, and migrating sites that are too large to export through the browser.

**Note:** The command line is an alternative to the GravityMigrate screen in wp-admin, not a replacement. Both produce and read the same export bundle, so you can export in the browser and import on the command line, or the reverse.

## Before you begin

- [WP-CLI](https://wp-cli.org/#installing) installed on the server you run the commands on.
- GravityMigrate active on both the source and destination sites. GravityKit Foundation, bundled with the plugin, registers the `wp gk` commands.
- An administrator account. The `export`, `import`, and `reset` commands read and write your data, so they require one: pass `--user=`. Without it, the command stops and asks for an administrator.

## Quick start

The most common workflow is to export a bundle on one site and import it on another:

```

# On the source site: export everything to a ZIP
wp gk migrate export --user=admin --forms=all --data=all --output=/tmp/migration.zip

# Copy the ZIP to the destination site (scp, rsync, etc.), then import it
wp gk migrate import /tmp/migration.zip --user=admin --yes
```

```

# On the source site: export everything to a ZIP
wp gk migrate export --user=admin --forms=all --data=all --output=/tmp/migration.zip

# Copy the ZIP to the destination site (scp, rsync, etc.), then import it
wp gk migrate import /tmp/migration.zip --user=admin --yes
```

---

## Exporting a bundle

`wp gk migrate export` writes the forms and data you choose to a portable ZIP bundle.

```

# Export specific forms with their entries, Views, and pages
wp gk migrate export --user=admin --forms=3,5 --data=entries,views,posts --output=/srv/backups/forms.zip

# Export every form and every data type
wp gk migrate export --user=admin --forms=all --data=all --output=/srv/backups/all.zip

# Only entries created within a date range
wp gk migrate export --user=admin --forms=all --data=entries --date-start=2026-01-01 --date-end=2026-06-30 --output=/tmp/first-half.zip

# Encrypt the ZIP with a password
wp gk migrate export --user=admin --forms=all --data=all --password="a-strong-password" --output=/tmp/secure.zip
```

```

# Export specific forms with their entries, Views, and pages
wp gk migrate export --user=admin --forms=3,5 --data=entries,views,posts --output=/srv/backups/forms.zip

# Export every form and every data type
wp gk migrate export --user=admin --forms=all --data=all --output=/srv/backups/all.zip

# Only entries created within a date range
wp gk migrate export --user=admin --forms=all --data=entries --date-start=2026-01-01 --date-end=2026-06-30 --output=/tmp/first-half.zip

# Encrypt the ZIP with a password
wp gk migrate export --user=admin --forms=all --data=all --password="a-strong-password" --output=/tmp/secure.zip
```

| Flag | What it does |

|---|---|
| `--forms=` | Comma-separated form IDs, or `all`. |
| `--data=` | Comma-separated data types, or `all`. Defaults to `entries,views,posts`. See **Data types** below. |
| `--date-start=`, `--date-end=` | Limit exported entries to a date range. |
| `--password=` | Encrypt the ZIP (AES-256). |
| `--public-url=` | Rewrite this site's address to `` in exported file-upload links, so uploads download on import when the source's own address is not reachable from the destination. |
| `--output=` | Copy the finished ZIP to this path. Without it, the ZIP stays in the exports directory and is removed after three hours. |
| `--porcelain` | Output only the ZIP path. |

**Tip:** Use `--public-url` when the source site's stored address is not reachable from the destination, for example a local or staging clone. Entry file uploads are downloaded from the addresses stored in the bundle, so they must resolve from the importing server.

---

## Importing a bundle

`wp gk migrate import` reads a bundle and writes its forms, entries, Views, and other data into the current site. Import into a clean destination when you can, so results do not stack.

```

# Import everything in a bundle, skipping the confirmation prompt
wp gk migrate import /tmp/migration.zip --user=admin --yes

# Import only certain forms or data types from the bundle
wp gk migrate import /tmp/migration.zip --user=admin --forms=3,5 --data=entries,views --yes

# Import a password-protected bundle
wp gk migrate import /tmp/secure.zip --user=admin --password="a-strong-password" --yes

# Import without downloading entry file uploads
wp gk migrate import /tmp/migration.zip --user=admin --skip-uploads --yes
```

```

# Import everything in a bundle, skipping the confirmation prompt
wp gk migrate import /tmp/migration.zip --user=admin --yes

# Import only certain forms or data types from the bundle
wp gk migrate import /tmp/migration.zip --user=admin --forms=3,5 --data=entries,views --yes

# Import a password-protected bundle
wp gk migrate import /tmp/secure.zip --user=admin --password="a-strong-password" --yes

# Import without downloading entry file uploads
wp gk migrate import /tmp/migration.zip --user=admin --skip-uploads --yes
```

| Flag | What it does |
|---|---|
| `` | Path to the bundle. The first argument, required. |
| `--forms=` | Form IDs to import, or `all` (default). Each must exist in the bundle. |
| `--data=` | Data types to import, or `all` (default), intersected with what the bundle contains. |
| `--password=` | Password, if the bundle is encrypted. |
| `--skip-uploads` | Do not download entry file uploads. |
| `--yes` | Skip the confirmation prompt. |
| `--porcelain` | Output only the newly created form IDs, one per line. |
| `--download-timeout=`, `--max-download-bytes=`, `--max-dump-file-size=` | Per-run overrides for the import safety limits. |

**Note:** Importing writes into your Gravity Forms tables. Back up the destination site first, and prefer a clean destination so imported entries and Views are not mixed with existing data.

---

## Inspecting a bundle before importing

`wp gk migrate inspect` shows what a bundle contains without importing it: its forms, data types, source address, and whether its uploads will download from this server.

```
wp gk migrate inspect /tmp/migration.zip

# As JSON
wp gk migrate inspect /tmp/migration.zip --format=json
```

```
wp gk migrate inspect /tmp/migration.zip

# As JSON
wp gk migrate inspect /tmp/migration.zip --format=json
```

---

## Checking migration state

`wp gk migrate status` reports whether an import is in progress, whether a previous import stalled, and whether an export left state behind to clean up.

```
wp gk migrate status
wp gk migrate status --format=json
```

```
wp gk migrate status
wp gk migrate status --format=json
```

## Clearing stuck migration state

If an import was interrupted and a later one is refused, `wp gk migrate reset` clears the stuck state: the temporary tables, the extracted files, and the progress locks.

```
wp gk migrate reset --user=admin --yes
```

```
wp gk migrate reset --user=admin --yes
```

---

## Data types

The `--data` flag accepts a comma-separated list of these types, or `all`:

| Type | What it includes |
|---|---|
| `entries` | Form entries with their metadata and notes. |
| `uploads` | Entry file uploads. Downloaded from the source during import, so it requires `entries`. |
| `views` | GravityView Views. |
| `posts` | The pages that embed your Views, and other connected posts. |
| `revisions` | Form revision history. |
| `addon_feeds` | Add-on feeds, for example GravityView and GravityCharts. |
| `gravityflow` | Gravity Flow workflow activity, where present. |
| `drafts` | Saved and continued draft submissions. |
| `gf_settings` | Gravity Forms settings. |
| `gk_settings` | GravityKit settings. |
| `rest_api_keys` | Gravity Forms REST API keys. |

---

## Output formats

Commands that print data support `--format=table` (the default, human-readable) and `--format=json` (machine-readable). For scripting, `wp gk migrate export --porcelain` prints only the ZIP path, and `wp gk migrate import --porcelain` prints only the newly created form IDs.

---

## Scripting a migration between two servers

Because `--porcelain` prints only the essential value, you can chain export and import over SSH:

```
#!/bin/bash
set -e

# Export on the source site and capture just the ZIP path
ZIP=$(wp gk migrate export --user=admin --forms=all --data=all --porcelain)

# Copy it to the destination and import it there
scp "$ZIP" deploy@destination:/tmp/migration.zip
ssh deploy@destination "wp gk migrate import /tmp/migration.zip --user=admin --yes --porcelain"
```

```
#!/bin/bash
set -e

# Export on the source site and capture just the ZIP path
ZIP=$(wp gk migrate export --user=admin --forms=all --data=all --porcelain)

# Copy it to the destination and import it there
scp "$ZIP" deploy@destination:/tmp/migration.zip
ssh deploy@destination "wp gk migrate import /tmp/migration.zip --user=admin --yes --porcelain"
```

---

## Troubleshooting

**"'gk' is not a registered wp command":** Make sure GravityMigrate is active. The commands are registered through GravityKit Foundation, which is bundled with every GravityKit plugin.

**"Run with --user=<an administrator login>":** The export, import, and reset commands require an administrator. Add `--user=` with an administrator's username or ID.

**"Import already in progress":** A previous import did not finish. Run `wp gk migrate status` to confirm, then `wp gk migrate reset --user=admin --yes`, and try the import again.

**Entry file uploads did not download:** The source site's address is not reachable from the destination. Re-export with `--public-url=` set to an address that resolves from the importing server.

**The bundle's database dump is too large:** Raise the limit for a single run with `--max-dump-file-size=` on the import command.

---

## Related articles

- [Getting started with GravityMigrate](https://www.gravitykit.com/docs/gravitymigrate/getting-started-with-gravitymigrate/)
- [Best practices for moving data using GravityMigrate](https://www.gravitykit.com/docs/gravitymigrate/best-practices-for-moving-data-using-gravitymigrate/)

- [GravityMigrate hooks](https://www.gravitykit.com/docs/gravitymigrate/gravitymigrate-hooks/)