Upsert User Data

Prev Next

Upsert API enables you to send users' attributes and events to Insider. It allows you to insert and update user data whenever you need it. You can use the Upsert User Data for the following use cases:

  • Sending offline purchases or any other events
  • Sending leads that are collected from any other platform
  • Sending segments that are prepared in-house
Your title goes here
You can implement IP restrictions if you want to limit access to the Upsert API for users with a UCD API Key or control data transmission through this API. This ensures that only Upsert API requests from approved IP addresses will be accepted. If you want to make such a custom adjustment, please contact the Insider team.
Your title goes here
You should use the Identifier Update API if you want to update an identifier listed in your Identity Resolution Management Settings.

Endpoint and Headers

POST https://unification.useinsider.com/api/user/v1/upsert

Headers

HeaderSample ValueDescription
X-PARTNER-NAMEmybrandThis is your partner name. Navigate to InOne > Inone Settings > Account Settings to copy your partner name. The partner name should be lowercase.
X-REQUEST-TOKEN1a2b3c4e5d6fThis key is required to authorize your request. Refer to API Authentication Tokens to generate your token.
Content-Typeapplication/jsonThis header specifies the media type of the resource.

Body Parameters

You can send two data types to our data ingestion API: attributes and events.

An attribute is a single, static piece of information about a user, such as gender, age, or loyalty class. When you send data to an array attribute for a user, the new values are added to the existing ones by default. If you don't want to append values but overwrite the array attributes, you need to add "not_append": true or "append": false to the request. If you use both together, the value you provide for "append" will be accepted. 

An event is a collection of information, such as purchased products or visited stores. Any update request for an existing user with the same event name will append it to the collection.

Each user object must have at least one attributes object or one events object.
your title goes here
No default attribute is mandatory. If you use attributes object in the request, you need to have at least one attribute in your object.
your title goes here
You can use event group ID to group the events of the same type if you send multiple events of this type.
Your title goes here
When sending events via the Upsert API, ensure that the values fall within the TTL (Time-to-Live) of the events. Events with timestamps exceeding the TTL will not be written. You can refer to the Data Retention for further information.

Using Upsert API, you can import historical data. While importing historical data, if there is an active Architect On Event element or the data stream is set, and the imported data meets the conditions of the journey and the data stream, the Architect On Event element or data stream can be triggered.

For example, you send the purchase events from one year ago to users with Upsert API. At the same time, if an active Architect journey is set with a purchase condition using the On Event element, users will enter this journey because they meet the condition based on their data from a year ago.

A boolean flag called “skip_hook” is available in the Upsert request body to prevent historical data from entering the current journey. Thanks to this flag, you can choose whether to trigger the data stream or use the Architect On Event starter for the imported data.

This flag is not mandatory. If not specified, it is taken as skip_hook: false by default. If you do not want to trigger the data stream, it should be skip_hook: true.

Your title goes here
Identifiers must be placed under the identifiers object only. They should not be sent within attributes, events, or any other part of the payload. This structure ensures accurate identity resolution and consistent data processing across the platform.

Insider allows these parameters to send:

ParameterDescriptionData TypeRequired
usersArray of user information such as identifiers, attributes and events.ArrayYes
identifiersUser's identifier information.ObjectYes
attributesAttributes object of user information such as gender, age.ObjectNo
emailAttribute. User's email address, can be used as an identifier.StringNo
phone_numberAttribute. User's phone number in E.164 format (e.g. +6598765432), can be used as an identifier.StringNo
email_optinAttribute. User's permission for marketing emails:
True = emails allowed;
False = email not allowed
BooleanNo
gdpr_optinAttribute. User's permission for Insider campaigns, data collection and processing:
False = user will not see any Insider campaign or receive any message from any channel;
True or empty = Insider may interact with the user through personalization campaigns
BooleanNo
sms_optinAttribute. User's permission for SMS:
True = SMS allowed;
False = SMS not allowed
BooleanNo
whatsapp_optinAttribute. User's permission for WhatsApp Message:
True = WhatsApp Message allowed
False = WhatsApp Message not allowed
BooleanNo
nameAttribute. User's name.StringNo
surnameAttribute. User's surname.StringNo
birthdayAttribute. User's birthday in RFC 3339 format (e.g. 1993-03-12T00:00:00Z).
Note: Ensure the birthday ends with Z to indicate UTC time; no other time offset is included.
Date/TimeNo
genderAttribute. Gender of the userStringNo
ageAttribute. Age of the userNumberNo
languageLanguage information of the userStringNo
countryAttribute. The user's country information in ISO 3166-1 alpha-2 format.StringNo
cityAttribute. City information of the user.StringNo
list_idAttribute. Newsletter contact list IDs (users are added directly).Numbers (Number array)No
uuidAttribute. User’s UUID, can be used as an identifier.StringNo
error_callback_endpointAn endpoint to notify you if your upsert request fails on our side because of a unification error.URLNo
loUser's locale informationStringNo
eventsList of eventsArrayNo
event_name
Name of the eventStringYes
timestamp
Event. Event time, the purchase date for the purchase event in RFC3339 format.DatetimeYes
event_params
Event parameters for purchase-related properties.ObjectNo
         customObject consisting of custom event parametersObjectNo
event_group_id
Event group IDStringNo (Yes only when the event_name is purchase or cart_page_view)
product_id
Event parameter. Unique product ID.StringNo
name
Event parameter. Name of the product.StringNo
taxonomy
Event parameter. Category tree of the product.ArrayNo
         urlEvent parameter. Product URL for purchase eventsURLNo
currency
Event parameter. Currency used for product pricing, in ISO 4217 format (e.g. USD).StringNo (Yes only when the event_name is purchase or cart_page_view)
quantity
Event parameter. Quantity of the product.IntegerNo (Yes only when the event_name is purchase)
unit_price
Event parameter. Price of the product without any discount(s).FloatNo
unit_sale_price
Event parameter. Unit price of the product.FloatNo (Yes only when the event_name is purchase or cart_page_view)
         localeEvent parameter. Locale of the user.StringNo
color
Event parameter. Color of the product (selected by user).StringNo
size
Event parameter. Size of the product (selected by user).StringNo
shipping_cost
Event parameter. Shipping cost of the items in basket.StringNo
promotion_name
Event parameter. Name of the promotion.StringNo
promotion_discount
Event parameter. Total amount of discount applied by promotions.FloatNo

If your company obtains your users' consent in compliance with the local regulations, make sure to pass the GDPR opt-in field to Insider. If you want to stop collecting and processing the data of an identified user, GDPR opt-in field should have the false value. Insider cannot be held liable if these obligations are not fulfilled and reserves the right to seek compensation from your company.

Sample Requests

Your title goes here
Please be aware of the limitations while sending your request.
Your title goes here
If you send a custom attribute or parameter that doesn’t exist in the panel, it will be automatically created. However, if it’s not being created during your request, make sure that your custom attribute/parameter limit has not been reached — once the limit is full, no new custom attributes or parameters can be created.

The request body consists of a users array. Each user must have an identifiers object.

Your title goes here
The sample request below sends the default purchase event. To see the other default events and event parameters that you can use in your requests, refer to Default Events & Attributes.
curl --location --request POST 'https://unification.useinsider.com/api/user/v1/upsert' \
--header 'X-PARTNER-NAME: mybrand' \
--header 'X-REQUEST-TOKEN: 1a2b3c4e5d6f' \
--header 'Content-Type: application/json' \
--data-raw '{
  "skip_hook": false,
  "users": [
    {
      "identifiers": {
        "email": "sample@useinsider.com",
        "uuid": "1x2y3z",
        "custom": {
          "user_loyalty_id": "xyz123"
        }
      },
      "attributes": {
        "email_optin": true,
        "age": 30,
        "language": "en_US",
        "list_id": [
          1,
          2
        ],
        "birthday": "1980-01-01T00:00:00Z",
        "custom": {
          "favorite_color": [
            "green"
          ]
        }
      },
      "events": [
        {
          "event_name": "purchase",
          "timestamp": "2021-01-10T21:35:20Z",
          "event_params": {
            "product_id": "ABC21000",
            "name": "Your Product Name",
            "unit_price": 990.9,
            "unit_sale_price": 890.9,
            "event_group_id": "ORDER123",
            "taxonomy": [
              "Electronic",
              "Phone"
            ],
            "currency": "USD",
            "quantity": 1
          }
        },
        {
          "event_name": "account_created",
          "timestamp": "2021-01-17T14:41:21+03:00",
          "event_params": {
            "custom": {
              "customer_type": "trial",
              "trial_start_date": "2021-01-17T14:39:21+03:00",
              "trial_end_date": "2021-01-24T14:41:21+03:00"
            }
          }
        }
      ]
    }
  ]
}'

The request body below contains insider_id.

Your title goes here
insider id is an internal ID maintained by Insider for each user. To find the insider_id, you can refer to the Profile ID on the User Profiles.
Your title goes here
error_callback_endpoint is an endpoint that will notify you if your upset request fails on the Insider's side due to a unification error. For the relevant user, the exact same payload sent in the upsert request returns.
curl --location --request POST 'https://unification.useinsider.com/api/user/v1/upsert' \
--header 'X-PARTNER-NAME: mybrand' \
--header 'X-REQUEST-TOKEN: 1a2b3c4e5d6f' \
--header 'Content-Type: application/json' \
--data-raw '{
  "skip_hook": false,
  "error_callback_endpoint":"http://your-error-callback-endpoint.yourdomain.com",
  "users": [
    {
      "insider_id": "sampleinsiderid",
      "attributes": {
        "email_optin": true,
        "age": 30,
        "language": "en_US",
        "list_id": [
          1,
          2
        ],
        "birthday": "1980-01-01T00:00:00Z",
        "custom": {
          "favorite_color": [
            "green"
          ]
        }
      },
      "not_append": true,
      "events": [
        {
          "event_name": "purchase",
          "timestamp": "2021-01-10T21:35:20Z",
          "event_params": {
            "product_id": "ABC21000",
            "name": "Your Product Name",
            "unit_price": 990.9,
            "unit_sale_price": 890.9,
            "event_group_id": "ORDER123",
            "taxonomy": [
              "Electronic",
              "Phone"
            ],
            "currency": "USD",
            "quantity": 1
          }
        },
        {
          "event_name": "account_created",
          "timestamp": "2021-01-17T14:41:21+03:00",
          "event_params": {
            "custom": {
              "customer_type": "trial",
              "trial_start_date": "2021-01-17T14:39:21+03:00",
              "trial_end_date": "2021-01-24T14:41:21+03:00"
            }
          }
        }
      ]
    }
  ]
}'

The request below sends data for two users, each with their own attributes, events, and custom parameters.

curl --location --request POST 'https://unification.useinsider.com/api/user/v1/upsert' \
  --header 'X-PARTNER-NAME: mybrand' \
  --header 'X-REQUEST-TOKEN: 1a2b3c4e5d6f' \
  --header 'Content-Type: application/json' \
  --data-raw '{
    "skip_hook": false,
    "error_callback_endpoint":"http://your-error-callback-endpoint.yourdomain.com",
    "users": [
      {
        "insider_id": "sampleinsiderid",
        "attributes": {
          "email_optin": true,
          "age": 30,
          "language": "en_US",
          "list_id": [
            1,
            2
          ],
          "birthday": "1980-01-01T00:00:00Z",
          "custom": {
            "favorite_color": [
              "green"
            ]
          }
        },
        "not_append": true,
        "events": [
          {
            "event_name": "purchase",
            "timestamp": "2021-01-10T21:35:20Z",
            "event_params": {
              "product_id": "ABC21000",
              "name": "Your Product Name",
              "unit_price": 990.9,
              "unit_sale_price": 890.9,
              "event_group_id": "ORDER123",
              "taxonomy": [
                "Electronic",
                "Phone"
              ],
              "currency": "USD",
              "quantity": 1
            }
          },
          {
            "event_name": "account_created",
            "timestamp": "2021-01-17T14:41:21+03:00",
            "event_params": {
              "custom": {
                "customer_type": "trial",
                "trial_start_date": "2021-01-17T14:39:21+03:00",
                "trial_end_date": "2021-01-24T14:41:21+03:00"
              }
            }
          }
        ]
      },
      {
        "insider_id": "sampleinsiderid_2",
        "attributes": {
          "email_optin": true,
          "age": 23,
          "language": "en_US",
          "list_id": [
            1,
            2
          ],
          "birthday": "1996-08-08T00:00:00Z",
          "custom": {
            "favorite_color": [
              "blue"
            ]
          }
        },
        "not_append": true,
        "events": [
          {
            "event_name": "purchase",
            "timestamp": "2024-01-10T21:35:20Z",
            "event_params": {
              "product_id": "CYD21000",
              "name": "Your Product Name",
              "unit_price": 990.9,
              "unit_sale_price": 890.9,
              "event_group_id": "ORDER123",
              "taxonomy": [
                "Electronic",
                "Phone"
              ],
              "currency": "USD",
              "quantity": 1
            }
          },
          {
            "event_name": "account_created",
            "timestamp": "2022-02-17T14:41:21+03:00",
            "event_params": {
              "custom": {
                "customer_type": "trial",
                "trial_start_date": "2021-04-17T14:39:21+03:00",
                "trial_end_date": "2021-04-24T14:41:21+03:00"
              }
            }
          }
        ]
      }
    ]
  }'
Your title goes here
If some attributes or parameters are not reflected, the issue is likely related to the request structure or the data being sent. As a solution, check the request structure using a sample payload and ensure that the data types match the values you are trying to send. If the problem persists, feel free to contact the Insider team.
Your title goes here
If none of the attributes, events, or parameters are reflected, or if the user profile is not created after a few hours of sending the request, please reach out to the Insider team.

Sample Responses

200 OK

This response indicates that the event_group_id and unit_sale_price parameters are included together in the request for the purchase event.

{
    "data": {
        "successful": {},
        "fail": {
            "count": 1,
            "errors": {
                "users.0.events.0.event_params.*.required": [
                    "event_group_id parameter is required on purchase event",
                    "unit_sale_price parameter is required on purchase event"
                ]
            }
        }
    }
}

200 OK

For the request below, you need to use an identifier for the user, which can be either insider_id or UUID, email or phone number, or a custom attribute. Besides, you can also send these attributes as attributes if any one of them is not an identifier.

{
    "data": {
        "successful": {},
        "fail": {
            "count": 1,
            "errors": {
                "users.0.events.0.event_params.*.required": [
                    "event_group_id parameter is required on purchase event",
                    "unit_sale_price parameter is required on purchase event"
                ],
                "users.0.identifiers.required": [
                    "either insider_id or idenifiers must be specified"
                ],
                "users.0.insider_id.required": [
                    "either insider_id or idenifiers must be specified"
                ]
            }
        }
    }
}

200 OK

For the request below, you need to have a valid email address in the format stated in the parameters table.

{
    "data": {
        "successful": {},
        "fail": {
            "count": 1,
            "errors": {
                "users.0.events.0.event_params.*.required": [
                    "event_group_id parameter is required on purchase event",
                    "unit_sale_price parameter is required on purchase event"
                ],
                "users.0.identifiers.*.regexp(^.+@.+\\..+$)": [
                    "not a valid email address: sample"
                ]
            }
        }
    }
}

200 OK

For the request below, you need to have the valid UUID in the format stated in the parameters table.

{
    "data": {
        "successful": {},
        "fail": {
            "count": 1,
            "errors": {
                "users.0.events.0.event_params.*.required": [
                    "event_group_id parameter is required on purchase event",
                    "unit_sale_price parameter is required on purchase event"
                ],
                "users.0.identifiers.*.type(string)": [
                    "uuid must be string: 12345"
                ]
            }
        }
    }
}

200 OK

For the request below, you need to have a valid identifier in the format stated in the parameters table.

{
    "data": {
        "successful": {},
        "fail": {
            "count": 1,
            "errors": {
                "users.0.events.0.event_params.*.required": [
                    "event_group_id parameter is required on purchase event",
                    "unit_sale_price parameter is required on purchase event"
                ],
                "users.0.identifiers.*.in(defaults_column)": [
                    "key must be one of phone_number(pn), email(em) or uuid"
                ]
            }
        }
    }
}

200 OK

For the request below, you need to have a valid phone number in the format stated in the parameters table.

{
    "data": {
        "successful": {},
        "fail": {
            "count": 1,
            "errors": {
                "users.0.events.0.event_params.*.required": [
                    "event_group_id parameter is required on purchase event",
                    "unit_sale_price parameter is required on purchase event"
                ],
                "users.0.identifiers.*.regexp(^\\+[1-9]\\d{6,14}$)": [
                    "user has an invalid phone number: 12345"
                ]
            }
        }
    }
}
Your title goes here
Insider returns a 200 status code because it indicates that the payload structure is valid and the data has been correctly sent. Since Insider validates the payload itself, a successful HTTP response is returned as long as there are no issues with the request format.
However, the actual ingestion of the data is evaluated separately on a profile level and is reflected in the response body with a success count and a fail count. For example, a request may return status 200 with success_count: 0 and fail_count: 1, meaning that although the request structure was correct, the data could not be fully processed or written to the profile.

400 Bad Request

If you do not include user in your request, you receive an error shown below:

{"error":"users must be defined: bad request"}

400 Bad Request

The entire request must be no larger than 5 MB in size. If you send more than that limit, you receive an error shown below:

{"error": "request body is bigger than maximum allowed size 5,000,000 bytes"}

429 Too Many Requests

If you exceed the rate limits, you receive an error shown below:

{
    "error": "rejected: too many requests"
}
Your title goes here
If this error occurs, consider implementing retries and reviewing your connection configuration to remain within the Upsert API's rate limits. Not retrying may prevent some data from being successfully applied.

Error Codes

  • 400 Bad Request
  • 500 Internal Server Error
  • 403 Forbidden
  • 429 Too Many Requests
Your title goes here
If you receive a 403 response instead of 200 OK, stop or pause the current data sending. Check your headers, which are your partner name and token, and correct any errors. Once the issues are fixed, resume your integration and retry the failed requests. If your headers are correct but you continue encountering issues, please create a ticket for the Insider team.
Your title goes here
For 5XX and 429 errors, implement a retry mechanism with exponential backoff, as these are likely short-term issues. Adding a retry feature would be highly beneficial in handling these errors effectively.

Limitations

  • All functions must be executed with a simple HTTPS POST request.
  • Only new data can be inserted and updated with this API. No data can be retrieved.
  • The request token should be provided in the request header. If the token is incorrect, no operation will be executed.
  • The entire request must not exceed 5 MB.
  • Each request can upsert data for a maximum of 1,000 records (user).
  • The rate limit is shared with the Delete User Attribute, allowing a total of 25,000 requests per minute, which means you can process up to 25 million user records per minute with full batching.
  • The value of X-PARTNER-NAME header should be lowercase.