Upload Device Tokens
Overview
The Upload Device Tokens API enables you to add an existing device token to a CleverTap user profile. For example, you can use this API to add a GCM or APNS token to a user profile. Adding this information enables you to send push notifications to that device.
Uploading device tokens to CleverTap requires a POST request with a JSON payload specifying the device token information. A maximum of 1000 device token records can be sent per API call.
Uploading Historical Device Tokens for Android, iOS, and WebDevice token upload is only allowed after the user is live on the app, post SDK integration. Tokens of users prior to SDK integration cannot be fetched.
Supported Token TypesUploading device tokens via API is available for APNS, FCM, GCM, Chrome (Web Push), WNS, and MPNS.
Base URL
The following is a sample base URL:
https://<region>.api.clevertap.com/1/upload
For region-specific endpoints, refer to Region.
HTTP Method
POST
Headers
Refer to Headers for more details.
Body Parameters
Device tokens are uploaded as a JSON payload. The payload is an object keyed with d whose value is an array describing the device tokens.
For each device token record, objectId is required. This is the only supported identifier for token records. Identity, FBID, and GPID are not accepted for token uploads.
The following table lists the body parameters.
| Parameter | Description | Type | Example Value |
|---|---|---|---|
| type | Set to token. Required. | string | "token" |
| tokenData | Device token properties passed as key/value pairs. Required. `id` and `type` are required properties. `type` must be one of: `apns`, `fcm`, `gcm`, `chrome`, `wns`, `mpns`. For Chrome Web Push tokens, a `keys` object containing `p256dh` and `auth` is strongly recommended (see note below). | object | {"id": "dYfuuBm...", "type": "fcm"} |
| objectId | The CleverTap Global Object ID for the user. Required. This is the only supported identifier for token records. | string | "37b08803c1af4e10849f530264bac7f8" |
Chrome Web Push encryption keys
For Chrome Web Push tokens,
keys.p256dhandkeys.authare strongly recommended. If omitted, the token is stored but encrypted push notifications to this device will not be deliverable, as the token will not carry the required encryption material.
Example Payloads
The following is a sample payload for iOS, Android, or Windows tokens.
{
"d": [
{
"type": "token",
"tokenData": {
"id": "<device_token>",
"type": "apns"
},
"objectId": "<clevertap_object_id>"
}
]
}The following is a sample payload for a Chrome Web Push token.
{
"d": [
{
"type": "token",
"tokenData": {
"id": "<device_token>",
"type": "chrome",
"keys": {
"p256dh": "<p256dh_key>",
"auth": "<auth_key>"
}
},
"objectId": "<clevertap_object_id>"
}
]
}The following is a sample payload for adding device tokens for multiple token types in a single call.
{
"d": [
{
"type": "token",
"tokenData": {
"id": "frfsgvrwe:APfdsafsgdfsgghfgfgjkhfsfgdhjhbvcvnetry767456fxsasdf",
"type": "chrome",
"keys": {
"p256dh": "BLc4xRzKlKORKWlbdgFaBrrPK3ydWAHo4M0gs0i1oEKgPpWC5cW8OCzVrOQRv-1npXRWk8udnW3oYhIO4475rds=",
"auth": "5I2Bu2oKdyy9CwL8QVF0NQ=="
}
},
"objectId": "QBOpVJZmKilRAzfaiVS86Tovxm75lHxg"
},
{
"type": "token",
"tokenData": {
"id": "dYfuuBmHLGI:APA91bEfAq1b6NAmz0uhUbVxwSLqgKF25zDb7vhgajzS-bOAEUKekH_jbzO5oU1Qip-ZLvDpwKccxAxVNjC3rUUJnFTKDUiBcF9AtuG03_PRfjoUxLKHMR9qykK22SiubrLirNzQtNnO",
"type": "fcm"
},
"objectId": "__gc4grg4053N1eYkW6OBH71jhFev7b1iP"
},
{
"type": "token",
"tokenData": {
"id": "frfsgvrwe:APfdsafsgdfsgghfgfgjkhfsfgdhjhbvcvnetry767456fxsasdf",
"type": "gcm"
},
"objectId": "__QlXHaDHBZxZPLEMpPo6VvwdZ7FnbGvWA"
},
{
"type": "token",
"tokenData": {
"id": "frfsgvrwe:APfdsafsgdfsgghfgfgjkhfsfgdhjhbvcvnetry767456fxsasdf",
"type": "apns"
},
"objectId": "-HwB9gZWb3RcKhXCQ222FhAhkjeYQs0Hj"
},
{
"type": "token",
"tokenData": {
"id": "frfsgvrwe:APfdsafsgdfsgghfgfgjkhfsfgdhjhbvcvnetry767456fxsasdf",
"type": "wns"
},
"objectId": "~9XrS4Dy6GsnDbdX98Ijs63kEtJDQbhJA"
},
{
"type": "token",
"tokenData": {
"id": "frfsgvrwe:APfdsafsgdfsgghfgfgjkhfsfgdhjhbvcvnetry767456fxsasdf",
"type": "mpns"
},
"objectId": "~y9MqjkDGRfbzwwH8fZI6LIXgTKaEPxHr"
}
]
}Example Request
The following is a sample request to the Upload Device Tokens API, showing the headers needed to authenticate the request.
curl -X POST -d '{"d": [{"type": "token","tokenData": {"id": "dYfuuBmHLGI:APA91bEfAq1b6NAmz0uhUbVxwSLqgKF25zDb7vhgajzS-bOAEUKekH_jbzO5oU1Qip-ZLvDpwKccxAxVNjC3rUUJnFTKDUiBcF9AtuG03_PRfjoUxLKHMR9qykK22SiubrLirNzQtNnO","type": "gcm"},"objectId": "37b08803c1af4e10849f530264bac7f8"}]}' "https://<region>.api.clevertap.com/1/upload" \
-H "X-CleverTap-Account-Id: ACCOUNT_ID" \
-H "X-CleverTap-Passcode: PASSCODE" \
-H "Content-Type: application/json; charset=utf-8"require 'net/http'
require 'uri'
require 'json'
uri = URI.parse("https://<region>.api.clevertap.com/1/upload")
request = Net::HTTP::Post.new(uri)
request.content_type = "application/json; charset=utf-8"
request["X-Clevertap-Account-Id"] = "ACCOUNT_ID"
request["X-Clevertap-Passcode"] = "PASSCODE"
request.body = JSON.dump({
"d" => [
{
"type" => "token",
"tokenData" => {
"id" => "dYfuuBmHLGI:APA91bEfAq1b6NAmz0uhUbVxwSLqgKF25zDb7vhgajzS-bOAEUKekH_jbzO5oU1Qip-ZLvDpwKccxAxVNjC3rUUJnFTKDUiBcF9AtuG03_PRfjoUxLKHMR9qykK22SiubrLirNzQtNnO",
"type" => "gcm"
},
"objectId" => "37b08803c1af4e10849f530264bac7f8"
}
]
})
req_options = {
use_ssl: uri.scheme == "https",
}
response = Net::HTTP.start(uri.hostname, uri.port, req_options) do |http|
http.request(request)
endimport requests
headers = {
'X-CleverTap-Account-Id': 'ACCOUNT_ID',
'X-CleverTap-Passcode': 'PASSCODE',
'Content-Type': 'application/json; charset=utf-8',
}
data = '{"d": [{"type": "token","tokenData": {"id": "dYfuuBmHLGI:APA91bEfAq1b6NAmz0uhUbVxwSLqgKF25zDb7vhgajzS-bOAEUKekH_jbzO5oU1Qip-ZLvDpwKccxAxVNjC3rUUJnFTKDUiBcF9AtuG03_PRfjoUxLKHMR9qykK22SiubrLirNzQtNnO","type": "gcm"},"objectId": "37b08803c1af4e10849f530264bac7f8"}]}'
response = requests.post('https://<region>.api.clevertap.com/1/upload', headers=headers, data=data)<?php
include('vendor/rmccue/requests/library/Requests.php');
Requests::register_autoloader();
$headers = array(
'X-CleverTap-Account-Id' => 'ACCOUNT_ID',
'X-CleverTap-Passcode' => 'PASSCODE',
'Content-Type' => 'application/json; charset=utf-8'
);
$data = '{"d": [{"type": "token","tokenData": {"id": "dYfuuBmHLGI:APA91bEfAq1b6NAmz0uhUbVxwSLqgKF25zDb7vhgajzS-bOAEUKekH_jbzO5oU1Qip-ZLvDpwKccxAxVNjC3rUUJnFTKDUiBcF9AtuG03_PRfjoUxLKHMR9qykK22SiubrLirNzQtNnO","type": "gcm"},"objectId": "37b08803c1af4e10849f530264bac7f8"}]}';
$response = Requests::post('https://<region>.api.clevertap.com/1/upload', $headers, $data);var request = require('request');
var headers = {
'X-CleverTap-Account-Id': 'ACCOUNT_ID',
'X-CleverTap-Passcode': 'PASSCODE',
'Content-Type': 'application/json; charset=utf-8'
};
var dataString = '{"d": [{"type": "token","tokenData": {"id": "dYfuuBmHLGI:APA91bEfAq1b6NAmz0uhUbVxwSLqgKF25zDb7vhgajzS-bOAEUKekH_jbzO5oU1Qip-ZLvDpwKccxAxVNjC3rUUJnFTKDUiBcF9AtuG03_PRfjoUxLKHMR9qykK22SiubrLirNzQtNnO","type": "gcm"},"objectId": "37b08803c1af4e10849f530264bac7f8"}]}';
var options = {
url: 'https://<region>.api.clevertap.com/1/upload',
method: 'POST',
headers: headers,
body: dataString
};
function callback(error, response, body) {
if (!error && response.statusCode == 200) {
console.log(body);
}
}
request(options, callback);// Standard token upload (FCM, GCM, APNS, WNS, MPNS):
type TokenData struct {
ID string `json:"id"`
Type string `json:"type"`
}
// Chrome Web Push token upload (includes encryption keys):
// type TokenData struct {
// ID string `json:"id"`
// Type string `json:"type"`
// Keys struct {
// P256DH string `json:"p256dh"`
// Auth string `json:"auth"`
// } `json:"keys"`
// }
type Record struct {
Type string `json:"type"`
TokenData TokenData `json:"tokenData"`
ObjectID string `json:"objectId"`
}
type Payload struct {
D []Record `json:"d"`
}
data := Payload{
// fill struct
}
payloadBytes, err := json.Marshal(data)
if err != nil {
// handle err
}
body := bytes.NewReader(payloadBytes)
req, err := http.NewRequest("POST", "https://<region>.api.clevertap.com/1/upload", body)
if err != nil {
// handle err
}
req.Header.Set("X-Clevertap-Account-Id", "ACCOUNT_ID")
req.Header.Set("X-Clevertap-Passcode", "PASSCODE")
req.Header.Set("Content-Type", "application/json; charset=utf-8")
resp, err := http.DefaultClient.Do(req)
if err != nil {
// handle err
}
defer resp.Body.Close()Example Response
The following is a sample response.
{
"status": "success",
"processed": 1,
"unprocessed": []
}Debugging
Requests with processing errors are returned in the API call response. The following is a sample error response structure.
{
"status": "success | partial | fail",
"processed": <count>,
"unprocessed": [{"status": "fail", "code": <error code>, "error": <error message>, "record": <record>}]
}To test if your data submits without errors, add the parameter dryRun=1 to the URL. This validates the input without submitting the data to CleverTap.
For more information on request limits, refer to API Request Limit. To understand common queries and concerns related to CleverTap APIs, refer to API FAQs.
Error Codes
The following table lists the error codes returned by this API:
| HTTP Status | Error | Description | Example Error Response |
|---|---|---|---|
| 400 | "Payload is mandatory" | Empty request body | {"status":"fail","error":"Payload is mandatory","code":400} |
| 400 | "Malformed request" | JSON parse failure | {"status":"fail","error":"Malformed request","code":400} |
| 401 | "Invalid credentials" | Wrong or missing passcode | {"status":"fail","error":"Invalid credentials","code":401} |
| 403 | "API access has been temporally suspended" | Account API access suspended | {"status":"fail","error":"API access has been temporally suspended","code":403} |
| 429 | "Too many concurrent requests" | Per-account concurrent request limit exceeded. Retry with exponential backoff. | {"status":"fail","error":"Too many concurrent requests","code":429} |
| 503 | "12 digit account ID mandatory." | Missing or invalid X-CleverTap-Account-Id header | {"status":"fail","error":"12 digit account ID mandatory.","code":503} |
| 503 | "Please come back later" | Global throttle limit exceeded. Retry with backoff. | {"status":"fail","error":"Please come back later","code":503} |
| 200 | "Data is not of type Event, Profile or Token." | type field is not "token", "event", or "profile" | {"status":"fail","code":524,"error":"Data is not of type Event, Profile or Token.","record":{...}} |
| 200 | "Invalid 'objectId'." | objectId missing or empty | {"status":"fail","code":530,"error":"Invalid 'objectId'.","record":{...}} |
| 200 | "Invalid token data." | tokenData is null or has fewer than 2 fields | {"status":"fail","code":531,"error":"Invalid token data.","record":{...}} |
| 200 | "Token 'id' is not present." | tokenData.id missing or empty | {"status":"fail","code":532,"error":"Token 'id' is not present.","record":{...}} |
| 200 | "Token 'type' is not present." | tokenData.type missing or empty | {"status":"fail","code":533,"error":"Token 'type' is not present.","record":{...}} |
| 200 | "Token 'type' is not valid for 'objectId'." | Token type doesn't match the device platform (for example, fcm for an iOS objectId) | {"status":"fail","code":534,"error":"Token 'type' is not valid for 'objectId'.","record":{...}} |
| 200 | "Invalid token type" | tokenData.type is not one of: apns, gcm, fcm, chrome, wns, mpns | {"status":"fail","code":535,"error":"Invalid token type","record":{...}} |
