Skip to main content
POST https://app.vern.so/api/v1/migrations
Creates a migration for one of your customers — a workbook with one sheet per template. You can name the system you’re migrating from in the source field, but no import logic is bound to the migration: the managed agent decides what to run. Later calls reference only the migration ID. A new migration starts in awaiting_files — your next step is to upload files.

Authentication

Requires an x-api-key header — this endpoint requires API-key auth specifically (a session token is rejected). The key is scoped to your account and can address every migration in it. See Authentication.

Request body

name
string
required
Display name for the migration. Typically your customer’s organization name.
source
string
The name of the source this migration comes from — the system its data is coming out of. List your sources to find it. Optional: omit it (or pass null/empty) for a sourceless migration, where the agent works purely from the uploaded files.
external_id
string
Your own identifier for this customer (e.g. their ID in your database). Echoed back so you can match the migration to your records. Max 255 characters; alphanumeric, hyphens, and underscores only. Makes creation idempotent — re-sending the same external_id (with the same source) returns the existing migration with a 200. See Errors & limits.
templates
string[]
The slugs of the templates to create sheets from — the objects this customer will import. List your templates to choose. If omitted, every active template in your account is used.

Response

201 Created (or 200 OK when an existing migration is returned via external_id idempotency).
{
  "migration": {
    "id": "c0a8012e-4f1b-4d3a-9b2c-7e6f5a4b3c2d",
    "name": "Acme Corp",
    "source": "Salesforce",
    "status": "awaiting_files",
    "templates": [
      { "slug": "contacts", "name": "Contacts" }
    ]
  }
}
migration.id
string (uuid)
The migration ID — pass it to every run and export call.
migration.name
string
The display name you provided.
migration.source
string | null
The source name, or null for a sourceless migration.
migration.status
string
The migration’s overall state. awaiting_files for a fresh migration; for one returned via idempotency it reflects progress so far (awaiting_files, ready, awaiting_approval, or completed). See Core concepts → Migration.
migration.templates
object[]
The templates that became sheets, each { slug, name }.

Errors

StatusMeaning
400name missing; source not a string; external_id malformed; templates not an array of slugs; one or more template slugs not found (Unknown template slug(s): …).
401API key missing or invalid, or the request used a session token instead of an API key.
404The named source isn’t a source in your account.
409external_id already used by another migration, the source name is ambiguous (two sources share it), or your account’s region isn’t live yet.
429Rate limit hit — back off and retry.
500Server error.
See Errors & limits for the shared error model.

Example

curl -X POST https://app.vern.so/api/v1/migrations \
  -H "x-api-key: $VERN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Acme Corp",
    "source": "Salesforce",
    "external_id": "acme-001",
    "templates": ["contacts"]
  }'

Next

  • Upload files — push the customer’s data into the migration.
  • Start a run — generate a preview once files are uploaded.