Settingsintermediate

Recipe — Fire a webhook when a case closes

When a case in a chosen workflow closes, POST a webhook to a downstream system so it can start its own work. The universal escape hatch for systems Atender doesn't natively integrate with.

5 min read

Recipe — Fire a webhook when a case closes

Use a case-close automation to notify a downstream system as soon as a case reaches its closed state. This is useful for refund queues, escalation reporting, fulfillment systems, data warehouses, or any external workflow that should start when a case in a particular workflow is resolved.

What this rule does

This recipe creates a rule that:

  • Trigger: Runs when a case is closed.
  • Condition: Continues only when the case belongs to the workflow you choose — for this recipe, Refunds. Case conditions can also match on stage, status, priority, assigned agent or team, title, or description. There is no case-tag condition.
  • Action: POSTs a JSON payload you write to your downstream system.

The webhook body is sent as you wrote it. There are no case merge tags, and the contact merge tags resolve to empty on a case trigger because a case-close run carries no contact — so the payload can’t identify which case closed. If your receiver needs the case itself, subscribe it to the case.status_changed webhook event, which delivers the full case, or have it query the API (GET /api/v1/cases?status=closed). Use this rule when a fixed “a case closed in this workflow” ping is enough, or as the filtered nudge that tells the receiver to go and look.

Before you start

Prepare:

  • The destination webhook URL from your downstream system.
  • Any required authentication header, such as Authorization: Bearer your-token or X-Shared-Secret: your-token.
  • The payload your receiver expects.
  • A test case in the workflow that can be closed safely.

Store credentials for outbound or inbound integrations securely, and rotate them if they are shared with an external system.

Build it

  1. Go to Settings → Automation rules, click Add rule, then Build it by hand instead.
  2. Under When, choose A case is closed.
  3. Under Only if, add a condition: Workflow is your refunds workflow. The case fields are listed under Cases in the field picker.
  4. Under Then, add the Send webhook to an external service step.
  5. Set the method to POST.
  6. Paste the destination URL.
  7. Add any required headers, for example:
    Content-Type: application/json
    Authorization: Bearer your-token
    X-Shared-Secret: your-token
  8. Paste the body (see below).
  9. Click Create rule. The rule starts Off.
  10. Turn on Run this rule, then close a safe test case to check it before production traffic arrives.

Body template

Use the payload shape your downstream system expects. The body is fixed text: it can’t carry the case’s ID or fields (see above), so keep it to what the receiver needs to know which rule fired.

Example:

{ “event”: “case.closed”, “workflow”: “Refunds”, “source”: “atender-automation” }

Idempotency

Any webhook receiver should be idempotent. Webhook actions can fire more than once for the same logical event under unusual conditions such as network retries, manual re-runs, or re-triggers from edits.

Because the payload doesn’t identify the case, key duplicates on an idempotency key generated by your receiver, or on the case ID once the receiver has looked it up through a webhook subscription or the API.

Throttling

Turn on Limit how often it runs in More options if your downstream system has rate limits. Common pattern: at most 60 every 1 minute, Across the workspace, to protect a small downstream service from a burst of automation events.

Verify it worked

Close a test case that matches the rule condition. Check Run history for the rule. A run shows Success or Failed, with a badge per action:

  • A 2xx response from the receiver leaves the webhook action successful. The response body isn’t stored, so confirm receipt on the receiver’s side.
  • A non-2xx response or a network error marks the action failed and the run Failed; the row shows the error message, which carries the status code and the first part of the receiver’s response body — read it to debug.

Variants

  • Multiple downstream systems. Add more webhook steps under Then — they run in order.
  • Different payloads by workflow or priority. Use branches (More options → Add branch) on the case conditions (Workflow, Stage, Priority, and so on) to send a different fixed payload per branch.
  • Include the case itself. Not possible from this action. Use the case.status_changed webhook subscription instead: it delivers the full case with a previous snapshot, and every delivery is signed with HMAC-SHA256.
  • Authenticate the request. Add a custom header carrying a shared secret (e.g. X-Shared-Secret: your-token) so the receiver can reject requests that don’t come from your rule. Header values are fixed text plus fields — the action can’t compute per-request signatures. If you need cryptographically signed deliveries, use webhook subscriptions instead.

Troubleshooting

  • Symptom: You cannot find the A case is closed trigger. Fix: It is in the Cases group of the When picker. You can also search for “case closed”.

  • Symptom: You cannot find a case-tag condition. Fix: There isn’t one. Filter on Workflow, Stage or Priority instead, or do the tag filtering in your receiver after it has looked the case up.

  • Symptom: Receiver doesn’t see the POST. Fix: Open Run history and read the run’s error message. If the run shows success but the receiver disagrees, the URL is wrong or being intercepted by a proxy. If the run failed with a network error, the URL is unreachable from Atender’s egress IPs — confirm DNS and any IP allowlists.

  • Symptom: Receiver returns 401. Fix: Bearer token is stale or the wrong header name. Some systems expect X-Auth-Token rather than Authorization.

  • Symptom: Receiver returns 422 with a “missing field” error. Fix: Your receiver expected a field the fixed body doesn’t carry — usually a case or contact identifier. This action can’t supply those; get them from a webhook subscription or the API instead.

  • Symptom: Webhook fires multiple times for one event. Fix: Add an appropriate throttle. Make sure the receiver is idempotent regardless.

See also

Tags

Recipe