POST - Set or update
The Custom Data API allows you to send custom data on specific custom user IDs (iOS/Android/Web) and improve your campaign targetings.
This is helpful when users can perform actions outside of the app (e.g. purchase, subscription, updated profile, etc). You can use the API to post, update data or remove data.
Request structure
The users data endpoint allows you to set user data either for one user, or for multiple users.
Important Note: Any data changed by calling this API will not be available in real time: Processing time can be required. See this section for more info.
Route
The Custom Data API exposes two POST endpoints:
https://api.batch.com/1.0/BATCH_API_KEY/data/users/YOUR_USER_ID
for a single updatehttps://api.batch.com/1.0/BATCH_API_KEY/data/users
for bulk updates
NOTE: YOUR_USER_ID
is the Custom ID matching the ones you set using the SDKs.
Bulk updates allow you to update custom data for multiple users (up to 10,000) with one API call.
Here are two valid cURL examples.
Single update:
curl -H "Content-Type: application/json" -H "X-Authorization: BATCH_REST_API_KEY" -X POST -d "@payload.json" "https://api.batch.com/1.0/BATCH_API_KEY/data/users/YOUR_USER_ID"
Bulk update:
curl -H "Content-Type: application/json" -H "X-Authorization: BATCH_REST_API_KEY" -X POST -d "@payload.json" "https://api.batch.com/1.0/BATCH_API_KEY/data/users"
The BATCH_API_KEY
value is either your Live, Dev or SDK Batch API key from the settings page of your app within the dashboard (Settings → General):
Please note Batch manages each platform separately, so you will have to call the API twice with a different Dev/Live API key if you want to target iOS and Android.
Headers
In order to authenticate with the API, you need to provide your company REST API Key as the value of the X-Authorization
header. You can find it in ⚙ Settings → General.
Insufficient privileges issue: You may see that error in the REST API key field. This happens because the REST API key is only visible to managers. Make sure the managers of the account share that key with you or ask them to grant you access through the team manager.
Post data
For a single update, the body of the request must contain a valid JSON payload describing the update operations to execute for the user's custom data.
Here is a how a complete JSON payload looks like:
{
"overwrite": false,
"values": {
"u.nickname": "The Rock",
"u.force": 42,
"ut.hobbies": ["Lifting", "Wrestling", "Acting"],
"u.is_subscribed": null,
"date(u.last_subscription)": "2016-01-10T10:00:00.000",
"date(u.last_purchase)": 1472656161,
"ut.locations": { "$add": ["Paris"], "$remove": ["Berlin"] }
}
}
Let's see the parameters in detail.
Id | Description | |
---|---|---|
overwrite | Boolean - Optional Instead of merging the data we already have for a user, the existing data will be *deleted* and replaced by the incoming data. Defaults to false E.g. {"overwrite":true} | |
values | Object - Required An object containing all attributes and tags with their respective update operations |
Using the tag operations
$add
and$remove
whenoverwrite
is set to true might not have the behaviour you would expect:$add
will work but will append tags on an empty tag collection, clearing any previously set tag.$remove
is simply ignored.
The values object
The values object details what operations to do on a set of attributes or tags. It has the following form:
{
"<scope>.<attribute name>": <attribute value>,
"<scope>.<attribute name>": <attribute value>,
"<scope>.<attribute name>": <attribute value>,
"<scope>.<attribute name>": <attribute value>,
"<scope>.<tag name>": <tag update operation>
}
Only one operation per attribute or tag is allowed in one call to the API.
The scope
The scope determines what the key refers to: an attribute or tags:
u
is for attributesut
is for tags
Important note: Attributes/tags names are string. They should be made of letters, numbers or underscores ([a-z0-9_]). They can't be longer than 30 characters and cannot contain uppercase characters.
The attribute value
The value describes what you want to do on an attribute; either set or remove a value. The rules are as follow:
- When the value is
null
, the attribute is removed. - Otherwise the attribute's value is inserted or updated.
The following types are supported in a value:
- string. E.g:
{"u.nickname": "Johnny"}
- integer. E.g:
{"u.age": 23}
- boolean. E.g:
{"u.is_subscribed": true}
- float. E.g:
{"u.level_progress": 45.09}
Additional types
Date
We support dates, unfortunately JSON does not, thus we need extra information to know an attribute is actually a date.
We do this via wrapping the key name in the date()
function.
{
"date(u.promo_starts)": 1451642400,
"date(u.promo_ends)": "2021-01-01T04:00:00.000"
}
If you're using date()
on a string, be sure to use the format YYYY-MM-ddTHH:mm:ss. Be aware that we will interpret the date as UTC in both cases.
URL
URL type is also supported. You will need to wrap the key name in the url()
function.
{
"url(u.product_image)": "https://batchstore/product/4729/image.png",
"url(u.product_deeplink)": "myapp://path/to/content"
}
You need to provide a valid URL, in the limit of 2048 characters:
- A scheme is compulsory (
myapp://
,https://
...) ://
is compulsory after the scheme
If the URL provided isn't valid, the API call will fail.
The tag update operation
The value describes what you want to do on a tag. The rules are as follow:
- When the value is
null
, the tag is removed. - When the value is in array, the tag's content is replaced.
- When the value is an object, that object must describe the update to do. See below for the description of that object.
Here is the description of a tag update object.
Id | Description | |
---|---|---|
$add | Array - Optional The values to add to the tag E.g. {"$add":["Paris","Berlin","San Francisco"]} | |
$remove | Array - Optional The values to remove from the tag E.g. {"$remove":["Tokyo","London","New York"]} |
Here is a complete example combining all possible operations:
{
"ut.hobbies": ["Cooking", "Chess"],
"ut.previous_locations": null,
"ut.locations": { "$add": ["Paris", "London"], "$remove": ["Berlin"] }
}
Bulk post data
Bulk updates work basically the same way as a single update, except now you need to provide an array of objects of the following type:
Id | Description | |
---|---|---|
id | String - Required The user id E.g. {"id":"Vincent"} | |
update | Object - Required The update operation as described for the single update above |
Here is an example of a valid JSON payload:
[
{
"id": "Vincent",
"update": {
"values": {
"u.nickname": "Vincent",
"u.age": 55
}
}
},
{
"id": "Johnny",
"update": {
"overwrite": true,
"values": {
"u.nickname": "BeGood",
"u.age": 30
}
}
}
]
Responses
Success
If the POST to the API endpoint is successful you will receive an HTTP 200 confirmation and a unique token reprensenting the transaction.
{ "token": "fd576e9f-8b07-4844-91f9-ecfc2137c6f8" }
Please keep this token: it will be useful for upcoming features, and it will also help in getting faster support.
Failure
If the POST data does not meet the API requirements you will receive an actionable error message. Contact us at support@batch.com if you need further support.
AUTHENTICATION_INVALID
(Http status code: 401, Error code: 10)API_MISUSE
(Http status code: 403, Error code: 12)ROUTE_NOT_FOUND
(Http status code: 404, Error code: 20)MISSING_PARAMETER
(Http status code: 400, Error code: 30)MALFORMED_PARAMETER
(Http status code: 400, Error code: 31)MALFORMED_JSON_BODY
(Http status code: 400, Error code: 32)SERVER_ERROR
(Http status code: 500, Error code: 1)MAINTENANCE_ERROR
(Http status code: 503, Error code: 2)
Processing time
Data you send using this API is processed almost instantly.
However, your userbase's global analytics may not be. This only affects the dashboard in two places: the Userbase
page, and the visual query editor.
Since the dashboard's visual query editor depends on the same data that powers Userbase
, you might see outdated or missing data in the autocompleted fields.
This issue will fix itself in a matter of hours: the userbase data is refreshed at worse once per 24H, but may be refreshed more often.
Calling the API again will not have any effect whatsoever on the scheduled refresh.
Rest assured: once you actually run the campaign, the latest data will be used. Same goes for API-only usage, and the debug page.
You can see when the userbase data was last refreshed by hovering any User level
section of your app's Userbase
dashboard page.