Skip to content

Contacts

Manage your recipients with the Contacts API. Create, update, search, import via CSV, export, and organize contacts into segments for targeted broadcasts.

POST
/contacts

Create a new contact. The email address must be unique within your account.

json
{
  "email": "alice@example.com",
  "first_name": "Alice",
  "last_name": "Smith",
  "properties": {
    "plan": "pro",
    "signed_up": "2026-01-15"
  },
  "unsubscribed": false
}
GET
/contacts

List contacts with pagination. Supports search by email or name, and filtering by segment.

json
{
  "contacts": [
    {
      "id": "ct_abc123def456ghi789",
      "email": "alice@example.com",
      "first_name": "Alice",
      "last_name": "Smith",
      "unsubscribed": false,
      "created_at": "2026-03-23T10:00:00.000Z"
    }
  ],
  "pagination": {
    "total": 1250,
    "page": 1,
    "per_page": 20,
    "total_pages": 63
  }
}
GET
/contacts/:id

Retrieve a single contact by ID, including all properties and subscription status.

json
{
  "id": "ct_abc123def456ghi789",
  "email": "alice@example.com",
  "first_name": "Alice",
  "last_name": "Smith",
  "properties": {
    "plan": "pro",
    "signed_up": "2026-01-15"
  },
  "unsubscribed": false,
  "created_at": "2026-03-23T10:00:00.000Z",
  "updated_at": "2026-03-23T12:00:00.000Z"
}
PATCH
/contacts/:id

Update a contact's details. Only provided fields are updated.

json
{
  "first_name": "Alice",
  "properties": {
    "plan": "enterprise",
    "upgraded_at": "2026-03-23"
  }
}
DELETE
/contacts/:id

Permanently delete a contact and remove them from all segments.

json
{
  "deleted": true
}
POST
/contacts/:id/unsubscribe

Unsubscribe a contact from all future emails. They will still exist in your contact list but will not receive broadcasts.

json
{
  "id": "ct_abc123def456ghi789",
  "email": "alice@example.com",
  "unsubscribed": true,
  "unsubscribed_at": "2026-03-23T15:00:00.000Z"
}

CSV Import

Import contacts in bulk from a CSV file. The CSV must include an email column. Optional columns: first_name, last_name, and any property fields. Existing contacts are updated, new contacts are created.

bash
curl -X POST https://api.poststack.dev/contacts/import \
  -H "Authorization: Bearer sk_live_..." \
  -F "file=@contacts.csv"
typescript
// SDK import with a file buffer
const result = await poststack.contacts.import({
  file: csvBuffer,
  filename: 'contacts.csv',
});
// { imported: 450, updated: 30, errors: 2 }

Export

Export contacts as a CSV file. Optionally filter by segment:

typescript
// Export all contacts
const csv = await poststack.contacts.export();

// Export contacts in a specific segment
const segmentCsv = await poststack.contacts.export({
  segment_id: 'seg_abc123def456',
});
bash
curl "https://api.poststack.dev/contacts/export?segment_id=seg_abc123" \
  -H "Authorization: Bearer sk_live_..." \
  -o contacts.csv

Custom Properties

Store arbitrary key-value data on contacts using the properties field. Property values can be used in template variables, segment rules, and workflow conditions:

typescript
const contact = await poststack.contacts.create({
  email: 'alice@example.com',
  first_name: 'Alice',
  properties: {
    plan: 'enterprise',
    company: 'Acme Inc',
    signup_source: 'website',
    lifetime_value: '4500',
  },
});

// Use properties in dynamic segments
await poststack.segments.create({
  name: 'Enterprise Users',
  type: 'dynamic',
  rules: [
    { field: 'properties.plan', operator: 'equals', value: 'enterprise' },
  ],
});