Skip to content

Update contacts

PATCH
https://api.getsitecontrol.com/v1/sites/{site_id}/contacts
curl --request PATCH \
--url https://api.getsitecontrol.com/v1/sites/1/contacts \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '{ "items": [ { "id": 1, "email": "example", "status": "subscribed", "first_name": "example", "last_name": "example", "country": "example", "phone": "example", "timezone": "example", "language": "example", "fields": { "additionalProperty": "example" }, "add_tags": [ "example" ], "remove_tags": [ "example" ] } ] }'

Changes the named contacts at once: names, phone, country, time zone, language, custom fields, subscription status, tags added or removed, a new e-mail. Each item names a contact by id; to find one by its address, use list_contacts with email. Up to 100 items per call, the page size of list_contacts; one contact is a list of one.

The answer reports every item in the order given: updated, unchanged (nothing to change, nothing written) or failed with a reason; one failed item writes nothing of its own and does not stop the others.

A field left out is kept; null clears first_name, last_name, phone, country, timezone and language; fields are keyed by field ids from list_contact_fields, merged by key, and null removes a value. Tags go by name, compared without case: add_tags adds them and creates a tag the site does not have, remove_tags takes them off; tags not named stay. changed names the fields that were written.

Status: subscribed is allowed from unsubscribed, and subscribes again a contact who opted out, as the admin does; leave status out to keep what the contact chose. unsubscribed is allowed from subscribed or from awaiting double opt-in. A bounced contact changes status only with a new e-mail, and a contact awaiting double opt-in is never subscribed here. A status change that is not allowed does not stop the rest: the other fields are written and reason says why.

A bounced contact with a new e-mail becomes unsubscribed unless status says otherwise; its links to sent e-mails are dropped, email_stats start over and the new address is checked. An item that changes nothing keeps updated_at.

FieldDescription
site_id
required
Site Id
integer
Media typeapplication/json
ContactsUpdate
object
FieldDescription
items
required
Items

Up to 100 contacts, each id once

Array<object>
>= 1 items <= 100 items
ContactUpdateItem

The fields every contact write takes; an upsert finds by email.

object
FieldDescription
id
required
Id

Contact id from list_contacts

integer
>= 1
email
Email

A new address, stored in lower case; may not be null

string
<= 250 characters
status
Status

subscribed or unsubscribed; bounced is set only by e-mail delivery. Left out: unchanged, a new contact is subscribed; may not be null

string
Allowed values: subscribed unsubscribed
first_name
First Name

Null clears it

string
nullable <= 250 characters
last_name
Last Name

Null clears it

string
nullable <= 250 characters
country
Country

ISO 3166-1 alpha-2 code or an English country name; stored as the code; null clears it

string
nullable <= 250 characters
phone
Phone

In the international format, or national with country in the same request; stored normalized; null clears it

string
nullable <= 250 characters
timezone
Timezone

IANA time zone name such as Europe/Berlin; null clears it

string
nullable <= 250 characters
language
Language

ISO 639-1 code such as de; stored in lower case; null clears it

string
nullable <= 250 characters
fields
Fields

Values by field id from list_contact_fields: a string for text, a whole number for integer, a number, an ISO 8601 string for a datetime (UTC without an offset), YYYY-MM-DD for a date, true or false for a boolean. Fields of the other type are read-only. Merged into the stored values: null removes a value, keys not given stay as they are

object
FieldDescription
key
additional properties
Allowed types:
stringintegernumberboolean
string:
<= 1000 characters
add_tags
Add Tags

Tag names to add, compared without case; a tag the site does not have is created. Tags the contact has stay

Array<string>
<= 100 items
remove_tags
Remove Tags

Tag names to remove, compared without case; a name with no tag, or a tag the contact does not have, is no change. Never creates a tag

Array<string>
<= 100 items

Successful Response

Media typeapplication/json
ContactsBatch
object
FieldDescription
items
required
Items

Every item, in the order given

Array<object>
ContactBatchItem
object
FieldDescription
index
required
Index

Position of the item in the request, from 0

integer
id
Id

The contact; a failed item of update_contacts or delete_contacts keeps the id it was given. Null when no contact was found

integer
nullable
result
required
ContactBatchResult

Created: a new contact, by upsert_contacts or upsert_contact. updated: something was written, changed names it; in delete_contacts the contact was deleted. restored: the address belonged to a deleted contact, which is back with its old data and the item applied over it. unchanged: nothing to change, nothing written; in delete_contacts the contact was deleted before. failed: nothing of this item was written, see reason.

string
Allowed values: created updated restored unchanged failed
changed
required
Changed

Names of the fields whose stored value changed, from is_deleted, email, status, first_name, last_name, phone, country, timezone, language, fields, tags; empty when none did. A new contact names email, status and every field it was given; a restored one starts with is_deleted

Array<string>
reason

Why it failed, or why the status sent was not applied; null otherwise

string
Allowed values: contact_not_found contact_email_taken contact_tag_invalid contact_field_invalid contact_unreadable contact_status_transition contact_value_invalid
detail
Detail
string
nullable
contact
Contact

The contact after the call; null when it was not found

object
FieldDescription
id
required
Id
integer
email
required
Email

As stored

string
status
required
Status

After the call

string
Allowed values: subscribed unsubscribed bounced
created
required
Created
integer
updated
required
Updated
integer
restored
required
Restored
integer
unchanged
required
Unchanged
integer
failed
required
Failed
integer

Example

{
"items": [
{
"result": "created",
"reason": "contact_not_found",
"contact": {
"status": "subscribed"
}
}
]
}
FieldDescription
GSC-Version
string

API version the response was produced for

X-Request-Id
string

Request id, echoed from the request when valid

X-RateLimit-Limit
integer

Limit of the tightest bucket

X-RateLimit-Remaining
integer

Requests left in its window

X-RateLimit-Reset
integer

End of its window, epoch seconds

Unsupported GSC-Version

Media typeapplication/problem+json
Problem

The documented shape of every error body on the versioned surface.

object
FieldDescription
type
required
Type
string
title
required
Title
string
status
required
Status
integer
detail
Detail
string
nullable
instance
required
Instance
string
reason
Reason
string
nullable
next
Next
string
nullable
request_id
required
Request Id
string
errors
Errors
Array<object>
nullable
ValidationIssue
object
FieldDescription
loc
required
Loc
Array
msg
required
Msg
string
type
required
Type
string
metadata
Metadata
object

Example · Generated

{
"type": "example",
"title": "example",
"status": 1,
"detail": "example",
"instance": "example",
"reason": "example",
"next": "example",
"request_id": "example",
"errors": [
{
"loc": [
"example"
],
"msg": "example",
"type": "example"
}
],
"metadata": {}
}
FieldDescription
GSC-Version
string

API version the response was produced for

X-Request-Id
string

Request id, echoed from the request when valid

X-RateLimit-Limit
integer

Limit of the tightest bucket

X-RateLimit-Remaining
integer

Requests left in its window

X-RateLimit-Reset
integer

End of its window, epoch seconds

Missing or invalid API key or access token

Media typeapplication/problem+json
Problem

The documented shape of every error body on the versioned surface.

object
FieldDescription
type
required
Type
string
title
required
Title
string
status
required
Status
integer
detail
Detail
string
nullable
instance
required
Instance
string
reason
Reason
string
nullable
next
Next
string
nullable
request_id
required
Request Id
string
errors
Errors
Array<object>
nullable
ValidationIssue
object
FieldDescription
loc
required
Loc
Array
msg
required
Msg
string
type
required
Type
string
metadata
Metadata
object

Example · Generated

{
"type": "example",
"title": "example",
"status": 1,
"detail": "example",
"instance": "example",
"reason": "example",
"next": "example",
"request_id": "example",
"errors": [
{
"loc": [
"example"
],
"msg": "example",
"type": "example"
}
],
"metadata": {}
}
FieldDescription
GSC-Version
string

API version the response was produced for

X-Request-Id
string

Request id, echoed from the request when valid

X-RateLimit-Limit
integer

Limit of the tightest bucket

X-RateLimit-Remaining
integer

Requests left in its window

X-RateLimit-Reset
integer

End of its window, epoch seconds

WWW-Authenticate
string

Authentication scheme: Bearer

forbidden: the key or token lacks contacts.edit

Media typeapplication/problem+json
Problem

The documented shape of every error body on the versioned surface.

object
FieldDescription
type
required
Type
string
title
required
Title
string
status
required
Status
integer
detail
Detail
string
nullable
instance
required
Instance
string
reason
Reason
string
nullable
next
Next
string
nullable
request_id
required
Request Id
string
errors
Errors
Array<object>
nullable
ValidationIssue
object
FieldDescription
loc
required
Loc
Array
msg
required
Msg
string
type
required
Type
string
metadata
Metadata
object

Example · Generated

{
"type": "example",
"title": "example",
"status": 1,
"detail": "example",
"instance": "example",
"reason": "example",
"next": "example",
"request_id": "example",
"errors": [
{
"loc": [
"example"
],
"msg": "example",
"type": "example"
}
],
"metadata": {}
}
FieldDescription
GSC-Version
string

API version the response was produced for

X-Request-Id
string

Request id, echoed from the request when valid

X-RateLimit-Limit
integer

Limit of the tightest bucket

X-RateLimit-Remaining
integer

Requests left in its window

X-RateLimit-Reset
integer

End of its window, epoch seconds

Not found

Media typeapplication/problem+json
Problem

The documented shape of every error body on the versioned surface.

object
FieldDescription
type
required
Type
string
title
required
Title
string
status
required
Status
integer
detail
Detail
string
nullable
instance
required
Instance
string
reason
Reason
string
nullable
next
Next
string
nullable
request_id
required
Request Id
string
errors
Errors
Array<object>
nullable
ValidationIssue
object
FieldDescription
loc
required
Loc
Array
msg
required
Msg
string
type
required
Type
string
metadata
Metadata
object

Example · Generated

{
"type": "example",
"title": "example",
"status": 1,
"detail": "example",
"instance": "example",
"reason": "example",
"next": "example",
"request_id": "example",
"errors": [
{
"loc": [
"example"
],
"msg": "example",
"type": "example"
}
],
"metadata": {}
}
FieldDescription
GSC-Version
string

API version the response was produced for

X-Request-Id
string

Request id, echoed from the request when valid

X-RateLimit-Limit
integer

Limit of the tightest bucket

X-RateLimit-Remaining
integer

Requests left in its window

X-RateLimit-Reset
integer

End of its window, epoch seconds

Conflict

Media typeapplication/problem+json
Problem

The documented shape of every error body on the versioned surface.

object
FieldDescription
type
required
Type
string
title
required
Title
string
status
required
Status
integer
detail
Detail
string
nullable
instance
required
Instance
string
reason
Reason
string
nullable
next
Next
string
nullable
request_id
required
Request Id
string
errors
Errors
Array<object>
nullable
ValidationIssue
object
FieldDescription
loc
required
Loc
Array
msg
required
Msg
string
type
required
Type
string
metadata
Metadata
object

Example · Generated

{
"type": "example",
"title": "example",
"status": 1,
"detail": "example",
"instance": "example",
"reason": "example",
"next": "example",
"request_id": "example",
"errors": [
{
"loc": [
"example"
],
"msg": "example",
"type": "example"
}
],
"metadata": {}
}
FieldDescription
GSC-Version
string

API version the response was produced for

X-Request-Id
string

Request id, echoed from the request when valid

X-RateLimit-Limit
integer

Limit of the tightest bucket

X-RateLimit-Remaining
integer

Requests left in its window

X-RateLimit-Reset
integer

End of its window, epoch seconds

Request body too large

Media typeapplication/problem+json
Problem

The documented shape of every error body on the versioned surface.

object
FieldDescription
type
required
Type
string
title
required
Title
string
status
required
Status
integer
detail
Detail
string
nullable
instance
required
Instance
string
reason
Reason
string
nullable
next
Next
string
nullable
request_id
required
Request Id
string
errors
Errors
Array<object>
nullable
ValidationIssue
object
FieldDescription
loc
required
Loc
Array
msg
required
Msg
string
type
required
Type
string
metadata
Metadata
object

Example · Generated

{
"type": "example",
"title": "example",
"status": 1,
"detail": "example",
"instance": "example",
"reason": "example",
"next": "example",
"request_id": "example",
"errors": [
{
"loc": [
"example"
],
"msg": "example",
"type": "example"
}
],
"metadata": {}
}
FieldDescription
GSC-Version
string

API version the response was produced for

X-Request-Id
string

Request id, echoed from the request when valid

X-RateLimit-Limit
integer

Limit of the tightest bucket

X-RateLimit-Remaining
integer

Requests left in its window

X-RateLimit-Reset
integer

End of its window, epoch seconds

Media typeapplication/problem+json

validation_failed: the body is invalid: more than 100 items, an id or an e-mail repeated, a tag both added and removed

Problem

The documented shape of every error body on the versioned surface.

object
FieldDescription
type
required
Type
string
title
required
Title
string
status
required
Status
integer
detail
Detail
string
nullable
instance
required
Instance
string
reason
Reason
string
nullable
next
Next
string
nullable
request_id
required
Request Id
string
errors
Errors
Array<object>
nullable
ValidationIssue
object
FieldDescription
loc
required
Loc
Array
msg
required
Msg
string
type
required
Type
string
metadata
Metadata
object

Example · Generated

{
"type": "example",
"title": "example",
"status": 1,
"detail": "example",
"instance": "example",
"reason": "example",
"next": "example",
"request_id": "example",
"errors": [
{
"loc": [
"example"
],
"msg": "example",
"type": "example"
}
],
"metadata": {}
}
FieldDescription
GSC-Version
string

API version the response was produced for

X-Request-Id
string

Request id, echoed from the request when valid

X-RateLimit-Limit
integer

Limit of the tightest bucket

X-RateLimit-Remaining
integer

Requests left in its window

X-RateLimit-Reset
integer

End of its window, epoch seconds

Rate limited

Media typeapplication/problem+json
Problem

The documented shape of every error body on the versioned surface.

object
FieldDescription
type
required
Type
string
title
required
Title
string
status
required
Status
integer
detail
Detail
string
nullable
instance
required
Instance
string
reason
Reason
string
nullable
next
Next
string
nullable
request_id
required
Request Id
string
errors
Errors
Array<object>
nullable
ValidationIssue
object
FieldDescription
loc
required
Loc
Array
msg
required
Msg
string
type
required
Type
string
metadata
Metadata
object

Example · Generated

{
"type": "example",
"title": "example",
"status": 1,
"detail": "example",
"instance": "example",
"reason": "example",
"next": "example",
"request_id": "example",
"errors": [
{
"loc": [
"example"
],
"msg": "example",
"type": "example"
}
],
"metadata": {}
}
FieldDescription
GSC-Version
string

API version the response was produced for

X-Request-Id
string

Request id, echoed from the request when valid

X-RateLimit-Limit
integer

Limit of the tightest bucket

X-RateLimit-Remaining
integer

Requests left in its window

X-RateLimit-Reset
integer

End of its window, epoch seconds

Retry-After
integer

Seconds until the bucket refills

Media typeapplication/problem+json

temporarily_unavailable: the request took too long, or limits or idempotency keys cannot be enforced; retry later

Problem

The documented shape of every error body on the versioned surface.

object
FieldDescription
type
required
Type
string
title
required
Title
string
status
required
Status
integer
detail
Detail
string
nullable
instance
required
Instance
string
reason
Reason
string
nullable
next
Next
string
nullable
request_id
required
Request Id
string
errors
Errors
Array<object>
nullable
ValidationIssue
object
FieldDescription
loc
required
Loc
Array
msg
required
Msg
string
type
required
Type
string
metadata
Metadata
object

Example · Generated

{
"type": "example",
"title": "example",
"status": 1,
"detail": "example",
"instance": "example",
"reason": "example",
"next": "example",
"request_id": "example",
"errors": [
{
"loc": [
"example"
],
"msg": "example",
"type": "example"
}
],
"metadata": {}
}
FieldDescription
GSC-Version
string

API version the response was produced for

X-Request-Id
string

Request id, echoed from the request when valid

X-RateLimit-Limit
integer

Limit of the tightest bucket

X-RateLimit-Remaining
integer

Requests left in its window

X-RateLimit-Reset
integer

End of its window, epoch seconds