Doorbell

Documentation

Getting started · Ringing · Ringtones · Deadlines · Senders · Keeping ring URLs private · Limits and bans · API reference

Getting started

  1. Download and run the Mac app. It creates a listener key, registers a doorbell, and shows your ring URL.
  2. Use the app's Open test page to ring yourself from the browser, or Test to ring from the app.
  3. Give the ring URL to your agents, ideally in the DOORBELL_URL environment variable.

A ring URL looks like https://doorbell.test01.tomorrowtoday.com/r/db_7h3kq9x2mvb8wz4tn6rc5py1fd. Anyone with it can ring you. Only your Mac can read the rings.

Ringing

Ring with a GET on the ring URL, or a POST of JSON to it. Both take the same fields.

curl "$DOORBELL_URL?source=ci&ringtone=done&message=Build%20passed"

curl -X POST "$DOORBELL_URL" \
  -H 'Content-Type: application/json' \
  -d '{"source":"ci","ringtone":"done","message":"Build passed","link":"https://ci.example/runs/8812"}'
FieldRequiredLimitMeaning
sourceYes40 charactersThe sending app or agent. Use the same name every time.
ringtoneNo; defaults to defaultMust be in the doorbell's listWhich ringtone plays
messageNo80 characters; longer is cutText shown with the ring
linkNo2,000 characters; http or httpsOpened when the ring is clicked
ResultStatusBody
Accepted202ring_id, received_at, and truncated: true if the message was cut
Same ring within the last 60 seconds200duplicate_of: the earlier ring ID
No source400Plain text explaining how to ring
Unknown ringtone422error and valid_ringtones
Other malformed request400error
Too many rings, or banned429Retry-After header
Unknown address404The same plain response as any unknown path

Ring once per event, and do not retry a ring that returned 2xx. A duplicate counts as delivered.

Ringtones and naming

Ringtone names are lowercase kebab-case: letters a to z, digits, and single hyphens, starting with a letter, at most 32 characters. Most doorbells have default, done, needs-input, error, missed, and emergency. The Mac app owns the list and the sounds; the server knows only names and descriptions. Until the app publishes its list, only default is accepted.

curl -s "$DOORBELL_URL/info"

returns the doorbell's ringtones with descriptions, so an agent can choose one. It never returns rings.

Deadlines

Before long or fragile work, an agent can promise a ring. If no matching ring arrives in time, the server rings missed, so you know to check on the agent.

curl -s "$DOORBELL_URL/deadline?source=etl-agent&ringtone=done&like=Refresh*&minutes=20"
FieldRequiredMeaning
sourceYesThe source the expected ring will come from
ringtoneNo; defaultThe ringtone the expected ring will use
likeNo; *Pattern for the whole message: * is any run of characters, ? is one, case-insensitive
minutesYes1 to 1,440
missed_ringtoneNo; missedThe ringtone played if the deadline is missed

The response is 202 with deadline_id and due_at. Any matching ring clears the deadline, including a duplicate. Setting the same source, ringtone, and pattern again restarts the clock. Cancel with DELETE $DOORBELL_URL/deadlines/{deadline_id}. A doorbell may have 20 active deadlines. Deadlines are checked when your Mac polls, so a missed one rings within one poll interval, or when the Mac comes back online.

Senders

Keeping ring URLs private

A ring URL is a secret, like a webhook URL. Keep it in DOORBELL_URL or a config file rather than in code. Never commit it to a public repository, and do not paste it into chat: link previews can fetch it and ring you. If it leaks, use Replace address in the app and update your agents. The worst a leaked URL allows is unwanted rings, which the limits below contain.

Messages are readable by the server and held for an hour. Treat a message like a text on a lock screen.

Limits and bans

API reference

OperationMethod and pathNeeds
RingGET /r/{address}, POST /r/{address}Ring URL
Doorbell infoGET /r/{address}/infoRing URL
Set a deadlineGET /r/{address}/deadline, POST /r/{address}/deadlinesRing URL
Cancel a deadlineDELETE /r/{address}/deadlines/{deadline_id}Ring URL and deadline ID
RegisterPOST /v1/doorbellsListener key
Start a sessionPOST /v1/doorbells/{address}/sessionsListener key
Poll for ringsGET /v1/doorbells/{address}/ringsSession token
Publish ringtone listPUT /v1/doorbells/{address}/ringtonesSession token
Replace addressPOST /v1/doorbells/{address}/replaceSession token
Test pageGET /test/{address}?exp=…&sig=…A link signed by the app
HealthGET /health, GET /health.jsonNothing
Agent skillGET /downloads/doorbell-skill.zipNothing

Desktop endpoints are used by the Mac app. Their signing rules are part of the project's scope notes rather than this page.