Skip to main content
POST https://app.vern.so/api/v1/migrations/{migration_id}/files
GET  https://app.vern.so/api/v1/migrations/{migration_id}/files
Files are workbook-level — you upload them to the migration, not to a specific template; the generate run reads whatever’s been uploaded. Uploading is a two-step handshake: ask for a signed URL, then PUT the bytes straight to storage. {migration_id} is the id from creating a migration.

Authentication

Requires an x-api-key header. See Authentication.

Mint signed upload URLs

POST https://app.vern.so/api/v1/migrations/{migration_id}/files
Request one entry per file, declaring its name (and, ideally, content type):
files
object[]
required
A non-empty array of files to upload. Each entry is { "name": "contacts.csv", "content_type": "text/csv" }. name is required; content_type is optional but recommended.
curl -X POST https://app.vern.so/api/v1/migrations/c0a8012e-.../files \
  -H "x-api-key: $VERN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "files": [
      { "name": "contacts.csv", "content_type": "text/csv" }
    ]
  }'
201 Created — one signed upload per requested file:
{
  "files": [
    {
      "name": "contacts.csv",
      "storage_path": "workbooks/b3d9.../<uuid>-contacts.csv",
      "signed_url": "https://storage.vern.so/object/upload/sign/...&token=...",
      "token": "ey...",
      "content_type": "text/csv"
    }
  ]
}
files[].name
string
The display name you requested, preserved for the round trip.
files[].storage_path
string
Where the object will land in storage once uploaded.
files[].signed_url
string
The single-use URL to PUT the file’s bytes to. The upload token is embedded in the URL.
files[].token
string
The raw upload token, if you prefer a storage SDK’s uploadToSignedUrl helper over a plain PUT.

Upload the bytes

PUT each file’s raw bytes to its signed_url, with a Content-Type matching what you declared:
curl -X PUT "$SIGNED_URL" \
  -H "Content-Type: text/csv" \
  --data-binary @contacts.csv
Once your files are up, start a generate run.

List uploaded files

GET https://app.vern.so/api/v1/migrations/{migration_id}/files
Lists the customer-uploaded files for the migration — useful to confirm an upload landed before generating.
{
  "files": [
    {
      "name": "contacts.csv",
      "storage_path": "workbooks/b3d9.../<uuid>-contacts.csv",
      "size": 184320,
      "content_type": "text/csv",
      "uploaded_at": "2026-06-19T15:30:02.000Z"
    }
  ]
}

Errors

StatusMeaning
400files missing or empty, or an entry is missing name.
401API key missing or invalid.
404No migration with that {migration_id} in your account.
429Rate limit hit — back off and retry.
500Server error (including a failure to mint the signed URL).

Next

  • Start a run — generate a preview from the uploaded files.
  • Poll a run — track the run to completion.