DeckleDocs
Dashboard

API reference

Contacts

Create, read, update, and delete the contacts in your audience.

A contact is an email address plus optional profile and custom data. Contacts are unlimited — Deckle bills on sends, not audience size.

The contact object#

json
{
  "id": "contact_a1b2c3",
  "email": "jane@example.com",
  "name": "Jane Doe",
  "subscribed": true,
  "source": "api",
  "data": { "plan": "pro" },
  "created_at": "2026-07-10T10:30:00.000Z",
  "updated_at": "2026-07-10T10:30:00.000Z"
}

Create or update a contact#

POST/v1/contacts

Upserts by email. A new email returns 201; an existing one is updated and returns 200. Omitted fields are left unchanged on update.

Body parameters

emailstringRequired
The contact’s email address. Normalized to lowercase.
namestringOptional
Display name. An empty string is stored as null.
subscribedbooleanOptional
Subscription state. Defaults to true on create.
sourcestringOptional
Where the contact came from. Defaults to api on create.
dataobjectOptional
Arbitrary custom fields as a JSON object (not an array), e.g. { "plan": "pro" }.
curl -X POST https://app.getdeckle.com/api/v1/contacts \
  -H "Authorization: Bearer sk_live_..." \
  -H "Content-Type: application/json" \
  -d '{ "email": "jane@example.com", "name": "Jane Doe",
        "data": { "plan": "pro" } }'

Automation enrollment

A newly-created subscribed contact is automatically enrolled in any live automation triggered by contact.subscribed.

List contacts#

GET/v1/contacts

Query parameters

limitintegerOptional
Items per page. Default 50, max 100.
cursorstringOptional
Pagination cursor.
emailstringOptional
Filter by exact email address.
subscribedbooleanOptional
Filter by subscription state (true or false).
ts
const { data, has_more, next_cursor } = await deckle.contacts.list({ limit: 50 });

Retrieve a contact#

GET/v1/contacts/:id
ts
const contact = await deckle.contacts.get("contact_a1b2c3");

Update a contact#

PATCH/v1/contacts/:id

Partial update — only the fields you send change. The email address cannot be changed via PATCH.

ts
await deckle.contacts.update("contact_a1b2c3", {
  subscribed: false,
  data: { plan: "free" },
});

Delete a contact#

DELETE/v1/contacts/:id
await deckle.contacts.delete("contact_a1b2c3");