Your backend can attach a phone notification to an approved custom event. Barua queues it for the person the event names and hands it to Apple for each of their phones on its next run, once a minute.
Before you start
The owner has turned notifications on and
your backend registers phones. The
custom event also needs an enabled service policy, the same approval a
service email uses. Send with a live key that has events:write and
service:write. Backfill and test keys never send.
Add the block
{"event_id":"notes_ready:meeting-4812","name":"notes_ready","external_id":"4812","occurred_at":"2026-11-12T09:00:00Z",
"service_notification":{"title":"Your notes are ready","body":"Open the app to read them.","data":{"screen":"notes"}}}
title is one line of at most 200 characters and body is the text. data
holds string values your app reads when the person taps; aps is Apple's
name and is refused. expires_in_seconds is 0 to 2,419,200, one day by
default, counted from when Barua accepted the event. Apple keeps it that long
for a phone that is offline. Barua tries for at most an hour, so 0 sends
nothing. An event whose notification is over Apple's 4,096 bytes is
quarantined.
Use marketing_notification for marketing, with the same fields. It also
needs the owner's marketing statement and the person's yes. An event carries
only one of the two blocks. Resending the same event_id with the other block is
an event_id_conflict.
It goes to every live device registered for that external_id, across your
apps. A merged person can hold two identity rows; only the one you name is
notified.
When a request is refused
409 notifications_not_enabled refuses the whole request while
notifications are off, so drop the block or stop sending. 409 marketing_notifications_not_enabled refuses the whole request,
service events in it included, while the marketing statement is off. Keep
marketing notifications in a request of their own until it is on.
Marketing answers
A missing answer ends the delivery no_consent. Send the person's answer
first, as notification_consent_updated or
marketing_notification_opt_in on signed_up, with the live key, a new
event_id for every change and the current time, and wait until it shows as
applied. The iPhone permission prompt is a separate question; your app needs
both.
Read the outcome
curl https://barua.ai/api/integrations/v1/service-notifications/notes_ready%3Ameeting-4812 \
-H "Authorization: Bearer $BARUA_EVENT_KEY"
Use the live key that sent the event. The answer has class, status,
reason (a code and a message for the owner) and a count per device
outcome, never the text. A 404 means the event isn't applied
yet, or another key sent it.
queued is waiting to send or to retry. accepted means Apple took it for
at least one phone; Apple delivers it when the phone is online, and the
person's settings decide whether it shows. unconfirmed means a
request reached Apple with no answer, and Barua never sends it again.
no_devices means no live phone, or Apple reported every token gone.
no_consent means no recorded yes. cancelled means an approval changed, or the
person was erased, before it went. failed means an
hourly limit was spent (20 per person and 1,000 per workspace, for each
kind), Apple refused it for every phone (apple_refused, or
wrong_environment for a token from the other build type), Apple refused
the app's key (app_key_rejected), or an hour passed without Apple taking
it (expired). A later device or a later yes does not revive a finished
delivery.
Nothing Barua does later, a pause or an erasure included, can recall what Apple already accepted. Erasing a person removes the stored text and keeps the status. Stored text has no retention window yet. Exact rules are in the events reference.