# Schedules and time

> Read time entries (who worked when) and the schedule blocks that are not jobs.

- Canonical URL: https://couplrfsm.com/developers/api-reference/schedules-and-time
- Markdown: https://couplrfsm.com/developers/api-reference/schedules-and-time.md
- API version: v1 (base URL https://couplrfsm.com/api/v1)
- OpenAPI specification: https://couplrfsm.com/developers/openapi.yaml
- All documentation pages: https://couplrfsm.com/llms.txt

> **Flip:** Here is who clocked in and when, on a job or around the shop, and the blocks on the schedule that are not jobs, like time off and meetings. I give you hours. I do not give you what anyone is paid.

Base URL: `https://couplrfsm.com/api/v1`. Conventions shared by every endpoint (examples, ids, dates, money) are on the [API reference](https://couplrfsm.com/developers/api-reference) page. Errors, pagination and idempotency are in [Errors, limits and retries](https://couplrfsm.com/developers/errors-and-limits).

## List time entries

`GET /api/v1/time-entries` · requires the `timesheets:read` ability

Each time someone clocked in, most recent first: on a job, or on
other paid time such as the shop or training. Hours only. Pay rates
and payroll figures are not available through the API.

**Query parameters**

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `page` | integer | No | Default: `1`. |
| `per_page` | integer | No | Values above 100 are served as 100. Default: `25`. |
| `updated_since` | string (date-time) | No | Only records changed at or after this time. ISO 8601, for example `2026-11-14T15:00:00Z`. |
| `technician_id` | integer | No |  |
| `job_id` | integer | No |  |
| `type` | string: `job`, `shift` | No |  |
| `from` | string (date-time) | No | Clocked in at or after this time. |
| `to` | string (date-time) | No | Clocked in at or before this time. |

**Example request**

```bash
curl "https://couplrfsm.com/api/v1/time-entries" \
  -H "Authorization: Bearer YOUR_API_KEY"
```

**Example response** (`200`)

```json
{
    "data": [
        {
            "id": 30211,
            "technician_id": 14,
            "technician_name": "Sam Wrench",
            "job_id": 9312,
            "type": "job",
            "category": null,
            "clock_in_at": "2026-11-14T15:02:11+00:00",
            "clock_out_at": "2026-11-14T16:47:40+00:00",
            "worked_minutes": 95,
            "created_at": "2026-11-14T15:02:11+00:00",
            "updated_at": "2026-11-14T16:47:40+00:00"
        }
    ],
    "meta": {
        "page": 1,
        "per_page": 25,
        "total": 1,
        "last_page": 1
    }
}
```

**Errors**

| Status | When |
| --- | --- |
| `401` | No key (`api_key_missing`), the key is unknown or revoked (`api_key_invalid`), the key had an end date that has passed (`api_key_expired`), or the key belongs to a private trial sandbox whose access window has ended (`sandbox_expired`). |
| `403` | The key lacks the ability this endpoint needs (`ability_missing`), no admin user is left to act for the key (`no_acting_admin`), or the company's account is not yet verified. |
| `422` | A parameter or field is invalid (`validation_failed`). `errors` maps each field to its messages. |
| `429` | Too many requests (`rate_limited`). Wait `Retry-After` seconds. |

## List schedule events

`GET /api/v1/schedule-events` · requires the `timesheets:read` ability

Blocks on the schedule that are not jobs: time off, meetings and
held slots. Most recent date first. Jobs are read with the Jobs
endpoints.

**Query parameters**

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `page` | integer | No | Default: `1`. |
| `per_page` | integer | No | Values above 100 are served as 100. Default: `25`. |
| `updated_since` | string (date-time) | No | Only records changed at or after this time. ISO 8601, for example `2026-11-14T15:00:00Z`. |
| `technician_id` | integer | No | Events for this person, and events for the whole company. |
| `kind` | string: `time_off`, `meeting`, `hold`, `other` | No |  |
| `from` | string (date) | No |  |
| `to` | string (date) | No |  |

**Example request**

```bash
curl "https://couplrfsm.com/api/v1/schedule-events" \
  -H "Authorization: Bearer YOUR_API_KEY"
```

**Example response** (`200`)

```json
{
    "data": [
        {
            "id": 512,
            "kind": "time_off",
            "title": "Vacation",
            "date": "2026-12-24",
            "start_time": null,
            "end_time": null,
            "is_company_wide": false,
            "technician_ids": [
                14
            ],
            "created_at": "2026-11-01T12:00:00+00:00",
            "updated_at": "2026-11-01T12:00:00+00:00"
        }
    ],
    "meta": {
        "page": 1,
        "per_page": 25,
        "total": 1,
        "last_page": 1
    }
}
```

**Errors**

| Status | When |
| --- | --- |
| `401` | No key (`api_key_missing`), the key is unknown or revoked (`api_key_invalid`), the key had an end date that has passed (`api_key_expired`), or the key belongs to a private trial sandbox whose access window has ended (`sandbox_expired`). |
| `403` | The key lacks the ability this endpoint needs (`ability_missing`), no admin user is left to act for the key (`no_acting_admin`), or the company's account is not yet verified. |
| `422` | A parameter or field is invalid (`validation_failed`). `errors` maps each field to its messages. |
| `429` | Too many requests (`rate_limited`). Wait `Retry-After` seconds. |
