Quickstart
Send your first message in about five minutes. You’ll need a 9bits account — everything else is below.
-
Get your API token
Section titled “Get your API token”In the dashboard, go to Settings → Security and copy your API token.
Keep it in an environment variable rather than pasting it into code:
Terminal window export NINEBITS_TOKEN="your_api_token_here" -
Register a sender ID
Section titled “Register a sender ID”The
fromfield is a sender ID — the name recipients see the message from. It must be approved before you can use it, which is a network operator requirement, not a 9bits one.Add one under Messaging → Sender IDs in the dashboard. Approval typically takes a business day.
Sending with an unapproved sender ID fails with
sender_id_invalid, so get this started first. See Sender IDs for what gets approved. -
Send the message
Section titled “Send the message”Replace the destination with your own number so you can watch it arrive.
Terminal window curl -X POST https://api.9bits.net/ng/v1/sendsms \-H "Authorization: Bearer $NINEBITS_TOKEN" \-H "Content-Type: application/json" \-d '{"from": "9bits","to": ["2348020000000"],"content": "Hello from the 9bits API 👋","delivery_report": true}'const res = await fetch('https://api.9bits.net/ng/v1/sendsms', {method: 'POST',headers: {Authorization: `Bearer ${process.env.NINEBITS_TOKEN}`,'Content-Type': 'application/json',},body: JSON.stringify({from: '9bits',to: ['2348020000000'],content: 'Hello from the 9bits API 👋',delivery_report: true,}),});const batch = await res.json();if (!res.ok) throw new Error(batch.error.code);console.log(batch.reference_id); // keep this — it's how you track deliveryimport os, requestsres = requests.post("https://api.9bits.net/ng/v1/sendsms",headers={"Authorization": f"Bearer {os.environ['NINEBITS_TOKEN']}"},json={"from": "9bits","to": ["2348020000000"],"content": "Hello from the 9bits API 👋","delivery_report": True,},timeout=10,)res.raise_for_status()batch = res.json()print(batch["reference_id"]) # keep this — it's how you track delivery<?php$ch = curl_init('https://api.9bits.net/ng/v1/sendsms');curl_setopt_array($ch, [CURLOPT_RETURNTRANSFER => true,CURLOPT_POST => true,CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('NINEBITS_TOKEN'),'Content-Type: application/json',],CURLOPT_POSTFIELDS => json_encode(['from' => '9bits','to' => ['2348020000000'],'content' => 'Hello from the 9bits API 👋','delivery_report' => true,]),]);$batch = json_decode(curl_exec($ch), true);echo $batch['reference_id'];payload, _ := json.Marshal(map[string]any{"from": "9bits","to": []string{"2348020000000"},"content": "Hello from the 9bits API 👋","delivery_report": true,})req, _ := http.NewRequest("POST","https://api.9bits.net/ng/v1/sendsms", bytes.NewReader(payload))req.Header.Set("Authorization", "Bearer "+os.Getenv("NINEBITS_TOKEN"))req.Header.Set("Content-Type", "application/json")res, err := http.DefaultClient.Do(req)if err != nil {return err}defer res.Body.Close()var batch struct {ReferenceID string `json:"reference_id"`}json.NewDecoder(res.Body).Decode(&batch) -
Read the response
Section titled “Read the response”{"reference_id": "fdab8f46df049e58b0af7c2d7","status": "accepted","accepted_at": "2026-07-14T18:48:14+01:00","recipients_accepted": 1,"status_url": "/ng/v1/sendsms/status/fdab8f46df049e58b0af7c2d7","cost_estimate": {"total_cost": 6.4,"currency": "NGN","pages": 2,"accepted_recipients": 1,"sufficient": true}}Two things to notice.
statusisaccepted, notdelivered. Sending is asynchronous. A200means we queued your batch, not that the phone buzzed. Store thereference_id— it’s the only way to ask what happened next.pagesis2. That message is well under 160 characters, so why two pages? The 👋 emoji forces the whole message into UCS-2 encoding, which cuts the page size from 160 characters to 70. One emoji doubled the cost. This surprises people in production, so it’s worth understanding now — see Encoding & pricing. -
Check delivery
Section titled “Check delivery”Terminal window curl https://api.9bits.net/ng/v1/sendsms/status/fdab8f46df049e58b0af7c2d7 \-H "Authorization: Bearer $NINEBITS_TOKEN"{"reference_id": "fdab8f46df049e58b0af7c2d7","total": 1,"counts": { "delivered": 1 },"recipients": [{"destination": "2348020000000","status": "delivered","operator": "mtn","message_id": "4f2a9c1b7e"}]}Polling is fine while you’re building. In production, set
callback_urlon the send and let us push receipts to you instead — see Webhooks.