Skip to main content

Queue SLA breach: worked SDK samples

The per-queue SLA pipeline (objective → forecast → breach → escalation) is mapped on the parent page; this page is the runnable reference. Every call below uses the queue id in the path and unwraps Orbit’s standard success envelope (data plus meta.request_id and meta.timestamp). No typed SDK helper covers the sla-breach routes yet, so the SDK examples use each client’s generic request escape hatch.

PUT the complete breach policy

A policy write can carry all seven policy fields. escalationSteps may be empty when you want the single-shot breachAction; a non-empty ladder takes precedence over that field. This is a complete, copy-pasteable payload:
The Node and Python forms use the same fields:
Node SDK
Python SDK
The write is validated before it is saved and normalized before it is used. escalationSteps is capped at 20 entries; each step index must be 1–1000 and each delay 0–1440 minutes. Surviving steps are sorted by stepIndex and renumbered from 1; malformed entries are dropped rather than making the queue fail closed.

The five single-action bodies

When escalationSteps is omitted or [], breachAction selects the one-shot route. These are complete policy bodies; only the action and its related target values differ:
open_ticket — org-admin bell/email notification
page_supervisor — tenant webhook for a paging tool
reroute_to_overflow_queue — both the bell and tenant webhook
enqueue_callback — webhook for downstream callback automation
none — record the breach without fan-out
The single-action surface mapping is open_ticket → bell, page_supervisor → webhook, reroute_to_overflow_queue → both, enqueue_callback → webhook, and none → neither. Every one of them routes notifications and webhooks; none places a call.

Escalation ladder samples

A ladder is authoritative as soon as it contains one valid step: the breach scan ignores breachAction and routes the ladder’s immediate rungs instead. A step 1 with delayMinutesAfterBreach: 0 fires at breach + 0 minutes; delayed steps run off the recorded breach event by the follow-up executor. The six delivery action types are notify, reassign, slack_alert, webhook, slack_webhook, and teams_webhook; none is also accepted as a record-only step. Surface routing is: Use actionConfig.user_ids for notify and reassign. Webhook steps accept an actionConfig.webhook_url; slack_alert can use the same webhook-oriented configuration for the alert integration. The route validates actionConfig as an object and preserves its keys for the configured action.

Three-rung ladder: notify, Slack, then Teams

Two-rung ladder: reassign, then a general webhook

In the second example, page_supervisor is deliberately ignored because the ladder is non-empty. The first reassign rung fires at breach time; the webhook rung is delayed. For the conceptual model and recovery behavior, see Per-queue SLA breach alerting and escalation policies.

Bounds and save-time rejections

The PUT route validates these limits before it saves the policy, and the table is deliberately exhaustive: thresholdSeconds joins the policy fields here because it shares the same 1–86400-second bound. The scan enforces a 60-second floor even when a saved cooldown is 0, so a five-second monitoring loop cannot page more than once per minute. A value of 0 means no additional configured delay beyond that scan floor. shortAbandons changes the denominator to max(0, offeredCalls - shortAbandons); when that denominator is zero, observed_service_level is null and the scan cannot mark the window breached. Validation errors use Orbit’s VALIDATION_ERROR envelope and this route returns HTTP 400 (some client libraries label the same class “unprocessable input,” but do not assume a 422 status here):
For example, sending 21 ladder entries, targetPercentage: 0, breachCooldownSeconds: 86401, or actionType: "pagerduty" reaches this validation path. Send enabled: false instead when you want to remove the saved policy without a validation error.

GET the policy when it is unset

An unset queue returns a normalized disabled policy rather than 404:
Those defaults are 80 / 30 / 15 / none / 300. They describe a disabled policy; they do not enable scans. A queue without a saved row logs nothing, gates nothing, and alerts nothing. PUT with enabled: false has the same disabled result and deletes the queue’s policy entry from the organization-owned settings map. DELETE .../sla-breach/policy is also available when you want the intent to be explicit.

POST a breach scan

Feed one measured window to the scan. windowStart is stored as the event’s window_start; windowEnd is optional request context, but the current event contract stores window_minutes rather than a separate window_end field. If you need a display value, derive windowEnd from windowStart + evaluationWindowMinutes.
Here the denominator is 120 - 3 = 117, so the observed service level is 87 / 117 = 0.743589.... The scan returns breached, observed_service_level, alert_fired (the surfaces that fired, such as ["bell", "webhook"]), policy_configured, event_logged, and cooldown state in data.
Node SDK
A queue with no saved policy returns policy_configured: false, breached: false, event_logged: false, and an empty alert_fired array. A breach inside the scan floor or configured cooldown returns cooldown_active: true and does not append another event.

GET the breach event log

The event log is newest-first and retains at most 200 entries per queue. The endpoint returns 50 events by default; limit is clamped to 1–100.
Go SDK
A full event response looks like this:
Decode the fields this way:
  • occurred_at is the server time when the breach event was saved. window_start is the caller-supplied business timestamp. To display a windowEnd, add window_minutes to window_start; the current response does not expose a separate windowEnd property.
  • offered_calls and answered_within_sla are the values sent to the scan. shortAbandons is a scan-input-only value: it is subtracted from offeredCalls for the denominator, but is not copied into the event row.
  • observed_service_level is the ratio answeredWithinSla / max(0, offeredCalls - shortAbandons), capped at 1. When a window closes with a zero denominator (offeredCalls - shortAbandons = 0), the scan reports observed_service_level: null because there is no observation to compare against the target; such a scan cannot breach and appends no event. Treat null in verdicts as “no data for this window,” never as a breached value.
  • breach_action: "escalation_ladder" means a non-empty ladder won and the single-shot breachAction was ignored. surfaces_fired records the surfaces actually attempted, not every delayed rung that may fire later.
Use Per-queue SLA breach alerting and escalation policies for the conceptual model, and this page when you need a request body, a response shape, or a boundary case. Set ORBIT_API_KEY to a sandbox key (dv_test_sk_...) first. The policy write and scan use the same contract with sandbox and live keys, and these samples do not send a call.