Skip to main content

Squillify development is paused indefinitely. Read why, and discover what this experiment achieved. Read the story

MicroSkills Reference

SLA Deadline Calculator

business.sla_deadline

ProductionBounded custom (Class B)Deterministicstrictfastv1.0.0
No network

Overview

You send the instant the clock started, the priority, and the policy that governs it — business hours per weekday, the weekend, the holidays, and the target minutes per priority. We walk working time forward and return the deadline in UTC and in the policy's own timezone, together with the escalation instants and the pauses that were actually applied. A BUSINESS target consumes only time inside your windows, so evenings, weekends and holidays cost nothing; a CALENDAR target is plain elapsed time for a 24x7 commitment. Pauses suspend the clock for their overlap with working time only, which is why pausing over a weekend consumes nothing. Send asOf as well and we also report how much of the target has been used, what is left, and whether it has been breached. Weekend, holiday and next-working-day questions are answered by the same calendar engine as the time skills, so two answers can never disagree about whether a date is a working day. The clock is never read: every instant is yours.

Every support tool computes SLA deadlines, and most of them get the edges wrong: a ticket opened at 16:50 on the Friday before a public holiday, a lunch gap that should not count, a pause taken over a weekend, a clock walked in local time straight through a daylight-saving transition. Getting those right needs a walk over declared working time, not an addition of hours, and it needs the same weekend and holiday definition the rest of the platform uses.

Reliability

Fully deterministic: the same request always gives the same instant, and no clock is read. Time is measured as elapsed real time between instants, so a 09:00-17:00 window is seven hours on the spring-forward Sunday and nine on the autumn-back one — which is how long the office was open. A window that falls entirely inside a spring-forward gap contributes nothing that day. Minutes are computed on BigDecimal and rounded HALF_UP to whole minutes; percentages are decimals at 4 places, so 0.2500 is a quarter. Failures: SLA_START_INVALID means start or asOf is not an ISO-8601 instant. SLA_PRIORITY_UNKNOWN means the priority is not a key of slaPolicy.targets. SLA_TIMEZONE_UNKNOWN means the zone id is not an IANA one. SLA_POLICY_INVALID covers the rest of the policy: no targets or more than 32, a duration below 1, a weekday name that is not MONDAY to SUNDAY, a holiday that is not YYYY-MM-DD, an atPercent outside 0 to 1, a repeated escalation name, or an unaccepted property. SLA_BUSINESS_HOURS_REQUIRED means a target uses BUSINESS and no businessHours were sent. SLA_BUSINESS_HOURS_INVALID means a window is inverted, crosses midnight, overlaps the one before it, or a weekday declares more than 4. SLA_PAUSE_INVALID means a pause does not run forward, or is not an instant pair. SLA_HORIZON_EXCEEDED means the target cannot be consumed within 2048 days of start — shorten it or open more working time. SLA_NO_WORKING_TIME means a BUSINESS target met a calendar that never opens, refused immediately rather than walked to the horizon. None is worth retrying unchanged.

Context footprint

The answer is one small object plus one entry per merged pause and per escalation, both capped low. The policy you send dominates the request, and the largest part of it is your own holiday list. A successful call costs 1 execution credit.

When to use it

When you need the instant a commitment expires from a start, a priority and a calendar you can declare — and when you want the escalation points and the breach state from the same answer.

When you only need whole business days, when the calendar is not yours to declare, or when you expect the platform to watch the clock and act.

Scope

Note
Walk a declared working calendar forward from an instant to find when an SLA target runs out, with the escalation points and the pauses actually applied.

Non-goals

  • Does not read the clock — start, asOf and every pause are inputs
  • Does not know your holidays: a holiday is whatever you send
  • Does not escalate, notify, assign or store anything
  • Does not decide priority — you send the one to apply
  • Does not count business days on its own: day classification is the time pack's calendar engine

Properties

IdempotentRetry safeStreaming supportedFile input supportedRequires external service

Capabilities

math

Cost & billing

Flat rate per invocation

MetercallsBillable onsuccessCost per call1 credit

File handling

Accepts file_refProduces file_refMax input1 MB

How we handle your data

Sensitive input, safe output
What this means

This skill may receive sensitive content, but it does not target sensitive data and returns only a structured non-sensitive result.

Squillify guarantees
  • Runs inside Squillify
  • This skill runs inside Squillify.
  • Payloads are not sent to an external service by this skill.
  • Squillify does not permanently store submitted payloads.
  • Telemetry records metadata only, not submitted content.
  • Submitted payloads are not used for training.
  • Submitted payloads are not reviewed by humans.
  • This skill does not target sensitive data.
  • The response does not contain submitted content.
Your responsibility

Squillify does not determine whether submitted content is sensitive. Your application is responsible for deciding what data it is allowed to submit. Your application is responsible for securing the response.

Read the Microskill Data Handling Policy

Input schema

FieldTypeRequiredDescription
startstringYesISO-8601 instant the SLA clock started, never defaulted from a wall clock.
prioritystringYesPriority key looked up exactly in slaPolicy.targets.
slaPolicyobjectYesClosed SLA policy with timezone, targets, optional hours, holidays, weekend, and escalations.
pausesarrayNoBounded array of 0 through 100 pause intervals; omit it when the clock ran uninterrupted.
asOfstringNoISO-8601 progress instant; omit it to return the deadline without consumed or remaining fields.

Output schema

FieldTypeRequiredDescription
deadlinestringYesUTC instant the target runs out, to the second.
deadlineLocalstringYesThe same deadline in the policy timezone with offset.
timezonestringYesIANA timezone the windows were read in.
clockstringYesClock the chosen target declared.
durationMinutesintegerYesTarget minutes the chosen priority declared.
workingMinutesConsumedintegerYesUnpaused working minutes consumed up to asOf or the full target.
pausesarrayYesBounded array of 0 through 100 applied pauses after merge; empty when none were sent.
escalationsAtarrayYesBounded array of 0 through 8 escalation instants in declaration order.
consumedPercentnumberNoConsumed minutes over target, present only when asOf was supplied.
remainingMinutesintegerNoUnspent target minutes, present only when asOf was supplied, never below zero.
breachedbooleanNoWhether asOf is past the deadline, present only when asOf was supplied.

API contract

POST /v1/execute
curl
curl -sS -X POST "$BASE/v1/execute" -H "Authorization: Bearer $KEY" -H 'Content-Type: application/json' -d '{"skillKey":"business.sla_deadline","input":{"start":"2026-03-02T08:00:00Z","priority":"P2","slaPolicy":{"timezone":"Europe/Brussels","targets":{"P2":{"durationMinutes":480}},"businessHours":{"MONDAY":[{"from":"09:00","to":"17:00"}],"TUESDAY":[{"from":"09:00","to":"17:00"}],"WEDNESDAY":[{"from":"09:00","to":"17:00"}],"THURSDAY":[{"from":"09:00","to":"17:00"}],"FRIDAY":[{"from":"09:00","to":"17:00"}]}}}}'
Integrations
TypeScript SDK
import { Squillify } from "@squillify/sdk";

const sq = new Squillify({ apiKey: process.env.SQUILLIFY_API_KEY });

const { output } = await sq.execute("business.sla_deadline", {"start":"2026-03-02T08:00:00Z","priority":"P2","slaPolicy":{"escalations":[{"atPercent":0.75,"name":"notify-lead"}],"businessHours":{"MONDAY":[{"from":"09:00","to":"17:00"}],"TUESDAY":[{"from":"09:00","to":"17:00"}],"WEDNESDAY":[{"from":"09:00","to":"17:00"}],"THURSDAY":[{"from":"09:00","to":"17:00"}],"FRIDAY":[{"from":"09:00","to":"17:00"}]},"timezone":"Europe/Brussels","targets":{"P2":{"durationMinutes":480},"P1":{"durationMinutes":120}}}});

Errors

CodeHTTPRetryableDescription
VALIDATION_ERROR400NoThe request payload failed schema validation.
UNAUTHORIZED401NoMissing or invalid API key.
SKILL_NOT_ACCESSIBLE403NoThe API key is not granted access to this skill.
SKILL_NOT_AVAILABLE_FOR_PLAN403NoThis skill is not included in your current plan.
PLAN_ELIGIBILITY_UNAVAILABLE503YesPlan eligibility could not be decided. Retry after backoff.
SKILL_NOT_FOUND404NoThe requested skill or version does not exist.
TENANT_RATE_LIMITED429YesRequest rate limit exceeded. Retry after backoff.
QUOTA_EXCEEDED429YesPlan quota exhausted. Retryable once the quota period resets.
EXECUTION_TIMEOUT504YesExecution exceeded the allowed time budget.
SLA_START_INVALID400NoThe request payload failed this skill's input validation.
SLA_PRIORITY_UNKNOWN400NoThe request payload failed this skill's input validation.
SLA_POLICY_INVALID400NoThe request payload failed this skill's input validation.
SLA_BUSINESS_HOURS_REQUIRED400NoThe request payload failed this skill's input validation.
SLA_BUSINESS_HOURS_INVALID400NoThe request payload failed this skill's input validation.
SLA_TIMEZONE_UNKNOWN400NoThe request payload failed this skill's input validation.
SLA_PAUSE_INVALID400NoThe request payload failed this skill's input validation.
SLA_HORIZON_EXCEEDED429NoA size, quota, rate, or time limit was exceeded.
SLA_NO_WORKING_TIME412NoThe input is valid but cannot be processed as-is.

Other limits

LimitValue
Recommended inline bytes32 KiB

Limitations

  • Does not read the clock — start, asOf and every pause are inputs
  • Does not know your holidays: a holiday is whatever you send
  • Does not escalate, notify, assign or store anything
  • Does not decide priority — you send the one to apply
  • Does not count business days on its own: day classification is the time pack's calendar engine
  • Counting whole business days between two dates — that is time.business_days_between
  • Adding business days to a date — that is time.add_business_days
  • Deciding which priority a ticket deserves
  • Watching a clock and firing the escalation for you

How to call

POST /v1/execute (requires authentication)

Request bodyjson
{
  "skillKey": "business.sla_deadline",
  "input": {
    "start": "2026-03-02T08:00:00Z",
    "priority": "P2",
    "slaPolicy": {
      "escalations": [
        {
          "atPercent": 0.75,
          "name": "notify-lead"
        }
      ],
      "businessHours": {
        "MONDAY": [
          {
            "from": "09:00",
            "to": "17:00"
          }
        ],
        "TUESDAY": [
          {
            "from": "09:00",
            "to": "17:00"
          }
        ],
        "WEDNESDAY": [
          {
            "from": "09:00",
            "to": "17:00"
          }
        ],
        "THURSDAY": [
          {
            "from": "09:00",
            "to": "17:00"
          }
        ],
        "FRIDAY": [
          {
            "from": "09:00",
            "to": "17:00"
          }
        ]
      },
      "timezone": "Europe/Brussels",
      "targets": {
        "P2": {
          "durationMinutes": 480
        },
        "P1": {
          "durationMinutes": 120
        }
      }
    }
  }
}

Examples

An eight-hour business target opened at the start of a Monday

Inputjson
{
  "start": "2026-03-02T08:00:00Z",
  "priority": "P2",
  "slaPolicy": {
    "escalations": [
      {
        "atPercent": 0.75,
        "name": "notify-lead"
      }
    ],
    "businessHours": {
      "MONDAY": [
        {
          "from": "09:00",
          "to": "17:00"
        }
      ],
      "TUESDAY": [
        {
          "from": "09:00",
          "to": "17:00"
        }
      ],
      "WEDNESDAY": [
        {
          "from": "09:00",
          "to": "17:00"
        }
      ],
      "THURSDAY": [
        {
          "from": "09:00",
          "to": "17:00"
        }
      ],
      "FRIDAY": [
        {
          "from": "09:00",
          "to": "17:00"
        }
      ]
    },
    "timezone": "Europe/Brussels",
    "targets": {
      "P2": {
        "durationMinutes": 480
      },
      "P1": {
        "durationMinutes": 120
      }
    }
  }
}
Expected outputjson
{
  "deadline": "2026-03-02T16:00:00Z",
  "timezone": "Europe/Brussels",
  "durationMinutes": 480,
  "pauses": [],
  "clock": "BUSINESS",
  "escalationsAt": [
    {
      "name": "notify-lead",
      "atPercent": 0.75,
      "at": "2026-03-02T14:00:00Z",
      "atLocal": "2026-03-02T15:00:00+01:00"
    }
  ],
  "deadlineLocal": "2026-03-02T17:00:00+01:00",
  "workingMinutesConsumed": 480
}

The same target opened late on a Friday, over a weekend, a holiday and a pause that costs nothing

Inputjson
{
  "priority": "P1",
  "start": "2026-03-06T15:00:00Z",
  "slaPolicy": {
    "businessHours": {
      "MONDAY": [
        {
          "from": "09:00",
          "to": "17:00"
        }
      ],
      "TUESDAY": [
        {
          "from": "09:00",
          "to": "17:00"
        }
      ],
      "WEDNESDAY": [
        {
          "from": "09:00",
          "to": "17:00"
        }
      ],
      "THURSDAY": [
        {
          "from": "09:00",
          "to": "17:00"
        }
      ],
      "FRIDAY": [
        {
          "from": "09:00",
          "to": "17:00"
        }
      ]
    },
    "timezone": "Europe/Brussels",
    "targets": {
      "P1": {
        "clock": "BUSINESS",
        "durationMinutes": 480
      }
    },
    "holidays": [
      "2026-03-09"
    ]
  },
  "pauses": [
    {
      "from": "2026-03-07T00:00:00Z",
      "to": "2026-03-08T00:00:00Z",
      "reason": "waiting on customer"
    }
  ],
  "asOf": "2026-03-10T09:00:00Z"
}
Expected outputjson
{
  "durationMinutes": 480,
  "timezone": "Europe/Brussels",
  "breached": false,
  "pauses": [
    {
      "from": "2026-03-07T00:00:00Z",
      "to": "2026-03-08T00:00:00Z",
      "reason": "waiting on customer",
      "effectiveMinutes": 0
    }
  ],
  "deadlineLocal": "2026-03-10T16:00:00+01:00",
  "remainingMinutes": 360,
  "deadline": "2026-03-10T15:00:00Z",
  "workingMinutesConsumed": 120,
  "clock": "BUSINESS",
  "escalationsAt": [],
  "consumedPercent": 0.25
}
  • Set a due date on a ticket at creation, from the priority and the support calendar
  • Show a customer when their case is due, in their own timezone
  • Compute escalation instants once, so the reminder job has nothing to guess
  • Report how much of an SLA is spent at a point in time, and whether it is breached

Avoid for

  • Counting whole business days between two dates — that is time.business_days_between
  • Adding business days to a date — that is time.add_business_days
  • Deciding which priority a ticket deserves
  • Watching a clock and firing the escalation for you

Composable with

Safety & privacy

  • Runs without calling any external service.
  • Your payloads are never stored permanently.
  • Telemetry captures metadata only — never your payload contents.
  • We never train models on your payloads.
  • No human reviews your payloads.

Tags

date-timebusinesssladeadline