API Documentation

Send messages programmatically via REST API. Integrate with Make, Zapier, Claude, GPT, or your own code. No local server required. The API is fully cloud-hosted.

On this page

How it works

Text Your List's API is cloud-hosted. You send a request to https://textyourlist.com/api/make/send from anywhere, Make, Zapier, a Python script, an AI agent, and the message is delivered through your desktop app to your phone.

No tunnel or local server needed. Your desktop app connects out to the cloud, polls for queued messages, and sends them. As long as the app is open, messages go through automatically.

The flow is:

  1. Your automation or code calls POST /api/make/send with your API key.
  2. The server creates a queued job and assigns it to your desktop app.
  3. Your open desktop app picks up the message within seconds and sends it via Messages (Mac) or Phone Link (Windows).
  4. Send history and counters update in real time.
Pro plan required for API sends. Free and Starter plans cannot use the send endpoint. Upgrade here.

Authentication

All API endpoints require a Bearer token in the Authorization header.

Get your API key

API access requires a Pro plan. Free and Starter accounts cannot create API keys or use the send endpoint.
  1. Open the Text Your List desktop app.
  2. Go to Developer in the left sidebar.
  3. Under API Keys, enter a name (e.g. "Make integration") and click Create.
  4. Copy the key immediately. It is shown only once. It is stored on our server and works even when your app is closed.

To revoke a key, return to Developer → API Keys → Revoke. Any Make/Zapier scenario using the revoked key will stop working immediately.

Store your key securely. Anyone with your key can send messages from your account.

Pass the key in every request

Authorization: Bearer tbk_your_api_key_here
Content-Type: application/json

Send one message to one person Pro

POST https://textyourlist.com/api/make/send

Send a single text to one phone number: a follow-up, a reminder, a quick reply triggered by something in another app. The message goes out through your desktop app from your own number.

Request body

FieldTypeRequiredDescription
phonestringRequiredRecipient phone number. US format: +12125550100 or 2125550100.
messagestringRequiredMessage text. Max 1,600 characters.
image_urlstringOptionalPublic URL of an image to attach as MMS. Must start with https:// or http://. Supported formats: JPEG, PNG, GIF, HEIC. The desktop app downloads the image at send time and attaches it, your URL just needs to stay publicly accessible until the message is processed.

Example: text only

curl -X POST https://textyourlist.com/api/make/send \
  -H "Authorization: Bearer tbk_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "phone": "+12125550100",
    "message": "Hey! Just wanted to follow up on your quote."
  }'

Example: with image (MMS)

curl -X POST https://textyourlist.com/api/make/send \
  -H "Authorization: Bearer tbk_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "phone": "+12125550100",
    "message": "Here is your custom proposal.",
    "image_url": "https://s3.amazonaws.com/your-bucket/proposal.jpg"
  }'

The image URL can point to S3, Airtable attachments, Dropbox direct links, or any publicly accessible file. The desktop app handles the download. Nothing is uploaded to or stored on Text Your List servers.

Response 201

{
  "job_id": "3f2d...",
  "message_id": "9a1c...",
  "status": "queued",
  "preview": "Here is your custom proposal."
}

The status field tells you what happened:

  • queued: desktop is open, message will send shortly.
  • api_pending: desktop is closed or set to "Hold for review". Message waits until you open the app and choose to send.

Send to a whole contact list Pro

Use this when you want to kick off a full campaign and send a message to everyone on one of your saved contact lists, personalized for each person.

Desktop app must be open. Unlike the single-send endpoint, list sends run through your local desktop app and require it to be open on your Mac or Windows machine.
POST https://textyourlist.com/api/make/send-to-list

Request body

FieldRequiredDescription
list_nameRequired*The name of a saved contact list in your app (not case-sensitive). Use list_id instead if you prefer the ID.
list_idOptionalID of the contact list. Either list_name or list_id is required.
templateRequired*The message text to send. Use {first_name}, {last_name}, or any column name from your list in curly braces to personalize each message (e.g. Hey {first_name}, just checking in!).
template_nameOptionalUse a saved template from your app by name instead of typing inline.
template_idOptionalUse a saved template by ID.
campaign_nameOptionalA label for this send in your History tab. Defaults to "API: [list name]".
pace_secondsOptionalSend speed: 0 = as fast as possible, 7 = smart throttle (7–14s random delay, recommended), -1 = hold for your review. Defaults to your account setting.

Example: send to a saved list using a saved template

curl -X POST https://textyourlist.com/api/make/send-to-list \
  -H "Authorization: Bearer tbk_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "list_name": "April Leads",
    "template_name": "Follow Up",
    "pace_seconds": 7
  }'

Example: send with an inline personalized message

curl -X POST https://textyourlist.com/api/make/send-to-list \
  -H "Authorization: Bearer tbk_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "list_name": "April Leads",
    "template": "Hey {first_name}, just following up, let me know if you have questions!",
    "campaign_name": "April Follow-Up",
    "pace_seconds": 7
  }'

Response 201

{
  "job_id": "abc123-...",
  "campaign_name": "April Follow-Up",
  "list": "April Leads",
  "status": "queued",
  "queued": 147,
  "skipped_suppressed": 3,
  "skipped_invalid": 1,
  "skipped_duplicate": 0,
  "note": "Job is queued and will send when the desktop app is open."
}

status is queued (sending now) or api_pending (held for your review). Numbers on your suppression list, duplicate numbers, and invalid phone numbers are automatically skipped and counted in the response.

Look up your lists and templates

Not sure of the exact name of a list or template? These endpoints let any tool (including an AI agent) look them up before sending.

GET https://textyourlist.com/api/make/lists

Returns all your saved contact lists: name, ID, contact count, and date created.

curl https://textyourlist.com/api/make/lists \
  -H "Authorization: Bearer tbk_your_api_key"
[
  { "id": 12, "name": "April Leads", "row_count": 150, "created_at": "2026-04-01T..." },
  { "id": 11, "name": "VIP Clients", "row_count": 42, "created_at": "2026-03-15T..." }
]
GET https://textyourlist.com/api/make/templates

Returns all your saved message templates: name, ID, and a short preview of the content.

curl https://textyourlist.com/api/make/templates \
  -H "Authorization: Bearer tbk_your_api_key"
[
  { "id": 5, "name": "Follow Up", "preview": "Hey {first_name}, just following up..." },
  { "id": 4, "name": "Event Reminder", "preview": "Don't forget, the event is tomorrow..." }
]

Desktop behavior & send speed

How fast messages go out, and whether they need your approval first, is controlled by the API send behavior setting in your Account settings. You can also override this per-request using the pace_seconds field.

Fast

Sends immediately when the desktop app is open. Messages are only sent while you have the app open. Nothing goes out without the app running.

Smart throttle (default)

7 – 14 second randomized delay between sends when the app is open. Reduces carrier filtering risk on high-volume sends.

Hold for review

All API messages are always held as pending regardless of whether the app is open. When you open the app, you will be prompted to send now, keep holding, or cancel. Nothing goes out until you explicitly approve it.

App closed in any mode: API messages are held and visible in your dashboard under "Waiting for approval." You can release them at any time from the dashboard, or the app will prompt you when you next open it.

You can configure this setting in the desktop app: Account → Api send behavior.

Mac vs Windows preference

If you have both Mac and Windows desktops with Text Your List installed, you can control which one handles API sends.

SettingBehavior
Mac (default)Only your Mac desktop picks up and sends API messages via Messages.app.
WindowsOnly your Windows desktop picks up and sends via Phone Link.
AnyWhichever desktop polls first picks up the message (first-come-first-served).

Set your preference in Account → Api send behavior → Send platform.

Windows note: API sends on Windows go through Phone Link, the same as manual sends. Phone Link must be running and connected to your phone. Because Phone Link generates system notifications and brief UI interruptions when sending, automated sends may disrupt you if you're actively using your Windows machine. We recommend enabling Hold for review for Windows if this is a concern. Messages will only send after you explicitly approve them when opening the app.

Suppression list

Numbers on the suppression list are automatically skipped in all bulk and API sends.

GET https://textyourlist.com/api/suppression

Returns all suppressed numbers for your account.

[
  { "phone": "+12125550100", "reason": "Opted out", "created_at": "2026-04-01T12:00:00Z" }
]
POST https://textyourlist.com/api/suppression

Add a number to the suppression list.

FieldRequiredDescription
phoneRequiredPhone number to suppress.
reasonOptionalFree-text reason (e.g. "Opted out").
curl -X POST https://textyourlist.com/api/suppression \
  -H "Authorization: Bearer tbk_your_key" \
  -H "Content-Type: application/json" \
  -d '{"phone": "+12125550100", "reason": "Opted out"}'
DELETE https://textyourlist.com/api/suppression/{phone}

Remove a number. URL-encode the phone number.

curl -X DELETE "https://textyourlist.com/api/suppression/%2B12125550100" \
  -H "Authorization: Bearer tbk_your_key"

Errors & limits

StatusMeaning
201Message queued successfully.
400Missing required fields or invalid input.
401Missing or invalid API key.
402Monthly send limit reached. Upgrade your plan.
403Pro plan required for /api/make/send.
422Number is on your suppression list. Send was skipped.
429Rate limit: max 120 requests per minute per API key.

All error responses return JSON with an error field: {"error": "description"}

Make setup (step by step)

Connect Make to Text Your List using the HTTP module.

  1. In your Make scenario, add an HTTP → Make a request module.
  2. Set the URL to: https://textyourlist.com/api/make/send
  3. Set the Method to POST.
  4. Under Headers, add:
    • AuthorizationBearer tbk_your_api_key
    • Content-Typeapplication/json
  5. Set Body type to Raw and Content type to JSON (application/json).
  6. In the Request content body, enter:
    {"phone": "{{phone_variable}}", "message": "{{message_variable}}"}
    Replace {{phone_variable}} and {{message_variable}} with your scenario data mappings. To attach an image, add "image_url": "{{image_url_variable}}" (omit the field entirely if you're not sending an image).
  7. Enable Follow all redirects (required for this endpoint).
  8. Save and run your scenario.
Make sure the module's Parse response is enabled so Make can read the JSON result and handle errors gracefully.
If you get a BundleValidationError: Missing value of required parameter 'followAllRedirects', open the HTTP module, scroll to Advanced settings, and enable Follow all redirects.

Zapier setup (step by step)

  1. In your Zap, add a Webhooks by Zapier action.
  2. Choose POST as the event type.
  3. Set the URL to: https://textyourlist.com/api/make/send
  4. Set Payload type to JSON.
  5. Under Data, add two fields:
    • phone → map from your trigger data (e.g. a form field)
    • message → your message text or a mapped variable
  6. Under Headers, add: Authorization: Bearer tbk_your_api_key
  7. Test the step to confirm a 201 response.

AI agent / Claude setup

If you use an AI assistant like Claude, you can give it your API key and tell it to send texts in plain English. No coding or automation setup needed.

How to set it up

  1. Generate an API key in the Developer tab of the desktop app (see Authentication above).
  2. Give the key to your AI assistant and ask it to save it as a secret or environment variable called TYL_API_KEY.
  3. That's it. Now you can say things like:
    • "Send 'I hope you're having a good day' to 9085550142"
    • "Text John at 9085550142 that dinner is at 7"
    • "Send my Follow Up template to my April Leads list"
    • "Text everyone on my VIP list that the sale starts tomorrow"

The agent handles everything. It knows to call the API, pass your key, and format the request correctly. You just tell it what to say and who to send it to.

Sends from your real number. Text Your List uses your own Mac or Windows machine to send messages through your actual phone number. Recipients see your name (the same one they have saved in their contacts) and replies come straight back to your messages app. iMessage, SMS, and Android all work the same way.

For developers: quick integration reference

If you're building something yourself or wiring up an agent framework, here's the minimum you need:

# Single send, works from any machine, no app required at call time
curl -X POST https://textyourlist.com/api/make/send \
  -H "Authorization: Bearer $TYL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"phone": "9085550142", "message": "Hey, just checking in!"}'

# List send, agent checks available lists first, then sends
curl https://textyourlist.com/api/make/lists \
  -H "Authorization: Bearer $TYL_API_KEY"

curl -X POST https://textyourlist.com/api/make/send-to-list \
  -H "Authorization: Bearer $TYL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"list_name": "April Leads", "template_name": "Follow Up", "pace_seconds": 7}'

Tool definition (for agent frameworks)

If you're integrating with an agent framework that uses tool/function calling (Claude API, OpenAI, etc.):

{
  "name": "send_text",
  "description": "Send a text message from the user's own phone number via Text Your List.",
  "parameters": {
    "type": "object",
    "properties": {
      "phone":     { "type": "string", "description": "Recipient phone number (US format, e.g. +12125550100 or 9085550142)" },
      "message":   { "type": "string", "description": "Message body. Max 1600 characters." },
      "image_url": { "type": "string", "description": "Optional. Public URL of an image to send as MMS (JPEG, PNG, GIF)." }
    },
    "required": ["phone", "message"]
  }
}
If the response comes back with "status": "api_pending", the message is held. Either the desktop app was closed when the request arrived, or you have "Hold for review" turned on. Open the app and check the Jobs tab to release it.

Need help?

Email us at [email protected] and we'll get back to you within one business day.