TextPreflight API v1 · Beta

Developer documentation

Preflight SMS before it becomes an invoice.

TextPreflight is a provider-neutral JSON API for GSM-7/UCS-2 detection, exact segment counting, batch analysis, safe typography optimization, template simulation and campaign forecasting.

Protected APIThe website playground uses a separately rate-limited demo. Paid endpoints require the license key issued with a TextPreflight Launch subscription.

Quick start

curl -X POST https://textpreflight.kadircoteli.workers.dev/api/v1/sms/analyze \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer TPF-YOUR-LICENSE-KEY" \
  -d '{"text":"Your order is ready.","recipients":1000,"unitPrice":0.0075}'

Every successful API response wraps its result in data and includes a versioned meta object. Errors use a stable error.code.

Authentication

Send the TextPreflight license key as Authorization: Bearer TPF-…. The X-API-Key header is also accepted for clients that cannot set a Bearer token. TextPreflight validates that the key is active and belongs to the Launch benefit.

Keep the license key private. Never place it in browser code, public repositories or support screenshots. Rotate an exposed key from the customer portal.
POST

/api/v1/sms/analyze

Analyze encoding, units, segment boundaries, non-GSM characters, Unicode risks and optional estimated cost.

Request

textstring · required

Message text, up to 10,000 UTF-16 code units.

profilestring

standard or tollfree-us-ca.

recipientsinteger

Recipient count, 1 to 100,000,000. Defaults to 1.

unitPricenumber

Your provider's price per billable segment.

Example response

{
  "data": {
    "encoding": "GSM-7",
    "length": { "codePoints": 20, "utf16CodeUnits": 20, "encodingUnits": 20 },
    "segments": { "count": 1, "remainingInFinalPart": 140, "billable": 1000 },
    "characters": { "nonGsmCount": 0, "extendedCount": 0 },
    "unicode": { "riskLevel": "none", "findingCount": 0 },
    "estimatedCost": { "currency": "USD", "total": 7.5 }
  }
}
POST

/api/v1/sms/analyze-batch

Analyze up to 50 independent messages in one network round trip. A stable optional id is returned with each item so results can be matched without relying only on position.

Top-level options act as defaults. Each message may override profile, recipients, unitPrice and currency.

{
  "profile": "standard",
  "unitPrice": 0.0075,
  "currency": "USD",
  "messages": [
    { "id": "welcome", "text": "Welcome, Ada.", "recipients": 1000 },
    { "id": "alert", "text": "Status ✅", "recipients": 250 }
  ]
}

The response contains a full analysis under each result's data and a summary with encoding counts, total billable segments and currency-grouped estimated costs.

POST

/api/v1/sms/optimize

Apply a conservative, inspectable set of typography replacements. It does not paraphrase or rewrite message meaning.

textstring · required

Message to inspect and optimize.

removeInvisibleboolean

Explicitly remove selected controls and invisible characters. Defaults to false; ZWJ and ZWNJ are never removed.

{
  "text": "Your delivery is “ready” — collect now.",
  "recipients": 10000,
  "unitPrice": 0.0075,
  "removeInvisible": false
}
POST

/api/v1/template/simulate

Render every supplied {{variable}} combination, capped at 250 cases, and report the min/average/max segment outcomes.

Try the constrained, license-free version in the template lab. Production access supports up to 50 samples per variable and 250 rendered cases.

{
  "template": "Hi {{name}}, your code is {{code}}.",
  "variables": {
    "name": ["Ada", "Aleksandra", "Zoë"],
    "code": [1234, 987654]
  },
  "recipients": 5000,
  "unitPrice": 0.0075
}
POST

/api/v1/campaign/estimate

Aggregate up to 500 message variants and their recipient counts into a billable-segment forecast.

{
  "messages": [
    { "text": "Delivery today.", "recipients": 8500 },
    { "text": "Delivery tomorrow.", "recipients": 1500 }
  ],
  "unitPrice": 0.0075,
  "currency": "USD"
}

Errors & limits

400invalid_jsonMalformed JSON body
401license_key_requiredLicense key missing or invalid
403license_not_entitledLicense inactive or for another benefit
405method_not_allowedUnsupported HTTP method
413payload_too_largeBody exceeds 64 KB
415unsupported_media_typeExpected application/json
422validation_errorInvalid or missing input
429rate_limitedBurst or monthly quota exceeded
503license_service_unavailableLicense or usage service temporarily unavailable

The demo is limited to 20 requests per minute per client. Launch access has a 300 requests/minute limit per validated license and a separate coarse abuse guard. The monthly allowance is 25,000 analysis units per UTC calendar month.

One analysis unit is one message evaluated: a single analyze or optimize call uses one unit; batch calls use the number of messages; template simulations use the number of rendered cases; campaign estimates use the number of message variants. Rejected requests never partially consume units. Successful paid responses include X-Analysis-Units-Limit, X-Analysis-Units-Remaining and X-Analysis-Units-Reset. Legacy X-RateLimit-* quota headers remain available. GET /api/v1/usage reads usage without consuming units.

Provider profiles

standardGSM 160 / 153UCS-2 70 / 67
tollfree-us-caGSM 160 / 152UCS-2 70 / 66

Actual billing may vary by provider, route, country and message technology. Supply the relevant profile and validate your provider's current rules.

Data handling

Message bodies are processed in Worker memory and are not written to application storage or logs. Operational errors record the endpoint, method, status, error code and request ID—not request payloads. Pseudonymous usage counters are deleted after 13 months. See the privacy notice.

Provider-neutral by design. TextPreflight is an independent product and is not affiliated with or endorsed by messaging providers.