# Support First Response Business Hours Report (`h_murdock/support-business-hours-evidence`) Actor

Compute first-response business duration and target due dates from normalized ticket exports and expanded work intervals. Flag incomplete calendars or response observations; export traceable evidence without support-system access.

- **URL**: https://apify.com/h_murdock/support-business-hours-evidence.md
- **Developed by:** [Gilad Ronen](https://apify.com/h_murdock) (community)
- **Categories:** Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$0.25 / completed report

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Support First Response Business Hours Report

Calculate first-response business duration and declared-target due dates from a normalized ticket export and a finite set of working intervals. Use it for a weekly spreadsheet handoff, a consultant review, or checking how a changed working calendar affects a supplied batch. Each ticket includes the exact calendar segments consumed, source references, response-observation status, and a target classification.

Zendesk and Freshdesk already provide business-hour metrics and policies. This Actor is useful when you need a portable calculation and evidence report from authorized exports. It does not connect to either service or reproduce their channel-specific, automation, solved-ticket, or advanced SLA rules. You decide which response qualifies as the first reply before uploading the data.

### Prepare the input

Supply `snapshotId`, an explicit `asOf` timestamp, `responseObservation`, `schedules`, and both input tables. `tickets` contains `sourceId`, `ticketId`, `createdAt`, `firstReplyAt`, `scheduleId`, and `targetMinutes`. Use literal string IDs so values such as `0001` retain their zeros. `firstReplyAt` must be an explicit instant or JSON `null`; target minutes must be a positive integer between 1 and 525,600. Creation and reply cannot be after `asOf`, and reply cannot precede creation.

Each schedule declares `scheduleId`, `coverageStart`, `coverageEnd`, and `coverage`: `complete`, `incomplete`, or `unknown`. `workIntervals` contains `scheduleId`, `intervalId`, `start`, and `end`. Expand weekdays, split shifts, holidays, and daylight saving changes yourself. All dates require seconds and `Z` or a known numeric RFC3339 offset; local timestamps, unknown `-00:00` offsets, leap seconds, and precision beyond milliseconds are rejected. Output instants use UTC.

Intervals are half-open `[start,end)`, must remain inside the schedule's coverage bounds, and cannot overlap. Adjacent intervals are allowed. Duplicate schedule IDs, duplicate `sourceId` plus `ticketId`, and duplicate schedule plus interval IDs are rejected, including identical duplicates. Deduplicate the export intentionally before submission; the Actor never chooses a winning duplicate silently.

For `responseObservation`, declare `from`, `through`, and `coverage`. These boundaries are inclusive and apply to all supplied ticket sources. `complete` means you assert that the supplied first reply, or its absence, is fully observed over that period. Both response observation and the calendar must be complete over creation through the measured endpoint before the report reaches a target conclusion. In a complete calendar, time without a supplied interval is non-working. In an incomplete calendar, that omission cannot establish a closure.

### Understand the result

An answered ticket consumes working time between creation and its supplied first reply. A ticket without a reply consumes working time through `asOf`. An answered duration equal to the target is `answered_within_target`. A missing response at equality is `pending_at_target`; only a strictly greater duration is `pending_after_target`.

`observedBusinessMilliseconds`, seconds, and minutes show supplied interval intersections even when evidence is partial. `measuredBusinessMilliseconds` is `null` when calendar coverage does not establish the whole duration. `classification` is `unresolved` when calendar or response coverage is insufficient. A blank reply does not prove lateness without complete response observation. Unknown due dates are separate from response conclusions: an already answered ticket can have a measured duration while its longer target falls beyond the supplied future calendar. The Actor never invents future work intervals.

The sample shows a ticket created at 17:30 and answered at 09:30 the next working day. With shifts from 09:00 to 18:00, it consumes 60 business minutes and meets a 60-minute target exactly. It also includes an answered-after-target ticket and pending tickets below, at, and above their target.

### CSV and downloads

Instead of either array, remove that array and provide its nonempty CSV alternative: `ticketsCsv` or `workIntervalsCsv`. Canonical headers are the field names above. `ticketColumns` and `intervalColumns` can map every canonical field to a distinct header; no extra columns are accepted. `csvDelimiter` supports comma, semicolon, or tab. BOMs and quoted fields are accepted; duplicate headers, irregular rows, and noncanonical integer targets are rejected. An empty first-reply CSV cell means `null`; header-only CSV means an explicitly empty table.

The dataset contains one complete report. Download `OUTPUT` JSON, flat `evidence.csv`, review `findings.csv`, and standalone `report.html`. JSON retains all calendar sources and interval traces. CSV includes interval arrays as JSON cells and neutralizes formula prefixes. HTML escapes identifiers, has no scripts or external assets, and should be downloaded before opening locally.

### Price, limits, and privacy

The intended price is **$0.25 per completed report**, with platform usage included. There is no startup fee or additional dataset-item fee. Invalid input, insufficient report budget, and output-cap failures produce no report event. Resuming the same run restores exports and keeps one report and one charge; a new run is a new billable report. An interrupted export may leave partial uncharged files until the same run resumes. If delivery or billing state is inconsistent, recovery refuses to guess.

Limit each input to 4 MB, 100 schedules, and 5,000 combined ticket and interval rows. Reports support at most 10,000 combined measured and due-date evidence segments, JSON below 8 MB, and each export below 9 MB; split a batch if one of those bounds is exceeded. An empty ticket table produces an unresolved summary and provides no evidence about tickets absent from the export. All findings require human review and are conditional on your supplied coverage assertions. This is not legal SLA certification, employee ranking, alerting, or a source-system update.

Use authorized exports and opaque identifiers; do not include names, email addresses, message bodies, credentials, or confidential content unnecessary for the calculation. Apify retains the cloud run's input and results under your account and platform retention settings. The Actor makes no external requests and does not use paid AI APIs.

# Actor input Schema

## `snapshotId` (type: `string`):

Opaque reference for the supplied batch; no implicit clock or sample fallback.

## `asOf` (type: `string`):

Real RFC3339 instant with seconds and Z or known numeric offset; at most3fractional digits. Measures missing replies through this instant. Future ticket creation or replies rejected.

## `responseObservation` (type: `object`):

Required {from,through,coverage}. Instants use explicit RFC3339 offsets, from≤through inclusive. coverage complete/incomplete/unknown declares whether all first responses or their absence were observed over the full window across supplied sources. Target conclusions require complete coverage of ticket creation through its supplied reply or asOf. A missing reply is not proof of no reply outside complete coverage.

## `schedules` (type: `array`):

Unique scheduleId, coverageStart, coverageEnd, coverage (complete/incomplete/unknown). All fields required; real explicit-offset instants; start\<end. Caller already expands weekdays, holidays and DST. In complete coverage, unlisted time is non-working. Partial/unknown coverage yields unresolved conclusions. No recurring calendar guessing.

## `tickets` (type: `array`):

Each row requires literal sourceId, ticketId, createdAt, firstReplyAt (instant or null), scheduleId and targetMinutes (positive integer1–525600). Caller determines which reply counts under their policy; no native-channel emulation. Duplicate sourceId+ticketId rejected, including identical rows. Supply this array OR ticketsCsv; remove this array when using CSV. Explicit\[] accepted. Combined tickets+workIntervals≤5000;4MB input;10000report evidence segments.

## `workIntervals` (type: `array`):

Each row requires scheduleId, intervalId, start,end. Intervals are \[start,end), positive duration, explicit RFC3339 offsets; inside schedule coverage. Duplicate schedule+interval IDs and overlaps rejected. Adjacent intervals allowed. Supply this array OR workIntervalsCsv; remove this array for CSV. Explicit\[] means no supplied work intervals.

## `ticketsCsv` (type: `string`):

Remove tickets array before supplying nonempty CSV. Exactly sourceId,ticketId,createdAt,firstReplyAt,scheduleId,targetMinutes unless mapped. Blank firstReplyAt means null. Canonical positive integer target; unknown/duplicate headers and ragged rows rejected; quoted fields/BOM accepted. Header-only CSV is an explicit empty batch.

## `workIntervalsCsv` (type: `string`):

Remove workIntervals array before supplying nonempty CSV. Exactly scheduleId,intervalId,start,end unless mapped. Quoting/BOM accepted; unknown/duplicate headers and irregular records rejected.

## `ticketColumns` (type: `object`):

Optional complete mapping of canonical fields (sourceId,ticketId,createdAt,firstReplyAt,scheduleId,targetMinutes) to distinct literal CSV headers, no extra mapping keys. Omit for canonical headers. Noncanonical mapping requires ticket CSV.

## `intervalColumns` (type: `object`):

Optional complete mapping of canonical fields (scheduleId,intervalId,start,end) to distinct literal CSV headers, no extra mapping keys. Noncanonical mapping requires interval CSV.

## `csvDelimiter` (type: `string`):

Comma, semicolon or tab, applying to both CSV tables. Omit for comma. Does not alter array inputs.

## Actor input object example

```json
{
  "snapshotId": "support-week-2026-10-02",
  "asOf": "2026-10-02T12:00:00Z",
  "responseObservation": {
    "from": "2026-09-28T00:00:00Z",
    "through": "2026-10-02T12:00:00Z",
    "coverage": "complete"
  },
  "schedules": [
    {
      "scheduleId": "weekday-9-18",
      "coverageStart": "2026-09-28T00:00:00Z",
      "coverageEnd": "2026-10-06T00:00:00Z",
      "coverage": "complete"
    }
  ],
  "tickets": [
    {
      "sourceId": "helpdesk-export",
      "ticketId": "0001",
      "createdAt": "2026-10-01T17:30:00Z",
      "firstReplyAt": "2026-10-02T09:30:00Z",
      "scheduleId": "weekday-9-18",
      "targetMinutes": 60
    },
    {
      "sourceId": "helpdesk-export",
      "ticketId": "0002",
      "createdAt": "2026-10-02T09:00:00Z",
      "firstReplyAt": "2026-10-02T10:15:00Z",
      "scheduleId": "weekday-9-18",
      "targetMinutes": 60
    },
    {
      "sourceId": "helpdesk-export",
      "ticketId": "0003",
      "createdAt": "2026-10-02T11:30:00Z",
      "firstReplyAt": null,
      "scheduleId": "weekday-9-18",
      "targetMinutes": 60
    },
    {
      "sourceId": "helpdesk-export",
      "ticketId": "0004",
      "createdAt": "2026-10-02T11:00:00Z",
      "firstReplyAt": null,
      "scheduleId": "weekday-9-18",
      "targetMinutes": 60
    },
    {
      "sourceId": "helpdesk-export",
      "ticketId": "0005",
      "createdAt": "2026-10-02T09:00:00Z",
      "firstReplyAt": null,
      "scheduleId": "weekday-9-18",
      "targetMinutes": 60
    }
  ],
  "workIntervals": [
    {
      "scheduleId": "weekday-9-18",
      "intervalId": "2026-09-28",
      "start": "2026-09-28T09:00:00Z",
      "end": "2026-09-28T18:00:00Z"
    },
    {
      "scheduleId": "weekday-9-18",
      "intervalId": "2026-09-29",
      "start": "2026-09-29T09:00:00Z",
      "end": "2026-09-29T18:00:00Z"
    },
    {
      "scheduleId": "weekday-9-18",
      "intervalId": "2026-09-30",
      "start": "2026-09-30T09:00:00Z",
      "end": "2026-09-30T18:00:00Z"
    },
    {
      "scheduleId": "weekday-9-18",
      "intervalId": "2026-10-01",
      "start": "2026-10-01T09:00:00Z",
      "end": "2026-10-01T18:00:00Z"
    },
    {
      "scheduleId": "weekday-9-18",
      "intervalId": "2026-10-02",
      "start": "2026-10-02T09:00:00Z",
      "end": "2026-10-02T18:00:00Z"
    },
    {
      "scheduleId": "weekday-9-18",
      "intervalId": "2026-10-05",
      "start": "2026-10-05T09:00:00Z",
      "end": "2026-10-05T18:00:00Z"
    }
  ],
  "ticketColumns": {
    "sourceId": "sourceId",
    "ticketId": "ticketId",
    "createdAt": "createdAt",
    "firstReplyAt": "firstReplyAt",
    "scheduleId": "scheduleId",
    "targetMinutes": "targetMinutes"
  },
  "intervalColumns": {
    "scheduleId": "scheduleId",
    "intervalId": "intervalId",
    "start": "start",
    "end": "end"
  },
  "csvDelimiter": ","
}
```

# Actor output Schema

## `dataset` (type: `string`):

One report containing every ticket conclusion, measured and due-date intervals, calendar sources and coverage.

## `json` (type: `string`):

No description

## `evidence` (type: `string`):

No description

## `findings` (type: `string`):

No description

## `html` (type: `string`):

Escaped standalone HTML; download and open locally.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "snapshotId": "support-week-2026-10-02",
    "asOf": "2026-10-02T12:00:00Z",
    "responseObservation": {
        "from": "2026-09-28T00:00:00Z",
        "through": "2026-10-02T12:00:00Z",
        "coverage": "complete"
    },
    "schedules": [
        {
            "scheduleId": "weekday-9-18",
            "coverageStart": "2026-09-28T00:00:00Z",
            "coverageEnd": "2026-10-06T00:00:00Z",
            "coverage": "complete"
        }
    ],
    "tickets": [
        {
            "sourceId": "helpdesk-export",
            "ticketId": "0001",
            "createdAt": "2026-10-01T17:30:00Z",
            "firstReplyAt": "2026-10-02T09:30:00Z",
            "scheduleId": "weekday-9-18",
            "targetMinutes": 60
        },
        {
            "sourceId": "helpdesk-export",
            "ticketId": "0002",
            "createdAt": "2026-10-02T09:00:00Z",
            "firstReplyAt": "2026-10-02T10:15:00Z",
            "scheduleId": "weekday-9-18",
            "targetMinutes": 60
        },
        {
            "sourceId": "helpdesk-export",
            "ticketId": "0003",
            "createdAt": "2026-10-02T11:30:00Z",
            "firstReplyAt": null,
            "scheduleId": "weekday-9-18",
            "targetMinutes": 60
        },
        {
            "sourceId": "helpdesk-export",
            "ticketId": "0004",
            "createdAt": "2026-10-02T11:00:00Z",
            "firstReplyAt": null,
            "scheduleId": "weekday-9-18",
            "targetMinutes": 60
        },
        {
            "sourceId": "helpdesk-export",
            "ticketId": "0005",
            "createdAt": "2026-10-02T09:00:00Z",
            "firstReplyAt": null,
            "scheduleId": "weekday-9-18",
            "targetMinutes": 60
        }
    ],
    "workIntervals": [
        {
            "scheduleId": "weekday-9-18",
            "intervalId": "2026-09-28",
            "start": "2026-09-28T09:00:00Z",
            "end": "2026-09-28T18:00:00Z"
        },
        {
            "scheduleId": "weekday-9-18",
            "intervalId": "2026-09-29",
            "start": "2026-09-29T09:00:00Z",
            "end": "2026-09-29T18:00:00Z"
        },
        {
            "scheduleId": "weekday-9-18",
            "intervalId": "2026-09-30",
            "start": "2026-09-30T09:00:00Z",
            "end": "2026-09-30T18:00:00Z"
        },
        {
            "scheduleId": "weekday-9-18",
            "intervalId": "2026-10-01",
            "start": "2026-10-01T09:00:00Z",
            "end": "2026-10-01T18:00:00Z"
        },
        {
            "scheduleId": "weekday-9-18",
            "intervalId": "2026-10-02",
            "start": "2026-10-02T09:00:00Z",
            "end": "2026-10-02T18:00:00Z"
        },
        {
            "scheduleId": "weekday-9-18",
            "intervalId": "2026-10-05",
            "start": "2026-10-05T09:00:00Z",
            "end": "2026-10-05T18:00:00Z"
        }
    ],
    "ticketsCsv": "",
    "workIntervalsCsv": "",
    "ticketColumns": {
        "sourceId": "sourceId",
        "ticketId": "ticketId",
        "createdAt": "createdAt",
        "firstReplyAt": "firstReplyAt",
        "scheduleId": "scheduleId",
        "targetMinutes": "targetMinutes"
    },
    "intervalColumns": {
        "scheduleId": "scheduleId",
        "intervalId": "intervalId",
        "start": "start",
        "end": "end"
    },
    "csvDelimiter": ","
};

// Run the Actor and wait for it to finish
const run = await client.actor("h_murdock/support-business-hours-evidence").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "snapshotId": "support-week-2026-10-02",
    "asOf": "2026-10-02T12:00:00Z",
    "responseObservation": {
        "from": "2026-09-28T00:00:00Z",
        "through": "2026-10-02T12:00:00Z",
        "coverage": "complete",
    },
    "schedules": [{
            "scheduleId": "weekday-9-18",
            "coverageStart": "2026-09-28T00:00:00Z",
            "coverageEnd": "2026-10-06T00:00:00Z",
            "coverage": "complete",
        }],
    "tickets": [
        {
            "sourceId": "helpdesk-export",
            "ticketId": "0001",
            "createdAt": "2026-10-01T17:30:00Z",
            "firstReplyAt": "2026-10-02T09:30:00Z",
            "scheduleId": "weekday-9-18",
            "targetMinutes": 60,
        },
        {
            "sourceId": "helpdesk-export",
            "ticketId": "0002",
            "createdAt": "2026-10-02T09:00:00Z",
            "firstReplyAt": "2026-10-02T10:15:00Z",
            "scheduleId": "weekday-9-18",
            "targetMinutes": 60,
        },
        {
            "sourceId": "helpdesk-export",
            "ticketId": "0003",
            "createdAt": "2026-10-02T11:30:00Z",
            "firstReplyAt": None,
            "scheduleId": "weekday-9-18",
            "targetMinutes": 60,
        },
        {
            "sourceId": "helpdesk-export",
            "ticketId": "0004",
            "createdAt": "2026-10-02T11:00:00Z",
            "firstReplyAt": None,
            "scheduleId": "weekday-9-18",
            "targetMinutes": 60,
        },
        {
            "sourceId": "helpdesk-export",
            "ticketId": "0005",
            "createdAt": "2026-10-02T09:00:00Z",
            "firstReplyAt": None,
            "scheduleId": "weekday-9-18",
            "targetMinutes": 60,
        },
    ],
    "workIntervals": [
        {
            "scheduleId": "weekday-9-18",
            "intervalId": "2026-09-28",
            "start": "2026-09-28T09:00:00Z",
            "end": "2026-09-28T18:00:00Z",
        },
        {
            "scheduleId": "weekday-9-18",
            "intervalId": "2026-09-29",
            "start": "2026-09-29T09:00:00Z",
            "end": "2026-09-29T18:00:00Z",
        },
        {
            "scheduleId": "weekday-9-18",
            "intervalId": "2026-09-30",
            "start": "2026-09-30T09:00:00Z",
            "end": "2026-09-30T18:00:00Z",
        },
        {
            "scheduleId": "weekday-9-18",
            "intervalId": "2026-10-01",
            "start": "2026-10-01T09:00:00Z",
            "end": "2026-10-01T18:00:00Z",
        },
        {
            "scheduleId": "weekday-9-18",
            "intervalId": "2026-10-02",
            "start": "2026-10-02T09:00:00Z",
            "end": "2026-10-02T18:00:00Z",
        },
        {
            "scheduleId": "weekday-9-18",
            "intervalId": "2026-10-05",
            "start": "2026-10-05T09:00:00Z",
            "end": "2026-10-05T18:00:00Z",
        },
    ],
    "ticketsCsv": "",
    "workIntervalsCsv": "",
    "ticketColumns": {
        "sourceId": "sourceId",
        "ticketId": "ticketId",
        "createdAt": "createdAt",
        "firstReplyAt": "firstReplyAt",
        "scheduleId": "scheduleId",
        "targetMinutes": "targetMinutes",
    },
    "intervalColumns": {
        "scheduleId": "scheduleId",
        "intervalId": "intervalId",
        "start": "start",
        "end": "end",
    },
    "csvDelimiter": ",",
}

# Run the Actor and wait for it to finish
run = client.actor("h_murdock/support-business-hours-evidence").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "snapshotId": "support-week-2026-10-02",
  "asOf": "2026-10-02T12:00:00Z",
  "responseObservation": {
    "from": "2026-09-28T00:00:00Z",
    "through": "2026-10-02T12:00:00Z",
    "coverage": "complete"
  },
  "schedules": [
    {
      "scheduleId": "weekday-9-18",
      "coverageStart": "2026-09-28T00:00:00Z",
      "coverageEnd": "2026-10-06T00:00:00Z",
      "coverage": "complete"
    }
  ],
  "tickets": [
    {
      "sourceId": "helpdesk-export",
      "ticketId": "0001",
      "createdAt": "2026-10-01T17:30:00Z",
      "firstReplyAt": "2026-10-02T09:30:00Z",
      "scheduleId": "weekday-9-18",
      "targetMinutes": 60
    },
    {
      "sourceId": "helpdesk-export",
      "ticketId": "0002",
      "createdAt": "2026-10-02T09:00:00Z",
      "firstReplyAt": "2026-10-02T10:15:00Z",
      "scheduleId": "weekday-9-18",
      "targetMinutes": 60
    },
    {
      "sourceId": "helpdesk-export",
      "ticketId": "0003",
      "createdAt": "2026-10-02T11:30:00Z",
      "firstReplyAt": null,
      "scheduleId": "weekday-9-18",
      "targetMinutes": 60
    },
    {
      "sourceId": "helpdesk-export",
      "ticketId": "0004",
      "createdAt": "2026-10-02T11:00:00Z",
      "firstReplyAt": null,
      "scheduleId": "weekday-9-18",
      "targetMinutes": 60
    },
    {
      "sourceId": "helpdesk-export",
      "ticketId": "0005",
      "createdAt": "2026-10-02T09:00:00Z",
      "firstReplyAt": null,
      "scheduleId": "weekday-9-18",
      "targetMinutes": 60
    }
  ],
  "workIntervals": [
    {
      "scheduleId": "weekday-9-18",
      "intervalId": "2026-09-28",
      "start": "2026-09-28T09:00:00Z",
      "end": "2026-09-28T18:00:00Z"
    },
    {
      "scheduleId": "weekday-9-18",
      "intervalId": "2026-09-29",
      "start": "2026-09-29T09:00:00Z",
      "end": "2026-09-29T18:00:00Z"
    },
    {
      "scheduleId": "weekday-9-18",
      "intervalId": "2026-09-30",
      "start": "2026-09-30T09:00:00Z",
      "end": "2026-09-30T18:00:00Z"
    },
    {
      "scheduleId": "weekday-9-18",
      "intervalId": "2026-10-01",
      "start": "2026-10-01T09:00:00Z",
      "end": "2026-10-01T18:00:00Z"
    },
    {
      "scheduleId": "weekday-9-18",
      "intervalId": "2026-10-02",
      "start": "2026-10-02T09:00:00Z",
      "end": "2026-10-02T18:00:00Z"
    },
    {
      "scheduleId": "weekday-9-18",
      "intervalId": "2026-10-05",
      "start": "2026-10-05T09:00:00Z",
      "end": "2026-10-05T18:00:00Z"
    }
  ],
  "ticketsCsv": "",
  "workIntervalsCsv": "",
  "ticketColumns": {
    "sourceId": "sourceId",
    "ticketId": "ticketId",
    "createdAt": "createdAt",
    "firstReplyAt": "firstReplyAt",
    "scheduleId": "scheduleId",
    "targetMinutes": "targetMinutes"
  },
  "intervalColumns": {
    "scheduleId": "scheduleId",
    "intervalId": "intervalId",
    "start": "start",
    "end": "end"
  },
  "csvDelimiter": ","
}' |
apify call h_murdock/support-business-hours-evidence --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,h_murdock/support-business-hours-evidence"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/Wx6O892ZZ5qhMouhF/builds/KiaC5xzXr1b3qbHGF/openapi.json
