Send SMS with Express
Send a booking reminder from a server route, keep the accepted message ID and read its delivery status. This example uses the existing Bird TypeScript SDK.
1. Prepare the workspace
Prepare an SMS-capable US number owned by your workspace, enable the US destination, complete its required sender registration and add balance. The fixed recipient +15005550006 simulates delivery, is billed at the normal destination rate and does not reach a handset. Complete the first-message setup and create a server-side API key before running the application.
2. Create the application
Use Node.js 20.3 or later and Express 5:
Przykład kodu
mkdir bird-sms-express
cd bird-sms-express
npm init -y
npm install express@5 @messagebird/sdk tsx
export BIRD_API_KEY="YOUR_API_KEY"
export BIRD_SMS_FROM="YOUR_ELIGIBLE_US_NUMBER"3. Add the routes
Save this as server.mts. The fixed payload keeps this first test separate from a public message composer. Express routing supplies the HTTP handlers.
Przykład kodu
import express from "express";
import { BirdClient } from "@messagebird/sdk";
function required(name: string): string {
const value = process.env[name];
if (!value) throw new Error(`Configure ${name}.`);
return value;
}
const sender = required("BIRD_SMS_FROM");
const bird = new BirdClient({ apiKey: required("BIRD_API_KEY") });
const app = express();
const uuid = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
app.post("/api/sms/messages", async (req, res) => {
const key = req.get("Idempotency-Key");
if (!key || !uuid.test(key)) {
res.status(400).json({ error: "Supply an Idempotency-Key UUID." });
return;
}
try {
const message = await bird.sms.send(
{
from: sender,
to: "+15005550006",
text: "Your studio visit is tomorrow at 14:00.",
category: "transactional",
metadata: { booking: "FN-1042" },
},
{ idempotencyKey: key },
);
res.status(202).json({ id: message.id, status: message.status });
} catch (error) {
console.error(error);
res
.status(503)
.json({ error: "Could not confirm the send. Inspect the original attempt before retrying." });
}
});
app.get("/api/sms/messages", async (req, res) => {
if (typeof req.query.id !== "string" || !req.query.id) {
res.status(400).json({ error: "Supply a message id." });
return;
}
try {
const message = await bird.sms.get(req.query.id);
res.json({ id: message.id, status: message.status });
} catch (error) {
console.error(error);
res.status(503).json({ error: "Could not read the message." });
}
});
app.listen(3000, "127.0.0.1");4. Run the example
Start the server:
Przykład kodu
npx tsx server.mtsIn a second terminal, create an operation ID once and send the fixed example:
Przykład kodu
export DEMO_OPERATION_ID="$(python3 -c 'import uuid; print(uuid.uuid4())')"
curl -i -X POST http://127.0.0.1:3000/api/sms/messages \
-H "Idempotency-Key: $DEMO_OPERATION_ID"Keep DEMO_OPERATION_ID with this attempt. Do not regenerate it while resolving an uncertain response. The SDK infers the API region from the key.
Inspect the result and recover
The POST returns 202 with the message id and current status. Acceptance precedes delivery. Copy the ID and read it without sending again:
Przykład kodu
curl "http://127.0.0.1:3000/api/sms/messages?id=YOUR_MESSAGE_ID"The read returns the recorded status. Follow SMS events for asynchronous outcomes, and use the product log or event guide to investigate a missing receipt. A missing receipt does not establish delivery or failure.
- A missing or malformed Idempotency-Key produces 400 in this application before it calls Bird.
- If the send fails, the application returns 503 and leaves the result unresolved. Inspect the SDK error in the server terminal and the product log. Correct authentication, sender, destination, template or balance errors before retrying.
- For an uncertain response, retain the same key and identical payload. Read the idempotency guide before retrying; a new key creates a new operation, and response retention does not provide an indefinite exactly-once guarantee.
For real reminders, load the booking and its permitted recipient from your database after authorizing the caller. Keep the booking ID with the accepted message ID. Handle replies and opt-outs before adding an automated reply.
These handlers use a fixed test recipient and bind the development server to loopback. Before publishing, authorize each customer action, associate message IDs with the owning account before permitting reads, and apply your application's abuse limits. The booking and workflow are sample application logic.
Continue the integration
- SMS API reference: exact send contract.
- Events and webhooks: verify signatures and retain event identity.
- Migration guides: map an existing provider's behavior.
- SMS resources: setup, operation and comparison paths.
Powiązane zasoby
Kontynuuj z dokumentacją, przewodnikami i przykładami dotyczącymi tego tematu. Zasoby są w języku angielskim.
Obejrzyj przewodnikSending your first SMSZrozum koncepcjęWhat does SMS mean?Poznaj możliwościSMSPodążaj ścieżką naukiBuild your first integration
Wypróbuj ćwiczenie i uzyskaj brief wdrożeniowy