Create profile with server-side API
Creates a new end user of your app in Adapty.
Method and endpoint
POST https://api.adapty.io/api/v2/server-side-api/profile/
Example request
- cURL
- Python
- JavaScript
curl --location 'https://api.adapty.io/api/v2/server-side-api/profile/' \
--header 'Authorization: Api-Key <YOUR_SECRET_API_KEY>' \
--header 'adapty-customer-user-id: <YOUR_CUSTOMER_USER_ID>' \
--header 'adapty-platform: <OPTIONAL_DEVICE_PLATFORM>' \
--header 'Content-Type: application/json' \
--data-raw '{
"first_name": "Jane",
"last_name": "Doe",
"gender": "f",
"email": "jane.doe@example.com",
"phone_number": "+1234567890",
"birthday": "2000-12-31",
"ip_country": "FR",
"store_country": "US",
"store": "app_store",
"analytics_disabled": true,
"custom_attributes": [
{
"key": "favourite_sport",
"value": "yoga"
}
],
"installation_meta": {
"device_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"device": "string",
"locale": "en",
"os": "string",
"platform": "iOS",
"timezone": "Europe/Rome",
"user_agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 17_1_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.1 Mobile/15E148 Safari/604.1",
"idfa": "EA7583CD-A667-48BC-B806-42ECB2B48333",
"idfv": "E9D48DA5-3930-4B41-8521-D953AECD2F33",
"advertising_id": "",
"android_id": "",
"android_app_set_id": ""
}
}'
import requests
url = "https://api.adapty.io/api/v2/server-side-api/profile/"
payload = {
"first_name": "Jane",
"last_name": "Doe",
"gender": "f",
"email": "jane.doe@example.com",
"phone_number": "+1234567890",
"birthday": "2000-12-31",
"ip_country": "FR",
"store_country": "US",
"store": "app_store",
"analytics_disabled": True,
"custom_attributes": [
{
"key": "favourite_sport",
"value": "yoga"
}
],
"installation_meta": {
"device_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"device": "string",
"locale": "en",
"os": "string",
"platform": "iOS",
"timezone": "Europe/Rome",
"user_agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 17_1_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.1 Mobile/15E148 Safari/604.1",
"idfa": "EA7583CD-A667-48BC-B806-42ECB2B48333",
"idfv": "E9D48DA5-3930-4B41-8521-D953AECD2F33",
"advertising_id": "",
"android_id": "",
"android_app_set_id": ""
}
}
headers = {
"Authorization": "Api-Key <YOUR_SECRET_API_KEY>",
"adapty-customer-user-id": "<YOUR_CUSTOMER_USER_ID>",
"adapty-platform": "<OPTIONAL_DEVICE_PLATFORM>",
"Content-Type": "application/json"
}
response = requests.post(url, headers=headers, json=payload)
print(response.text)
const myHeaders = new Headers();
myHeaders.append("Authorization", "Api-Key <YOUR_SECRET_API_KEY>");
myHeaders.append("adapty-customer-user-id", "<YOUR_CUSTOMER_USER_ID>");
myHeaders.append("adapty-platform", "<OPTIONAL_DEVICE_PLATFORM>");
myHeaders.append("Content-Type", "application/json");
const raw = JSON.stringify({
"first_name": "Jane",
"last_name": "Doe",
"gender": "f",
"email": "jane.doe@example.com",
"phone_number": "+1234567890",
"birthday": "2000-12-31",
"ip_country": "FR",
"store_country": "US",
"store": "app_store",
"analytics_disabled": true,
"custom_attributes": [
{
"key": "favourite_sport",
"value": "yoga"
}
],
"installation_meta": {
"device_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"device": "string",
"locale": "en",
"os": "string",
"platform": "iOS",
"timezone": "Europe/Rome",
"user_agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 17_1_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.1 Mobile/15E148 Safari/604.1",
"idfa": "EA7583CD-A667-48BC-B806-42ECB2B48333",
"idfv": "E9D48DA5-3930-4B41-8521-D953AECD2F33",
"advertising_id": "",
"android_id": "",
"android_app_set_id": ""
}
});
const requestOptions = {
method: "POST",
headers: myHeaders,
body: raw,
redirect: "follow"
};
fetch("https://api.adapty.io/api/v2/server-side-api/profile/", requestOptions)
.then((response) => response.text())
.then((result) => console.log(result))
.catch((error) => console.error(error));
Placeholders:
<YOUR_CUSTOMER_USER_ID>
: The unique ID of the customer in your system.<YOUR_SECRET_API_KEY>
: Your secret API key for authorization.<OPTIONAL_DEVICE_PLATFORM>
: The platform of the device where the user has your app installed. Useful when the user has installed your app on multiple devices.
Parameters
Parameter | Type | Required in request | Nullable in request | Description |
---|---|---|---|---|
first_name | String | ➖ | ➕ | Your end user's first name. |
last_name | String | ➖ | ➕ | Your end user's last name. |
gender | String | ➖ | ➕ | Your end user's gender. |
String | ➖ | ➕ | Your end user's email. | |
phone_number | String | ➖ | ➕ | Your end user's phone number. |
birthday | ISO 8601 date | ➖ | ➖ | Your end user's birthday. |
ip_country | String | ➖ | ➖ | Country of the end user in ISO 3166-2 format. It needs to be passed if the request is made from the server and not from the client in order to set the current country. Otherwise, we determine the country by the IP address of the request. |
store_country | String | ➖ | ➕ | Country of the end user's app store. |
store | String | ➖ | ➕ | The platform the user uses to make purchases in your app. Possible values: app_store , play_store , or stripe . |
analytics_disabled | Boolean | ➖ | ➖ | Option to opt out of external analytics. When analytics is disabled, events won’t be sent to integrations, and the fields ON: External analytics is opted out for this user. OFF: Analytics is active by default. |
custom_attributes | Dictionary | ➖ | ➖ | Allows setting up to 30 custom attributes for the profile. If you use the Key: Must be a string with no more than 30 characters, using only letters, numbers, dashes, periods, and underscores. Value: Must be a string or float with no more than 30 characters. Booleans and integers will be converted to floats. To delete an attribute, send an empty value or |
installation_meta | Dictionary | ➖ | ➖ | Contains information about the specific app on a specific device, structured as a dictionary of Installation Meta objects. |
To authorize the request, make sure to include profile_id
and/or customer_user_id
in the header, as explained in the Authorization section.
- If you're adding a
customer_user_id
to a new user profile, include only thecustomer_user_id
in the request header. This will create a new profile with a randomprofile_id
and the specifiedcustomer_user_id
. - If you're adding a
customer_user_id
to an existing profile, include both theprofile_id
andcustomer_user_id
in the header. This will attach thecustomer_user_id
to the existing profile.
Successful response: 200: OK
The request is successful. The response body contains the data
field, which encapsulates the user's profile and associated information.
Parameter | Type | Nullable | Description |
---|---|---|---|
data | Object | ➖ | Contains the Profile object with user details and metadata. |
data object structure
The data
field is the primary container for the user profile. It includes several fields:
Parameter | Type | Nullable | Description |
---|---|---|---|
app_id | String | ➖ | The internal ID of your app. You can see in the the Adapty Dashboard: App Settings -> General tab. |
profile_id | UUID | ➖ | Adapty profile ID. You can see it in the Adapty ID field on the Adapty Dashboard -> Profiles -> specific profile page. |
customer_user_id | String | ➕ | The ID of your user in your system. You can see it in the Customer user ID field on the Adapty Dashboard -> Profiles -> specific profile page. It will work only if you identify the users in your mobile app code via Adapty SDK. |
total_revenue_usd | Float | ➖ | A float value representing the total revenue in USD earned in the profile. |
segment_hash | String | ➖ | Internal parameter. |
timestamp | Integer | ➖ | Response time in milliseconds, needs for resolve a race condition. |
custom_attributes | Dictionary | ➖ | A maximum of 30 custom attributes to the profile are allowed to be set. If you provide the Key: The key must be a string with no more than 30 characters. Only letters, numbers, dashes, points, and underscores allowed Value: The attribute value must be no more than 30 characters. Only strings and floats are allowed as values, booleans will be converted to floats. Send an empty value or null to delete the attribute. |
access_levels | Dictionary | ➕ | Profile Paid Access Level objects. Dictionary where the keys are paid access level identifiers configured by a developer in the Adapty Dashboard. Values are Access level objects. Can be null if the customer has no access levels. |
subscriptions | Dictionary | ➕ | Dictionary where the keys are vendor product IDs. Values are Subscription objects. Can be null if the customer has no subscriptions. |
non_subscriptions | Dictionary | ➕ | Dictionary where the keys are vendor product ids. Values are an array of Non-Subscription objects. Can be null if the customer has no purchases. |
Successful response example
{
"data": {
"app_id": "14c3d623-2f3a-455a-aa86-ef83dff6913b",
"profile_id": "3286abd3-48b0-4e9c-a5f6-ac0a006804a6",
"customer_user_id": "jane.doe@example.com",
"total_revenue_usd": 0.0,
"segment_hash": "8f45947bad31ab0c",
"timestamp": 1736425645861,
"custom_attributes": [
{
"key": "favourite_sport",
"value": "yoga"
}
],
"access_levels": [],
"subscriptions": [],
"non_subscriptions": []
}
}
Errors
401: Unauthorized
The request failed due to missing or incorrect authorization. Check the Authorization page, paying close attention to the Authorization header.
The request also failed because the specified profile wasn’t found.
Body
Parameter | Type | Description |
---|---|---|
errors | Object |
|
error_code | String | Short error name. Always not_authenticated . |
status_code | Integer | HTTP status. Always 401. |
Response example
{
"errors": [
{
"source": "non_field_errors",
"errors": [
"Authentication credentials were not provided."
]
}
],
"error_code": "not_authenticated",
"status_code": 401
}
404: Not found
The request failed because the specified profile wasn’t found. Double-check the customer_user_id
or profile_id
for any typos.
Body
Parameter | Type | Description |
---|---|---|
errors | Object |
|
error_code | String | Short error name. Always profile_does_not_exist . |
status_code | Integer | HTTP status. Always 404 . |
Response example
{
"errors": [
{
"source": null,
"errors": [
"Profile not found"
]
}
],
"error_code": "profile_does_not_exist",
"status_code": 404
}
See also: