Skip to main content
Templates let you define a message body once, with {{.variable}} placeholders, and render it server-side on every send. Benefits: shorter requests, consistent copy, and a single place to edit when the copy changes.

Create a template

curl -X POST https://api.robase.dev/v1/sms-templates \
  -H "Authorization: Bearer rb_live_xxx" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Ride arriving",
    "body": "Hi {{.driver_name}}, your ride arrives in {{.eta}} min."
  }'
Response:
{
  "id": "tpl_01H8XKQJ3Z...",
  "name": "Ride arriving",
  "slug": "ride-arriving",
  "body": "Hi {{.driver_name}}, your ride arrives in {{.eta}} min.",
  "variables": ["driver_name", "eta"]
}
The slug is derived from name and doubles as a stable identifier — use it (instead of the UUID) in sends so renaming a template doesn’t break callers.

Send using the template

await pm.sms.send({
  to:   '+2348012345678',
  from: 'SHUTTLERS',
  template: 'ride-arriving',             // slug or UUID both work
  variables: { driver_name: 'Chidi', eta: 3 },
});
The server renders the body, re-computes segments and cost, and proceeds normally.

Variable syntax

We use Go’s text/template engine:
SyntaxRenders
{{.name}}The value of variables.name
{{.user.email}}Nested lookup — requires a map
{{printf "%d" .count}}Formatters via pipe
{{if .is_first}}Welcome!{{end}}Conditionals
Missing variables render as <no value> — not an error. This is deliberate so a typo doesn’t block a send; but test your templates with the render endpoint (below) to catch them in dev.

Preview before sending

POST /v1/sms-templates/:id/render renders the template with variables and returns the body + segment count without sending anything. Great for previews in your admin UI:
const preview = await pm.smsTemplates.render('tpl_01H8...', {
  driver_name: 'Chidi',
  eta: 3,
});
// → { body: "Hi Chidi, your ride arrives in 3 min.", encoding: "GSM7", segments: 1 }

List, update, delete

await pm.smsTemplates.list();
await pm.smsTemplates.get('tpl_01H8...');
await pm.smsTemplates.update('tpl_01H8...', { body: 'Updated: ...' });
await pm.smsTemplates.remove('tpl_01H8...');

Keeping segment count predictable

Variables change the final length. A good pattern: cap user-supplied variables to a max length before passing them, so your template never balloons past one segment:
const eta = Math.min(Number(rawEta), 99);  // cap at 99 → 2 chars max
const driver = String(driverName).slice(0, 20);

await pm.sms.send({
  to, from, template: 'ride-arriving',
  variables: { eta, driver_name: driver },
});
The render endpoint is useful here too — check segments before batch-sending to estimate cost.