Invio
Invia SMS in blocco con POST /v1/batches
/v1/batchesInvia a fino a 10.000 numeri in una richiesta. L'intero costo viene prelevato dal saldo in una volta sola.
Corpo della richiesta
- toarray of stringsopzionale
Numeri per un testo condiviso. Usa to con text, oppure messages.
- textstringopzionale
Il testo condiviso, richiesto con to.
- messagesarray of objectsopzionale
Uno {to, text} per destinatario, per testi personalizzati.
- namestringopzionale
Un'etichetta per la console, fino a 100 caratteri.
- referencestringopzionale
Il tuo id, fino a 100 caratteri, restituito sul batch e su ogni messaggio.
- send_atstringopzionale
Orario ISO 8601, da 2 minuti a 45 giorni in anticipo.
curl https://bulksmsapi.cc/v1/batches \
-H "Authorization: Bearer $BULKSMSAPI_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: spring-sale-0412" \
-d '{
"name": "Spring sale",
"text": "Spring sale at Northwind: 20% off until Sunday. Opt out: northwind.example/sms",
"to": [
"+14155550123",
"+447400123456",
"+4915123456789"
]
}'const res = await fetch("https://bulksmsapi.cc/v1/batches", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.BULKSMSAPI_KEY}`,
"Content-Type": "application/json",
"Idempotency-Key": "spring-sale-0412",
},
body: JSON.stringify({
name: "Spring sale",
text: "Spring sale at Northwind: 20% off until Sunday. Opt out: northwind.example/sms",
to: ["+14155550123", "+447400123456", "+4915123456789"],
}),
});
const batch = await res.json();
console.log(res.status, batch.id, batch.recipients, batch.cost);import json, os, urllib.request
req = urllib.request.Request(
"https://bulksmsapi.cc/v1/batches",
data=json.dumps({
"name": "Spring sale",
"text": "Spring sale at Northwind: 20% off until Sunday. Opt out: northwind.example/sms",
"to": ["+14155550123", "+447400123456", "+4915123456789"],
}).encode(),
headers={
"Authorization": "Bearer " + os.environ["BULKSMSAPI_KEY"],
"Content-Type": "application/json",
"Idempotency-Key": "spring-sale-0412",
"User-Agent": "northwind-app/1.0",
},
method="POST",
)
with urllib.request.urlopen(req) as res:
batch = json.load(res)
print(res.status, batch["id"], batch["recipients"], batch["cost"])<?php
$ch = curl_init("https://bulksmsapi.cc/v1/batches");
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
"Authorization: Bearer " . getenv("BULKSMSAPI_KEY"),
"Content-Type: application/json",
"Idempotency-Key: spring-sale-0412",
],
CURLOPT_POSTFIELDS => json_encode([
"name" => "Spring sale",
"text" => "Spring sale at Northwind: 20% off until Sunday. Opt out: northwind.example/sms",
"to" => ["+14155550123", "+447400123456", "+4915123456789"],
]),
]);
$batch = json_decode(curl_exec($ch), true);
echo $batch["id"], " ", $batch["recipients"], " ", $batch["cost"], "\n";package main
import (
"bytes"
"encoding/json"
"fmt"
"net/http"
"os"
)
func main() {
body, _ := json.Marshal(map[string]any{
"name": "Spring sale",
"text": "Spring sale at Northwind: 20% off until Sunday. Opt out: northwind.example/sms",
"to": []string{"+14155550123", "+447400123456", "+4915123456789"},
})
req, _ := http.NewRequest("POST", "https://bulksmsapi.cc/v1/batches", bytes.NewReader(body))
req.Header.Set("Authorization", "Bearer "+os.Getenv("BULKSMSAPI_KEY"))
req.Header.Set("Content-Type", "application/json")
req.Header.Set("Idempotency-Key", "spring-sale-0412")
res, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer res.Body.Close()
var batch map[string]any
json.NewDecoder(res.Body).Decode(&batch)
fmt.Println(res.StatusCode, batch["id"], batch["recipients"], batch["cost"])
}{
"id": "bat_6TQ2W8M1ZK4N",
"object": "batch",
"name": "Spring sale",
"status": "queued",
"source": "api",
"encoding": "GSM-7",
"recipients": 3,
"max_segments": 1,
"cost": "0.02741",
"refunded": "0.00000",
"currency": "USD",
"counts": { "scheduled": 0, "queued": 3, "sent": 0, "delivered": 0, "failed": 0, "canceled": 0 },
"send_at": null,
"reference": null,
"created_at": "2026-11-07T09:31:40.102Z",
"completed_at": null,
"set_aside": []
}Numeri che sono stati esclusi
Ogni numero viene pulito e prezzato singolarmente. I numeri che non possono essere inviati vengono esclusi dal batch, non addebitati, e elencati in set_aside con una motivazione:
| reason | Significato |
|---|---|
| invalid_number | Non leggibile come + e da 7 a 15 cifre dopo la pulizia. |
| duplicate | Lo stesso numero è apparso precedentemente nella richiesta. |
| unsupported_country | Il numero non appartiene a un paese prezzato. |
| too_long | Il suo testo personalizzato richiede più di 10 segmenti. |
| empty_text | Il suo testo personalizzato è vuoto. |
| suppressed | Il numero è nella tua lista di non invio. |
Se non rimane alcun numero, la richiesta fallisce con il codice della prima motivazione (ad esempio invalid_number) e nulla viene addebitato.
Testo personalizzato per numero
Usa messages per dare a ogni destinatario il proprio testo: nomi, orari, importi. Ogni testo viene conteggiato e prezzato singolarmente, quindi un batch può mescolare messaggi di uno e due segmenti.
curl https://bulksmsapi.cc/v1/batches \
-H "Authorization: Bearer $BULKSMSAPI_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "Appointment reminders, 14 May",
"send_at": "2026-05-13T16:00:00Z",
"messages": [
{ "to": "+14155550123", "text": "Hi Ana, your dental check-up is tomorrow at 09:30." },
{ "to": "+14155550178", "text": "Hi Sam, your dental check-up is tomorrow at 11:00." }
]
}'Pianificazione
Con send_at il batch e i suoi messaggi attendono nello stato scheduled e passano alla coda a quel minuto. Il costo viene prelevato quando la richiesta viene accettata, quindi un batch programmato ha sempre i suoi fondi. Un batch programmato può essere annullato fino a quando non inizia.
/v1/batches/{id}/cancelAnnulla un batch programmato: ogni messaggio viene annullato e l'intero costo torna al saldo come una riga di rimborso. Un batch che è iniziato risponde con 409 not_cancelable.
curl -X POST https://bulksmsapi.cc/v1/batches/bat_6TQ2W8M1ZK4N/cancel \
-H "Authorization: Bearer $BULKSMSAPI_KEY"Recupera e elenca i batch
/v1/batches/{id}Il batch con i conteggi in tempo reale per ogni stato. Interrogalo per monitorare l'avanzamento o utilizza i webhook.
/v1/batchesBatch dell'account, dal più recente, con limite (da 1 a 100) e starting_after (un ID bat_).
Campi del batch
- idstring
bat_ seguito da 12 caratteri.
- statusstring
programmato, in coda, in invio, completato o annullato.
- sourcestring
api o console.
- encodingstring
GSM-7, o UCS-2 quando il testo richiede Unicode.
- recipientsinteger
Numeri accettati nel batch.
- max_segmentsinteger
Conteggio segmenti più alto tra i testi.
- coststring
Totale prelevato dal saldo, USD.
- refundedstring
Totale restituito finora per messaggi falliti o annullati.
- countsobject
Messaggi per stato: programmato, in coda, inviato, consegnato, fallito, annullato.
- send_atstring or null
Orario programmato, se presente.
- completed_atstring or null
Quando l'ultimo messaggio ha raggiunto uno stato finale.
Liste più grandi
Dividi elenchi con oltre 10.000 numeri in più richieste, ciascuna con la propria Idempotency-Key (ad esempio l'ID dell'elenco e il numero della parte). I messaggi vengono passati alla rete in ordine fino a 1.200 al minuto per account, quindi una campagna con 50.000 numeri è in viaggio in meno di un'ora. La console accetta 50.000 numeri per campagna da un incolla o un file CSV.