You can also use the Upsert User Data API Wizard to generate an API key, configure headers, and create API payloads based on your planned user data.
The Upsert API allows you to send user attributes and events to Insider One. It supports both inserting and updating user data whenever needed.
You can use Upsert User Data for:
Sending offline purchases or other historical events.
Sending leads collected from external platforms.
Sending segments that were prepared in-house.
You can implement IP restrictions to limit access to the Upsert API for users with a UCD API Key, or to 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 get in touch with the Insider One team.
To update a user’s identifier (such as email or phone number) listed in your Identity Resolution Management Settings, use the Update Identifiers API. The Upsert API can add or modify attributes, but will not change an existing identifier.
Endpoint and Headers
Visit our Postman collection to test this request.
Headers
Header | Sample Value | Description |
|---|---|---|
X-PARTNER-NAME | mybrand | This is your partner name. Navigate to Inone Settings > Account Settings to copy your partner name. The partner name should be lowercase. |
X-REQUEST-TOKEN | 1a2b3c4e5d6f | This key is required to authorize your request. Refer to API Authentication Tokens to generate your token. |
Content-Type | application/json | This header specifies the media type of the resource. |
Body Parameters
You can send two types of data to our data ingestion API: attributes and events.
Each user object must have at least one attributes object or one events object.
Attributes
An attribute is a single, static piece of information about a user, such as gender, age, or loyalty class.
For array attributes, new values are appended by default.
To overwrite instead of append, include "not_append": true or "append": false in the request.
If both are included, the value of "append" will take priority.
No default attribute is mandatory. If you use the attributes object in the request, you need to have at least one attribute in your object.
Events
An event is a collection of information, such as purchased products or visited stores.
If you send multiple updates for the same user with the same event name, the new event will be added to the existing collection.
You can use the event group ID to group events of the same type when sending multiple events of this type.
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. For further information, refer to the Data Retention article.
Import historical data with the Upsert API
The Upsert API allows you to import historical data. When you do this, keep in mind:
If an active Architect On Event element or a set data stream is present, and the imported data meets their conditions, the journey or data stream can be triggered.
For example, if you send purchase events from one year ago via the Upsert API and an Architect journey is active with an On Event condition set to 'purchase', those users will enter the journey, even though the events occurred a year ago.
A boolean flag called skip_hook is available in the Upsert request body. This flag controls whether historical data should trigger journeys or data streams. This flag is not mandatory. Its rules are:
skip_hook: false → Default if not specified. Imported data can trigger Architect On Event elements and data streams.
skip_hook: true → Prevents imported data from triggering Architect journeys or data streams.
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 One allows these parameters to send:
Parameter | Description | Data Type | Required |
|---|---|---|---|
users | Array of user information, such as identifiers, attributes and events. | Array | Yes |
identifiers | User's identifier information. | Object | Yes |
attributes | Attributes object of user information, such as gender and age. | Object | No |
Attribute. User's email address, can be used as an identifier. | String | No | |
phone_number | Attribute. User's phone number in E.164 format (e.g. +6598765432), can be used as an identifier. | String | No |
email_optin | Attribute. User's permission for marketing emails: | Boolean | No |
gdpr_optin | Attribute. User's permission for Insider One campaigns, data collection, and processing: | Boolean | No |
sms_optin | Attribute. User's permission for SMS: | Boolean | No |
whatsapp_optin | Attribute. User's permission for WhatsApp Message: | Boolean | No |
name | Attribute. User's name. | String | No |
surname | Attribute. User's surname. | String | No |
birthday | Attribute. User's birthday in RFC 3339 format (e.g. 1993-03-12T00:00:00Z). | Date/Time | No |
gender | Attribute. Gender of the user | String | No |
age | Attribute. Age of the user | Number | No |
language | Language information of the user | String | No |
country | Attribute. The user's country information in ISO 3166-1 alpha-2 format. | String | No |
city | Attribute. City information of the user. | String | No |
static_segment_id | Attribute. Static segment IDs (users are added directly). | Numbers (Number array) | No |
uuid | Attribute. User’s UUID, can be used as an identifier. | String | No |
error_callback_endpoint | An endpoint to notify you if your upsert request fails on our end due to a unification error. Requests that receive an error are not retried. | URL | No |
locale | User's locale information | String | No |
events | List of events | Array | No |
event_name | Name of the event | String | Yes |
timestamp | Event. Event time, the purchase date for the purchase event in RFC3339 format. | Datetime | Yes |
event_params | Event parameters for purchase-related properties. | Object | No |
custom | Object consisting of custom event parameters | Object | No |
event_group_id | Event group ID | String | No (Yes only when the event_name is purchase or cart_page_view) |
product_id | Event parameter. Unique product ID. | String | No |
name | Event parameter. Name of the product. | String | No |
taxonomy | Event parameter. Category tree of the product. | Array | No |
url | Event parameter. Product URL for purchase events | URL | No |
currency | Event parameter. Currency used for product pricing, in ISO 4217 format (e.g., USD). | String | No (Yes only when the event_name is purchase or cart_page_view) |
quantity | Event parameter. Quantity of the product. | Integer | No (Yes, only when the event_name is purchase) |
unit_price | Event parameter. Price of the product without any discount(s). | Float | No |
unit_sale_price | Event parameter. Unit price of the product. | Float | No (Yes only when the event_name is purchase or cart_page_view) |
locale | Event parameter. Locale of the user. | String | No |
color | Event parameter. Color of the product (selected by user). | String | No |
size | Event parameter. Size of the product (selected by user). | String | No |
shipping_cost | Event parameter. Shipping cost of the items in basket. | String | No |
promotion_name | Event parameter. Name of the promotion. | String | No |
promotion_discount | Event parameter. Total amount of discount applied by promotions. | Float | No |
If your company obtains your users' consent in compliance with the local regulations, make sure to pass the GDPR opt-in field to Insider One. If you want to stop collecting and processing the data of an identified user, GDPR opt-in field should have the false value. Insider One cannot be held liable if these obligations are not fulfilled and reserves the right to seek compensation from your company.
Sample Requests
Please be aware of the limitations while sending your request using the Upsert API.
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.
Use one identifier per user object where possible. If you include multiple identifiers, such as email and uuid, that belong to different existing profiles, attributes may be applied to the wrong profile.
When you need to send multiple identifiers, verify they all belong to the same person before sending. Use insider_id when available; it resolves directly to a known profile without requiring cross-identifier lookup. Check success_count and fail_count in the response body to confirm per-user outcomes, and configure error_callback_endpoint to be notified of any processing issues
The request body contains a users array. Each user must include an identifiers object.
The sample request below shows a purchase event with user attributes. For more supported events and parameters, see 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",
"static_segment_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 includes insider_id, an internal ID maintained by Insider One for each user. You can find this value as the Profile ID on the User Profiles page.
It also includes error_callback_endpoint, which is triggered if the upsert request fails due to a unification error. In such cases, Insider One will resend the same payload you initially submitted for that user.
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",
"static_segment_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. If the request fails, the same payload is returned to your error_callback_endpoint.
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",
"static_segment_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",
"static_segment_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"
}
}
}
]
}
]
}'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, please don't hesitate to contact the Insider One team.
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 One 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, 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 must have a valid email address in the format specified 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 must have a valid identifier in the format specified 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 must provide a valid phone number in the format specified 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"
]
}
}
}
}Insider One returns a 200 status code because it indicates that the payload structure is valid and the data has been correctly sent. Since Insider One 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 at a profile level and is reflected in the response body, which includes 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 a 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"
}If a 429 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
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 problems, please create a ticket for the Insider One team.
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.
The default limit shown here is a standard baseline. If your use case requires higher capacity, feel free to reach out to the Insider One team — we can adjust it to fit your needs.