---
title: "Create Report"
description: "Creates an organization-level report configuration. Requires a plan that includes organization reports and available report quota."
---

`POST /api/organization/reports`

Creates a recurring organization report. The organization is derived from your authenticated session or API token. Requires organization **admin** (API tokens act as organization admins). Read-only users cannot create reports.

## Request Body

| Field | Type | Required | Notes |
|---|---|---|---|
| `name` | string | yes | 1-200 chars. |
| `enabled` | boolean | no | Default `true`. |
| `frequency` | `"daily" \| "weekly" \| "monthly"` | no | Default `monthly`. |
| `weekday` | integer 0-6 | when `weekly` | 0 = Sunday. |
| `dayOfMonth` | integer 1-28 | when `monthly` | Capped at 28. |
| `sendHour` | integer 0-23 | no | Default `2`, in `timezone`. |
| `timezone` | string | no | IANA tz, default `Europe/Berlin`. |
| `scopeMode` | `"all" \| "customers" \| "tags"` | no | Default `all`. |
| `scopeCustomerIds` | integer[] | when `customers` | Must belong to your organization. |
| `scopeTagIds` | integer[] | when `tags` | Must belong to your organization. |
| `inclusionMode` | `"all" \| "problems" \| "threshold"` | no | Default `all`. |
| `problemSignals` | object | no | `{ incident, downtimeMinutes, sslDaysLt, responseBreach }`. |
| `thresholdUptimeLt` | number | when `threshold` | e.g. `99.9`. |
| `thresholdResponseGt` | integer (ms) | when `threshold` | |
| `sendWhenEmpty` | boolean | no | Send an "all clear" report when no site matches. Default `false`. |
| `sections` | object | no | Six booleans toggling report sections. |
| `monitorTypes` | string[] | no | Which monitor types the report covers. One or more of `website`, `dns`, `dnsbl`, `domain`, `icmp`, `smtp`, `ssh`, `tcp`, `ftp`, `imap`. Default: all 10. Must contain at least one entry. |
| `sectionsByType` | object | no | Per-type section toggles: `{ "<monitorType>": { "<sectionKey>": boolean } }`. Legal `sectionKey`s depend on the type: see [Section keys by monitor type](#section-keys-by-monitor-type) below. Sending a section key that isn't legal for its type is rejected with `400 Bad Request`. |
| `groupByCustomer` | boolean | no | Sub-group each monitor type's table by customer. Default `false`. |
| `format` | `"email" \| "email_pdf"` | no | Default `email_pdf`. |
| `recipientEmails` | string[] | no | Agency-side email recipients (max 50). |
| `recipientUserIds` | string[] | no | Organization team member user ids (max 50). |

### Section keys by monitor type

| Monitor type | Legal `sectionKey`s |
|---|---|
| `website`, `dns`, `icmp`, `smtp`, `ssh`, `tcp`, `ftp`, `imap` | `fleetSummary`, `worstPerformers`, `perMonitorTable`, `incidentLog` |
| `website` (additionally) | `sslExpiry` |
| `dnsbl` | `dnsblStatus` |
| `domain` | `domainExpiry` |

## Example (cURL)

```bash
BASE_URL="https://uptimeify.io"
TOKEN="<your-api-token>"

curl -X POST "$BASE_URL/api/organization/reports" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Weekly Ops Digest",
    "frequency": "weekly",
    "weekday": 1,
    "scopeMode": "all",
    "inclusionMode": "problems",
    "problemSignals": { "incident": true, "downtimeMinutes": 5, "sslDaysLt": 14, "responseBreach": true },
    "format": "email_pdf",
    "recipientEmails": ["ops@agency.io"]
  }'
```

## Response

```json
{
  "id": "3f1c9c1e-8d2a-4c7e-9b1a-2d5f6a7b8c90",
  "name": "Weekly Ops Digest",
  "enabled": true,
  "frequency": "weekly",
  "weekday": 1,
  "dayOfMonth": null,
  "sendHour": 2,
  "timezone": "Europe/Berlin",
  "scopeMode": "all",
  "inclusionMode": "problems",
  "monitorTypes": ["website", "dns", "dnsbl", "domain", "icmp", "smtp", "ssh", "tcp", "ftp", "imap"],
  "sectionsByType": {},
  "groupByCustomer": false,
  "format": "email_pdf",
  "recipientEmails": ["ops@agency.io"],
  "recipientUserIds": []
}
```

## Common errors

- `401 Unauthorized`: not authenticated.
- `403 Forbidden` (`forbidden`): not an organization admin.
- `400` (`invalidReportSchedule`): `weekly` without `weekday`, or `monthly` without `dayOfMonth`.
- `400` (`invalidReportScope`): scope ids are not owned by your organization, or `threshold` mode without a threshold.
- `400 Bad Request`: a `sectionsByType` entry contains a `sectionKey` that isn't legal for its monitor type (see [Section keys by monitor type](#section-keys-by-monitor-type)), or `monitorTypes` is an empty array.
