Zapier SMS from your own number: send and receive

Checked against the docs:

In Zapier you send an SMS with the Webhooks by Zapier → Custom Request action: POST https://smsportal.app/api/v1/gateway/send-sms, headers x-api-key and Content-Type: application/json, and JSON with recipients and message in the Data field. Replies arrive at a Catch Hook trigger. Webhooks by Zapier needs the Professional plan or higher. The "SMSPortal" app in Zapier's directory is a different company, not smsportal.app.

What you need

  • Zapier on a Professional, Team or Enterprise plan (Webhooks by Zapier is not available on Free).
  • A smsportal account with an Android phone and SIM card connected.
  • An API key from the smsportal dashboard (API Keys → Generate API Key).
  • Do not pick the "SMSPortal" app from Zapier's directory: it is a separate company (smsportal.com) with its own accounts. Our key will not work there.

How to send an SMS from Zapier

  1. Add a Webhooks by Zapier action

    In your Zap add an action step, pick the Webhooks by Zapier app and the Custom Request action event. Custom Request sends the JSON exactly as you type it, so recipients stays a list.

  2. Set method, URL and headers

    Method POST, URL https://smsportal.app/api/v1/gateway/send-sms. Under Headers add two rows: x-api-key with the key from the dashboard, and Content-Type with application/json. Leave Data Pass-Through? on False.

  3. Paste the JSON into Data

    Paste the JSON below. Delete the bracketed labels such as [1. Phone] and insert fields from earlier steps from the data list in their place. Use international format, for example +14155550123. Optionally add deviceId, simSubscriptionId or scheduledAt (an ISO 8601 time in the future).

    Data field (Custom Request)
    {
      "recipients": ["[1. Phone]"],
      "message": "Hi [1. Name], your booking for [1. Start Time] is confirmed. Reply if anything changes."
    }
  4. Test with your own number

    Put your own number in for the test and click Test step. A 200 response with a data field means the message is queued. The status (sent, delivered) shows up in the smsportal dashboard, and every call is listed in Zap history.

How to receive a customer reply in Zapier

When the phone receives an SMS, smsportal POSTs JSON to your webhook URL. Catch Hook splits it into fields: sender (the number), message (the text), receivedAt and webhookEvent. Every request carries an X-Signature header: a hex HMAC-SHA256 of the raw body, keyed with your signing secret.

  1. Create a Zap with a Webhooks by Zapier trigger, Trigger event Catch Hook. On the Test tab copy the webhook URL.
  2. In the smsportal dashboard open Webhooks → Create Webhook, paste the URL, enter a signing secret (at least 20 characters) and tick MESSAGE_RECEIVED.
  3. Text your phone from another number and click Test trigger. Zapier shows a sample with sender and message fields that you can map in later steps.
  4. Publish the Zap. A Zap that is off answers webhooks with 404, and smsportal stops retrying that event after 3 such attempts.
  5. To verify the signature you need the raw body and headers, which the Catch Raw Hook trigger provides (up to 2 MB). Compute the HMAC-SHA256 with your secret in a Code by Zapier step and compare it with the x-signature header.
Example MESSAGE_RECEIVED body
{
  "smsId": "6720f0c2a1b2c3d4e5f60718",
  "message": "Confirmed, see you then",
  "deviceId": "671f9e10a1b2c3d4e5f60001",
  "webhookSubscriptionId": "671fa001a1b2c3d4e5f60002",
  "webhookEvent": "MESSAGE_RECEIVED",
  "idempotencyKey": "3f1c9a8e-5d2b-4c7a-9e1f-2b6d8c0a4e57",
  "sender": "+14155550123",
  "receivedAt": "2026-10-28T09:41:00.000Z"
}

Ready-made scenarios

  • A Calendly booking: confirmation and reminder

    Calendly → Invitee Created starts the Zap and Custom Request sends a confirmation to the number from the phone question. A second Custom Request with scheduledAt sets up the reminder: move the meeting time back 24 hours in Formatter (Date / Time → Add/Subtract Time) and output it as ISO 8601. For bookings less than 24 hours away add a Filter, because the API rejects a time in the past.

  • A new form entry gets a text

    Typeform → New Entry or Google Forms → New Form Response, then Custom Request with a confirmation. The form's phone field must collect the country code.

  • Customer replies in a sheet

    Catch Hook on MESSAGE_RECEIVED, then Google Sheets → Create Spreadsheet Row with sender, message and receivedAt columns. Your team sees every reply in one place, and you can swap that step for a CRM note.

Errors and fixes

Custom Request returns 401
Cause: An Authorization header instead of x-api-key, a wrong key, or a space in the value.
Fix: Name the header exactly x-api-key and put the bare key from the dashboard in the value, with no leading or trailing spaces.
400 Invalid recipients
Cause: The POST action with key-value fields was used: Zapier then sends the number as text, while the API expects a list.
Fix: Use the Custom Request action with raw JSON in the Data field: "recipients": ["+14155550123"].
400 on some messages only
Cause: The mapped text contains a double quote or a line break. Custom Request does not escape them, so the JSON is invalid.
Fix: Remove those characters first with a Formatter step (Text → Replace), or avoid mapping free text typed by customers into the message.
400 scheduledAt must be a future date
Cause: The computed reminder time is already in the past, for example a booking for today.
Fix: Add a Filter that only passes meetings more than 24 hours away, or send that reminder without scheduledAt.
Catch Hook receives nothing
Cause: The Zap is off (Zapier answers 404) or the dashboard has a different URL. smsportal stops retrying after 3 attempts that get a 4xx, and pauses a subscription that keeps failing.
Fix: Publish the Zap, then check the URL and the subscription status under Webhooks in the smsportal dashboard.
429 when sending
Cause: The SMS limit of your plan is used up.
Fix: The response body says which limit ran out. Check the counter in the dashboard or change plans on the pricing page.

Frequently asked questions

Is the SMSPortal app in Zapier the same as smsportal.app?

No. "SMSPortal" in Zapier's directory is a different company (smsportal.com) that sends through its own gateway and charges per message. smsportal.app has no Zapier app: you connect through Webhooks by Zapier, and the text goes out from your own phone.

Does this work on Zapier's free plan?

No. Webhooks by Zapier and API by Zapier are available on the Professional, Team and Enterprise plans. To start without paying, use Make (the HTTP module) or n8n.

How many tasks does one SMS use?

One: a task is any successful action, while triggers, filters and failed steps do not count. smsportal does not charge per message: your SIM plan pays the carrier.

How do I hide the API key from others who can edit the Zap?

A key in Headers is visible to anyone who edits the Zap. API by Zapier (beta) keeps it in a connection: Authentication type `Static Headers (API key)`, Headers `x-api-key: YOUR_API_KEY`, Domain filter `smsportal.app`. Then use the API Request action with the same URL and the JSON in Body.

Does Zapier know the SMS was delivered?

The Custom Request response only says the message was queued. Sending and delivery are reported by the `MESSAGE_SENT` and `MESSAGE_DELIVERED` events, which you can catch with a separate Catch Hook.

How many texts can I send at once?

The phone sends with a pause between messages (5 seconds by default, about 720 per hour per phone). This is for confirmations, reminders and replies, not for marketing campaigns.

Sources

  1. Zapier: Send webhooks in Zap workflows
  2. Zapier: Trigger Zap workflows from webhooks
  3. Zapier: How to get started with API by Zapier
  4. Zapier: How is task usage measured
  5. Zapier: the SMSPortal app (a different company)
  6. smsportal API documentation

More in the guides

Send your first SMS today

Create a free account, connect your phone and see how customers respond to messages from your number.