Skip to content
On this site

Imports

Bring a CSV of contacts in. The file is uploaded in one request and processed in the background; the import records what happened to every row.

The column map

column_map says which CSV column holds which field, and which columns become typed properties. A property entry is a column name, or { column, type } with type one of string, number or boolean — the default is string.

{
  "email": "Email",
  "first_name": "First name",
  "last_name": "Last name",
  "unsubscribed": "Opted out",
  "properties": {
    "plan": "Plan",
    "seats": {
      "column": "Seats",
      "type": "number"
    }
  }
}

What happens to a row

  • A new address is created. An address that already exists is updated with the row's values when on_conflict is upsert, and skipped when it is skip, the default.
  • A row with no usable address, a value that does not match its property's type, or a row past your plan's contact limit is failed. The first thousand failures are kept with their row numbers.
  • Rows are processed in batches, so an import that is in_progress already has some of its contacts. No contact.created webhook is sent per row.
  • The file is deleted seven days after the import completes. The counts stay.

Endpoints

POST /contacts/imports

Upload a file of up to 50 MB; the rows are processed in the background.

Body

Body
FieldTypeDescription
file*fileThe CSV, up to 50 MB, as a multipart part.
column_mapstringA JSON object mapping email, first_name, last_name, unsubscribed and properties to column names. A property entry is a column name, or { column, type } with type one of string, number or boolean.
on_conflictstringupsert updates a contact whose address already exists; skip (the default) leaves it alone.
2 more fields (segments, topics)
Body, less common
FieldTypeDescription
segmentsstringA JSON array of { id } segments every imported contact is added to.
topicsstringA JSON array of { id, subscription } topic choices applied to every imported contact.
curl -X POST "https://api.rasket.com/contacts/imports" \
  -H "Authorization: Bearer $RASKET_API_KEY" \
  -H "User-Agent: acme-billing/1.0" \
  -F "file=@contacts.csv" \
  -F "column_map={\"email\":\"Email\",\"first_name\":\"First name\",\"properties\":{\"plan\":\"Plan\"}}" \
  -F "on_conflict=upsert" \
  -F "segments=[{\"id\":\"78261eea-8f8b-4381-83c6-79fa7120f1cf\"}]"

Response 201

{
  "object": "contact_import",
  "id": "0199d2f1-4c4e-7a20-9c31-6f2b8a0e5d17"
}
  • The response is immediate; poll the import for its counts.
  • No contact.created or contact.updated webhook is sent per row. One audit entry records the import.
  • Rows past your plan's contact limit are counted as failed.

GET /contacts/imports

Every import, newest first.

Query parameters

Query parameters
FieldTypeDescription
statusstringqueued, in_progress, completed or failed.
limitintegerHow many items to return, 1–100. Defaults to 20.
afterstringReturn the page that follows this item ID. Mutually exclusive with before.
beforestringReturn the page that precedes this item ID. Mutually exclusive with after.
curl -X GET "https://api.rasket.com/contacts/imports?status=completed" \
  -H "Authorization: Bearer $RASKET_API_KEY" \
  -H "User-Agent: acme-billing/1.0"

Response 200

{
  "object": "list",
  "has_more": false,
  "data": [
    {
      "object": "contact_import",
      "id": "0199d2f1-4c4e-7a20-9c31-6f2b8a0e5d17",
      "status": "completed",
      "created_at": "2026-09-08T22:22:17.595Z",
      "completed_at": "2026-09-08T22:24:01.330Z",
      "counts": {
        "total": 1240,
        "created": 1180,
        "updated": 40,
        "skipped": 15,
        "failed": 5
      }
    }
  ]
}

GET /contacts/imports/{id}

One import, with its status and counts.

Path parameters

Path parameters
FieldTypeDescription
id*stringThe import's ID.
curl -X GET "https://api.rasket.com/contacts/imports/0199d2f1-4c4e-7a20-9c31-6f2b8a0e5d17" \
  -H "Authorization: Bearer $RASKET_API_KEY" \
  -H "User-Agent: acme-billing/1.0"

Response 200

{
  "object": "contact_import",
  "id": "0199d2f1-4c4e-7a20-9c31-6f2b8a0e5d17",
  "status": "completed",
  "created_at": "2026-09-08T22:22:17.595Z",
  "completed_at": "2026-09-08T22:24:01.330Z",
  "counts": {
    "total": 1240,
    "created": 1180,
    "updated": 40,
    "skipped": 15,
    "failed": 5
  }
}
  • counts is { total, created, updated, skipped, failed }. completed_at is null until the import finishes.
  • The uploaded file is deleted seven days after the import completes; the counts stay.