Contacts API
Endpoints for managing email contacts and static list membership.
lists field uses list slugs for segmentation only — it does not grant marketing consent. Use opt_in_subtype_slugs for consent. On contact responses, lists reflects static memberships only (not smart-list evaluation). See Contact Lists API./api/v1/contactsCreate a new contact or update an existing one (upsert by email). Use opt_in_subtype_slugs to grant marketing/operational subtype consent. See Subscriptions & Consent guide.
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
email | string | Yes | Contact email address |
name | string | No | Contact name |
data | object | No | Custom data fields |
custom_attributes | object | No | Custom contact attributes (dashboard-defined) |
locale | string | No | Contact locale (e.g. en, cs, en-US). Default: en. Not limited by dashboard supported locales |
lists | string[] | No | List slugs — append static memberships. Unknown or smart-list slugs return 400 with details.invalid_lists |
opt_in_subtype_slugs | string[] | No | Grant opt-in to these marketing/operational subtype slugs |
double_opt_in | boolean | No | Set false to skip DOI and confirm immediately (admin/import) |
confirm_template | string | No | Confirm email template slug (default: consent-confirm). Success redirect URL is read from the template. See Double Opt-In Redirect guide. |
Example Request
curl -X POST https://artamail.artatol.net/api/v1/contacts \ -H "Authorization: Bearer am_live_sk_xxx" \ -H "Content-Type: application/json" \ -d '{ "email": "[email protected]", "name": "John Doe", "locale": "en", "data": { "plan": "premium" }, "opt_in_subtype_slugs": ["weekly-digest"], "lists": ["customers"] }'Response
{ "id": "contact-uuid", "email": "[email protected]", "name": "John Doe", "data": { "plan": "premium" }, "custom_attributes": {}, "locale": "en", "subscribed": true, "validation_status": "pending", "lists": ["customers"], "pending_confirmation": true, "confirm_url": "https://artamail.artatol.net/api/confirm/...", "created_at": "2024-01-15T10:30:00Z", "updated_at": "2024-01-15T10:30:00Z", "test_mode": false}confirm_url is returned and pending_confirmation is true. You must send the confirm email (e.g. template consent-confirm) — ArtaMail does not auto-send it. Configure success redirect on the template. For multiple products, use one account per brand — see Multiple Products./api/v1/contacts/:emailRetrieve a contact by email address.
Example Request
curl https://artamail.artatol.net/api/v1/contacts/user%40example.com \ -H "Authorization: Bearer am_live_sk_xxx"Response
{ "id": "contact-uuid", "email": "[email protected]", "name": "John Doe", "data": { "plan": "premium", "role": "admin" }, "subscribed": true, "validation_status": "valid", "locale": "en", "lists": ["customers"], "custom_attributes": {}, "created_at": "2024-01-15T10:30:00Z", "updated_at": "2024-01-15T10:30:00Z", "test_mode": false}Returns 404 if contact not found. lists contains static list slugs only.
/api/v1/contacts/:emailUpdate an existing contact.
Request Body
| Field | Type | Description |
|---|---|---|
name | string | Contact name |
data | object | Custom data fields (merged with existing) |
lists | string[] | List slugs — append static memberships when provided. Unknown or smart-list slugs return 400 with details.invalid_lists. Omit the field to leave memberships unchanged; use POST .../lists to remove |
custom_attributes | object | Custom attribute fields (merged with existing) |
subscribed | boolean | Master subscription switch (blocks all marketing campaigns) |
locale | string | Contact locale |
Example Request
curl -X PATCH https://artamail.artatol.net/api/v1/contacts/user%40example.com \ -H "Authorization: Bearer am_live_sk_xxx" \ -H "Content-Type: application/json" \ -d '{ "name": "Jane Doe", "data": { "plan": "enterprise" } }'/api/v1/contacts/:email/listsAdd and/or remove a contact from static lists by slug. Smart list slugs return a validation error — membership on smart lists is computed automatically.
Request Body
| Field | Type | Description |
|---|---|---|
add | string[] | List slugs to add the contact to |
remove | string[] | List slugs to remove the contact from |
Example Request
curl -X POST https://artamail.artatol.net/api/v1/contacts/user%40example.com/lists \ -H "Authorization: Bearer am_live_sk_xxx" \ -H "Content-Type: application/json" \ -d '{ "add": ["vip", "newsletter"], "remove": ["trial"] }'Response
{ "id": "contact-uuid", "email": "[email protected]", "name": "John Doe", "lists": ["newsletter", "vip"], "test_mode": false}Error response
{ "message": "Invalid or non-modifiable list slug(s)", "code": "VALIDATION_ERROR", "details": { "invalid_lists": ["product-news-cs"] }}invalid_lists includes unknown slugs and smart list slugs. See Contact Lists API.
/api/v1/contacts/:emailPermanently delete a contact when a user deletes their account in your app. Removes the contact profile, all subscription preferences, list memberships, and anonymizes stored email content. Cannot be undone — use POST /api/v1/contacts to add them again as a new contact.
Example Request
curl -X DELETE https://artamail.artatol.net/api/v1/contacts/user%40example.com \ -H "Authorization: Bearer am_live_sk_xxx"Returns 204 No Content on success. See also SDK deleteContact.
/api/v1/contacts/:email/subscription-preferencesRead per-subtype consent for a contact. See Subscription Types API.
/api/v1/contacts/:email/subscription-preferencesUpdate per-subtype consent from your app (API key). Partial update — send only changed keys. Consent is confirmed immediately (no double opt-in on this endpoint). Use type_slug/subtype_slug keys when subtype slugs are not unique per account.
Request Body
| Field | Type | Description |
|---|---|---|
preferences | object | Map of subtype key → subscribed boolean |
unsubscribe_all | boolean | Opt out all marketing and operational subtypes |
Example Request
curl -X PATCH https://artamail.artatol.net/api/v1/contacts/user%40example.com/subscription-preferences \ -H "Authorization: Bearer am_live_sk_xxx" \ -H "Content-Type: application/json" \ -d '{ "preferences": { "newsletter/weekly-digest": true, "newsletter/product-updates": false } }'GET/POST /api/u/{token}/... with a signed token instead — see Custom Preference URLs.Validation Statuses
Contacts are automatically validated after creation:
| Status | Description |
|---|---|
pending | Awaiting validation |
valid | Email address is valid |
invalid | Email address is invalid (bounced, bad syntax, etc.) |
risky | Potentially deliverable but flagged (disposable, role-based, etc.) |
unknown | Validation could not complete (e.g. DNS timeout) |
test_mode: true and includes confirm_url when opt-in would be pending.