Generated banner for AWS Sms Voice
Generated logo for AWS Sms Voice

AWS Sms Voice

AWSOfficialPublished by AWS

  • Skill
  • Tool integration
  • Cloud and DevOps
  • Apache-2.0
  • Low risk

From the author

Onboards RCS Business Messaging and Notify OTP via the pinpoint-sms-voice-v2 AWS CLI. Covers creating a branded RCS test agent (logo, banner, rich cards, suggested replies), adding verified testers, and sending/receiving the first RCS message; and configuring AWS End User Messaging Notify to send one-time-passcode (OTP) verification codes through AWS-managed phone numbers without buying a number or completing carrier registration. Also discovers which registration type a country requires from live API definitions and runs the universal registration lifecycle (create, derive fields, fill, submit, recover from denial, resubmit) shared by 10DLC, toll-free, short code, sender ID, RCS country launch, and Notify tier upgrade. Applicable to RCS agent setup, RCS message send/receive, Notify OTP configuration, verification-code delivery, registration requirements by country, and registration submission. Does not cover WhatsApp (see aws-social-messaging).
— the description by AWS

AutoGineer summary

Written by AutoGineer from the skill’s own files, not by the author

This skill provides a structured approach to using the AWS End User Messaging SMS and Voice (pinpoint-sms-voice-v2) API. It guides users through the rapid setup of RCS Business Messaging test agents and Notify OTP configurations, as well as the more complex lifecycle of production registration for various messaging identities. It emphasizes using the AWS MCP server for secure, audited execution and provides clear paths for both testing and moving to production-grade messaging.

What it does

  • Creates branded RCS test agents with rich cards and suggested replies.
  • Configures Notify for OTP delivery using AWS-managed templates.
  • Discovers registration requirements for specific countries and identity types.
  • Executes the full registration lifecycle including submission and denial recovery.
  • Provides procedures for exiting the SMS sandbox and upgrading to production tiers.
  • Offers guidance on least-privilege IAM policies and security best practices.

When to use it

  • When you need to send rich, branded RCS messages to test devices.
  • When you require a fast, production-ready OTP verification solution.
  • When you need to determine registration requirements for international messaging.
  • When you are ready to move messaging identities from sandbox to production.
  • When you need to manage the registration lifecycle for 10DLC, toll-free, or short codes.

Advantages

  • Enables rapid prototyping with no phone number purchase required.
  • Provides a unified engine for diverse registration types.
  • Includes built-in failure mode analysis and cleanup procedures.
  • Promotes secure practices through least-privilege IAM and audit logging.
  • Supports both CLI and MCP-based execution for flexibility.

Usage examples

“Help me set up an RCS test agent to send a branded message.”
The agent will guide you through creating an RCS agent, adding a verified test device, and sending your first rich message using the pinpoint-sms-voice-v2 API.
“How do I send an OTP code using AWS Notify?”
The agent will assist in creating a Notify configuration, selecting an approved template, and sending a verification code to your specified phone number.
“What are the registration requirements for sending SMS in France?”
The agent will query live API definitions to identify the specific registration type and field requirements for the target country.
“I need to move my SMS identity out of the sandbox.”
The agent will walk you through the production go-to-production guide, including checking account attributes and managing spend limits.

Install

  1. Download the skill as a ZIP:

    https://mp-staging.autogineer.com/agent-skills/aws/aws-sms-voice/download
  2. Unzip it into the cross-client skills folder of your project:

    mkdir -p .agents/skills && unzip aws-sms-voice.zip -d .agents/skills

Documentation by AWS

AWS End User Messaging — SMS, Voice, RCS & Notify

Overview

AWS End User Messaging SMS and Voice (the pinpoint-sms-voice-v2 API) is the control and data plane for SMS, Voice, RCS Business Messaging, and Notify (OTP). This skill covers the two fastest onboarding paths — each reaches a real message on a real phone in about five minutes, with no phone-number purchase and no carrier registration:

  1. Create an RCS test agent and send your first branded message — a branded RCS Business Messaging agent, a verified test device, and a rich outbound + inbound message. See references/hello-rcs-test-agent.md.

  2. Send an OTP with Notify — a one-time-passcode text through AWS-managed sending identities and pre-approved templates. See references/hello-notify-otp.md.

Beyond onboarding, this skill takes an identity to production registration in three steps:

  1. Find which registration a country requires — discover the registration type and its live field set for a target country and identity type, reconciled with the official docs. See references/registration-requirements-by-country.md.

  2. Run the registration lifecycle — the universal engine (create, derive fields, fill, submit, poll, recover from denial, resubmit) shared by every registration type, including RCS country launch. See references/registration-core-engine.md.

  3. Take an identity to production — exit the SMS sandbox, launch RCS in a country with carrier monitoring and SMS fallback, upgrade Notify to Advanced, and apply production hygiene (keywords, configuration sets, protect configurations). See references/customer-go-to-production-guide.md.

Guardrail — where this skill's files live (MCP vs local install)

This skill can be loaded two ways, and the references/ files resolve differently:

  • Loaded through the AWS MCP retrieve_skill tool. Reference files do not exist on the local filesystem. Fetch them via retrieve_skill with the file parameter (e.g., file="references/hello-rcs-test-agent.md"). Do NOT file_read these paths locally — they are not there.

  • Installed locally (e.g., .kiro/skills/aws-sms-voice/). Read references from the local skill directory using the relative paths shown in this file.

This applies only to the skill's own packaged files. User-created artifacts (brand-assets/, temp files) are always in the user's working directory.

Execute commands using available tools from the AWS MCP server when connected — it provides sandboxed execution, audit logging, and observability. When the MCP server is not available, fall back to the AWS CLI or shell as needed.

Choosing a path

You want to…Go to
Send rich, branded messages (cards, logo, two-way) to your own test phonehello-rcs-test-agent.md
Send a verification code / OTP to any supported phone, fastest possible pathhello-notify-otp.md
Find out which registration a country needs and what fields it requiresregistration-requirements-by-country.md
Create and submit a registration of any type (10DLC, toll-free, sender ID, RCS launch, Notify tier)registration-core-engine.md
Take an identity to production (sandbox exit, RCS carrier launch + fallback, Notify Advanced, hygiene)customer-go-to-production-guide.md

RCS test agents deliver only to verified test devices and require a short brand registration (auto-reviewed in minutes). Notify sends to any recipient in its supported countries immediately, but is limited to AWS-managed OTP templates. Pick RCS to explore rich messaging; pick Notify for the shortest path to a production-grade verification text.

Before you start (both paths)

The AWS MCP server is recommended for the best experience here — it runs the many pinpoint-sms-voice-v2 and sts calls with sandboxed execution, audit logging, and observability. It is not a hard requirement: every step also works with the plain AWS CLI or the AWS Agent Toolkit when the MCP server is not available.

  1. Credentials. Run aws sts get-caller-identity --region <REGION> (pass --region to use the regional STS endpoint; the global sts.amazonaws.com endpoint is legacy). If it fails, configure the user's auth (named profile / SSO / access keys — --profile <PROFILE> on every command if a profile is in play) and prefer an assumed IAM role with ephemeral credentials. Each reference file's Prerequisites carry the full auth, CloudTrail-audit, and CLI-freshness steps.

  2. Least-privilege access. These tasks need a small set of specific sms-voice: actions in the target account (the reference files enumerate the read/write actions each step uses — for example sms-voice:DescribeRcsAgents, CreateRcsAgent, CreateRegistration, CreateNotifyConfiguration, and SendNotifyTextMessage). Scope the policy to exactly the actions the chosen path uses; do not grant sms-voice:* or *FullAccess.

  3. Don't trust the CLI version. Treat any Invalid choice '<operation>' on a pinpoint-sms-voice-v2 command, at any step, as a stale/partial local service model (not a permissions or account problem). The RCS and Notify reference files (prerequisite 3) carry the full reactive resolution: clear a stale ~/.aws/models/pinpoint-sms-voice-v2/ override, else upgrade the AWS CLI, with a boto3 fallback. AccessDeniedException means the identity is missing the required sms-voice: permissions.

Each reference file is self-contained: it tracks the IDs you collect as session state, audits required inputs against the service before any submit, and ends with a Failure modes table and a Cleanup section. Follow the file for the path the user chose rather than improvising the API sequence — several steps fail silently or depend on service-version-specific field sets that must be read live.

Security Considerations

  • Least-privilege IAM. Scope policies to specific sms-voice: actions; never use *FullAccess or sms-voice:* in production. The reference files enumerate the minimal read/write actions each onboarding path needs.

  • Ephemeral credentials. Assume an IAM role with ephemeral credentials; never embed long-lived access keys in code, config, or environment variables.

  • No secrets in messages or fields. OTP codes and message bodies can surface in CloudTrail and downstream logs — treat them as sensitive and never hardcode real codes. Enable CloudTrail logging for sms-voice API calls and encrypt CloudTrail logs and CloudWatch Log groups with a KMS CMK. Attach a configuration set with an event destination (CloudWatch Logs or Kinesis) for delivery monitoring before production traffic. Create CloudWatch alarms on key security signals (repeated AccessDeniedException, unusual send volumes, spend limit approaching threshold) for proactive alerting. Registration contact fields (email, phone, URLs) are submitted to partner review; use real but non-sensitive business contacts.

  • Consent and opt-out. Only message recipients who have opted in. Honor STOP / opt-out state; the RCS path shows how to check the opt-out list before sending. Test agents intentionally restrict delivery to verified test devices — do not work around that to reach unconsented numbers.

  • Spend limits and abuse. Default account spend limits are intentionally low; raise them deliberately and monitor. Notify enforces a non-adjustable per-day cap per destination — do not attempt to bypass it.

  • Destructive cleanup. The teardown steps delete agents, registrations, and configurations. They are irreversible — confirm with the user before running cleanup, and note RCS agents have deletion protection enabled by default in the onboarding flow.

Additional Resources

Files

references/hello-notify-otp.md

Hello AWS End User Messaging: Send an OTP with AWS End User Messaging Notify in minutes

By the end of this task, the user has received a real one-time-passcode text on their phone, sent through AWS End User Messaging Notify. No phone number to buy, no carrier registration, no wait times — AWS manages the sending identities, routing, and pre-approved message templates. Working time is about 5 minutes end to end. This is the fastest possible path to a production-grade verification message; the Basic tier works in many countries out of the box (use list-notify-countries to see the current set).

You run every command yourself. The user provides inputs and confirms what arrives on their phone. Stop and consult the Failure modes table on any error.

Session state

ValueFormatSource
REGIONe.g. us-east-1ask the user (default us-east-1)
PROFILEAWS CLI profile namecredential bootstrap (may be empty)
DISPLAY_NAME≤15 chars; letters, digits, _, -, spaceask the user (their brand/app name)
NC_IDnotify- + 32 hexCreateNotifyConfiguration response
TEMPLATE_IDe.g. notify-code-verification-english-001DescribeNotifyTemplates response
PHONEE.164ask the user (their real phone)

Prerequisites

  1. AWS CLI — check the version: aws --version. v2 recommended; v1 verified working for every command in this task.

  2. Credentials — run aws sts get-caller-identity --region <REGION>. Pass --region so STS uses the regional endpoint (sts.<region>.amazonaws.com); the global endpoint (sts.amazonaws.com) is legacy and best avoided. If it fails, ask the user how they authenticate. Prefer assuming an IAM role with ephemeral credentials over long-lived access keys (named profile / IAM Identity Center (SSO) / access keys), configure accordingly, and from then on append --profile <PROFILE> to EVERY command if a profile is in play. Enable AWS CloudTrail in the account so all pinpoint-sms-voice-v2 API calls (notably SendNotifyTextMessage) are logged — OTP flows are abuse-sensitive (toll fraud, OTP pumping) and need an audit trail.

  3. Service access — read-only check: aws pinpoint-sms-voice-v2 describe-notify-configurations --region <REGION> Minimum IAM actions for this task: sms-voice:CreateNotifyConfiguration, DescribeNotifyConfigurations, DescribeNotifyTemplates, ListNotifyCountries, SendNotifyTextMessage, and DeleteNotifyConfiguration (for cleanup).

  4. Input validation — validate display name (≤15 chars, allowed characters), phone (E.164), and country before mutating APIs.

  5. Inputs — ask the user for: a display name (their brand or app name, 15 chars max — this is what recipients may see, and it goes through an automated brand review; a made-up brand is fine for testing, but a well-known third-party brand name will be flagged), their phone number in E.164, and the destination country if not obvious from the number.

Steps

1. Create the Notify configuration
aws pinpoint-sms-voice-v2 create-notify-configuration \
  --display-name "<DISPLAY_NAME>" \
  --use-case CODE_VERIFICATION \
  --enabled-channels SMS \
  --region <REGION>

Save NotifyConfigurationId as NC_ID. (CODE_VERIFICATION is the only use case Notify supports.)

2. Poll until ACTIVE

Most configurations activate within seconds. Only ACTIVE can send.

aws pinpoint-sms-voice-v2 describe-notify-configurations \
  --notify-configuration-ids <NC_ID> --region <REGION> \
  --query 'NotifyConfigurations[0].Status'
  • PENDING → wait a few seconds and re-poll (control-plane APIs are rate-limited to ~1 request/second — do not poll faster than every 2–3 seconds).

  • ACTIVE → proceed.

  • REQUIRES_VERIFICATION or REJECTED → see Failure modes.

3. Pick a template

You cannot write your own message — Notify uses AWS-managed, pre-approved templates. List the SMS templates available on the Basic tier:

aws pinpoint-sms-voice-v2 describe-notify-templates \
  --filters '[{"Name":"channels","Values":["SMS"]},{"Name":"tier-access","Values":["BASIC"]}]' \
  --region <REGION>

The unfiltered payload is very large (every template lists all supported countries) — add a language-code filter to keep it manageable, e.g. append {"Name":"language-code","Values":["en"]} to the filters array — values are lowercase ISO codes (en, es, fr-CA, ...); uppercase fails with INVALID_FILTER_VALUES. Save the chosen TemplateId as TEMPLATE_ID, and read its variable definitions: variables marked CUSTOMER you supply; variables marked SYSTEM are filled automatically — notably brandName, which comes from your configuration's display name, so you do NOT pass it. Most English code-verification templates take only code (must match ^\d{4,8}$), but some variants require additional variables (e.g. time) — read the Variables list of the specific template you pick rather than assuming; a missing required variable fails the send with ValidationException.

4. Confirm the destination country is enabled (cheap, avoids a failed send)
aws pinpoint-sms-voice-v2 list-notify-countries \
  --channels SMS --tier BASIC --region <REGION>

The Basic tier covers a curated set of countries — the list-notify-countries output above shows the current list. If the user's country is not listed, tell them — the fix is the Advanced tier (see Next steps), not a different command.

5. Dry run, then send

Generate a 6-digit code (this is a demo — in production your app generates and stores it). First validate everything without sending or charging:

aws pinpoint-sms-voice-v2 send-notify-text-message \
  --notify-configuration-id <NC_ID> \
  --destination-phone-number "<PHONE>" \
  --template-id <TEMPLATE_ID> \
  --template-variables '{"code":"482913"}' \
  --dry-run \
  --region <REGION>

(All template variable values are passed as strings, even numbers and booleans.)

Production note: In production, pass template variables via --cli-input-json from a file rather than inline to avoid shell history exposure. Ensure CloudTrail logs are encrypted with a KMS CMK since they will contain OTP codes.

A passing dry run returns the same shape as a real send — MessageId plus ResolvedMessageBody (the rendered text) — with nothing transmitted or charged. If the dry run passes, confirm with the user — "the next command sends a real text to <PHONE>, ready?" — then send for real by repeating the command without --dry-run. If the user only wanted validation, stop here: the dry run already proved the configuration end to end.

Save MessageId. The response also contains ResolvedMessageBody — the exact rendered text. Show it to the user and ask: "This should be on your phone now — did it arrive?" Treat ResolvedMessageBody as sensitive — it contains the OTP code. Do not log or persist it beyond this confirmation.

Verify

  • The user confirms the OTP text arrived and the code matches.

  • ResolvedMessageBody in the response shows the rendered template.

Print a summary: display name, NC_ID, TEMPLATE_ID, region, and the daily-limit reminder below.

Testing note: Notify enforces a non-adjustable per-day cap per destination number, applied at both the configuration and account level — check the applicable value in the Service Quotas console or documentation. Don't burn the day's budget on retries.

Next steps

  • Production hardening for OTP: set a default template (update-notify-configuration --default-template-id <TEMPLATE_ID>), route delivery events to your systems via a configuration set (the configuration-sets-and-event-destinations guide), and read the Notify compliance prerequisites (terms, privacy policy, opt-in) before real traffic.

  • Observability (required before production): Enable CloudTrail logging and attach a configuration set with an event destination (SNS with SSE/KMS, aws:SourceArn/aws:SourceAccount condition keys, and authorized subscriptions only; CloudWatch Logs encrypted with a KMS CMK, or Kinesis Firehose with server-side encryption) for delivery event monitoring. Create CloudWatch alarms on send failure rates and spend approaching the daily cap to detect misuse early.

  • Rate-limit OTP verification: Implement application-side rate limiting on verification attempts (max 3–5 per code, lockout after failures) to prevent brute-force attacks.

  • Rate-limit OTP sends: Implement application-side throttling on send requests (max 1 OTP per phone per 60s, progressive backoff) to prevent SMS pumping and toll fraud.

  • Voice OTP: add VOICE to --enabled-channels, then send-notify-voice-message ... --voice-id JOANNA. Format the code as "4. 8. 2. 9. 1. 3." so text-to-speech reads digits individually.

  • Higher volume / more countries: upgrade Basic → Advanced (higher daily limits, higher TPS, broader country coverage — see applicable limits in the AWS End User Messaging Notify documentation) via a tier-upgrade registration with opt-in proof; review timeline per the ETA page: see references/customer-go-to-production-guide.md (Path C), which discovers the exact registration type live. This is OPTIONAL — Basic is production-usable within its limits. Countries that additionally need your own identity are live data — see the registration-requirements-by-country guide.

  • Beyond OTP — conversational and rich messaging needs your own origination identity: start with references/hello-rcs-test-agent.md or references/customer-go-to-production-guide.md.

Security Considerations

  • Ephemeral credentials: Prefer IAM roles over long-lived access keys.

  • OTP codes in logs: CloudTrail and downstream logs contain OTP codes; encrypt with KMS CMK.

  • Rate limiting: Throttle both send requests and verification attempts at the application layer.

  • Event destination encryption: Use SSE/KMS on SNS topics, encrypt CloudWatch Logs, restrict subscriptions.

  • Input validation: Validate display name, phone (E.164), and country before mutating APIs.

Failure modes

Error / symptomCauseFix
AccessDeniedExceptionMissing IAM actions or expired sessionRe-auth; attach the IAM actions from Prerequisites step 3
Status stays PENDINGValidation in progressRe-poll every few seconds; escalate only after several minutes
Status REQUIRES_VERIFICATIONBrand/display name needs verification (third-party brand names need a letter of authorization ≤30 days old, via a Support case)Easiest for a demo: create a new configuration with a generic display name
Status REJECTEDAutomated review rejected the display name (profanity, URLs, impersonation)Read RejectionReason in describe output; recreate with a compliant name
ConflictException on sendConfiguration not ACTIVEWait for ACTIVE (step 2)
ValidationException on sendMissing/invalid template variable, malformed E.164, or destination country not enabledCheck required variables against step 3's definitions; re-verify phone format; re-run step 4
ResourceNotFoundExceptionWrong NC_ID or TEMPLATE_IDRe-list and re-save the IDs
ServiceQuotaExceededExceptionDaily limit (per-destination and account daily caps (check applicable limits via Service Quotas)) or spend limit hitWait for the daily reset; for spend, SetNotifyMessageSpendLimitOverride (account-level change — confirm with the user; Notify's override is separate from SMS)
Send succeeds but nothing arrivesCarrier filtering or wrong numberConfirm the number; retry once; check delivery events if a configuration set was attached
User replies STOP and worriesOn AWS-managed identities STOP is informational only for OTP — each new OTP request is an implicit opt-inNo action needed; explain the semantics

Cleanup (destructive — confirm with the user first)

aws pinpoint-sms-voice-v2 delete-notify-configuration \
  --notify-configuration-id <NC_ID> --region <REGION>

Requirements and compatibility

Works with: Claude Code, Claude apps, OpenAI Codex, GitHub Copilot, Cursor, Gemini CLI, Kiro, OpenCode, Goose, Amp, Roo Code, JetBrains Junie, Factory Droid, Devin (ex-Windsurf), Mistral Vibe, OpenHands, Letta

“Works with” means the tool reads the open Agent Skills format; a skill written for one tool may use features others lack.

Needs: Needs an MCP server

Security

What our scanner noticed· Low risk

  • Instructions that use the network

A static scan is not a guarantee. Skills are third-party content: review a skill before you let an agent use it.

Attribution and licence

Published by
AWS
Publisher
AWS (Official)
Source
aws/agent-toolkit-for-aws · skills/specialized-skills/customer-communications-skills/aws-sms-voice · commit 0a218f8
Licence
Apache License 2.0 (redistribution allowed)
  • LICENSE (added by AutoGineer from LICENSE)
  • NOTICE (added by AutoGineer from NOTICE)
  • ATTRIBUTION.md (written by AutoGineer)
Synced

AutoGineer is not affiliated with or endorsed by AWS.

Download ZIP

The ZIP holds the skill’s files, its licence files and an ATTRIBUTION.md. Download aws-sms-voice.zip