Skip to main content
Wildo.ai Coming soon

Events and external data

Send transactional text messages

Use the configured SMS provider for transactional messages such as phone verification and sign-in codes.

Partially available today — the limit is described on this page.

A transactional verification message passes through the configured SMS provider.

Send transactional text messages

Wildo’s SMS service sends transactional text messages through a configured provider. Phone verification and SMS sign-in challenges use that service, keeping provider access and transport out of each authentication flow.

This is the transactional send path. Selecting SMS on a declarative resource notification does not currently send a message through the general notification dispatcher.

Example — Deliver a phone verification code

A person requests phone verification. The authentication flow supplies the message to the SMS service, which resolves the selected provider and submits its request. The person then enters the received code.

For engineers

Enable EngineCapability.SMS, configure an enabled provider using SMS_PROVIDER, select its primary provider and supply the provider’s credential and sender configuration. Wonder Todos currently declares SMS disabled; that configuration is not a working send example.

For example, select the shipped Twilio backend provider in wildo.saas.config.ts. Import EngineCapability from @wildo-ai/saas-models. These are entries to merge into the existing configuration, preserving its other capabilities, providers and selections:

engineCapabilities: {
  [EngineCapability.SMS]: { enabled: true },
},
providers: {
  scopes: {
    backend: {
      providers: {
        twilio: {
          engineCapabilities: [EngineCapability.SMS],
          providerCapabilities: ['SMS'],
          protocols: ['SMS_PROVIDER'],
        },
      },
      selection: { [EngineCapability.SMS]: { primary: 'twilio', whenUnavailable: [] } },
    },
  },
},

Run wildo config sync to synchronize the provider artifacts. This is the backend contribution; a provider configured only on a frontend cannot send the authentication message. Keep credentials in the backend deployment environment, not this shared declaration.

The provider’s required TWILIO_CREDENTIALS secret accepts a JSON bundle shaped as {"accountId":"<account SID>","secret":"<auth token>"}. Both values come from the provider account. The engine resolves that secret, uses the account identifier in the send endpoint and constructs the authorization header. The separate fromNumber below belongs to backend application configuration and must identify the intended sender.

Set the sender, then handle the send result

The backend service is injected as SAAS_SERVICE_TYPES.SMSService. Its default sender comes from the application configuration path below; configuredSenderNumber is the number approved for your provider account. Import ExternalProvider_ExchangeProtocol_Kind from @wildo-ai/external-connectors-models. This is a configuration fragment, not a credential declaration.

providerConfigurations: {
  twilio: {
    [ExternalProvider_ExchangeProtocol_Kind.SMS_PROVIDER]: {
      fromNumber: configuredSenderNumber,
    },
  },
},

In the calling service, smsService is the injected SMS service, recipientPhone is an E.164 number and localizedMessage is the application’s translated message. This illustrative body shows the result boundary:

const result = await smsService.send(recipientPhone, localizedMessage);
if (!result.success) {
  throw new Error('The SMS provider did not accept the message');
}

const submission = {
  providerId: result.providerId,
  messageId: result.messageId,
};

The optional third argument overrides the configured sender for that call. success describes provider submission; neither that value nor the optional message identifier proves handset delivery. Preserve failure information in the application’s normal diagnostics without exposing message contents or credentials. Do not mark a verification challenge delivered simply because the promise resolved.

The existing SMS sign-in and phone-verification controllers follow this pattern: obtain a localized message, call send, inspect success, and reject the request on failure. Keep challenge generation, throttling and validation in those authentication flows rather than constructing a second authentication flow around this short send example.

Let the provider own its wire format

The runtime contract supplies the send endpoint, request-body builder and response parser. The engine resolves credentials, composes its authorization header, executes the bounded request and validates the parsed response against StandardSMS_SendResponseSchema. A provider’s accepted response is not proof of handset delivery.

Twilio is the shipped provider for this path. Its account-and-secret credential shape is parsed by the engine; secret values remain deployment material. The provider contract determines encoding and response interpretation rather than making every caller speak Twilio.

Keep the notification channels distinct

Authentication consumers invoke this service for codes and phone verification with their own throttling and continuation checks. The general notification dispatcher’s SMS branch still logs instead of invoking it. Use the existing transactional API for its supported workflows; do not advertise SMS delivery by adding CoreUserNotificationChannel.SMS to an operation declaration alone.

Building a B2B product or an internal tool?

Wildo is not self-service yet. Tell us what you have in mind and we will say plainly whether it fits, and what happens next.