Skip to main content
POST
/
v2
/
history
/
sends
{
  "success_count": 2,
  "error_count": 0,
  "duplicates_skipped": 0,
  "invalid_phones": 0,
  "errors": []
}
Bulk import up to 1,000 historical send records per request. Use this endpoint to migrate data from another platform into Trackly SMS. Duplicate message IDs are automatically skipped, and invalid phone numbers are flagged in the response.

Authentication

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

Body Parameters

records
array
required
An array of send records to import. Maximum of 1,000 records per request. Each record accepts the following fields:
All records imported via this endpoint are automatically marked as imported=true. This flag is set by the server and cannot be overridden. Imported records can be selectively cleared later via the Clear History endpoint.

Response Fields

success_count
integer
Number of send records successfully imported.
error_count
integer
Number of records that failed validation or processing.
duplicates_skipped
integer
Number of records skipped because their ID already exists.
invalid_phones
integer
Number of records skipped due to invalid phone numbers.
errors
array
Array of error objects (maximum 100 returned). Each object contains:
  • index (integer) — Position of the failed record in the input array.
  • id (string) — The message ID of the failed record.
  • code (string) — Machine-readable error code.
  • error (string) — Human-readable error description.
cURL
curl -X POST https://app.tracklysms.com/api/v2/history/sends \
  -H "X-Api-Key: trk_your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "records": [
      {
        "id": "hist_0001",
        "list_number": "+14155551234",
        "to_number": "+12025559876",
        "message": "Check out this deal!",
        "send_type": "campaign",
        "delivered": true,
        "length": 21,
        "timestamp": "2025-11-15T14:30:00Z"
      },
      {
        "id": "hist_0002",
        "list_id": 42,
        "to_number": "+13105558888",
        "message": "Limited time offer",
        "creative_id": 101,
        "send_type": "campaign",
        "delivered": true,
        "timestamp": "2025-11-15T14:31:00Z"
      }
    ],
    "imported": true
  }'
Python
import requests

response = requests.post(
    "https://app.tracklysms.com/api/v2/history/sends",
    headers={
        "X-Api-Key": "trk_your_api_key_here",
        "Content-Type": "application/json",
    },
    json={
        "records": [
            {
                "id": "hist_0001",
                "list_number": "+14155551234",
                "to_number": "+12025559876",
                "message": "Check out this deal!",
                "send_type": "campaign",
                "delivered": True,
                "length": 21,
                "timestamp": "2025-11-15T14:30:00Z",
            },
            {
                "id": "hist_0002",
                "list_id": 42,
                "to_number": "+13105558888",
                "message": "Limited time offer",
                "creative_id": 101,
                "send_type": "campaign",
                "delivered": True,
                "timestamp": "2025-11-15T14:31:00Z",
            },
        ],
        "imported": True,
    },
)

print(response.json())
Node.js
const response = await fetch("https://app.tracklysms.com/api/v2/history/sends", {
  method: "POST",
  headers: {
    "X-Api-Key": "trk_your_api_key_here",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    records: [
      {
        id: "hist_0001",
        list_number: "+14155551234",
        to_number: "+12025559876",
        message: "Check out this deal!",
        send_type: "campaign",
        delivered: true,
        length: 21,
        timestamp: "2025-11-15T14:30:00Z",
      },
      {
        id: "hist_0002",
        list_id: 42,
        to_number: "+13105558888",
        message: "Limited time offer",
        creative_id: 101,
        send_type: "campaign",
        delivered: true,
        timestamp: "2025-11-15T14:31:00Z",
      },
    ],
    imported: true,
  }),
});

const data = await response.json();
console.log(data);
{
  "success_count": 2,
  "error_count": 0,
  "duplicates_skipped": 0,
  "invalid_phones": 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_idA record is missing the id field.
400missing_to_numberA record is missing the to_number field.
400missing_timestampA record is missing the timestamp field.
400invalid_phoneThe phone number is not a valid E.164 format.
404list_not_foundNo sending list found matching the given list_id or list_number.
400invalid_timestampThe timestamp is not a valid ISO 8601 datetime.
500save_errorAn unexpected error occurred while saving the record.

Next Steps

Reporting Overview

Analyze your imported data

Bulk Create Contacts

Import contacts alongside history