Documentation Index Fetch the complete documentation index at: https://docs.tracklysms.com/llms.txt
Use this file to discover all available pages before exploring further.
Record up to 1,000 revenue events in a single API call. Each record follows the same schema as the single revenue endpoint. The response includes per-record error details so you can identify and retry failures individually.
Authentication
Your Trackly SMS API key. Format: trk_[32-char-hex].
Body Parameters
An array of revenue records to process. Maximum of 1,000 records per request. Each record accepts the following fields: The 8-character message ID. This is the same value passed via the {{sendId}} macro.
Revenue amount. Must be greater than or equal to 0.
One of: sale, click, or send.
The offer ID this revenue is associated with. Can be either the externalId or the offer ID generated by TracklySMS. If omitted, the system will attempt to resolve the offer from the message’s short link.
ISO 8601 timestamp. Assumed to be UTC if no timezone is provided. Defaults to the current time.
Set to true to mark these records as imported data.
Response Fields
Number of revenue records successfully created.
Number of records that failed validation or processing.
Sum of all successfully processed revenue amounts.
Array of error objects for failed records. Each object contains:
index (integer) — Position of the failed record in the input array.
code (string) — Machine-readable error code.
error (string) — Human-readable error description.
curl -X POST https://api.tracklysms.com/api/v2/revenue/bulk \
-H "X-Api-Key: trk_your_api_key_here" \
-H "Content-Type: application/json" \
-d '{
"records": [
{
"message_id": "a1b2c3d4",
"revenue": 24.99,
"offer_id": "offer_123",
"attribution_type": "sale"
},
{
"message_id": "e5f6g7h8",
"revenue": 12.50,
"offer_id": "offer_456",
"attribution_type": "click"
}
],
"imported": false
}'
import requests
response = requests.post(
"https://api.tracklysms.com/api/v2/revenue/bulk" ,
headers = {
"X-Api-Key" : "trk_your_api_key_here" ,
"Content-Type" : "application/json" ,
},
json = {
"records" : [
{
"message_id" : "a1b2c3d4" ,
"revenue" : 24.99 ,
"offer_id" : "offer_123" ,
"attribution_type" : "sale" ,
},
{
"message_id" : "e5f6g7h8" ,
"revenue" : 12.50 ,
"offer_id" : "offer_456" ,
"attribution_type" : "click" ,
},
],
"imported" : False ,
},
)
print (response.json())
const response = await fetch ( "https://api.tracklysms.com/api/v2/revenue/bulk" , {
method: "POST" ,
headers: {
"X-Api-Key" : "trk_your_api_key_here" ,
"Content-Type" : "application/json" ,
},
body: JSON . stringify ({
records: [
{
message_id: "a1b2c3d4" ,
revenue: 24.99 ,
offer_id: "offer_123" ,
attribution_type: "sale" ,
},
{
message_id: "e5f6g7h8" ,
revenue: 12.5 ,
offer_id: "offer_456" ,
attribution_type: "click" ,
},
],
imported: false ,
}),
});
const data = await response . json ();
console . log ( data );
201 - Success
201 - Partial Success
400 - Validation Error
413 - Payload Too Large
{
"success_count" : 2 ,
"error_count" : 0 ,
"total_revenue" : 37.49 ,
"errors" : []
}
Error Codes
HTTP Status Error Code Description 400 missing_recordsThe records field is required and must be a non-empty array. 413 too_many_recordsExceeded the maximum of 1,000 records per request. 400 missing_message_idA record is missing the message_id field. 400 missing_revenueA record is missing the revenue field. 400 missing_attribution_typeA record is missing the attribution_type field. 400 invalid_revenueRevenue must be a number greater than or equal to 0. 400 invalid_attribution_typeMust be one of: sale, click, or send. 400 message_not_foundNo message exists with the given ID. 400 contact_not_foundThe contact associated with the message could not be found.
Next Steps
Revenue Tracking Track and attribute revenue
Send Message Send messages to drive revenue