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:
NoneAliases:text_modePossible 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:
- signal-cli-rest-api: Dockerized REST API wrapper for signal-cli
- secured-signal-api: Security proxy for signal-cli-rest-api with authentication and access control
Common setup involves:
- Phone Number: A dedicated phone number registered with Signal
- API Server: A server running signal-cli with REST API capabilities
- Account Linking: Linking the server as a secondary device to your Signal account
- 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=yesfor HTTP (insecure, for local testing only) - Use
skiptlsverify=yesto 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
textmodeis omitted, the JSONtext_modefield 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.