---
title: Create / Update Profile
description: "The Profile Upsert API allows you to send bulk profile updates to* Releva. *Any profiles which do not exist in Releva will be created. Unilke the Profile Register API, this API is intended for backfill purposes only and will therefore emit backfill…"
url: "https://releva.ai/documentation/profiles-2/profile-upsert/"
updated: "2026-09-22"
category: Developer Documentation / Profiles
---

# Create / Update Profile

The Profile Upsert API allows you to send bulk profile updates to* Releva. *Any profiles which do not exist in Releva will be created.

Unilke the Profile Register API, this API is intended for backfill purposes only and will therefore emit backfill events. Backfill events cannot be used to trigger campaigns.

Any change will be available according to our SLA.

### Do I need to call it?

You will need this method when you want to bootstrap Releva initially with profile data. Another use case is with custom integrations where you need to change profile properties based on internal events of your system but the general purpose *push method*from the front-end integration doesn't work for your use case. Note that you can associate *tags* and *custom properties*to profiles. ***If you add custom properties using this API, please make sure to pass the same custom properties when pushing profile data using the Push API, or you will overwrite them.***

### Request Parameters

You may perform requests to the API using the following curl equivalent:

```js
curl -H 'Content-Type: application/json' -H 'Authorization: Bearer <secretKey>' -XPOST https://releva.ai/api/v0/profiles -d'{
    "profiles": [
        {
            "profile": {
                "id": "<customer-id>"
                "email": "georgi@releva.ai",
                "firstName": "Georgi",
                "lastName": "Georgiev",
                "phoneNumber": "+359....",
                "registeredAt": "2019-08-18T05:48:42.419Z",
                "subscribedAt": "2019-08-18T05:48:42.419Z",
                "unsubscribeLink": "http://shop.com/unsubscribe/...",
                "location": {"lat": 39.9352959, "lon": 23.5825895}
                "addTags": [
                    "availabe",
                    "acceptingMessages"
                ],
                "custom": {
                  "string": [
                    {"key": "gender", "values": ["M"]},
                    {"key": "ageGroup", "values": ["30-40"]}
                  ]
                },
                "subscriptions": ["weeklyNewsletter", "promo"],
            },
            "subscribedAtChanged": true

        },
        {
            "profile": {
                "email": "test@releva.ai",
                "firstName": "Georgi",
                "lastName": "Georgiev",
                "phoneNumber": "+3598....",
                "registeredAt": "2019-08-18T05:48:42.419Z",
                "subscribedAt": "2019-08-18T05:48:42.419Z",
                "birthday": "1986-01-17",
                "addTags": [
                    "availabe",
                    "acceptingMessages"
                ],
                "custom": {
                  "string": [
                    {"key": "gender", "values": ["M"]},
                    {"key": "ageGroup", "values": ["30-40"]}
                  ]
                }
            },
            "subscribedAtChanged": true
        }
    ]
}'
```

| **profiles** | Array [Profile] | List of profiles to create / update |
| --- | --- | --- |
| **profiles[].profile** | Profile | Profile attributes (See below) |
| **profiles[].subscribedAtChanged** | Boolean | True if the profile subscription status has been changed, false otherwise. |

### The *Profile* Object

| Field | Type | Description |
| --- | --- | --- |
| **id** | String | User's id. This Id needs to uniquely identify each user in your database and needs to match what you send us in the frontend integration (see [Standard integration steps 1-6](https://releva.ai/documentation/developer-documentation/front-end-integration/)) |
| **email** | String (Optional) | User’s email address. ***Required unless phoneNumber is set.*** |
| **firstName** | String (Optional) | User’s first name. |
| **lastName** | String (Optional) | User’s last name. |
| **phoneNumber** | String (Optional) | User's phones number. Phone numbers must start with “+” followed by numbers only. Valid phone number: +49875345976. ***This field is required unless email is set.*** |
| **consent** | String (Optional) | User's consent, may be one of these: - legitimateInterest - this is the default one, and every user has this consent by default - privacyPolicy - mandatoryCookies - cookiesPolicy |
| **registeredAt** | [ISO-8601](https://en.wikipedia.org/wiki/ISO_8601) String (Optional) | The date and time when this visitor created their account. |
| **subscribedAt** | [ISO-8601](https://en.wikipedia.org/wiki/ISO_8601) String (Optional) | The date and time when this visitor subscribed for our marketing. *Imporant: If you do not send this field, the subscription status will not change. If you send `null`, the profile will be unsubscribed.* Note that in order to change this field in our database, you also need to send us `subscribedAtChanged: true` |
| **birthday** | [ISO-8601](https://en.wikipedia.org/wiki/ISO_8601) String **(date without time)**(Optional) | The users's birthday e.g. 1989-09-16 |
| **unsubscribeLink** | String (Optional) | The unsubscribe link for the profile. ***Leave this blank if the profile is not subscribed.*** |
| **custom** | Object (Optional) | Custom fields for profile. ***Can be used to build segments and conditions in workflows.*** |
| **addTags** | Array[String] (Optional) | Tags to add to the profile. |
| **removeTags** | Array[String] (Optional) | Tags to remove from profile. |
| **subscriptions** | Array[String] (Optional) | Profile subscriptions. This lets you segment users by what they have subscribed for, in case you have multiple subscriptions. ***Note: setting this to null has no effect.*** ***To clear existing subscriptions, set this to empty array.*** |
| **location** | Object (Ooptional) | The location of the user represented as coordinates in decimal notation |
| **location.lat** | Float | The latitude of the visitor, e.g. 39.123 |
| **location.lon** | Float | The longitude of the visitor, e.g. 23.234 |

A successful response will return HTTP Status **202** with an empty response body (**{}**).

### Response Format

An error response will return a HTTP **4xx** or **5xx** status code and have the following structure:

```js
{
  "message": "A description of the error and how to fix it, if it's a client error."
}
```
