Skip to content

Push & security alerts

Once a user is paired, the backend pushes two families of notifications to their devices, all signed with HMAC #1:

  • send/auth-challenge — an Approve / Reject prompt (TOTP, golden number, biometrics).
  • send/security-alert — a passive notification (no buttons), for example “new sign-in approved”.

Both broadcast (fan-out) to all of the device tokens the user has registered for the calling tenant.

custom_type chooses the UX the device renders (totp, goldenNumber, or localAuth). instruction_id is your correlation identifier — reuse it later with fetch/delivery-status. ttl_seconds ranges from 10 to 600 (default 180).

Fenêtre de terminal
curl $BASE_URL/api/v1/relay/send/auth-challenge \
-X POST \
-H "X-Bloonio-Tenant-Id: tnt_..." \
-H "X-Bloonio-Timestamp: 1718966400000" \
-H "X-Bloonio-Signature: <hex_hmac_sha256>" \
-H "Content-Type: application/json" \
-d '{
"user_socket_hash": "9f86d081884c7d659a2feaa0c55ad015",
"instruction_id": "instr_abc123",
"custom_type": "totp",
"expected_action": "transfer_funds",
"backend_url": "https://api.example.com",
"description": "Confirm a transfer",
"ttl_seconds": 180
}'

You can attach a structured display block (display) so the app renders typed fields (amount, masked IBAN, party name, etc.):

{
"display": {
"title": "Confirm the transfer",
"subtitle": "Check the details before approving",
"fields": [
{ "key": "amount", "title": "Amount", "value": "1000 USD", "data_type": "CURRENCY_USD" },
{ "key": "to", "title": "Beneficiary", "value": "ACME Corp", "data_type": "PARTY_NAME" }
]
}
}

Response when delivered to at least one device:

{
"success": true,
"status_code": 200,
"message": "Challenge pushed to 1 device(s)",
"data": {
"instruction_id": "instr_abc123",
"delivered_count": 1,
"failed_count": 0,
"fcm_message_ids": ["projects/.../messages/..."],
"failed_tokens_sample": [],
"sent_at": "2026-06-21T..."
}
}

Passive notification — no challenge category, no Approve / Reject buttons. kind is a severity hint (sign_in, security, info) that the app maps to an inbox icon / tint. ttl_seconds ranges from 60 to 604,800 (default 86,400).

Fenêtre de terminal
curl $BASE_URL/api/v1/relay/send/security-alert \
-X POST \
-H "X-Bloonio-Tenant-Id: tnt_..." \
-H "X-Bloonio-Timestamp: 1718966400000" \
-H "X-Bloonio-Signature: <hex_hmac_sha256>" \
-H "Content-Type: application/json" \
-d '{
"user_socket_hash": "9f86d081884c7d659a2feaa0c55ad015",
"title": "New sign-in",
"body": "A new web sign-in was approved on your account.",
"kind": "sign_in",
"notification_id": "ntf_abc123"
}'
{
"success": true,
"status_code": 200,
"message": "Security alert pushed to 1 device(s)",
"data": {
"instruction_id": "ntf_abc123",
"delivered_count": 1,
"failed_count": 0,
"fcm_message_ids": ["projects/.../messages/..."],
"failed_tokens_sample": [],
"sent_at": "2026-06-21T..."
}
}

The failure codes (404 / 502 / 503) are identical to those of send/auth-challenge.

Retrieve the delivery record of an already-sent push, by instruction_id.

Fenêtre de terminal
curl "$BASE_URL/api/v1/relay/fetch/delivery-status?instruction_id=instr_abc123" \
-H "X-Bloonio-Tenant-Id: tnt_..." \
-H "X-Bloonio-Timestamp: 1718966400000" \
-H "X-Bloonio-Signature: <hex_hmac_sha256>"

If no record exists for that instruction_id, the relay returns 404.