SMS Segment Counter
communication.sms_segments
Overview
Nothing here is sent and nothing is connected to: you hand us the text of a message and we hand back arithmetic, with no gateway, no carrier lookup and no phone number involved. We work out which alphabet your text needs, how many segments it occupies, and how many characters you have left in the last one, using the published GSM 03.38 tables — 160 characters in a single 7-bit segment and 153 in each segment once a message is split, or 70 and 67 when the text needs UCS-2. The surprises are the point. Nine characters cost two septets instead of one, so a 160-character message with a single curly brace in it needs two segments; and one emoji outside the basic multilingual plane eats two of your 70. We show you exactly which characters pushed you into UCS-2, so you can find the one that tripled the bill. We never return the split segments themselves: splitting belongs to whoever sends the message, and handing the pieces back would only be your own text in slices.
Segment arithmetic looks trivial and almost nobody gets it right by hand. Splitting a message costs you seven septets of every segment, not zero; nine ordinary-looking characters cost two septets each; and a single emoji collapses your budget from 160 characters to 70, of which it takes two. The result is a campaign that was priced at one segment and billed at three. We give you the same numbers your provider will, from the published tables, before you send anything.
Reliability
The same text always produces the same numbers — there is no clock, no randomness and nothing outside your request. Segments are packed left to right so that a two-unit character is never broken across a boundary, which is what a real transport does; with no two-unit character present that is exactly the familiar division, so 160, 161, 153 and 154 characters land where you expect. The characters that cost two septets are the caret, the four brackets and braces, the backslash, the tilde, the pipe, the euro sign and a form feed. Three things can stop the call rather than answer it. SMS_TEXT_TOO_LARGE means the text is longer than 65536 characters, which is far beyond any sendable message — measure the part you actually intend to send; SMS_ENCODING_UNSUPPORTED means encoding was something other than AUTO, GSM7 or UCS2, and we refuse rather than quietly fall back to AUTO — correct the value and retry; SMS_ENCODING_INCOMPATIBLE means you asked for GSM7 on text the GSM alphabet cannot carry, and the details say how many distinct characters and where the first one is — either switch to AUTO and accept UCS-2, or replace those characters yourself, since we will not substitute them for you. Going past maxSegments is never a failure: it comes back as exceedsMaxSegments so you can decide.
Context footprint
The answer is a dozen numbers plus at most 32 single characters, so it stays a fraction of a kilobyte no matter how long your message is. Your text is never echoed back and never written to a log. A successful call costs 1 execution credit.
When to use it
Before a message goes out, or live while somebody is writing one, whenever the segment count changes what you pay or what fits.
When you want the message sent or split for you, when you need a per-segment price, or when you are measuring anything other than SMS.
Scope
Non-goals
- Does not send a message, reach a gateway, or open any connection
- Does not return the split segments — counting is the whole job
- Does not look up a carrier, a route, a price or a phone number
- Does not rewrite your text to make it cheaper, and never substitutes a character to squeeze it into GSM-7
- Does not know what your provider charges per segment
Properties
Capabilities
Cost & billing
Flat rate per invocation
File handling
How we handle your data
What this means
This skill may receive sensitive content, but it does not target sensitive data and returns only a structured non-sensitive result.
Squillify guarantees
- Runs inside Squillify
- This skill runs inside Squillify.
- Payloads are not sent to an external service by this skill.
- Squillify does not permanently store submitted payloads.
- Telemetry records metadata only, not submitted content.
- Submitted payloads are not used for training.
- Submitted payloads are not reviewed by humans.
- This skill does not target sensitive data.
- The response does not contain submitted content.
Your responsibility
Squillify does not determine whether submitted content is sensitive. Your application is responsible for deciding what data it is allowed to submit. Your application is responsible for securing the response.
Input schema
| Field | Type | Required | Description |
|---|---|---|---|
| text | string | Yes | Exact message text to measure. |
| encoding | string | No | Encoding policy; omit it for AUTO. |
| forceConcatenation | boolean | No | Whether concatenation capacity is forced; omit it for false. |
| maxSegments | integer | No | Advisory segment ceiling; omit it for the transport maximum. |
Output schema
| Field | Type | Required | Description |
|---|---|---|---|
| encoding | string | Yes | Applied SMS encoding. |
| segments | integer | Yes | Bounded SMS count for segments. |
| charsUsed | integer | Yes | Bounded SMS count for charsUsed. |
| charsPerSegment | integer | Yes | Bounded SMS count for charsPerSegment. |
| charsRemaining | integer | Yes | Bounded SMS count for charsRemaining. |
| unitsTotal | integer | Yes | Bounded SMS count for unitsTotal. |
| extendedCharCount | integer | Yes | Bounded SMS count for extendedCharCount. |
| nonGsmCharacters | array | Yes | From 0 through the reporting cap distinct non-GSM characters. |
| concatenated | boolean | Yes | Whether concatenation overhead was applied. |
| exceedsMaxSegments | boolean | Yes | Whether the advisory segment ceiling was exceeded. |
| summary | object | Yes | Closed summary containing codePointCount, javaCharCount, and encodingSelectedBy properties. |
API contract
POST /v1/executecurl -sS -X POST "$BASE/v1/execute" -H "Authorization: Bearer $KEY" -H 'Content-Type: application/json' -d '{"skillKey":"communication.sms_segments","input":{"text":"Northwind: order 4417 ships today and arrives Thursday.","encoding":"AUTO"}}'import { Squillify } from "@squillify/sdk";
const sq = new Squillify({ apiKey: process.env.SQUILLIFY_API_KEY });
const { output } = await sq.execute("communication.sms_segments", {"text":"Northwind: order 4417 ships today and arrives Thursday. Track it at nwnd.co/t/4417, or reply STOP to opt out."});Errors
| Code | HTTP | Retryable | Description |
|---|---|---|---|
| VALIDATION_ERROR | 400 | No | The request payload failed schema validation. |
| UNAUTHORIZED | 401 | No | Missing or invalid API key. |
| SKILL_NOT_ACCESSIBLE | 403 | No | The API key is not granted access to this skill. |
| SKILL_NOT_AVAILABLE_FOR_PLAN | 403 | No | This skill is not included in your current plan. |
| PLAN_ELIGIBILITY_UNAVAILABLE | 503 | Yes | Plan eligibility could not be decided. Retry after backoff. |
| SKILL_NOT_FOUND | 404 | No | The requested skill or version does not exist. |
| TENANT_RATE_LIMITED | 429 | Yes | Request rate limit exceeded. Retry after backoff. |
| QUOTA_EXCEEDED | 429 | Yes | Plan quota exhausted. Retryable once the quota period resets. |
| EXECUTION_TIMEOUT | 504 | Yes | Execution exceeded the allowed time budget. |
| SMS_TEXT_TOO_LARGE | 429 | No | A size, quota, rate, or time limit was exceeded. |
| SMS_ENCODING_UNSUPPORTED | 400 | No | The skill does not support the requested variant. |
| SMS_ENCODING_INCOMPATIBLE | 412 | No | The input is valid but cannot be processed as-is. |
Other limits
| Limit | Value |
|---|---|
| Recommended inline bytes | 32 KiB |
Limitations
- Does not send a message, reach a gateway, or open any connection
- Does not return the split segments — counting is the whole job
- Does not look up a carrier, a route, a price or a phone number
- Does not rewrite your text to make it cheaper, and never substitutes a character to squeeze it into GSM-7
- Does not know what your provider charges per segment
- Actually sending the message, which needs a gateway we deliberately do not have
- Getting the segments' text back so you can send them yourself
- Pricing a message, since what a segment costs is between you and your provider
How to call
POST /v1/execute (requires authentication)
{
"skillKey": "communication.sms_segments",
"input": {
"text": "Northwind: order 4417 ships today and arrives Thursday. Track it at nwnd.co/t/4417, or reply STOP to opt out."
}
}Examples
A plain transactional alert that fits one GSM-7 segment
{
"text": "Northwind: order 4417 ships today and arrives Thursday. Track it at nwnd.co/t/4417, or reply STOP to opt out."
}{
"extendedCharCount": 0,
"encoding": "GSM7",
"summary": {
"javaCharCount": 109,
"codePointCount": 109,
"encodingSelectedBy": "AUTO_DETECTED"
},
"segments": 1,
"charsPerSegment": 160,
"exceedsMaxSegments": false,
"charsUsed": 109,
"concatenated": false,
"nonGsmCharacters": [],
"charsRemaining": 51,
"unitsTotal": 109
}A campaign with an accent and an emoji, which forces UCS-2
{
"maxSegments": 2,
"text": "Rentrée sale — 30% off everything until Sunday 🎉 Shop now at maisonclaire.example/sale and use code RENTREE30 at checkout."
}{
"extendedCharCount": 0,
"encoding": "UCS2",
"summary": {
"javaCharCount": 123,
"codePointCount": 122,
"encodingSelectedBy": "AUTO_DETECTED"
},
"segments": 2,
"charsPerSegment": 67,
"exceedsMaxSegments": false,
"charsUsed": 123,
"concatenated": true,
"nonGsmCharacters": [
{
"char": "—",
"codePoint": 8212,
"firstIndex": 13
},
{
"char": "🎉",
"codePoint": 127881,
"firstIndex": 47
}
],
"charsRemaining": 11,
"unitsTotal": 129
}Recommended use cases
- Show a live segment count and remaining characters while somebody composes a message
- Catch the one emoji or curly brace that turned a one-segment alert into three
- Budget a campaign before you send it, by pricing the segment count per recipient
- Decide whether a template still fits one segment after you add an opt-out line
Avoid for
- Actually sending the message, which needs a gateway we deliberately do not have
- Getting the segments' text back so you can send them yourself
- Pricing a message, since what a segment costs is between you and your provider
Related skills
Composable with
Safety & privacy
- Runs without calling any external service.
- Your payloads are never stored permanently.
- Telemetry captures metadata only — never your payload contents.
- We never train models on your payloads.
- No human reviews your payloads.