PUT /contacts/bulk.type and basis sit on the envelope, not on the items. Signing is per-message, so a mixed batch would be technically sendable — this is a deliberate API restriction. One declaration per request means the entitlement and rate-limit decisions happen once, it matches the real use case (a batch is 100 order confirmations), and it removes the failure mode where one transactional item is smuggled into a marketing batch and silently exempted from consent.POST /messages/sms/batch/async returning a jobId — mirroring POST /contacts/bulk/async.curl --location '/messages/sms/batch' \
--header 'Authorization: Bearer <token>' \
--header 'Idempotency-Key: 0f3e2b1a-7c4d-4e2a-9b11-2f6d8c1a5e30' \
--header 'Content-Type: application/json' \
--data '{
"type": "transactional",
"basis": "contract_performance",
"messages": [
{
"to": {
"contactId": "string",
"clientContactId": "string",
"phoneNumber": "string"
},
"from": "string",
"templateId": 0,
"content": "string",
"language": "string",
"variables": {},
"tags": [
"string"
],
"metadata": {},
"sendAt": "string",
"createContact": true,
"retainBody": true,
"event": "string",
"permId": "string"
}
]
}'{
"accepted": 0,
"rejected": 0,
"messages": [
{
"index": 0,
"messageId": "string",
"to": "string",
"status": "queued",
"reason": "string",
"error": "string"
}
]
}