Connect 23 Telecom to HubSpot
Copy page
| Setup type | Custom code · technical admin |
| Setup time | About 20 minutes |
| Sends SMS | Yes |
| Delivery status in HubSpot | No — check 23 Telecom |
| Who can configure | HubSpot admin (Data Hub Professional or Enterprise) |
What this connection does
Section titled “What this connection does”A HubSpot custom-code workflow action calls the 23 Telecom API to send an SMS. We recommend custom code over Send a webhook because it lets you build the exact JSON body, read the key from a secret, and use a per-execution idempotency key. HubSpot records the action result; carrier delivery reports stay in 23 Telecom.
Before you start
Section titled “Before you start”- Data Hub Professional or Enterprise (custom-code actions require it).
- An active workspace, an
approved sender ID and an E.164 test number, e.g.
+447911123456. - A restricted 23 Telecom API key with only
sms.send— start with a sandboxsk_test_key (Sandbox & test mode).
POST
/api/v1/sms/send-individual
· Permission: sms.send
Connect 23 Telecom
Section titled “Connect 23 Telecom”-
In your workflow choose + → Custom code.
-
Add a secret named
TELECOM23_KEYholding your restricted key, and add the contact phone as an input property. -
Paste the action code (below) and map the phone input.
-
Use Test action on a test record, then check the status, output and logs.
Action code
Section titled “Action code”// Secret: TELECOM23_KEY Input property: phoneconst axios = require('axios'); // bundled in HubSpot custom-code actions
exports.main = async (event, callback) => { const phone = event.inputFields.phone; try { const { data } = await axios.post( 'https://restlink23telecom.com/api/v1/sms/send-individual', { messages: [{ to: phone, message: 'Your message', sender_id: 'YourBrand' }] }, { headers: { 'Content-Type': 'application/json', 'X-API-Key': process.env.TELECOM23_KEY, 'Idempotency-Key': event.callbackId, // unique per execution }, } );
// 2xx only: the body must still say "accepted" with an id. Any other body // is not confirmed acceptance and must not be auto-retried. const result = data && data.results && data.results[0]; if (!result || result.status !== 'accepted' || !result.message_id) { throw new Error(`not accepted: ${result && result.status}`); } callback({ outputFields: { message_id: result.message_id, status: 'accepted' } }); } catch (err) { const status = err.response && err.response.status; // Transient (429/5xx): re-throw the original AxiosError — HubSpot only retries // an action that throws an axios / @hubspot/api-client error for those codes. if (status === 429 || (status >= 500 && status <= 599)) { throw err; } // Permanent (other 4xx, or a 200 that wasn't "accepted"): fail with a // plain error and do NOT ask HubSpot to retry. throw new Error(`send failed permanently (status ${status || 'none'})`); }};Send a test
Section titled “Send a test”Run Test action on a test record with your sk_test_ key. Expect the output
message_id to be set and the log to show results[0].status: "accepted".
Production activation
Section titled “Production activation”Unlike the webhook-only platforms, the HubSpot custom code validates the response
body — it fails unless results[0].status is "accepted" with a message_id,
so a bare 2xx never turns the workflow green. That satisfies the production
acceptance requirement without a dedicated endpoint. After the sandbox check,
your 23 Telecom account manager enables production for the workspace and confirms
the account limits; then swap the TELECOM23_KEY secret from the sandbox
sk_test_ key to a restricted sk_prod_ key.
Verify the result
Section titled “Verify the result”Accepted means queued. Read carrier delivery in Message status or Statistics, or add a live delivery webhook. If you need delivery status inside HubSpot, ask us to scope a managed contact-property or custom-event bridge.
Troubleshooting
Section titled “Troubleshooting”| Response | Cause & fix |
|---|---|
400 IDEMPOTENCY_KEY_REQUIRED | Send event.callbackId as Idempotency-Key |
401 INVALID_API_KEY | Wrong or disabled key in the TELECOM23_KEY secret |
403 NO_SMS_ACCESS | SMS not enabled — contact 23 Telecom |
429 RATE_LIMIT_EXCEEDED | Sending faster than your budget — throttle the workflow |
Need help?
Section titled “Need help?”- Workflow, custom code, secrets or limits — HubSpot support.
- API key, sender ID, accepted-but-not-delivered — your 23 Telecom account manager, or the contact form.
Official platform documentation
Section titled “Official platform documentation”Last verified: 16 July 2026.