Skip to main content
POST
/
v2
/
history
/
clicks
{
  "success_count": 2,
  "error_count": 0,
  "duplicates_skipped": 0,
  "errors": []
}
Bulk import up to 1,000 historical click records per request. Each click is associated with an existing message and offer. Only one click per message_id is stored (MessageClick uses message_id as its primary key), so duplicate entries are automatically skipped. Importing clicks also updates the associated ListContact’s denormalized stats: click_count and last_clicked_at.

Authentication

X-Api-Key
string
required
Your Trackly SMS API key. Format: trk_[32-char-hex].

Body Parameters

records
array
required
An array of click records to import. Maximum of 1,000 records per request. Each record accepts the following fields:

Response Fields

success_count
integer
Number of click records successfully imported.
error_count
integer
Number of records that failed validation or processing.
duplicates_skipped
integer
Number of records skipped because a click already exists for that message_id.
errors
array
Array of error objects (maximum 100 returned). 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
curl -X POST https://app.tracklysms.com/api/v2/history/clicks \
  -H "X-Api-Key: trk_your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "records": [
      {
        "message_id": "a1b2c3d4",
        "offer_id": "offer_123",
        "phone_number": "+12025559876",
        "send_timestamp": "2025-11-15T14:30:00Z",
        "timestamp": "2025-11-15T14:35:22Z"
      },
      {
        "message_id": "e5f6g7h8",
        "offer_id": "offer_456",
        "phone_number": "+13105558888",
        "timestamp": "2025-11-15T15:10:45Z"
      }
    ]
  }'
Python
import requests

response = requests.post(
    "https://app.tracklysms.com/api/v2/history/clicks",
    headers={
        "X-Api-Key": "trk_your_api_key_here",
        "Content-Type": "application/json",
    },
    json={
        "records": [
            {
                "message_id": "a1b2c3d4",
                "offer_id": "offer_123",
                "phone_number": "+12025559876",
                "send_timestamp": "2025-11-15T14:30:00Z",
                "timestamp": "2025-11-15T14:35:22Z",
            },
            {
                "message_id": "e5f6g7h8",
                "offer_id": "offer_456",
                "phone_number": "+13105558888",
                "timestamp": "2025-11-15T15:10:45Z",
            },
        ],
    },
)

print(response.json())
Node.js
const response = await fetch("https://app.tracklysms.com/api/v2/history/clicks", {
  method: "POST",
  headers: {
    "X-Api-Key": "trk_your_api_key_here",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    records: [
      {
        message_id: "a1b2c3d4",
        offer_id: "offer_123",
        phone_number: "+12025559876",
        send_timestamp: "2025-11-15T14:30:00Z",
        timestamp: "2025-11-15T14:35:22Z",
      },
      {
        message_id: "e5f6g7h8",
        offer_id: "offer_456",
        phone_number: "+13105558888",
        timestamp: "2025-11-15T15:10:45Z",
      },
    ],
  }),
});

const data = await response.json();
console.log(data);
{
  "success_count": 2,
  "error_count": 0,
  "duplicates_skipped": 0,
  "errors": []
}

Error Codes

HTTP StatusError CodeDescription
400missing_recordsThe records field is required and must be a non-empty array.
413too_many_recordsExceeded the maximum of 1,000 records per request.
400missing_message_idA record is missing the message_id field.
400missing_offer_idA record is missing the offer_id field.
400missing_phone_numberA record is missing the phone_number field.
400missing_timestampA record is missing the timestamp field.
404message_not_foundNo message exists with the given message_id.
404offer_not_foundNo offer exists with the given offer_id.
400invalid_timestampThe timestamp is not a valid ISO 8601 datetime.
500save_errorAn unexpected error occurred while saving the record.

Next Steps

Reporting Overview

Analyze click data

Bulk Create Contacts

Import contacts alongside history