Skip to content

Signal

URL Format

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

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
  • Usernames: In the format u:nickname.123

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=

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.