Quickstart
Send a notification, ask for approval, and read the result.
1. Get a send key
Sign in to the app and create a channel to get a send key. The Manual has the steps. The key is shown only once, so put it in an environment variable.
export NODD_KEY="nodd_live_s_..."
2. Send a notification
curl https://api.nodd.blipdrop.net/v1/messages \
-H "Authorization: Bearer $NODD_KEY" \
-H "Content-Type: application/json" \
-d '{"kind":"notice","title":"Deploy finished"}'
The API answers 202 when it accepts the message. That does not guarantee it reaches a device.
{
"id": "msg_01JBX7Q2M4N8R5T6V9W0Y1Z2A3",
"status": "queued",
"reply_token": "rt_...",
"sent_at": "2026-11-02T04:12:09Z"
}
3. Ask for approval
With kind set to approval, the message has Approve and Reject buttons and needs Face ID to answer.
curl https://api.nodd.blipdrop.net/v1/messages \
-H "Authorization: Bearer $NODD_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: deploy-482" \
-d '{
"kind": "approval",
"level": "high",
"title": "Production deploy approval",
"body": "Deploys api v2.4.1 to production",
"fields": [{"label": "Environment", "value": "production"}],
"expires_in": 3600
}'
4. Read the result
Read the state with the id. While no response is recorded, the reply has Retry-After, so wait that many seconds before trying again.
curl https://api.nodd.blipdrop.net/v1/messages/msg_01JBX7Q2M4N8R5T6V9W0Y1Z2A3 \
-H "Authorization: Bearer $NODD_KEY"
{
"id": "msg_01JBX7Q2M4N8R5T6V9W0Y1Z2A3",
"kind": "approval",
"source": "api",
"sent_at": "2026-11-02T04:12:09Z",
"expires_at": "2026-11-02T05:12:09Z",
"action_state": "claimed",
"approvals_required": 1,
"response": {
"option_id": "reject",
"actor": {"id": "usr_...", "display_name": "Sato"},
"assurance": "biometric",
"responded_at": "2026-11-02T04:13:40Z",
"note": "Check it on staging first",
"signature": {"alg": "ES256", "key_id": "dev_...", "value": "...", "nonce": "..."}
},
"delivery": {"confirmed": 1, "delayed": 0, "unconfirmed": 0, "failed": 0}
}
- Continue only when
response.option_idisapprove - If
action_stateisexpired,cancelled, orfailedwith noresponse, it ended without an answer. Never treat no response as approval response.noteis the rejection reason or the answer toinput, present only if the responder wrote one
Instead of polling, you can use callbacks or the events API. When your work is done, report it with POST /v1/messages/{id}/result and the card changes to done.
The same with the CLI
The CLI waits for approval and returns the result as an exit code.
brew install blipdrop/tap/nodd
nodd login
nodd ask "Deploy to production?" && ./deploy.sh
Scan the QR code from nodd login with the app. See the CLI page for more.