Contacts

Learn how to send contacts to Retainful API

Creates or updates a contact in Retainful. If a contact with a matching identifier already exists (such as the same email), that contact is updated. Otherwise, a new contact is created. Email identifier is required to create a contact.

Endpoint

POST /v2/contacts

Authentication You must include your App ID and the API key in the request headers.

Example header:

Retainful-Api-Key: <Your API Key>
Retainful-App-Id: <Your App ID>

Request Body

Field
Required?
Type
Description

firstName

Yes

string

Contact’s first name.

lastName

No

string

Contact’s last name.

birthDate

No

string (date)

Date of birth in ISO 8601 format.

city

No

string

City of residence.

countryCode

No

string

Two-letter country code (e.g., US, CA).

country

No

string

Full country name (e.g., United States).

provinceCode

No

string

Province or state code (e.g., CA for California).

state

No

string

Full state or province name (e.g., California).

postalCode

No

string

ZIP or postal code.

gender

No

string

Gender of the contact (m, f, etc.).

createdAt

No

string (date)

Contact creation date. If omitted, the current time will be used.

triggerWelcomeEmail

No

boolean

If true, triggers a welcome email flow (if configured). Default is false.

listIds

Yes

array of string

Array of list IDs to which the contact will be subscribed.

identifiers

Yes

array of object

Required. An array that defines how to identify this contact (email, phone, etc.). See table below for detailed structure.

Identifiers Object

Each item in the identifiers array describes a unique identifier (such as an email or phone number) and includes the subscription status and consent details.

Field
Type
Required?
Description

type

string

Yes

Type of identifier (e.g., email, phone). Accepted values: email phone

id

string or number

Yes

The actual identifier (e.g., the email address or phone number).

channels

object

Yes

An object with channel-specific statuses. E.g., { "email": { "status": "subscribed" } }. See Channels object

consent

object

Yes

Contains details about when, how, and where consent was granted. See Consent object

Channels

The channels object tracks subscription statuses for each communication channel. For example:

{
  "channels": {
    "email": {
      "status": "subscribed"
    },
    "phone": {
      "status": "unsubscribed"
    }
  }
}

Channel Key
Value
Required?
Description

email

object (see below)

Yes (if no phone given)

Subscription status for email channel. Example: "status": "subscribed" or "unsubscribed".

phone

object (see below)

Yes (if no email given)

Subscription status for phone/SMS channel. Example: "status": "subscribed" or "unsubscribed".

Within each channel’s object, the most common field is:

  • status: string. Represents the subscription status. Typical values: subscribed, unsubscribed

The consent object captures how and when the contact gave permission for communication.

{
  "consent": {
    "createdAt": "2024-03-21T10:30:00.000Z",
    "ip": "192.168.1.1",
    "source": "web_form"
  }
}
Field
Type
Required?
Description

createdAt

string (date)

Yes

Date-time (in ISO 8601 format) when the contact gave consent (e.g., "2024-03-21T10:30:00.000Z").

ip

string

Yes

IP address from which the contact provided consent.

source

string

Yes

Source through which consent was provided (e.g., web_form, import, etc.).

Example Request

POST /v2/contacts
Retainful-Api-Key: YOUR_API_KEY
Retainful-App-Id: YOUR_APP_ID
Content-Type: application/json

{
  "firstName": "John",
  "lastName": "Doe",
  "birthDate": "1990-01-15T00:00:00.000Z",
  "city": "San Francisco",
  "countryCode": "US",
  "country": "United States",
  "provinceCode": "CA",
  "createdAt": "2024-03-21T10:30:00.000Z",
  "gender": "m",
  "postalCode": "96162",
  "state": "California",
  "triggerWelcomeEmail": false,
  "listIds": [
    "NdrDSPTeIvRMEtzufwDyKMWjmcOMsOxkxTCs"
  ],
  "identifiers": [
    {
      "type": "email",
      "id": "johndoe@gmail.com",
      "channels": {
        "email": {
          "status": "subscribed"
        }
      },
      "consent": {
        "createdAt": "2024-03-21T10:30:00.000Z",
        "ip": "192.168.1.1",
        "source": "web_form"
      }
    },
    {
      "type": "phone",
      "id": "+19013421324",
      "channels": {
        "phone": {
          "status": "subscribed"
        }
      },
      "consent": {
        "createdAt": "2024-03-21T10:30:00.000Z",
        "ip": "192.168.1.1",
        "source": "web_form"
      }
    }
  ]
}

Example Responses

Successful Creation or Update (200 OK)

{
  "status": true,
}

Error Responses

  • 400 Bad Request Returned if any required fields are missing or invalid.

    {
      "status": "error",
      "message": "Invalid request. 'identifiers' field is required."
    }
  • 401 Unauthorized Returned if the provided API key or App ID is missing or invalid.

    {
      "status": "error",
      "message": "Unauthorized access. Invalid or missing credentials."
    }
  • 500 Internal Server Error Returned if an unexpected error occurred on the server.

    {
      "status": "error",
      "message": "An unexpected error occurred."
    }

Best Practices & Notes

  1. Identifiers Are Mandatory Always supply at least one item in the identifiers array so Retainful can correctly locate or create the contact.

  2. ISO 8601 Date Formats Ensure date fields (birthDate, createdAt, consent.createdAt) are valid ISO 8601 strings.

  3. Consent Accuracy Provide accurate IP and timestamp in the consent object to comply with privacy regulations.

  4. Subscription Management Use the channels field to manage a contact’s subscription status for different communication channels.

  5. Welcome Email Set triggerWelcomeEmail to true if you have configured an automated welcome email flow and want it triggered for this contact.

Last updated

Was this helpful?