Skip to content

Signal

URL Format

signal://[user[:password]@]host[:port]/source_phone/recipient1[/recipient2/...]

A URL without a host, such as signal:///+1234567890/+0987654321, uses localhost, with port 8080 unless the URL sets one.

URL Fields

Query/Param Props

Props can be either supplied using the params argument or through the URL using ?key=value&key=value etc.

  • recipients - Recipient phone numbers, group IDs, or u: usernames (Required) Aliases: to

  • source - Source phone number (with country code) (Required)

  • attachments - Comma-separated raw base64 attachments; a data: value is one URI Default: empty

  • disabletls - Disable TLS for Signal REST API connection Default: ❌ No

  • host - Signal REST API server hostname or IP Default: localhost

  • notifyself - Notify the sender's devices. When No, sends notify_self=false. Default: ✔ Yes

  • password - Password for HTTP Basic Auth Default: empty

  • port - Signal REST API server port Default: 8080

  • skiptlsverify - Skip TLS certificate verification Default: ❌ No

  • textmode - Message text mode (None omits text_mode; Styled enables markup) Default: None Aliases: text_mode Possible values: None, Normal, Styled

  • title - Optional title prepended to the message body Default: empty

  • token - API token for Bearer authentication Default: empty Aliases: apikey

  • user - Username for HTTP Basic Auth Default: empty

Authentication Priority

If both token and user/password are provided, the API token takes precedence and uses Bearer authentication. This is useful for secured-signal-api which prefers Bearer tokens.

Setting up Signal API Server

Signal notifications require a Signal API server that can send messages on behalf of a registered Signal account. These implementations are built on top of signal-cli, the unofficial command-line interface for Signal.

Popular open-source implementations include:

Common setup involves:

  1. Phone Number: A dedicated phone number registered with Signal
  2. API Server: A server running signal-cli with REST API capabilities
  3. Account Linking: Linking the server as a secondary device to your Signal account
  4. Optional Security Layer: Authentication and endpoint restrictions via a proxy

The server must be able to receive SMS verification codes during initial setup and maintain a persistent connection to Signal's servers.

Setup Resources

See the signal-cli-rest-api documentation and secured-signal-api documentation for detailed setup instructions.

Recipients

Recipients can be:

  • Phone numbers: With country code (e.g., +0987654321)
  • Group IDs: In the format group.groupId. A group ID can contain /, so it may span several path segments. It ends at the next phone number (+...), username (u:...), or group ID (group....).
  • Usernames: In the format u:nickname.123

Recipients set with the recipients (or to) query or send param are comma-separated and must use the same formats.

Important

The Signal API rejects mixed recipient types in a single /v2/send request. Shoutrrr splits them: all phone numbers go in one request, all usernames in another, and each group in its own request. A URL that lists phones and a group therefore results in more than one POST. If any of those requests fail, the others may already have been sent.

TLS Configuration

  • Use signal:// for HTTPS (default, recommended)
  • Use signal://...?disabletls=yes for HTTP (insecure, for local testing only)
  • Use skiptlsverify=yes to skip certificate-chain trust and hostname validation (expired, untrusted, and hostname-mismatched certificates). TLS 1.2 remains the minimum.

Examples

Send to a single phone number

signal://localhost:8080/+1234567890/+0987654321

Send to multiple recipients

signal://localhost:8080/+1234567890/+0987654321/+1123456789/group.testgroup

The two phone numbers are sent together. The group is a second /v2/send call.

Send to a group

signal://localhost:8080/+1234567890/group.abcdefghijklmnop=

Send to a group ID that contains a slash

signal://localhost:8080/+1234567890/group.ABCD/EFGH=/+0987654321

The recipients are the group group.ABCD/EFGH= and the phone number +0987654321.

With authentication

signal://user:password@localhost:8080/+1234567890/+0987654321

With API token (Bearer auth)

signal://localhost:8080/+1234567890/+0987654321?token=YOUR_API_TOKEN

Send to a username

signal://localhost:8080/+1234567890/u:someuser.123

Using HTTP instead of HTTPS

signal://localhost:8080/+1234567890/+0987654321?disabletls=yes

Styled message

signal://localhost:8080/+1234567890/+0987654321?textmode=styled

Note

  • When textmode=styled, the message body may include *italic*, **bold**, ~strikethrough~, ||spoiler||, and `monospace`.
  • Escape a formatting character with two backslashes.
  • If textmode is omitted, the JSON text_mode field is omitted and the API server default applies.

Title

Signal has no separate title field. A non-empty title (URL query, or the send title param) is prepended as the first line of the message. With textmode=styled the title is wrapped in **...**.

signal://localhost:8080/+1234567890/+0987654321?title=Alert&textmode=styled

Attachments

Use the attachments query parameter or send param with comma-separated raw base64 values. If the value contains data:, it is sent as a single data URI (data URIs contain commas, so they are not split).

signal://localhost:8080/+1234567890/+0987654321?attachments=base64data1,base64data2

Attachment Format

Raw base64 entries may be comma-separated. A data: URI must be sent as a single value.

Implementation Notes

Shoutrrr's Signal service sends messages using POST requests to the Signal API server's /v2/send endpoint. Requests use HTTPS by default and HTTP only when TLS is disabled. The JSON payload contains the message, source number, recipient list, and optional text_mode, notify_self, and base64_attachments. The API server handles the actual Signal protocol communication. A successful response lists the result of each send. If it reports recipients that Signal could not reach, such as unregistered numbers, the send returns an error that names each recipient and the failure reason.