<!-- https://developers.silktide.com/v1/governance/report-schedules/create-report-schedule | Governance / Report schedules -->

# Create a report schedule

`POST /v1/report-schedules`

Creates a report schedule: on each run it makes a snapshot from a [report template](https://developers.silktide.com/v1/governance/report-templates.md) and emails it to its subscribers. The response is the new schedule, as [Get a report schedule](https://developers.silktide.com/v1/governance/report-schedules/get-report-schedule.md) returns it, with status `200`.

The first run is due at `scheduleFromDate`, and then every `schedulePeriod` `scheduleInterval`s after it (see [Schedules](https://developers.silktide.com/v1/concepts/schedules.md)). `scheduleFromDate` defaults to now, so a schedule made without one makes its first snapshot and sends its first emails soon after you create it. Set it in the future if you are not ready.

Each snapshot covers the `durationPeriod` `durationInterval`s up to when it runs, and lands in [List reports](https://developers.silktide.com/v1/governance/reports/list-reports.md) with the schedule's `reportScheduleId`.

Subscribers are optional and can be set later. Send them as `subscribers.assigneeIds` and `subscribers.emails`, beside `reportSchedule`, not inside it. (The old documentation listed `assigneesIds` among the schedule's own fields; that is only how [List report schedules](https://developers.silktide.com/v1/governance/report-schedules/list-report-schedules.md) names them.) Silktide does not check `assigneeIds`: an id that names nobody is kept, and nobody gets that email. Email addresses are trimmed, lowercased and deduplicated.

`context` is not checked either: send it in the shape the template's `contextTypeId` takes (see [Context](https://developers.silktide.com/v1/concepts/context.md)), with ids as numbers.

The schedule runs with its creator's permissions, here the API key's.

## Request

### Body

- `reportSchedule` (object, required): The report schedule.
  - `reportTemplateId` (string, required, 1 to 16 characters): The report template to build each snapshot from. Required.
  - `name` (string, optional): Its name, in plain text. Left out or empty, Silktide names it from the template and what it covers.
  - `context` (object or map of any JSON or empty list, optional): What each snapshot covers, in the shape the template's `contextTypeId` takes. Left out, it has none.
    - `websiteId` (integer, required, at least 1): The website.
    - `sectionId` (integer, required): One of its sections. `0` for the whole website.
  - `scheduleInterval` (string, optional): The unit of how often it runs. Defaults to `week`. One of: `day`, `week`, `month`, `year`.
  - `schedulePeriod` (integer, optional, 1 to 90): How many `scheduleInterval`s apart runs are, from `1` to `90`. Defaults to `1`.
  - `scheduleFromDate` (integer, optional): When the schedule counts from, and when it first runs. Defaults to now.
  - `durationInterval` (string, optional): The unit of how far back each snapshot looks. Defaults to `day`. One of: `day`, `week`, `month`, `year`.
  - `durationPeriod` (integer, optional, 1 to 90): How many `durationInterval`s back each snapshot looks, from `1` to `90`. Defaults to `90`.
  - `emailSubject` (string, optional, up to 255 characters): The email's subject, in plain text. Defaults to the snapshot's name followed by "is ready".
  - `emailMessage` (string, optional, up to 4096 characters): Text to put at the top of the email, in plain text. Line breaks are kept.
- `subscribers` (object, optional): Who is emailed each snapshot.
  - `assigneeIds` (list of strings, optional): Users and roles to email, as assignee ids. Replaces the list; left out, it is kept.
  - `emails` (list of strings, optional): Other email addresses to send it to. Replaces the list; left out, it is kept.

## Response

Status `200`.

- `reportSchedule` (object, required): The report schedule.
  - `reportScheduleId` (integer, required, at least 1): The report schedule.
  - `name` (string, required, at least 1 characters): Its name. The snapshots it makes are named from their template, not from this.
  - `reportTemplateId` (string, required, 1 to 16 characters): The report template each snapshot is built from.
  - `context` (object or map of any JSON or empty list, required): What it covers, in the shape its `contextTypeId` takes: `{"websiteId": 3, "sectionId": 0}` for one website, `{"criteria": {...}}` for several. `[]` when it has none.
    - `websiteId` (integer, required, at least 1): The website.
    - `sectionId` (integer, required): One of its sections. `0` for the whole website.
  - `emailSubject` (string, required, up to 255 characters): The subject of the email subscribers get. Empty for the default, the snapshot's name followed by "is ready".
  - `emailMessage` (string, required, up to 4096 characters): Text at the top of the email subscribers get. Can be empty.
  - `scheduleInterval` (string, required): The unit of how often it runs. One of: `day`, `week`, `month`, `year`.
  - `schedulePeriod` (integer, required, 1 to 90): How many `scheduleInterval`s apart runs are. `week` and `2` runs every two weeks.
  - `scheduleFromDate` (integer, required): When the schedule counts from. Each run falls a whole number of periods after it.
  - `durationInterval` (string, required): The unit of how far back each snapshot looks. One of: `day`, `week`, `month`, `year`.
  - `durationPeriod` (integer, required, 1 to 90): How many `durationInterval`s back each snapshot looks, from when it runs.
  - `created` (integer, required): When it was created.
  - `lastRun` (integer, required): When it last made a snapshot. `0` if never.
  - `nextDue` (integer, required): When it next runs. In the past when a run is waiting to be picked up.
  - `creatorAssigneeId` (string, required): The assignee who created it: a user (`u:`), an API key (`a:`), or `system` for those Silktide made itself.
  - `skipped` (object, required, can be null): Null, or why its last due run made no snapshot and sent no email. It runs again by itself once the reason has gone.
    - `at` (integer, required): When the run was due.
    - `reason` (string, required): Why it was skipped, as a stable id: `no-platform-access` when the account has no active plan.
    - `message` (string, required, can be null): The reason, in the API user's language. Null for a reason without one.
- `permissions` (object, required): Who may see and admin the report schedule.
  - `components` (list of objects, required): The permissions a report schedule has: one to see it, one to admin it.
    - `permissionId` (string, required): The permission, such as `Report-ReportRead`.
    - `componentType` (string, required): What can be given it. `assignees` for users and roles.
    - `label` (string, required): Its name, such as `Can see this dashboard / snapshot`.
    - `description` (string, required, can be null): What it allows. Null for these permissions.
    - `inheritedPermissionIds` (list of strings, required): Permissions that include this one: anyone with those has this too.
    - `models` (list of any JSON, required): Reserved. Empty for these permissions.
  - `componentValues` (map of list of strings, required): Who was given each permission on this report schedule directly, as assignee ids (`u:` users, `g:` roles).
  - `fixedValues` (map of list of strings, required): Who has each permission from elsewhere, such as account-wide roles. Changed elsewhere, not here.
- `subscribers` (object, required): Who is emailed each snapshot.
  - `assigneeIds` (list of strings, required): Users and roles emailed when it runs, as assignee ids (`u:` users, `g:` roles).
  - `emails` (list of strings, required): Other email addresses it is sent to, lowercased.

## Errors

| Status | Type | When |
| --- | --- | --- |
| 403 | `EditionNotAvailable` | The account does not have Silktide 4. Reports, report schedules and report templates are Silktide 4's, so an account with only Silktide 5 cannot use them. |
| 403 | `AccessDenied` | The API key's user cannot create report schedules. |
| 400 | `InvalidRequest` | `reportSchedule`, `permissions` or `subscribers` is not an object; `reportTemplateId` is missing or names no report template the API key's user can see; `name`, `emailSubject` or `emailMessage` contains `<`, `>` or control characters; `schedulePeriod` is not a whole number from 1 to 90; `durationPeriod` is not a whole number from 1 to 90; an interval is not one of its values; `subscribers.assigneeIds` or `subscribers.emails` is not a list of strings; or a subscriber is not a user or role in the account, or not an email address. `properties.field` names the field. |
| 401 | `NotLoggedIn` | No API key was sent, or it is not a key for this region. |
| 429 | `TooManyRequests` | Too many requests to this path in five seconds. Retry after the number of seconds in the `Retry-After` header, which `properties.retryAfter` repeats. |
| 503 | - | Silktide is busy. Retry after the number of seconds in the `Retry-After` header. |

## Access

- Permission: Can create new report schedules
- Plan feature: none
- Edition: Silktide 4 only
- Cost: free
- Stability: stable, since 1.0.0

## Example: Email a weekly summary of pre-production websites

```bash
curl -X POST "https://api.eu.silktide.com/v1/report-schedules" \
  -H "Authorization: silktide token=$SILKTIDE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "reportSchedule": {
    "name": "Weekly pre-production website summary",
    "reportTemplateId": "websites",
    "context": {
      "criteria": {
        "tagIds": [
          "pre-production"
        ]
      }
    },
    "scheduleInterval": "week",
    "schedulePeriod": 1,
    "scheduleFromDate": 1796428800,
    "durationInterval": "day",
    "durationPeriod": 7
  },
  "subscribers": {
    "assigneeIds": [
      "u:eu-12",
      "u:eu-14"
    ],
    "emails": [
      "web-team@example.com"
    ]
  }
}'
```

Response:

```json
{
  "reportSchedule": {
    "reportScheduleId": 2,
    "name": "Weekly pre-production website summary",
    "reportTemplateId": "websites",
    "context": {
      "criteria": {
        "tagIds": [
          "pre-production"
        ]
      }
    },
    "emailSubject": "",
    "emailMessage": "",
    "scheduleInterval": "week",
    "schedulePeriod": 1,
    "scheduleFromDate": 1796428800,
    "durationInterval": "day",
    "durationPeriod": 7,
    "created": 1796380000,
    "lastRun": 0,
    "nextDue": 1796428800,
    "creatorAssigneeId": "a:3",
    "skipped": null
  },
  "permissions": {
    "components": [
      {
        "permissionId": "Report-ReportScheduleRead",
        "componentType": "assignees",
        "label": "Can see this report schedule",
        "description": null,
        "inheritedPermissionIds": [
          "Report-ReportScheduleAdmin",
          "Report-ReportScheduleReadAll"
        ],
        "models": []
      },
      {
        "permissionId": "Report-ReportScheduleAdmin",
        "componentType": "assignees",
        "label": "Can admin this report schedule",
        "description": null,
        "inheritedPermissionIds": [
          "Report-ReportScheduleAdminAll"
        ],
        "models": []
      }
    ],
    "componentValues": {
      "Report-ReportScheduleRead": [],
      "Report-ReportScheduleAdmin": []
    },
    "fixedValues": {
      "Report-ReportScheduleRead": [],
      "Report-ReportScheduleAdmin": [],
      "Report-ReportScheduleReadAll": [
        "g:2",
        "u:eu-12"
      ],
      "Report-ReportScheduleAdminAll": [
        "g:2",
        "u:eu-12"
      ]
    }
  },
  "subscribers": {
    "assigneeIds": [
      "u:eu-12",
      "u:eu-14"
    ],
    "emails": [
      "web-team@example.com"
    ]
  }
}
```
