---
title: "Send a policy-gated outbound SMS"
method: POST
path: "/v1/messages"
---

# Send a policy-gated outbound SMS

`POST /v1/messages`

## Request

- Base URL: `https://api.skysay.ai`
- URL: `https://api.skysay.ai/v1/messages`
- Auth: none declared

Requires sms:send. Message body, provider metadata, error detail and idempotency key are returned only with sms:read, for both fresh sends and idempotent replays.

## Request body

- SmsMessage: recipient_type is optional and never enforced; there is no recipient_type column on the SMS row, so it is accepted but not persisted. Blocked categories mirror carrier acceptable-use policy; debt collection is not a blocked category -- payment_reminder (first-party or third-party) is permitted with per-call authorization, subject to per-customer onboarding approval and the acceptable-use policy.
  - `body` string, required
  - `categories` string[]
  - `from_phone_number_id` string, required
  - `organization_id` string, required
  - `project_id` string, required
  - `purpose` string, required: Required, free-form outbound purpose declaration -- a non-empty purpose is the compliance paper trail; a novel purpose token is never refused for being novel. Documented catalog (pick one or send your own token): appointment, booking_confirmation, callback_requested, customer_outreach, delivery_notification, ops_alert, other, payment_reminder, personal_errand, reservation, status_check, support.
  - `recipient_type` string: Optional, never enforced or required -- outbound is not restricted to business recipients. Persisted verbatim on the call row if sent; SMS has no recipient_type column, so it is accepted but not stored there.
  - `to_phone_number` string, required
  - `user_authorization` object

## Response `201`

Message

---

[API](https://skmtc.dev/skysay/apis/skysay-api.md) · [All operations](https://skmtc.dev/skysay/apis/skysay-api/llms.txt) · [OpenAPI document](https://skmtc.dev/skysay/apis/skysay-api/revisions/95b8c66f99aa?raw)
