{"id":864,"date":"2026-10-09T21:22:31","date_gmt":"2026-10-09T21:22:31","guid":{"rendered":"https:\/\/text.email\/blog\/?p=864"},"modified":"2026-10-12T06:28:29","modified_gmt":"2026-10-12T06:28:29","slug":"api","status":"publish","type":"post","link":"https:\/\/text.email\/blog\/api\/","title":{"rendered":"Using the text.email API to Send Texts From Your Apps"},"content":{"rendered":"\n<p>The premise of text.email has always been: sending a text should be as easy as sending an email. And that&#8217;s great when you&#8217;re dropping your email-to-text address into a service dashboard that already sends email notifications.<\/p>\n\n\n\n<p>But when you&#8217;re building an app, writing a script, or setting up an automated workflow, sending an email just to generate a text adds an extra step.<\/p>\n\n\n\n<p><strong>We built the text.email API so your software can now send messages directly<\/strong>. Your program supplies a phone number and a message, and text.email handles sending it as SMS, MMS, or iMessage.<\/p>\n\n\n\n<p>Here&#8217;s everything you need to know about when to use it and how to set it up.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">text.email API: Table of Contents<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"#when-to-use\">When to Use Email-to-SMS vs. the API<\/a><\/li>\n\n\n\n<li><a href=\"#how-to-use\">How to Use the text.email API<\/a><\/li>\n\n\n\n<li><a href=\"#ready-to-try\">Ready to Try the text.email API?<\/a><\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"when-to-use\">When to Use Email-to-SMS vs. the API<\/h2>\n\n\n\n<p>The quick version:<\/p>\n\n\n\n<p><strong>Use email-to-text when<\/strong> it fits into your existing workflow. (For example: You have a SCADA controller with an email alert field, and you want a quick way to get text alerts.)<\/p>\n\n\n\n<p><strong>Use the API-to-text when<\/strong> you want texting built directly into your software. (For example: to send an appointment reminder when your scheduling system triggers it, notify yourself when a script finishes, or alert a customer when an order is ready).<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">What you can do with the API<\/h3>\n\n\n\n<p>You can send SMS, MMS, or iMessage. (SMS is the default.)<\/p>\n\n\n\n<p>You can send those with a browser URL, JSON request, or form post.<\/p>\n\n\n\n<p>There&#8217;s no need to configure an outgoing mail server or go through the email step; you can get started with a single URL.<\/p>\n\n\n\n<p>The API also gives your software a structured response on which to act. That way, your software can tell whether a request was accepted or rejected, handle errors, and retry without accidentally sending the same message twice.<\/p>\n\n\n\n<p>You can include one image (JPEG, PNG, or GIF) with an MMS message.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">What you can&#8217;t do (yet) with the API that you can do with email-to-text<\/h3>\n\n\n\n<p>You can&#8217;t use <a href=\"https:\/\/text.email\/blog\/distribution-lists\/\" data-type=\"post\" data-id=\"296\">distribution lists<\/a> or <a href=\"https:\/\/text.email\/blog\/scheduled-sms-routing\/\" data-type=\"post\" data-id=\"632\">on-call schedules<\/a> with the API.<\/p>\n\n\n\n<p>You can&#8217;t send multiple media files as <a href=\"https:\/\/text.email\/blog\/email-attachments-in-text-messages\/\" data-type=\"post\" data-id=\"609\">attachments<\/a> with the API; you can send one image as a part of an <a href=\"https:\/\/text.email\/blog\/email-to-mms\/\" data-type=\"post\" data-id=\"718\">MMS message<\/a>. (Also, with the API, SMS and iMessage are text-only.)<\/p>\n\n\n\n<p>And, of course, you can&#8217;t just drop in an address somewhere to get quick email-to-text messages.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"how-to-use\">How to Use the text.email API<\/h2>\n\n\n\n<p>Let get you started sending messages with the text.email API.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Get your text.email API key<\/h3>\n\n\n\n<p>You can get your <a href=\"https:\/\/text.email\/Manage\/Settings#api-keys\">API key<\/a> in the text.email settings. API access is currently included with all plans.<\/p>\n\n\n\n<figure data-wp-context=\"{&quot;imageId&quot;:&quot;6accaf19e03ee&quot;}\" data-wp-interactive=\"core\/image\" data-wp-key=\"6accaf19e03ee\" class=\"wp-block-image size-large wp-lightbox-container\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"495\" data-wp-class--hide=\"state.isContentHidden\" data-wp-class--show=\"state.isContentVisible\" data-wp-init=\"callbacks.setButtonStyles\" data-wp-on--click=\"actions.showLightbox\" data-wp-on--load=\"callbacks.setButtonStyles\" data-wp-on-window--resize=\"callbacks.setButtonStyles\" src=\"https:\/\/text.email\/blog\/wp-content\/uploads\/2026\/10\/api-create-tinified-1024x495.png\" alt=\"\" class=\"wp-image-875\" srcset=\"https:\/\/text.email\/blog\/wp-content\/uploads\/2026\/10\/api-create-tinified-1024x495.png 1024w, https:\/\/text.email\/blog\/wp-content\/uploads\/2026\/10\/api-create-tinified-300x145.png 300w, https:\/\/text.email\/blog\/wp-content\/uploads\/2026\/10\/api-create-tinified-768x371.png 768w, https:\/\/text.email\/blog\/wp-content\/uploads\/2026\/10\/api-create-tinified-1536x742.png 1536w, https:\/\/text.email\/blog\/wp-content\/uploads\/2026\/10\/api-create-tinified.png 1986w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><button\n\t\t\tclass=\"lightbox-trigger\"\n\t\t\ttype=\"button\"\n\t\t\taria-haspopup=\"dialog\"\n\t\t\taria-label=\"Enlarge\"\n\t\t\tdata-wp-init=\"callbacks.initTriggerButton\"\n\t\t\tdata-wp-on--click=\"actions.showLightbox\"\n\t\t\tdata-wp-style--right=\"state.imageButtonRight\"\n\t\t\tdata-wp-style--top=\"state.imageButtonTop\"\n\t\t>\n\t\t\t<svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"12\" height=\"12\" fill=\"none\" viewBox=\"0 0 12 12\">\n\t\t\t\t<path fill=\"#fff\" d=\"M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z\" \/>\n\t\t\t<\/svg>\n\t\t<\/button><\/figure>\n\n\n\n<p>And this is the shape for your calls&#8230;<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">text.email API request fields<\/h3>\n\n\n\n<div class=\"wp-block-group is-vertical is-layout-flex wp-container-core-group-is-layout-8cf370e7 wp-block-group-is-layout-flex\">\n<div style=\"overflow-x:auto;\">\n  <table>\n    <thead>\n      <tr>\n        <th scope=\"col\">Field<\/th>\n        <th scope=\"col\">Meaning<\/th>\n      <\/tr>\n    <\/thead>\n    <tbody>\n      <tr>\n        <td><code>api_key<\/code><\/td>\n        <td>Your API key, when not using an authentication header. Supported in the query string, JSON or form. Omit all credentials for anonymous testing; an empty or invalid supplied key is an error.<\/td>\n      <\/tr>\n      <tr>\n        <td><code>to<\/code><\/td>\n        <td>Required phone number. Prefer international format such as +14155550123. SMS and MMS support U.S. and Canadian numbers. iMessage accepts international numbers that can receive iMessages.<\/td>\n      <\/tr>\n      <tr>\n        <td><code>text<\/code><\/td>\n        <td>Required message: up to 1,000 characters for SMS\/MMS or 16,000 for iMessage. Long SMS is split into segments within your account&#8217;s configured segment limit; an oversized request is rejected, never truncated.<\/td>\n      <\/tr>\n      <tr>\n        <td><code>type<\/code><\/td>\n        <td>Optional: <code>sms<\/code>, <code>mms<\/code>, or <code>imessage<\/code> (case insensitive). Defaults to <code>sms<\/code>. The API honors this choice even if your email settings prefer another channel.<\/td>\n      <\/tr>\n      <tr>\n        <td><code>from_email<\/code><\/td>\n        <td>Required for anonymous tests. Omit when using an API key.<\/td>\n      <\/tr>\n      <tr>\n        <td><code>idempotency_key<\/code><\/td>\n        <td>Optional retry identifier, supplied in the query string, JSON or form, or through the <code>Idempotency-Key<\/code> header.<\/td>\n      <\/tr>\n      <tr>\n        <td><code>media<\/code><\/td>\n        <td>Optional for MMS only. One object with <code>content_type<\/code> (image\/jpeg, image\/png, image\/gif) and <code>data_base64<\/code> (base64 file bytes, no data-URL prefix). Maximum decoded size: 600,000 bytes. Text-only MMS is supported.<\/td>\n      <\/tr>\n    <\/tbody>\n  <\/table>\n<\/div>\n<\/div>\n\n\n\n<h3 class=\"wp-block-heading\">Access via a URL (mainly for testing, since this exposes your API key)<\/h3>\n\n\n\n<p>Replace the phone number, key, and message in the URL below, then paste it into your browser. It sends the message and returns JSON.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>https:&#47;&#47;api.text.email\/v1\/messages?api_key=YOUR_API_KEY&amp;to=14155550123&amp;text=Remember%20the%20milk.&amp;idempotency_key=reminder-001<\/code><\/pre>\n\n\n\n<p>Add <code>&amp;type=mms<\/code> or <code><code>&amp;<\/code><\/code>t<code>ype=imessage<\/code> if you want one of those message types, otherwise the API will use the default of SMS.<\/p>\n\n\n\n<p>A U.S.\/Canadian number can be written as <code>14155550123<\/code> without a plus sign. If you do include the plus sign in a URL, write it as <code>%2B<\/code>. Most servers read a bare <code>+<\/code> in a URL as a space.<\/p>\n\n\n\n<p>Keep the same <code>idempotency_key<\/code> to refresh or retry without sending again. If you omit it, each visit or refresh can send another message. Browser login cookies aren&#8217;t used to authenticate sends.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Using the API in your application<\/h3>\n\n\n\n<p>There are <strong>three different forms<\/strong> this can take: key in the Authorization header, key in the JSON body, and form post. The examples below use curl.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">API key in the Authorization header<\/h4>\n\n\n\n<pre class=\"wp-block-code\"><code>curl https:\/\/api.text.email\/v1\/messages \\\n  -H \"Authorization: Bearer YOUR_API_KEY\" \\\n  -H \"Content-Type: application\/json\" \\\n  -H \"Idempotency-Key: reminder-2026-001\" \\\n  -d '{\"to\":\"+14155550123\",\"text\":\"Remember the milk.\"}'<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">API key in the JSON body<\/h4>\n\n\n\n<pre class=\"wp-block-code\"><code>curl https:\/\/api.text.email\/v1\/messages \\\n  -H \"Content-Type: application\/json\" \\\n  -d '{\"api_key\":\"YOUR_API_KEY\",\"to\":\"+14155550123\",\"text\":\"Remember the milk.\",\"idempotency_key\":\"reminder-002\"}'<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">Form post<\/h4>\n\n\n\n<pre class=\"wp-block-code\"><code>curl https:\/\/api.text.email\/v1\/messages \\\n  --data-urlencode \"api_key=YOUR_API_KEY\" \\\n  --data-urlencode \"to=+14155550123\" \\\n  --data-urlencode \"text=Remember the milk.\" \\\n  --data-urlencode \"idempotency_key=reminder-003\"<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">MMS and iMessage<\/h4>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p>The MMS and iMessage examples below are just the request body. Send them like the first example, with your Authorization header and <code>Content-Type: application\/json<\/code>.<\/p>\n\n\n\n<p><strong>MMS<\/strong><\/p>\n<\/blockquote>\n\n\n\n<pre class=\"wp-block-code\"><code>{\n  \"to\": \"+14155550123\",\n  \"type\": \"mms\",\n  \"text\": \"Your delivery is here.\",\n  \"media\": {\n    \"content_type\": \"image\/jpeg\",\n    \"data_base64\": \"BASE64_ENCODED_JPEG_BYTES\"\n  }\n}<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\"><strong>iMessage<\/strong><\/h4>\n\n\n\n<pre class=\"wp-block-code\"><code>{\"to\":\"+14155550123\",\"type\":\"imessage\",\"text\":\"Remember the milk.\"}<\/code><\/pre>\n\n\n\n<p>iMessages are queued for delivery by text.email&#8217;s Mac sender. They do not automatically fall back to SMS \u2014 meaning if your recipient doesn&#8217;t have an iPhone, they won&#8217;t get this message.<\/p>\n\n\n\n<p>Media attachments are only currently supported with MMS, not iMessage (or SMS).<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Other details on sending with the API<\/h4>\n\n\n\n<p>Both standard URL-encoded forms and multipart forms are supported. For multipart clients, use the same field names. MMS file bytes use the JSON <code>media<\/code> object from the MMS example above.<\/p>\n\n\n\n<p>As I noted earlier about the exposed API keys, URLs can appear in browser history, server logs, and chat\/social media previews. So use a header or request body when you need to keep credentials and message text out of URLs. (Which, frankly, is the standard best practice anyway.)<\/p>\n\n\n\n<p><code>GET<\/code> and <code>POST<\/code> use the same endpoint. You can mix locations, like an API key in a header, <code>to<\/code> in the query string and <code>text<\/code> in JSON.<\/p>\n\n\n\n<p>Any repeated fields across locations must match exactly; conflicting values return 400. Duplicate query or form parameters are rejected. JSON field names are case sensitive.<\/p>\n\n\n\n<p>API requests require HTTPS and have a maximum body size of 900,000 bytes. Use a JSON or form body (not a URL) for larger messages, and the JSON <code>media<\/code> object for MMS images. URLs are subject to browser and web-server length limits.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Responses and safe retries<\/h3>\n\n\n\n<p>HTTP\/1.1 202 Accepted<br>{&#8220;id&#8221;:&#8221;e4199a63-2f96-42a7-b895-e789ae891c9b&#8221;,&#8221;type&#8221;:&#8221;sms&#8221;,&#8221;status&#8221;:&#8221;accepted&#8221;,&#8221;units&#8221;:1}<br><br>Here&#8217;s what this response means.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Status<\/h4>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>accepted<\/code> means the SMS\/MMS provider accepted the submission; it does not confirm delivery. <\/li>\n\n\n\n<li><code>queued<\/code> means iMessage was added to the delivery queue.<\/li>\n\n\n\n<li><code>unknown<\/code> means a provider outcome was uncertain, or only part of the message was accepted.<\/li>\n\n\n\n<li><code>processing_or_unknown<\/code> means the request started but a final response has not been recorded. (Don\u2019t resend an uncertain message with a new key.)\u201d <\/li>\n<\/ul>\n\n\n\n<p>Use a different <code>idempotency_key<\/code> for each intended message and reuse it when you\u2019re retrying the same request.<\/p>\n\n\n\n<p>Idempotency keys are scoped to your account (or to your email and IP address for trial tests). So if your first attempt was a browser URL, you can retry with the <code>Idempotency-Key<\/code> header and get the stored result instead of a second text.<\/p>\n\n\n\n<p>Replays return the stored result without sending again, even when you&#8217;re changing from a browser URL to JSON or a form; changed message content with the same key returns 409.<\/p>\n\n\n\n<p>You should only omit this identifier if you want each request to be a new send. <\/p>\n\n\n\n<p>Also, account requests are limited to 60 per minute. Replaying an idempotency key doesn&#8217;t consume another send allowance. <\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Units<\/h4>\n\n\n\n<p>The <code>units<\/code> field counts SMS segments (154 GSM septets or 67 Unicode code units each), or one MMS\/iMessage submission.<\/p>\n\n\n\n<p>A note about your character count: API messages use the supplied text directly, so other things that you have text.email add to your email-to-text messages (for example: elements from your <a href=\"https:\/\/text.email\/blog\/sms-formatting\/\" data-type=\"post\" data-id=\"213\">email formatting templates<\/a> or <a href=\"https:\/\/text.email\/blog\/required-ack\/\" data-type=\"post\" data-id=\"733\">acknowledgement reminders<\/a>) are not applied.<\/p>\n\n\n\n<p>Accepted messages appear in your message history and count toward your usage. (Your account&#8217;s verification, trial, sending limits and screening rules still apply.)<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Errors<\/h3>\n\n\n\n<pre class=\"wp-block-code\"><code>{\"error\":{\"code\":\"invalid_api_key\",\"message\":\"The API key is invalid or revoked.\"}}<\/code><\/pre>\n\n\n\n<p>Here are some of the errors you might get:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>400: invalid fields<\/li>\n\n\n\n<li>401: invalid key<\/li>\n\n\n\n<li>403: account or screening restriction<\/li>\n\n\n\n<li>409: idempotency conflict<\/li>\n\n\n\n<li>413: request too large<\/li>\n\n\n\n<li>415: wrong content type<\/li>\n\n\n\n<li>429: request or sending limit<\/li>\n\n\n\n<li>503: temporarily unavailable<\/li>\n<\/ul>\n\n\n\n<p>If a request fails before sending, its error may be stored for that idempotency key. Correct the problem and use a new key only once the response confirms that no message was sent.<\/p>\n\n\n\n<p>More on the 429 error, since it&#8217;s one of the few up there that isn&#8217;t self-explanatory.<\/p>\n\n\n\n<p>A 429 response indicates a rate or test limit; some test limits require an account or upgrade rather than waiting.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"ready-to-try\">Ready to Try the text.email API?<\/h2>\n\n\n\n<p>text.email is great for email-to-SMS&#8230; but sometimes, you need app-to-SMS instead.<\/p>\n\n\n\n<p>With the text.email API, <strong>you can now skip the whole &#8220;email&#8221; part and easily send SMS, MMS, and iMessages directly from your tool or application<\/strong>.<\/p>\n\n\n\n<p>And&#8230; <strong>you don&#8217;t even need to sign up to see it in action<\/strong>.<\/p>\n\n\n\n<p>You can send a trial test right now (and up to 10 total tests) without a text.email account.<\/p>\n\n\n\n<p>Use your own phone number and email address with these&#8230;<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>https:&#47;&#47;api.text.email\/v1\/messages?from_email=youremail%40yourdomain.com&amp;to=14155550123&amp;text=My%20first%20API%20text.&amp;idempotency_key=first-browser-test<\/code><\/pre>\n\n\n\n<pre class=\"wp-block-code\"><code>curl https:\/\/api.text.email\/v1\/messages \\\n  -H \"Content-Type: application\/json\" \\\n  -H \"Idempotency-Key: my-first-api-test\" \\\n  -d '{\"from_email\":\"youremail@yourdomain.com\",\"to\":\"+14155550123\",\"text\":\"My first API text.\"}'<\/code><\/pre>\n\n\n\n<p><em>Notes: These trial messages are logged as public tests, just like trial email-to-text messages, so don&#8217;t include private information. Supplying an account&#8217;s email address does not authenticate you or use that account&#8217;s paid allowance. An invalid or revoked API key returns an error.<\/em><\/p>\n\n\n\n<p>After you&#8217;ve given it a try, you can sign up for <a href=\"https:\/\/text.email\">text.email<\/a> \u2014 it takes less than a minute \u2014 and you&#8217;ll have full access to email-to-SMS <em>and<\/em> the text.email API for sending your critical messages.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>How to send messages from your app using the text.email API.<\/p>\n","protected":false},"author":1,"featured_media":867,"comment_status":"closed","ping_status":"","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[8],"tags":[],"class_list":["post-864","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-text-email-tips"],"_links":{"self":[{"href":"https:\/\/text.email\/blog\/wp-json\/wp\/v2\/posts\/864","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/text.email\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/text.email\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/text.email\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/text.email\/blog\/wp-json\/wp\/v2\/comments?post=864"}],"version-history":[{"count":12,"href":"https:\/\/text.email\/blog\/wp-json\/wp\/v2\/posts\/864\/revisions"}],"predecessor-version":[{"id":879,"href":"https:\/\/text.email\/blog\/wp-json\/wp\/v2\/posts\/864\/revisions\/879"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/text.email\/blog\/wp-json\/wp\/v2\/media\/867"}],"wp:attachment":[{"href":"https:\/\/text.email\/blog\/wp-json\/wp\/v2\/media?parent=864"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/text.email\/blog\/wp-json\/wp\/v2\/categories?post=864"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/text.email\/blog\/wp-json\/wp\/v2\/tags?post=864"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}