An actionable alert tells someone what changed, why it matters, and what they can safely do next. It names an owner, shows the evidence behind the proposed response, and says how to tell whether the problem is actually fixed. A notification with a button but no safe next step is still just a notification.
We will put a fictional failed import through that test, then send the resulting review request to ActionBox. You can try it with a test Source; there is no need to connect a production job.
What makes an alert actionable?
Imagine receiving “Import failed. Retry?” on your phone. You do not know which import failed, whether it changed anything, or whether retrying will create duplicate records. The button asks you to take responsibility for a decision without giving you the facts needed to make it.
Google's SRE guidance on being on-call says a page should call for an immediate human action that the system cannot take itself. Prometheus alerting guidance similarly recommends alerting on symptoms that matter to users and avoiding pages where there is nothing to do. Those are tests for whether to interrupt someone. The alert still needs to help that person respond.
The useful distinction is between four events:
| Event | What you know | What you do not know yet |
|---|---|---|
| Detection | A check found a problem. | Whether the right person saw it. |
| Delivery | An alert reached a channel or device. | Whether anyone understood or accepted the work. |
| Decision | A person chose a bounded response. | Whether the requested operation succeeded. |
| Verification | The service checked the resulting state. | Whether the same failure will recur tomorrow. |
Treating delivery or acknowledgement as resolution is how dashboards turn green while customers still see a broken result.
The six-field alert test
Before adding another notification route, ask whether the alert can answer these six questions. This is a design checklist for this guide, not a universal scoring standard.
| Field | Question for the recipient | Failed-import example |
|---|---|---|
| Symptom | What is wrong, in terms of the work people need? | Today's catalog import stopped before the new catalog was published. |
| Scope | Which run, customers, or records are affected? | Run catalog-demo-42; 742 of 800 rows completed, leaving 58 unprocessed. |
| Owner | Who can make the next decision? | The person responsible for the catalog feed, not every member of the engineering channel. |
| Choice | What specific response is possible now? | Retry the remaining rows after checking the checkpoint, or keep the run paused. |
| Safety | What must be true before that response executes? | The checkpoint still matches the run and processed rows will not be applied twice. |
| Proof | What would demonstrate recovery? | All 800 rows validate, the new catalog is published, and the expected version is visible. |
If the safety field is unknown, “Investigate” is a better next step than “Retry.” A useful alert can explicitly say that no operation is safe yet. Datadog's monitor guidance also emphasizes context such as the affected service, priority, and responsible team; it should be possible to follow that context to the relevant evidence without copying sensitive data into every message.
For your next alert, copy this packet and replace each line with a fact your system can establish. Leave a field marked unknown rather than filling it with a guess:
Problem: [user-visible symptom]
Affected: [service, run, or customer scope]
Owner: [person or team able to respond]
Evidence: [current state and restricted investigation link]
Next choice: [bounded action or investigation]
Safety check: [condition the executor must recheck]
Recovery check: [observable output that proves success]When to page or automate
Making every alert interactive does not make the system safer. Choose the response according to the impact and the uncertainty.
| Situation | Better default | Why |
|---|---|---|
| A transient failure with a tested, idempotent retry | Retry automatically within a limit; retain the record. | A person adds delay without adding judgment. |
| A warning with no current user impact | Record it or create a nonurgent task. | An interruption has no immediate benefit. |
| A failed job with possible partial side effects | Pause and present a reviewable choice. | Blind replay may duplicate work or publish incomplete data. |
| An ongoing user-visible outage with a documented mitigation | Page the responsible responder with the runbook and live evidence. | The person can take an immediate, defined step. |
| A signal whose cause and safe response are unknown | Route to investigation, without a one-click repair button. | The system has not established what an automated operation would do. |
An alert can lead to an incident tool, a ticket, an automated repair, or a human decision. ActionBox is useful for the last case: a specific person needs to choose between defined responses and your integration needs that answer back. It is not a replacement for the system that detects the failure.
A failed import: from vague warning to useful decision
Consider a synthetic catalog import for a storefront. The worker stopped after processing 742 of 800 rows, leaving 58 unprocessed. In this example, it recorded a checkpoint, did not publish the new catalog, and can check whether an attempted retry would repeat writes. These are assumptions of the example, not measured customer outcomes.
The weak alert is short but leaves the hard work to the reader:
Catalog import failed. Retry?The decision-ready version gives the reader a starting point:
Today's catalog update is on hold
Run: catalog-demo-42
Processed: 742 / 800 rows; new catalog not published
Last confirmed checkpoint: row 742
Next check: inspect the failure at row 743 and verify the checkpoint
Choice: retry remaining rows after that check, or keep the run paused
Recovery proof: 800 / 800 rows validated and catalog version updatedThat is longer than a lock-screen preview should be. Put a short, content-light hint in the notification and keep the full packet behind the authenticated review page. Provide a restricted link to error details if the reviewer needs them; do not paste customer records, credentials, or a raw log dump into the alert.
Notice what the packet does not say: it does not promise that clicking Retry will repair the source data. The worker must check the current run and the failure at row 743 first. If that evidence changes while someone is reading, the old decision must not authorize a different operation.
Try the example in ActionBox
First, create a free Source and copy its key into a trusted shell as ACTIONBOX_SOURCE_KEY. The quickstart shows how to send a harmless test Action before you connect a real job. Source keys belong in your server, worker, or CI secret store, never browser code.
The following request creates a demo decision only. It does not restart an import. Save the JSON as action.json and send it with a stable idempotency key:
{
"title": "Catalog import stopped before publishing",
"description": "Synthetic run catalog-demo-42 processed 742 of 800 rows. No new catalog was published. Inspect the failure at row 743 and confirm the checkpoint before any retry.",
"priority": "high",
"options": [
{ "id": "retry_remaining", "label": "Retry after checking", "style": "primary" },
{ "id": "hold", "label": "Keep run paused", "style": "default" }
],
"metadata": {
"run_id": "catalog-demo-42",
"checkpoint": 742
}
}curl --fail-with-body --request POST https://api.actionbox.cloud/v1/actions \
--header "Authorization: Bearer $ACTIONBOX_SOURCE_KEY" \
--header "Idempotency-Key: catalog-demo-42-review" \
--header "Content-Type: application/json" \
--data @action.jsonOpen the ActionBox inbox, inspect the request, and choose a response. Before you answer, you should see one open Action with two explicit choices. Repeating the identical request with the same Idempotency-Key inside the documented replay window returns the same Action instead of creating another one; changing its body while reusing that key is a conflict. See Actions and idempotency for the exact contract.
The first test is deliberately small: it proves that a worker can send a reviewable decision and a person can answer it. It does not prove that the failed job can resume safely. The Action is the decision record; your worker remains responsible for the import.
Connect the decision to real recovery
Once the harmless request works, connect a customer-owned worker to the decision. Persist its run ID, checkpoint, expected catalog version, and Action ID. The worker can wait by polling or receive a signed callback when the Action reaches a terminal state.
Before it acts, the worker should:
- Verify the callback signature and timestamp if it uses webhooks, deduplicate the event, and read the current Action state.
- Check that the reviewer chose
retry_remaining, that the Action is resolved by an eligible user, and that itsaction_versionandfingerprintstill match the reviewed run. - Recheck the checkpoint, source version, and downstream state. A response to yesterday's packet must not replay today's import.
- Execute the bounded retry idempotently, then validate the published catalog rather than equating process exit with success.
- Report the execution outcome for that resolved Action. Keep the job's output checks as the authoritative proof of recovery.
The hold option keeps the customer's run paused; it is a completed human decision, not a successful import. If the Action expires or the callback cannot be verified, leave the run paused and investigate. Do not infer consent from silence. For a full callback implementation, use the webhook approval example, which covers signatures, deduplication, and safe resumption.
Test the failure paths
A success-path screenshot is useful, but the failure paths show whether the workflow is safe. Run these checks against a disposable job and synthetic records:
| Exercise | Expected behavior |
|---|---|
| Send the same create request twice. | One Action is reviewed; duplicate sends do not create duplicate work. |
| Choose Keep run paused. | The worker does not retry; the decision remains visible. |
| Let the Action expire or interrupt callback delivery. | The worker stays paused until it reads an authoritative state. |
| Change the run or checkpoint before an approved retry. | The stale decision cannot authorize a different operation. |
| Simulate a retry that starts but fails verification. | The outcome is reported as failed; the catalog remains marked unrecovered. |
If a test fails, fix that boundary before putting a real operation behind the response. In particular, an accepted webhook is evidence of delivery, not evidence that the downstream job succeeded.
Measure whether your alerts help
You do not need a vendor benchmark to find weak alerts in your own system. Review a recent sample of pages and record, for each one, whether someone had a useful action to take, how long they spent finding context, whether the proposed response was safe, and whether recovery was verified. Keep the raw examples with private data removed so the team can discuss the same cases.
A simple actionability rate for that review is:
Pages that led to a necessary human action ÷ all pages reviewedThis is a local diagnostic, not an industry benchmark or an ActionBox performance claim. Track it alongside duplicate pages, time to assign an owner, and the share of attempted recoveries that passed their output check. A rising acknowledgement rate alone may mean people are clicking faster; it does not establish that incidents are being resolved.
If most pages have no useful next step, improve the alert condition before adding a response button. If pages are valid but reviewers keep opening three dashboards to find the same facts, improve the review packet. If decisions are quick but jobs stay broken, investigate execution and verification. Each failure points to a different part of the system.
Where ActionBox fits
ActionBox gives an integration a hosted place to create a durable Action, present defined responses in the web inbox or iPhone app, and return the decision to the calling system. The Action and its event history are the review record. Optional push helps someone notice it, but push delivery is not proof of review. The Source still owns detection, the operation, and the test of whether the operation worked.
Start with one harmless alert whose next step needs judgment. Create a free Source, send the example request above, and answer it in the inbox. Once reviewers understand the choices and your failure tests pass, connect the signed callback and your idempotent retry path. For implementation details, follow the Action API, notification behavior, and decision outcomes.
