V1
API v1•Templates

Templates

In API v1, all outbound SMS messages are validated against an approved SMS Template. Templates protect sender reputation, guarantee fast carrier delivery, and automatically determine priority routing and token pricing.

How Templates Work

A template consists of a unique slug (lowercase alphanumeric, dashes, or underscores), a rawText body containing {placeholder} variables, and a paramRules JSON object that strictly defines the format of each placeholder.

Scopes: Organization vs Public

  • ORGANIZATION (Default): Private to your organization. Can optionally be restricted to a single application via appId.
  • PUBLIC: Shared across all organizations on Emess once approved. If your organization defines a template with the same slug as a public template, your ORGANIZATION template takes precedence unless you explicitly pass scope: "PUBLIC" when sending.
Automated Caller Attribution: All public templates automatically prefix messages with [{app_name}] for clear brand attribution and phishing mitigation. The gateway automatically injects your application's registered name into {app_name} at runtime. You do not need to provide app_name in your request params (supplying it directly will be rejected to prevent caller spoofing).

Placeholders & Parameter Rules

Every placeholder extracted from rawText (matching /{([a-zA-Z0-9_]+)}/) must have a corresponding rule entry in paramRules.

Supported Rule Types

TypeRequired Rule PropertiesValidation Behavior
digitsEither exact length (int > 0) OR both min and max (integers)Digits only (0-9). Ideal for OTPs and PIN codes (e.g. { "type": "digits", "length": 6 }).
numberBoth min and max (numeric value bounds)Integer or decimal numbers within [min, max]. Ideal for currency amounts or quantities.
alphanumericBoth min and max (character length bounds)Letters and numbers only (a-zA-Z0-9) with length between min and max. Ideal for order/reference IDs.
stringmax (positive integer, max 64)Any non-empty text up to max characters (cannot exceed 64 characters).

Review Lifecycle & Pricing

  1. Submission (PENDING): When you create a template via the dashboard or POST /api/v1/templates, its initial status is PENDING. While unapproved (PENDING or REJECTED), re-POSTing to the same slug updates the existing template and resets it to PENDING.
  2. Approval (APPROVED): Upon approval, Emess compiles a validation regex, locks the template from direct edits (returning 409 Conflict if you try to overwrite an approved slug), and assigns its priorityTier (CRITICAL, STANDARD, or BULK) and tokenMultiplier (defaults: 4x for CRITICAL, 2x for STANDARD, 1x for BULK).
  3. Token Calculation: Each message sent using the template deducts Math.ceil(segments × tokenMultiplier) tokens.

POST/api/v1/templates

Create a new SMS template. For backward compatibility, POST /api/v1/templates also acts as a legacy upsert if an unapproved (PENDING or REJECTED) template with the same slug already exists (prefer PATCH /api/v1/templates/:slug for partial edits). Calling POST or PATCH on an APPROVED slug returns 409 Conflict.

Parameters (Body)

NameTypeRequiredDescription
namestringYesHuman-readable template name
slugstringYesUnique identifier (lowercase alphanumeric, dashes, underscores: ^[a-z0-9_-]+$)
rawTextstringYesTemplate body with {placeholder} variables
paramRulesobjectWhen placeholders existValidation rule definition for each placeholder
scopeenumNo (ORGANIZATION)ORGANIZATION or PUBLIC
priorityTierenumNoRequested tier: CRITICAL, STANDARD, or BULK
appIdstringNoOptional App ID to restrict this template to a specific app
tagsstring[]NoArray of category tags (e.g. ["security", "otp"]), max 16 characters each

Example Request

POST /api/v1/templates
{
"name": "Payment Confirmation",
"slug": "payment_receipt",
"scope": "ORGANIZATION",
"priorityTier": "STANDARD",
"rawText": "Hello {customer_name}, your payment of {amount} USD (Ref: {ref_id}) is confirmed. Code: {pin}",
"paramRules": {
"customer_name": { "type": "string", "max": 24 },
"amount": { "type": "number", "min": 1, "max": 10000 },
"ref_id": { "type": "alphanumeric", "min": 6, "max": 12 },
"pin": { "type": "digits", "length": 4 }
}
}

PATCH/api/v1/templates/:slug

Partially update an unapproved (PENDING or REJECTED) organization template. All body fields (name, rawText, paramRules, appId, priorityTier) are optional. The merged rawText and paramRules are re-validated, the status is reset to PENDING, and any previous rejectionReason / rejectionNotes are cleared.

  • 403 Forbidden: PUBLIC templates cannot be edited via this endpoint.
  • 409 Conflict: APPROVED templates are locked and cannot be modified directly.
  • 422 Unprocessable Entity: Merged placeholders and paramRules failed validation.
PATCH /api/v1/templates/payment_receipt
// PATCH /api/v1/templates/payment_receipt
{
"rawText": "Hello {customer_name}, payment of {amount} USD confirmed.",
"priorityTier": "CRITICAL"
}

GET/api/v1/templates

List all templates belonging to your organization as well as all APPROVED public templates.

Tag Filtering

Filter templates by category using the tag or tags query parameter. You can specify a single tag or comma-separated tags (each tag max 16 characters).

  • GET /api/v1/templates?tag=otp — Returns templates tagged with otp.
  • GET /api/v1/templates?tags=security,authentication — Returns templates matching either category.

Common categories include: authentication, security, billing, transactional, logistics, reminder, reservation, and account.

GET/api/v1/templates/:slug

Fetch a single template by its slug. Pass query parameter ?scope=public (or ?public=true) to inspect a public template instead of your organization's template.

DELETE/api/v1/templates/:slug

Delete a template owned by your organization by its slug.