Create a messaging program

Create a messaging program

POST/api/v1/sms/messaging-programs

POST /sms/messaging-programs
curl -X POST 'https://www.unitpost.com/api/v1/sms/messaging-programs' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'User-Agent: my-app/1.0' \
  -H 'Content-Type: application/json' \
  -d '{ }'
Response · 201
{
  "name": "Example",
  "description": "string",
  "message_type": "transactional",
  "canonical_purpose": "string",
  "frequency_disclosure": "string",
  "opt_in_type": "string",
  "opt_in_workflow": "string",
  "opt_in_confirmation": "string",
  "help_message": "string",
  "stop_message": "string",
  "terms_url": "https://example.com",
  "privacy_url": "https://example.com",
  "monthly_volume": "string",
  "sample_messages": [
    "string"
  ],
  "embedded_links": false,
  "embedded_link_sample": "string",
  "embedded_phones": false,
  "age_gated": false,
  "provider_overrides": {
    "toll_free": {
      "use_case_category": "string"
    },
    "ten_dlc": {
      "use_case": "string",
      "sub_use_cases": [
        "string"
      ]
    }
  },
  "recipe_id": "recipe_123",
  "consent_setup_id": "consent_setup_123",
  "object": "sms_messaging_program",
  "id": "id_123",
  "recipe_version": 0,
  "revision": 0,
  "readiness": {
    "ready": false,
    "missing": [
      "string"
    ]
  },
  "archived_at": "2026-01-01T00:00:00.000Z",
  "created_at": "2026-01-01T00:00:00.000Z",
  "updated_at": "2026-01-01T00:00:00.000Z"
}

Create a program (name required). Each field is checked by the carriers' rules (the dashboard's own): lengths, help and stop replies that are a sentence and not just a keyword, links to a real web address (no localhost, bare IP or other scheme). Pass an Idempotency-Key so a retry never makes a second one. Requires the sms:manage capability.

Parameters1 field
FieldTypeDescription
Idempotency-Keystring · headerAny unique string (1–256 characters, e.g. a UUID). Retrying with the same key and the same body within 24 hours returns the first result instead of sending again; the same key with a different body is `409 invalid_idempotent_request`, and one still in flight is `409 concurrent_idempotent_requests`.
Request body21 fields
FieldTypeDescription
namerequiredstring—
descriptionstring | null—
message_typeenumtransactional | marketing—
canonical_purposestring | null—
frequency_disclosurestring | null—
opt_in_typestring | null—
opt_in_workflowstring | null—
opt_in_confirmationstring | null—
help_messagestring | null—
stop_messagestring | null—
terms_urlstring | null—
privacy_urlstring | null—
monthly_volumestring | null—
sample_messagesstring[]—
embedded_linksboolean—
embedded_link_samplestring | null—
embedded_phonesboolean—
age_gatedboolean—
provider_overridesobject | null—
recipe_idenumACCOUNT_NOTIFICATIONS | SECURITY_ALERTS | ONE_TIME_PASSCODES | ORDER_UPDATES | APPOINTMENT_REMINDERS | CUSTOMER_SUPPORT | MARKETING_PROMOTIONS | OTHER_CUSTOMThe compliance recipe the program follows; its version is the recipe's current one. Left out, it's derived from `canonical_purpose`.
consent_setup_idstring | nullA consent setup (`cset_…`) this workspace has.
Response · 201 fields29 fields
FieldTypeDescription
namerequiredstring—
descriptionstring | null—
message_typerequiredenumtransactional | marketing—
canonical_purposestring | null—
frequency_disclosurestring | null—
opt_in_typestring | null—
opt_in_workflowstring | null—
opt_in_confirmationstring | null—
help_messagestring | null—
stop_messagestring | null—
terms_urlstring | null—
privacy_urlstring | null—
monthly_volumestring | null—
sample_messagesrequiredstring[]—
embedded_linksrequiredboolean—
embedded_link_samplestring | null—
embedded_phonesrequiredboolean—
age_gatedrequiredboolean—
provider_overridesobject | null—
recipe_idrequiredstring | null—
consent_setup_idstring | nullA consent setup (`cset_…`) this workspace has.
objectrequiredstring—
idrequiredstring—
recipe_versionrequiredinteger | null—
revisionrequiredintegerMoves on a material change; registrations keep the revision they copied.
readinessrequiredobjectWhether the program has what a registration needs; `missing` names the fields still to fill (the wizard's own check).
archived_atrequiredstring | null—
created_atrequiredstring—
updated_atrequiredstring—
201400401403404409422

Search docs and guides

Search the docs and product guides.