Build/Routes

Handling SMS

Process incoming text messages with router.sms()

Handle incoming SMS messages sent to a phone number. Phone numbers are configured in code and integrated with Twilio automatically when deployed.

Routes Location

All routes live in src/api/. Import agents you need and call them directly.

Basic Example

import { createRouter } from '@agentuity/runtime';
import smsResponder from '@agent/sms-responder';
 
const router = createRouter();
 
router.sms({ number: '+1234567890' }, async (c) => {
  // Parse Twilio payload
  const formData = await c.req.parseBody();
  const from = formData['From'] as string;
  const body = formData['Body'] as string;
 
  const reply = await smsResponder.run({
    sender: from,
    message: body,
  });
 
  // Return value is sent as SMS reply
  return c.text(reply);
});
 
export default router;

Parsing Twilio Payloads

Twilio sends webhooks in form-encoded format by default, but can also send JSON:

import smsHandler from '@agent/sms-handler';
 
router.sms({ number: '+1234567890' }, async (c) => {
  let from = 'unknown';
  let body = '';
 
  const contentType = c.req.header('content-type') || '';
 
  if (contentType.includes('application/x-www-form-urlencoded')) {
    // Default Twilio format
    const formData = await c.req.parseBody();
    from = formData['From'] as string;
    body = formData['Body'] as string;
  } else if (contentType.includes('application/json')) {
    // JSON format (if configured)
    const data = await c.req.json();
    from = data.From || data.from;
    body = data.Body || data.message;
  }
 
  const reply = await smsHandler.run({ from, body });
  return c.text(reply);
});

Full Example

An SMS handler that processes commands:

import { createRouter } from '@agentuity/runtime';
import statusChecker from '@agent/status-checker';
import balanceChecker from '@agent/balance-checker';
 
const router = createRouter();
 
router.sms({ number: '+1234567890' }, async (c) => {
  try {
    const formData = await c.req.parseBody();
    const from = formData['From'] as string;
    const body = (formData['Body'] as string).trim().toLowerCase();
 
    c.var.logger.info('SMS received', { from, body });
 
    // Handle commands
    if (body === 'help') {
      return c.text('Commands: STATUS, BALANCE, HELP');
    }
 
    if (body === 'status') {
      const status = await statusChecker.run({ userId: from });
      return c.text(`Your status: ${status.message}`);
    }
 
    if (body === 'balance') {
      const balance = await balanceChecker.run({ phone: from });
      return c.text(`Balance: $${balance.amount}`);
    }
 
    // Default response
    return c.text('Unknown command. Text HELP for options.');
  } catch (error) {
    c.var.logger.error('SMS processing failed', { error });
    return c.text('Sorry, something went wrong. Try again later.');
  }
});
 
export default router;

Phone Number Format

Phone numbers must use E.164 international format: +[country code][number] with no spaces or dashes (e.g., +1234567890).

How Replies Work

The text you return from the handler is automatically sent as an SMS reply to the sender. Agentuity handles the Twilio TwiML response format for you.

// This text is sent back to the sender as an SMS
return c.text('Thanks for your message!');

Standalone Usage

SMS handlers work without agents. This example sends an auto-reply based on keywords:

import { createRouter } from '@agentuity/runtime';
 
const router = createRouter();
 
router.sms({ number: '+1234567890' }, async (c) => {
  const formData = await c.req.parseBody();
  const body = (formData['Body'] as string).toLowerCase();
 
  if (body.includes('hours')) {
    return c.text('We are open Mon-Fri 9am-5pm EST.');
  }
  return c.text('Thanks for your message! Reply HOURS for business hours.');
});
 
export default router;

Next Steps

Need Help?

Join our DiscordCommunity for assistance or just to hang with other humans building agents.

Send us an email at hi@agentuity.com if you'd like to get in touch.

Please Follow us on

If you haven't already, please Signup for your free account now and start building your first agent!