Import contacts in bulk

POST
/v1/contacts/import

Creates or updates up to 1000 contacts at once (source import). Each entry is validated on its own: invalid ones are skipped and listed in invalid. Existing contacts get the new names and properties, but an import never re-subscribes an unsubscribed contact (kept_unsubscribed). Imports send no contact.* webhooks. Over the plan's contact limit nothing is imported.

Authorization

bearerAuth
headerAuthorizationBearer <token>

A secret API key from the dashboard: coss_live_… for production environments, coss_test_… for sandbox environments.

Header Parameters

Coss-Version?"2026-10-10"

The API version (a date) to use for this request. Defaults to your organization's version, pinned to the latest one when it first used the API and upgraded from the dashboard. The SDK always sends the version it was built for.

Value in"2026-10-10"

Request Body

application/json
  1. body
contacts*array<>
Items1 <= items <= 1000
audience_id?string

Adds every imported contact to this audience.

Response Body

What the import did.

application/json
  1. response
object*"contact_import"
Value in"contact_import"
created*integer
updated*integer
kept_unsubscribed*integer

Existing contacts the import marked subscribed that stay unsubscribed: an import never re-subscribes anyone.

invalid*array<>
import { Coss } from "coss";const coss = new Coss({  apiKey: process.env.COSS_API_KEY,  baseUrl: "https://api.coss.com",});const { data, error } = await coss.email.contacts.import({  contacts: [    {      email: "ada@example.com",      first_name: "Ada",      properties: {        plan: "pro",      },    },    {      email: "grace@example.com",      status: "unsubscribed",    },  ],});
{  "object": "contact_import",  "created": 1,  "updated": 1,  "kept_unsubscribed": 0,  "invalid": [    {      "index": 2,      "email": "not-an-address",      "message": "Must be an email address."    }  ]}