Skip to content
Nowlark
API reference menu

Links, images and buttons

A notification can carry a link two ways, and both end up in the same place.

The url field is the notification's link. It appears as a button on the detail screen, and as the Open Link button on the notification itself when you also send actions: ["open"].

A URL written inside title or body becomes tappable on its own. The app detects addresses in the text the way Messages and Mail do, which matters because a sender has one url field and routinely has two things worth pointing at:

{
  "source": "CI",
  "title": "Build 4181 failed",
  "body": "Log: https://ci.yourcompany.com/b/4181  Commit: https://git.yourcompany.com/c/9f3a1c"
}

Both links are live, without spending the url field on either.

Tapping the notification itself opens its link. A notification with a url goes straight to the page when its banner is tapped, the way Prowl did; one without opens the app on that notification. The same rule applies to a row in the app's feed.

Where they open is the person's choice, not yours. In Settings › Links they pick Nowlark's own in‑app browser or their default browser, and every link in the app honours it: the detail screen's button, an address inside the text, and the Open Link button on the notification, which is tapped without the app being open at all. A sender cannot override this, and there is no field to ask.

Only http and https. Prowl passed any scheme through. A link is something a phone opens on a tap, so the scheme is not a remote sender's to choose: anything else is refused 400 invalid_request. The same rule applies to a URL detected inside the text, where the app additionally allows mailto: and tel:, which the phone, not a browser, handles.

Images#

A notification can show a picture: on the notification itself and in the app.

An image already on the web: put its https address in image. The phone fetches it when the notification arrives; if it cannot, the notification arrives without the picture.

A screenshot or any file on your machine: upload it, then send with the id you get back. You need no server or file host of your own.

id=$(curl -sf https://nowlark.com/v1/images -H "X-Nowlark-Key: nlk_…" \
  --data-binary @failed-step.png | jq -er .id) || { echo "upload refused"; exit 1; }

curl https://nowlark.com/v1/notify -H "X-Nowlark-Key: nlk_…" -H 'Content-Type: application/json' \
  -d "{\"source\":\"Job applications\",\"title\":\"Application not sent\",\"image_id\":\"$id\"}"

POST /v1/images takes the file as the request body, or as the one file of a multipart/form-data form (curl -F file=@shot.png). It answers:

{"id": "img_…", "content_type": "image/png", "size": 48213, "expires_unused_at": 1789752000.0}

size is in bytes; expires_unused_at is in epoch seconds.

  • PNG or JPEG, up to 5 MB. Nowlark checks the file's contents, so any Content-Type will do, and a file that is not a real PNG or JPEG is refused 415 unsupported_image whatever its name or header says. Over 5 MB is 413 image_too_large.
  • Private by link. Each image gets an unguessable address that only its notification carries, to your devices. Images are never listed, and they are served with headers that tell search engines not to index them and caches not to store them.
  • Tied to your account. Any of your send keys can use an id. An id another account uploaded, or one that has expired, is refused 400 invalid_request, and so is a send with both image and  image_id.
  • A day to send it. An id you have not sent with yet expires 24 hours after the upload (expires_unused_at). Until then you can send it as many times as you like.
  • Then kept as long as the notification. Once sent, the image stays for as long as any notification showing it is in your history, or a scheduled send is waiting to show it. When the last of them is deleted, or leaves your history, Nowlark deletes the image. A notification already on a phone keeps its picture until it is cleared there.
  • Needs the Upgrade Pass, bought in the Nowlark app, like image. Without it, POST /v1/images returns 402 upgrade_required.
  • 50 MB of images per account. Past that, POST /v1/images returns 409 image_store_full. Space frees up as notifications with images are deleted or leave your history. Sends, including ones with an id you already have, are not affected.

Buttons#

actions puts up to three buttons on the notification, chosen from a fixed vocabulary. It is fixed because iOS renders buttons from a category the app registered before the notification arrived. Nothing in a payload can name a button, so the set has to be knowable in advance.

verb button what it does
open
Open Link
opens url. Requires url, or the send is refused
copy
Copy
puts copy_text on the clipboard without opening the app
mute
Mute Source
mutes this source
done
Mark as Read
marks it read from the Lock Screen
{
  "source": "Staging",
  "title": "Sign-in code for the new build",
  "body": "Valid for ten minutes",
  "url": "https://staging.yourcompany.com/login",
  "actions": ["copy", "open"],
  "copy_text": "4K2P-99MX-TTQ1"
}

copy is the one worth reaching for. A code you were sent is most useful copied straight off the Lock Screen, without unlocking anything.