> ## Documentation Index
> Fetch the complete documentation index at: https://developer.voyado.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Create contact

A vital part of any Engage integration journey is registering new contacts. This is done using the following endpoint:

```http Creating a contact theme={null}
POST /api/v3/contacts
```

This endpoint can be used to create a contact with `contactType` of "Contact", "Member" or any of your custom types. You will need to provide the mandatory fields for your specific contact type along with whatever key value you have specified in your configuration. That will be one of the following:

* **mobilePhone**
* **email**
* **externalId**
* **socialSecurityNumber** (Swedish or Finnish personal identity number)

<Warning>
  An important change when moving from API v2 to v3 is that values previously sent in the header when creating a contact (`source`, `storeExternalId`, `createAsUnapproved`) are now sent in the query string. If these are sent in the header in a v3 request, they will be ignored.
</Warning>

## Parameters

There are three optional parameters that can be sent in the query string of your request. They are:

<ResponseField name="source" type="string">
  This shows how the contact was created. Example values are “POS” or “e-com”. This is not mandatory, but highly recommended to reduce problems later on.
</ResponseField>

<ResponseField name="storeExternalId" type="string">
  The unique ID of the store or market where the customer signed up (also know as the recruited-by store). Often this is a numerical code like “600”. This parameter is not mandatory, but highly recommended to reduce problems later on.
</ResponseField>

<ResponseField name="createAsUnapproved" type="string">
  This creates an unverified contact which then must be verified by some other process or action, such as clicking a link in an email. It can have the string values “true” or “false”. An unverified contact like this will be ignored in reports and won’t be included in segmentations until specifically asked for. The default value is “false” so if you are not using this, you don’t need to worry about it.
</ResponseField>

While it is possible to send in any `source` value you want in the query string, in order to filter contacts in Engage using a specific `source` value, that value needs to be added in the back-end by your Voyado team. Contact them to do this.

<Warning>
  Before you try to create a contact, always check first if they already exists. For this, use [this endpoint](/docs/contacts/identify-contact/find-contact) where multiple identifiers can be used to see if a contact is already in the database.
</Warning>

## Payload

Here is the payload you will send in your create-contact request. You should specify the `contactType` in this payload. This needs to be a `contactType` that already exists. If you give one that doesn't exist, you'll get an error and no contact will be created.

If the `contactType` is not specified in your payload, it defaults to "Member".

<Accordion title="Payload example for creating a contact">
  ```json theme={null}
  {
    "firstName": "Example",
    "email": "example@example.com",
    "countryCode": "SE",
    "birthDay": "1966-06-26",
    "lang":"en",
    "contactType": "ExampleContactType",
    "preferences": {
      "acceptsEmail": true,
      "acceptsPostal": true,
      "acceptsSms": true
    },
    "consents": [{
        "id": "memberConsent",
        "value": true,
        "date": "2022-01-01T00:00:00+0100",
        "source": "ECOM",
        "comment": "Approved member terms at checkout"
     }]
  }
  ```
</Accordion>

For countries using multiple languages the `lang` attribute is used.

The field `birthDay`, if used, must have the format YYYY-MM-DD as in the example payload above. If it is used, the contact's age is calculated automatically when they are created.

The value of `countryCode` is mostly used in segmentation to decide which language to use when communicating with an end-user. It is therefore important that `countryCode` is correct.

<Warning>
  When creating a contact, the recommended approach is to ONLY specify `countryCode` in the payload. The value for `country` will be automatically populated based on what you specify for `countryCode` (assuming you have sent a valid value). So do *not* include `country` in the payload.
</Warning>

Your POS should have the option to easily update the end-user's `countryCode` when necessary.

The field `countryCode` is not mandatory when creating a contact but it is highly recommended.

## Response payload

After the POST operation, a new contact is created and their complete data set is returned.

<Accordion title="Response payload example after creating a contact">
  ```json theme={null}
  {
    "id": "e8f17b1d-b777-4688-862b-cf38009a726e",
    "attributes": {
      "firstName": "Example",
      "lastName": null,
      "street": null,
      "zipCode": null,
      "city": null,
      "email": "example@example.com",
      "mobilePhone": null,
      "countryCode": "SE",
      "careOf": null,
      "country": "Sweden",
      "age": 57,
      "birthDay": "1966-06-26",
      "externalId": null,
      "socialSecurityNumber": null,
      "gender": null,
      "staff": false,
      "memberNumber": "999032095",
      ...
      "currentStore": {
        "id": "b5e553d1-e4ba-40a0-8ee4-a9f631ee950b",
        "name": "Megashop E-commerce SE, 444",
        "externalId": "444"
      }
    },
    "meta": {
      "createdOn": "2022-10-24T11:22:19+02:00",
      "modifiedOn": "2022-10-24T11:22:19+02:00",
      "sourceType": "API",
      "approved": true,
      "contactType": "ExampleContactType"
    },
    "preferences": {
      "acceptsEmail": true,
      "acceptsPostal": true,
      "acceptsSms": true
    },
    "consents": [{
        "id": "memberConsent",
        "value": true,
        "date": "2022-01-01T00:00:00+0100",
        "source": "POS",
        "comment": "Approved member terms at checkout"
     }]
  }
  ```
</Accordion>

For consents, only the fields `id` and `value` are mandatory.

## Endpoint timeout

This endpoint has a significantly lower enforced timeout (under 10 seconds) compared to others in the API, and may return a *504 RequestTimeOut* status. This is intentional to ensure timely feedback in customer-facing flows like onboarding.

If Engage returns a timeout on this endpoint, no contact will have been created and all internal operations will be rolled back. In this case, the integrating system should retry the request in accordance with the [Retry Policy](/docs/api/the-engage-api#retry-policy), which provides guidance on recommended retry strategies.

## Response status codes

A successful creation will return *HTTP 201 Created* along with the contact's data set as the response body (as shown above).

If the request has failed, you'll get one of the following HTTP error codes:

* *400 : NoData*
* *409: ApprovedContactWithKeyExists, ContactWithKeyIsBeingCreated*
* *422: ValidationError*
* *504: RequestTimeOut*

<Warning>
  Don't send null or empty values in the JSON payload when updating or creating a contact. Empty values will override existing values. Send only what you want to change and nothing else.
</Warning>
