Skip to main content
RapidDev - Software Development Agency
bubble-integrationsBubble API Connector

Signal

Signal has no official public API. The only programmatic path is the open-source signal-cli-rest-api project — a Docker container you self-host on a VPS that registers a dedicated phone number with Signal and exposes a local REST API. Bubble connects to this relay via the API Connector with Basic Auth credentials marked Private. This is an Advanced integration requiring your own server infrastructure. Use only for low-volume, high-value encrypted alerts.

What you'll learn

  • Why Signal has no official API and what the signal-cli-rest-api relay project is and how it works
  • How to deploy and configure the signal-cli-rest-api Docker container on a VPS and register a dedicated phone number with Signal
  • How to configure Bubble's API Connector to connect to your self-hosted relay with Private Basic Auth credentials
  • How to send Signal messages to individual recipients and groups from Bubble Backend Workflows
  • What Signal's Terms of Service restrictions mean for automated messaging and why volume must stay low
Book a free consultation
4.9Clutch rating
600+Happy partners
17+Countries served
190+Team members
Advanced21 min read2-4 hoursCommunicationLast updated July 2026RapidDev Engineering Team
TL;DR

Signal has no official public API. The only programmatic path is the open-source signal-cli-rest-api project — a Docker container you self-host on a VPS that registers a dedicated phone number with Signal and exposes a local REST API. Bubble connects to this relay via the API Connector with Basic Auth credentials marked Private. This is an Advanced integration requiring your own server infrastructure. Use only for low-volume, high-value encrypted alerts.

Quick facts about this guide
FactValue
ToolSignal
CategoryCommunication
MethodBubble API Connector
DifficultyAdvanced
Time required2-4 hours
Last updatedJuly 2026

Send End-to-End Encrypted Signal Messages from Bubble via a Self-Hosted Relay

Signal is one of the most secure messaging apps available — but that security comes with a deliberate trade-off: Signal does not offer an official API. The organization intentionally avoids building one to prevent the bulk messaging and spam use cases that compromise other platforms. So why integrate Signal with Bubble at all?

There is a specific audience for this integration: security-conscious founders and operations teams who need to deliver high-value, encrypted alerts to a small group of people and for whom Slack, email, or SMS is not acceptable. Think compliance alerts to executives, security incident notifications to on-call teams, or privacy-sensitive operational messages where end-to-end encryption is a hard requirement rather than a nice-to-have.

The technical path is the **signal-cli-rest-api** project (github.com/bbernhard/signal-cli-rest-api) — an open-source Docker container that wraps the signal-cli Java library and exposes a local REST API. When deployed on a VPS, it registers a dedicated phone number with Signal's servers and acts as that number's Signal client. Bubble connects to this relay via the API Connector, sending an HTTP POST request that the relay translates into a Signal protocol message.

This is categorically different from most Bubble integrations. Before any Bubble configuration happens, you need a server: a VPS running Docker with persistent storage, a phone number capable of receiving an SMS verification code (a cheap VoIP number works), and HTTPS configured for the relay endpoint. Signal requires TLS for external connections and Bubble's API Connector will reject self-signed certificates.

The integration is labeled Advanced not to discourage you, but because it involves infrastructure choices that have real consequences: if the relay server's data volume is lost, the Signal registration for your number is gone and must be re-established with a new SMS verification. This is covered in the maintenance section. If you decide to proceed, this guide walks you through every step from VPS to Bubble workflow.

Signal's Terms of Service prohibit spam and automated bulk messaging. This integration is appropriate for low-volume operational alerts (single-digit to low double-digit messages per day to known recipients) — not for marketing campaigns or mass notifications.

Integration method

Bubble API Connector

Bubble connects to a self-hosted signal-cli-rest-api relay (a Docker container on a VPS or cloud VM) using the API Connector with Basic Auth credentials in a Private header. The relay acts as a Signal client for a dedicated phone number and exposes a REST API that Bubble calls to send messages. There is no official Signal API — this relay is a community-maintained open-source project (github.com/bbernhard/signal-cli-rest-api). Advanced difficulty: requires deploying Docker infrastructure before any Bubble configuration is possible.

Prerequisites

  • A VPS or cloud VM (DigitalOcean, Vultr, Hetzner, or similar — ~$5-20/month) with Docker and Docker Compose installed and a public IP address
  • A phone number capable of receiving an SMS verification code for Signal registration (a VoIP number from a provider like Twilio or a prepaid SIM works; the number must not already be registered as a personal Signal account)
  • A domain name (or subdomain) you can point to the VPS IP, used to set up HTTPS via Let's Encrypt
  • Basic comfort with SSH, command-line operations, and Docker (this tutorial covers the key commands, but some Linux familiarity is required)
  • A Bubble app on a paid plan (Starter or higher) to use Backend Workflows — required to keep relay credentials server-side
  • Signal installed on at least one phone to verify the relay is working and to add recipients to your sender number's contacts before messaging them

Step-by-step guide

1

Deploy the signal-cli-rest-api Relay on a VPS

This step happens entirely outside of Bubble and must be completed before any Bubble configuration. You need a Linux VPS with Docker and Docker Compose installed. SSH into your VPS and create a directory for the relay: ``` mkdir -p ~/signal-relay && cd ~/signal-relay ``` Create a `docker-compose.yml` file with the following content: ```yaml version: '3' services: signal-cli-rest-api: image: bbernhard/signal-cli-rest-api:latest ports: - '8080:8080' volumes: - './signal-cli-config:/home/.local/share/signal-cli' environment: - MODE=json-rpc restart: unless-stopped ``` The `./signal-cli-config` volume is critical — it stores your Signal registration keys. If this directory is lost, your Signal number loses its registration and must be re-verified. Start the relay: ``` docker compose up -d ``` Verify it is running: ``` docker compose logs -f ``` You should see the relay starting up without errors. The API is now accessible at `http://localhost:8080` on the VPS. In the next step, you will register a phone number. Do not expose port 8080 to the internet without authentication — set up a reverse proxy with Basic Auth and HTTPS first (Step 3).

docker-compose.yml
1version: '3'
2services:
3 signal-cli-rest-api:
4 image: bbernhard/signal-cli-rest-api:latest
5 ports:
6 - '8080:8080'
7 volumes:
8 - './signal-cli-config:/home/.local/share/signal-cli'
9 environment:
10 - MODE=json-rpc
11 restart: unless-stopped

Pro tip: Back up the `./signal-cli-config` directory regularly. This is the only copy of your Signal registration keys for the relay number. A crashed VM without a backup means starting registration over from scratch, which requires a new SMS verification.

Expected result: The signal-cli-rest-api container is running on your VPS and accessible at http://localhost:8080 from within the server. No phone number is registered yet.

2

Register a Dedicated Phone Number with Signal via the Relay

Signal requires every number to be verified via SMS (or voice call) before it can send or receive messages. This registration step is done via CLI commands or curl requests to the relay's local API — it cannot be done from Bubble. This is a one-time manual setup per phone number. From inside the VPS (while the relay container is running), request a verification SMS to your chosen phone number in E.164 format. Replace `+15551234567` with your actual number: ``` curl -X POST 'http://localhost:8080/v1/register/+15551234567' ``` Your phone (or VoIP number dashboard) will receive a 6-digit SMS code. Submit the code to complete registration: ``` curl -X POST 'http://localhost:8080/v1/register/+15551234567/verify/123456' ``` Set a profile name for the Signal account (required for some features): ``` curl -X PUT 'http://localhost:8080/v1/profiles/+15551234567' \ -H 'Content-Type: application/json' \ -d '{"name": "Bubble Alerts Bot"}' ``` Verify registration by listing accounts: ``` curl 'http://localhost:8080/v1/accounts' ``` You should see your number listed. The relay's `signal-cli-config` directory now contains the Signal protocol keys for this number — this is what needs to be backed up. **Important:** The phone number you register must NOT be actively in use as a personal Signal account on another device. If a number is registered on a Signal app, registering it on the relay will unregister it from your phone.

signal-registration-commands.sh
1# Step 1: Request verification SMS
2curl -X POST 'http://localhost:8080/v1/register/+15551234567'
3
4# Step 2: Verify with the code received via SMS (replace 123456)
5curl -X POST 'http://localhost:8080/v1/register/+15551234567/verify/123456'
6
7# Step 3: Set a profile name
8curl -X PUT 'http://localhost:8080/v1/profiles/+15551234567' \
9 -H 'Content-Type: application/json' \
10 -d '{"name": "Bubble Alerts Bot"}'
11
12# Step 4: Verify registration
13curl 'http://localhost:8080/v1/accounts'

Pro tip: If you cannot receive SMS on the number directly on the VPS, that is fine — you just need the 6-digit code. Use a VoIP provider's web dashboard (like Twilio console) to read the incoming SMS and then submit the code via curl.

Expected result: Your dedicated phone number is registered with Signal via the relay. The relay's accounts endpoint returns the number as registered. You can now send messages through the relay.

3

Set Up HTTPS and Basic Auth for the Relay Endpoint

Bubble's API Connector requires HTTPS endpoints and will reject self-signed certificates. You also need to protect the relay behind authentication so that only your Bubble app (and you) can use it. This is done with an nginx reverse proxy providing both TLS and Basic Auth. Install nginx and certbot on your VPS: ``` sudo apt update && sudo apt install -y nginx certbot python3-certbot-nginx apache2-utils ``` Create a Basic Auth password file (replace `bubbleuser` and choose a strong password): ``` sudo htpasswd -c /etc/nginx/.htpasswd bubbleuser ``` Create an nginx config at `/etc/nginx/sites-available/signal-relay`: ```nginx server { listen 80; server_name signal-relay.yourdomain.com; location / { auth_basic "Signal Relay"; auth_basic_user_file /etc/nginx/.htpasswd; proxy_pass http://localhost:8080; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } } ``` Enable the site and get a Let's Encrypt certificate: ``` sudo ln -s /etc/nginx/sites-available/signal-relay /etc/nginx/sites-enabled/ sudo nginx -t && sudo systemctl reload nginx sudo certbot --nginx -d signal-relay.yourdomain.com ``` Certbot will automatically configure HTTPS. Your relay is now accessible at `https://signal-relay.yourdomain.com` with Basic Auth protection. Alternatively, if you prefer not to manage nginx, **Cloudflare Tunnel** (free tier) can provide HTTPS and access control without managing TLS certificates manually — point the tunnel to `http://localhost:8080` and add Cloudflare Access rules for IP allowlisting.

nginx-signal-relay.conf
1# nginx reverse proxy configuration
2server {
3 listen 80;
4 server_name signal-relay.yourdomain.com;
5
6 location / {
7 auth_basic "Signal Relay";
8 auth_basic_user_file /etc/nginx/.htpasswd;
9 proxy_pass http://localhost:8080;
10 proxy_set_header Host $host;
11 proxy_set_header X-Real-IP $remote_addr;
12 }
13}

Pro tip: After certbot runs, verify the relay is accessible via HTTPS by running `curl -u bubbleuser:yourpassword https://signal-relay.yourdomain.com/v1/accounts` from your local machine (not the VPS). A successful response with your registered number confirms the full stack is working.

Expected result: The signal-cli-rest-api relay is accessible at https://signal-relay.yourdomain.com with a valid TLS certificate and Basic Auth protection. Unauthenticated requests return HTTP 401. This URL and credentials are what you will now configure in Bubble.

4

Configure the Bubble API Connector for the Signal Relay

Now that your relay is running with HTTPS and Basic Auth, you can configure Bubble's API Connector to connect to it. In your Bubble editor, go to the **Plugins** tab → **Add plugins** → search for **'API Connector'** (by Bubble) → **Install**. Click on the API Connector in your plugins list and click **Add another API**. Name it `Signal Relay`. In the **Base URL** field, enter your relay's domain: `https://signal-relay.yourdomain.com`. Check the **Private** checkbox next to the Base URL. In the **Shared headers** section, add: - Key: `Content-Type`, Value: `application/json`, Private: unchecked For **Authentication**: select **Basic auth**. Enter your nginx htpasswd username in the Username field and the password in the Password field. Check **Private** on both. Now add the send message call: click **Add a call**. Name it `Send Signal Message`. Set method to **POST**. Set the endpoint path to `/v1/send`. Set **Body type** to **JSON**. In the body, add: ```json { "message": "<dynamic:message_text>", "number": "+15551234567", "recipients": ["<dynamic:recipient_number>"] } ``` Replace `+15551234567` with your registered sender number (this can be hardcoded as a constant since you only have one relay number). Mark `message_text` and `recipient_number` as dynamic text parameters. Set **Use as** to **Action**. Click **Initialize call**. In the parameter fields, enter a real test message and a recipient phone number you control (in E.164 format, e.g. `+15559876543`). Click **Send**. A successful response returns HTTP 201 or 200 with an empty body or a messageId. Check the recipient's Signal app — the message should arrive within seconds. If you see 'There was an issue setting up your call', verify the relay URL is correct, your Basic Auth credentials match the htpasswd file, and the relay container is still running.

bubble-signal-api-connector-config.json
1{
2 "api_name": "Signal Relay",
3 "base_url": "https://signal-relay.yourdomain.com",
4 "authentication": "Basic Auth",
5 "username": "<relay username — Private>",
6 "password": "<relay password — Private>",
7 "shared_headers": [
8 { "key": "Content-Type", "value": "application/json" }
9 ],
10 "call_name": "Send Signal Message",
11 "method": "POST",
12 "endpoint": "/v1/send",
13 "body": {
14 "message": "<dynamic:message_text>",
15 "number": "+15551234567",
16 "recipients": ["<dynamic:recipient_number>"]
17 }
18}

Pro tip: The recipient number must be in E.164 format (+CountryCodeNumber, no spaces or dashes). Recipients also need to have Signal installed and active on their devices — you cannot send Signal messages to phone numbers that are not registered on Signal.

Expected result: The Signal Relay API is configured in Bubble's API Connector. The 'Send Signal Message' call is initialized with a real successful response. A test Signal message arrives on the recipient's phone.

5

Build a Bubble Backend Workflow to Send Signal Alerts

With the API Connector configured, wire it into your Bubble app logic using a Backend Workflow. Backend Workflows are required for this integration on a paid Bubble plan — they keep the relay credentials server-side and allow you to trigger alerts from database events, scheduled jobs, and other server-side triggers. Go to the **Backend Workflows** section (left sidebar under Workflow, or the Server-side actions area depending on your Bubble plan). Click **New API Workflow** and name it `Send Signal Alert`. This workflow should accept parameters: - `message` (text) — the alert message content - `recipient` (text) — the recipient phone number in E.164 format Add an action: **Plugins → Signal Relay - Send Signal Message**. Set: - `message_text` → this workflow's `message` parameter - `recipient_number` → this workflow's `recipient` parameter Optionally, add a second action to log the alert: **Data (Things) → Create a new Signal_Log** (create this data type with fields: recipient text, message text, sent_at date, status text). This audit log is valuable for debugging and for tracking alert delivery. Save the Backend Workflow. Now trigger it from anywhere in your app. From a client-side workflow (button click, condition met), add a **Schedule API Workflow** action pointing to `Send Signal Alert`. Pass the recipient number from your database (e.g., a User's phone field) and a dynamic message text (e.g., `'Alert: ' + triggering_record's details`). For automated alerts without a user action, use Bubble's **Recurring Backend Workflow** or trigger the Backend Workflow from a data condition. For example: when a new Error_Log record is created with severity = 'Critical', run the Send Signal Alert workflow. RapidDev's team has helped founders build advanced notification pipelines in Bubble with encrypted messaging, escalation logic, and multi-channel fallbacks — if you need help architecting a resilient alert system, a free scoping call is available at rapidevelopers.com/contact.

Pro tip: For Signal group messages, first retrieve the group ID via GET /v1/groups/+15551234567 on the relay (call it from Bubble or directly with curl during setup) and store group IDs in a Bubble data type. Replace the 'recipients' array with the group ID in the API call body.

Expected result: The 'Send Signal Alert' Backend Workflow is created in Bubble and can be triggered from any client-side or server-side workflow. Alert Signal messages arrive on recipient devices with end-to-end encryption.

6

Relay Maintenance, Backups, and Monitoring

The Signal relay requires ongoing maintenance that other API integrations do not. Unlike rotating an API key, losing the relay's data volume means a full re-registration — including getting a new SMS verification code for your Signal number and potentially losing group memberships. **Backups**: Set up an automated daily backup of the `./signal-cli-config` directory on your VPS. A simple cron job can compress and upload it to a cloud bucket: ```bash 0 3 * * * tar -czf /backup/signal-config-$(date +%Y%m%d).tar.gz ~/signal-relay/signal-cli-config && rclone copy /backup/ s3:your-bucket/signal-backup/ ``` **Relay updates**: The signal-cli-rest-api project releases updates to track Signal protocol changes. When Signal updates its protocol, older relay versions may stop working. Watch the project's GitHub releases and update the Docker image periodically: ```bash docker compose pull && docker compose up -d ``` **Monitoring**: Add a health check to your Bubble app — a scheduled Backend Workflow that calls `GET /v1/accounts` on the relay every few hours. If the call fails or returns an error, send an alert to yourself (email or another channel) so you know the relay is down before it causes missed notifications. **Volume awareness**: Each Signal message sent from Bubble = one API Connector call action + one database write for the log = approximately 2 Workload Units. At low message volumes (under 100 messages/day), this is negligible. Bubble's WU consumption is not a concern for the typical use case of this integration. **Privacy rules**: If you store Signal alert content in a Bubble data type (Signal_Log), apply privacy rules under **Data → Privacy** to restrict log reads to admin users only. Alert message content may be sensitive — do not leave it readable by all users by default.

signal-relay-maintenance.sh
1# Automated backup cron job (add to VPS crontab with: crontab -e)
2# Runs daily at 3am, compresses config, uploads to cloud storage
30 3 * * * tar -czf /tmp/signal-config-$(date +%Y%m%d).tar.gz ~/signal-relay/signal-cli-config
4
5# Relay update command (run manually or add to scheduled maintenance)
6cd ~/signal-relay && docker compose pull && docker compose up -d
7
8# Health check (test relay is responding)
9curl -u bubbleuser:yourpassword https://signal-relay.yourdomain.com/v1/accounts

Pro tip: If you receive a '404 Not Found' or connection refused when calling the relay from Bubble after it was previously working, first check that the Docker container is still running (docker compose ps on the VPS) and that the nginx reverse proxy is active (systemctl status nginx). Signal protocol updates can also cause relay failures — check the signal-cli-rest-api GitHub issues page for recent reports.

Expected result: You have automated backups of the relay's Signal keys, a monitoring workflow in Bubble that checks relay health, and a documented update process for keeping the relay software current.

Common use cases

Encrypted Security and Compliance Alerts

When a Bubble app detects a security-relevant event — a failed login threshold breach, an unusual data export, an admin account permission change — trigger a Backend Workflow that sends an encrypted Signal message to the security team's group. Signal's end-to-end encryption ensures the alert content cannot be read by intermediaries, which matters for compliance-sensitive environments where email or Slack logs may be discoverable.

Bubble Prompt

When more than 5 failed login attempts occur for a single user account within 10 minutes in my Bubble app, send a Signal message to the security team group with the account email, timestamp, and IP address.

Copy this prompt to try it in Bubble

Privacy-Sensitive Operational Notifications

Healthcare, legal, or financial apps handling sensitive personal data may need to notify staff about workflow states (a document is ready for review, a case status changed) without sending that information through email or standard messaging platforms. Bubble can send a Signal alert to the relevant staff member's number with just enough information to prompt them to open the app — keeping sensitive details inside the encrypted app, not in the notification itself.

Bubble Prompt

When a client document status changes to 'Ready for Review' in Bubble, send a Signal message to the assigned staff member saying 'A document in your queue is ready — please log in to review it.'

Copy this prompt to try it in Bubble

On-Call Escalation for Internal Tools

For internal Bubble apps managing infrastructure, payments, or critical business processes, use Signal alerts as a high-attention escalation channel distinct from email. If a payment processor reports a spike in failures, a scheduled Backend Workflow can send a Signal message to an on-call group so the alert is noticed even outside business hours — without routing that failure data through a third-party monitoring service.

Bubble Prompt

Every 30 minutes, check if any critical workflow in my Bubble app has failed more than 3 times in a row. If so, send a Signal message to the on-call team group listing the failed workflows.

Copy this prompt to try it in Bubble

Troubleshooting

Bubble's API Connector Initialize call shows 'There was an issue setting up your call' when testing the Signal relay connection

Cause: The most common causes are: (1) the relay's HTTPS certificate is invalid or self-signed — Bubble's API Connector rejects non-trusted TLS certificates; (2) the Basic Auth credentials in Bubble do not match the nginx htpasswd file; (3) the relay Docker container is not running or the nginx proxy is not forwarding to port 8080.

Solution: Test the relay from your local machine first using curl: `curl -u bubbleuser:password https://signal-relay.yourdomain.com/v1/accounts`. If this fails, the issue is with the relay infrastructure, not Bubble. Check: (1) `sudo certbot certificates` to verify TLS cert is valid; (2) `docker compose ps` on the VPS to confirm the relay container is Up; (3) `sudo nginx -t && sudo systemctl status nginx` to verify nginx config is valid. Fix the infrastructure issue, then re-test from Bubble.

Signal messages sent from Bubble are not delivered — the API call succeeds (201 response) but the recipient's Signal app does not show the message

Cause: This can happen if: (1) the recipient's phone number is not registered on Signal — you cannot send Signal messages to a number that is not an active Signal user; (2) the sender number registration has become stale or expired; (3) the relay's signal-cli version is out of date and incompatible with the current Signal protocol.

Solution: First, verify that the recipient has Signal installed and their number is registered by sending them a test Signal message from a personal Signal account. If that works but the relay cannot, check the relay's Docker logs: `docker compose logs --tail=50`. Look for Signal protocol errors indicating a version mismatch. If so, update the relay: `docker compose pull && docker compose up -d`. If the issue is a stale registration, you may need to re-register the sender number (Step 2 of this guide).

The relay returns an error about the sender number not being registered or 'Account not found'

Cause: The signal-cli-config volume data was lost (VPS reset, container recreation without volume mount) or the registration expired. Unlike most integrations where you just need to rotate a key, Signal registration is tied to the specific key material stored in the config volume.

Solution: If the config volume is lost, you must re-register the sender phone number from scratch (Step 2 of this guide — request a new SMS verification). If you have a backup, restore it: `tar -xzf signal-config-backup.tar.gz -C ~/signal-relay/signal-cli-config` then restart the container. This is why regular backups of the config volume are critical — treat it like a private key file.

'Workflow API is not enabled' error when trying to use Backend Workflows for Signal notifications in Bubble

Cause: Backend Workflows (API Workflows) require a paid Bubble plan. The relay credentials (username/password in Basic Auth) must be kept server-side — using client-side workflows exposes them in browser DevTools.

Solution: Upgrade to the Bubble Starter plan or higher to enable Backend Workflows. There is no secure client-side alternative for this integration because the relay URL and credentials would be visible in browser network requests. On the Free plan, this integration cannot be implemented securely.

Phone number format errors — the relay returns a 400 Bad Request when Bubble sends the recipient or sender number

Cause: Phone numbers must be in E.164 format: a leading plus sign, country code, and full number with no spaces, dashes, or parentheses. Bubble's text fields often store numbers in local format (e.g., 555-123-4567) without the country code.

Solution: In your Bubble Backend Workflow, use Bubble's 'Format as text' operator or a 'Regex replace' on the phone number field to strip non-numeric characters and ensure the E.164 format. For US numbers, prepend '+1' and remove spaces/dashes. Store recipient numbers in a Bubble data type field already validated to E.164 format when users register — easier than reformatting at send time.

Best practices

  • Back up the signal-cli-config Docker volume daily and store the backup in a separate cloud location — if this data is lost, your Signal number's registration must be rebuilt from scratch, which requires a new SMS verification code and a fresh phone number setup.
  • Use Signal integration only for low-volume, high-value notifications to known recipients. Signal's Terms of Service prohibit bulk and automated mass messaging — violating this can result in the relay number being banned by Signal's servers.
  • Always store relay Basic Auth credentials in Bubble's API Connector Private fields and use Backend Workflows (paid plan) to keep credentials server-side. Never use client-side Bubble actions for this integration — the relay URL and auth header would be visible in browser DevTools.
  • Monitor relay health with a Bubble scheduled Backend Workflow that calls GET /v1/accounts on the relay every few hours and sends an email alert (via Mailgun or SendGrid) if the health check fails — so you know before a critical alert fails silently.
  • Apply Bubble privacy rules to any data type storing Signal message logs or recipient phone numbers. Alert content and recipient identities may be sensitive — restrict these records to admin users only in the Data → Privacy tab.
  • Set up automatic relay software updates during low-activity windows. Signal's protocol can change and break older signal-cli versions without warning — run `docker compose pull && docker compose up -d` on a monthly maintenance schedule.
  • Store recipient phone numbers in a Bubble data type in E.164 format from the time of collection (e.g., when users provide their phone during onboarding) rather than trying to reformat numbers at send time. Validate format on input using a Bubble conditional check.
  • For group alerts, retrieve group IDs once via GET /v1/groups/{sender_number} during relay setup and store them in a Bubble data type — do not fetch group IDs on every message send, as this adds unnecessary relay API calls and relay WU cost.

Alternatives

Frequently asked questions

Does Signal have an official API I can use instead of the self-hosted relay?

No. Signal intentionally does not offer an official public API. The signal-cli-rest-api project used in this guide is community-maintained (github.com/bbernhard/signal-cli-rest-api) and is not affiliated with or endorsed by Signal Messenger LLC. This means it comes with no SLA, no official support, and the risk of breakage when Signal updates its protocol. It is the only available path for programmatic Signal messaging.

Can I use the same relay phone number to send messages to many different recipients, or do I need a number per recipient?

One relay number can send messages to many different recipients — you just pass different recipient numbers in the 'recipients' array of each API call. However, Signal may flag a number that sends to many unknown recipients in rapid succession as suspicious behavior. Keep volumes low, send only to users who expect your messages (opt-in), and do not blast to hundreds of recipients.

What happens if Signal changes its protocol and the relay stops working?

Signal protocol updates can break older signal-cli versions until the community releases a patch. The relay Docker image is updated with fixes — running `docker compose pull && docker compose up -d` on your VPS usually restores functionality once a fix is published. Monitor the signal-cli-rest-api GitHub repository issues for reports of breakage, and set up a Bubble health check workflow (Step 6) so you are notified when the relay goes down.

Can I receive inbound Signal messages in my Bubble app?

Technically yes — the signal-cli-rest-api relay supports receiving incoming messages via webhook or polling. However, setting up inbound Signal message processing in Bubble requires additional relay configuration (webhook mode or polling via a Bubble scheduled Backend Workflow calling GET /v1/receive/{number}). This is not covered in the basic setup and adds significant complexity. Start with outbound-only alerts before attempting inbound message processing.

Is this integration compliant with HIPAA, GDPR, or other regulations for healthcare or financial data?

Signal's end-to-end encryption means message content is encrypted between devices. However, your self-hosted relay server handles the messages transiently, and you are responsible for the security of that infrastructure. For regulated environments (HIPAA, GDPR), consult your compliance team about whether a self-hosted relay meets your data processing requirements. The relay server logs may capture message metadata — configure log retention accordingly.

Can Bubble Free plan users use this integration?

No, not securely. Backend Workflows — which are required to keep relay credentials (the relay URL and Basic Auth password) server-side — are only available on paid Bubble plans. On the Free plan, triggering the API call from a client-side workflow would expose the relay credentials in browser DevTools network requests, which would allow anyone to POST messages through your relay. This integration requires a paid Bubble plan.

RapidDev

Talk to an Expert

Our team has built 600+ apps. Get personalized help with your project.

Book a free consultation

Integrations are where projects stall

We wire Bubble integrations like this one every week — auth, webhooks, edge cases included. Fixed-price builds from $13K, delivered in 6–10 weeks.

Talk to an integration engineer

We put the rapid in RapidDev

Need a dedicated strategic tech and growth partner? Discover what RapidDev can do for your business! Book a call with our team to schedule a free, no-obligation consultation. We'll discuss your project and provide a custom quote at no cost.