Bulk create SMS subscribers
Start or continue an async bulk import of pre-verified SMS subscribers.
POST /app/subscribers/sms/subscribers/bulk
Starts or continues an async bulk import. Each request returns immediately with a jobId; its subscribers are queued for background processing right away (not held until the last chunk). Poll Get bulk import job until status is completed or failed.
While a job is active (uploading or processing), the organization is locked for SMS: single create, a second bulk SMS import, and status dashboard SMS sign-ups are temporarily blocked. (Email bulk imports use a separate lock.)
Set uploadComplete: true on the last request so the job can finish: that closes uploads, sets totalRows, and allows status to become completed once all batches are processed. If you never send it, any rows already queued may still be imported, but the job will not complete successfully — after about 30 minutes without progress it is marked failed and the lock is released. Partial results are not rolled back.
Limits:
- Up to 500 subscribers per request (send multiple requests to upload a large file)
- Up to 50,000 subscribers per job (entire import operation)
There is no admin-managed (locked) flag for SMS bulk rows — that concept applies only to email.
Request
See API Basics for required headers.
Body
| Field | Type | Required | Description |
|---|---|---|---|
subscribers | array | Yes | 1–500 items for this request |
subscribers[].phone | string | Yes | E.164 phone number (e.g. +14155552671) |
subscribers[].dashboardId | uuid | Yes | Target dashboard |
subscribers[].componentIds | uuid[] | Yes | At least one component on that dashboard |
jobId | uuid | No | Omit on the first request; include on subsequent chunk requests for the same import |
uploadComplete | boolean | No | Set to true on the final chunk when all rows have been sent. Required for the job to complete; omit or false while more chunks will follow. |
Sample request — start import
curl -X POST https://api.statusdashboard.com/app/subscribers/sms/subscribers/bulk \
-H "Authorization: Bearer bcf847abf5c6:def456" \
-H "Content-Type: application/json" \
-d '{
"subscribers": [
{
"phone": "+14155552671",
"dashboardId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"componentIds": ["b2c3d4e5-f6a7-8901-bcde-f12345678901"]
}
],
"uploadComplete": true
}'Sample response
Status: 202 Accepted
{
"jobId": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
"status": "processing",
"uploadedRows": 1,
"totalRows": 1,
"uploadComplete": true
}Before uploadComplete is set, status is uploading and totalRows is null.
Chunked upload
For imports larger than 500 rows, send multiple requests with the same jobId:
- First request — omit
jobId; receivejobIdin the response - Middle requests — include
jobId; omituploadCompleteor setfalse - Final request — include
jobIdand"uploadComplete": true
Each request may contain 1–500 subscribers. The job rejects uploads that would exceed 50,000 total rows.
Row classification (after processing)
Each row is classified asynchronously. Aggregated counts and samples are available on the job status endpoint:
| Result | Meaning |
|---|---|
created | New pre-verified subscription |
skipped | Already verified on that dashboard |
quotaExceeded | Org-wide unique phone quota exhausted (first subscription for a new number) |
errors | Invalid phone, dashboard, component, or channel not enabled |
Sample arrays (created, skipped, errors, quotaExceeded) are capped at 100 entries per job.
Error responses
| Status | When |
|---|---|
400 | Invalid body, more than 500 rows in one request, or job would exceed 50,000 rows |
403 | Requires admin or subscriber role, or feature disabled |
404 | jobId not found or does not belong to this organization |
409 | Another bulk import is already in progress, or job is no longer accepting uploads |

