/v1/scheduled-reports Create a scheduled report
Create a scheduled report. next_run_at is computed from frequency.
The fastest setup passes region_configs: every market (country, optional city, language) with its prompts, created in the same call, all or nothing. The schedule is active as soon as one of them has prompts, and every run leaves one report per active region config.
Without region_configs the schedule starts inactive (is_active: false): one with no region configs produces no reports. It activates by itself as soon as you attach the first active region config in step 2: complete the steps below and no extra call is needed. A schedule left without one never runs and never bills.
Step by step instead:
POST /v1/scheduled-reports(this endpoint).- For each region you want to track:
POST /v1/region-configswithscheduled_report_idset, or create the region config first and attach it viaPOST /v1/scheduled-reports/{id}/region-configs/{config_id}(max 20 configs per schedule). - Seed each config's prompts:
POST /v1/region-configs/{config_id}/prompts.
Every tick (or manual POST .../executions) materialises one report per active region config attached to the schedule.
Client delivery (Agency): set deliver_to_client to email a branded PDF report to the client after every completed run. New schedules hold each report for approval in the app (require_review: true); pass require_review: false to send automatically.
Query parameters
-
Preview the call without executing it. Runs auth, scope, eligibility and body validation, then returns
200with adry_runobject reporting the request-unit and credit cost plus a non-consuming quota snapshot. Nothing is debited, reserved, dispatched or mutated. An invalid body still returns422.default: false
Header parameters
-
Required with an API key, else
400 idempotency_key_required: a new value per operation (a UUID works). A retry with the same key and body within 24 hours replays the first response instead of running again. Ignored withdry_run=true.
Request body
application/json required-
Brand to attach the schedule to (UUID).
-
How often the schedule runs (
daily,weekly,monthly). -
Human-readable label that surfaces in dashboards/emails.
- account_template_id string (nullable) nullable
One of the account's own report templates, used instead of a house template. Pass an empty string to clear it.
- cc_self boolean
Copy the schedule owner on every client report.
- client_intro_message string (nullable) nullable
A short note that opens the client report email.
- deliver_to_client boolean
Email a branded report to the client after every completed run: a PDF built from the schedule's template, sent from the agency's sending domain to
recipient_emailsplus the brand's client email. Needs the brand owner on Agency (a paid plan, not a trial); asking for it below that answers403 brand_plan_required. - recipient_emails array of string
Extra recipients of the client report (up to 10), on top of the brand's client email.
- region_configs array of ScheduleRegionConfigCreate
Region configs to create with the schedule, up to 20: one per market (country, optional city, language), each seeded with its own
promptsor with the prompts of itssource_report_id(copy_report_prompts). Every run leaves one report per active config, never a merged one. All or nothing: if one config fails, the schedule is not created. - require_review boolean (nullable) nullable
When
true(the default for new schedules) the composed report waits for someone to approve and send it in the app. Setfalseto have it sent automatically when the run completes. - template_key string (nullable) nullable
House report template the run is composed from. Pass an empty string to clear it and fall back to the account's default template.
Example payload
{
"brand_id": "3f9c7e8a-1b6a-4d8e-92cf-7d9c8b1e2a04",
"frequency": "weekly",
"name": "adidas weekly visibility"
}Responses
-
Owning brand id (UUID).
-
ISO-8601 timestamp when the schedule was created.
-
Cadence the schedule runs at.
-
Stable schedule identifier (UUID).
-
Whether the schedule will run on its next tick.
-
Human-readable label.
- account_template_id string (nullable) nullable
One of the account's own report templates, used instead of a house template. Pass an empty string to clear it.
- cc_self boolean
Copy the schedule owner on every client report.
- client_intro_message string (nullable) nullable
A short note that opens the client report email.
- deliver_to_client boolean
Email a branded report to the client after every completed run: a PDF built from the schedule's template, sent from the agency's sending domain to
recipient_emailsplus the brand's client email. Needs the brand owner on Agency (a paid plan, not a trial); asking for it below that answers403 brand_plan_required. - last_delivered_at string (nullable) nullable
When the last client report was sent or attempted.
- last_delivery_status string (nullable) nullable
Outcome of the last client delivery, e.g.
sent 2/3orskipped: no recipients. - last_error_message string (nullable) nullable
Human-readable failure reason from the last run, when applicable.
- last_run_at string (nullable) nullable
ISO-8601 timestamp of the last execution.
- last_run_status enum (nullable) nullable
Outcome of the last execution.
- next_run_at string (nullable) nullable
ISO-8601 timestamp of the next scheduled execution.
- object string
Always
scheduled_report. - recipient_emails array of string
Extra recipients of the client report (up to 10), on top of the brand's client email.
- require_review boolean
When
true(the default for new schedules) the composed report waits for someone to approve and send it in the app. Setfalseto have it sent automatically when the run completes. - template_key string (nullable) nullable
House report template the run is composed from. Pass an empty string to clear it and fall back to the account's default template.
Example response
{
"brand_id": "3f9c7e8a-1b6a-4d8e-92cf-7d9c8b1e2a04",
"cc_self": false,
"created_at": "2026-03-01T10:00:00+00:00",
"deliver_to_client": true,
"frequency": "weekly",
"id": "018e7c2d-33ab-7df1-b1cd-2ac3a8f9112d",
"is_active": true,
"last_delivered_at": "2026-04-01T09:04:40+00:00",
"last_delivery_status": "sent 1/1",
"last_run_at": "2026-04-01T09:00:11.412+00:00",
"last_run_status": "completed",
"name": "adidas weekly visibility",
"next_run_at": "2026-04-08T09:00:00+00:00",
"object": "scheduled_report",
"recipient_emails": [
"marketing@e2e.test"
],
"require_review": false
}-
Show fields
-
Stable machine-readable error code from the catalog.
-
Human-readable description suitable for logging.
- details object
Optional, code-specific context (e.g.
errorsarray forvalidation_error,retry_afterforservice_unavailable). Shape depends onerror.code; treat as opaque otherwise.Show fields
Empty object (no properties).
-
- request_id string
Server-generated correlation id for the request. Mirrors the
X-Correlation-IDresponse header. Include this when contacting support.
Example response
{
"error": {
"code": "validation_error",
"message": "Request validation failed"
},
"request_id": "9f6c4e8a-1d3b-4c8b-9f1e-7a3b1c2d3e4f"
}-
Show fields
-
Stable machine-readable error code from the catalog.
-
Human-readable description suitable for logging.
- details object
Optional, code-specific context (e.g.
errorsarray forvalidation_error,retry_afterforservice_unavailable). Shape depends onerror.code; treat as opaque otherwise.Show fields
Empty object (no properties).
-
- request_id string
Server-generated correlation id for the request. Mirrors the
X-Correlation-IDresponse header. Include this when contacting support.
Example response
{
"error": {
"code": "unauthorized",
"message": "Missing or invalid credentials"
},
"request_id": "9f6c4e8a-1d3b-4c8b-9f1e-7a3b1c2d3e4f"
}-
Show fields
-
Stable machine-readable error code from the catalog.
-
Human-readable description suitable for logging.
- details object
Optional, code-specific context (e.g.
errorsarray forvalidation_error,retry_afterforservice_unavailable). Shape depends onerror.code; treat as opaque otherwise.Show fields
Empty object (no properties).
-
- request_id string
Server-generated correlation id for the request. Mirrors the
X-Correlation-IDresponse header. Include this when contacting support.
Example response
{
"error": {
"code": "forbidden",
"message": "You do not have permission to access this resource"
},
"request_id": "9f6c4e8a-1d3b-4c8b-9f1e-7a3b1c2d3e4f"
}-
Show fields
-
Stable machine-readable error code from the catalog.
-
Human-readable description suitable for logging.
- details object
Optional, code-specific context (e.g.
errorsarray forvalidation_error,retry_afterforservice_unavailable). Shape depends onerror.code; treat as opaque otherwise.Show fields
Empty object (no properties).
-
- request_id string
Server-generated correlation id for the request. Mirrors the
X-Correlation-IDresponse header. Include this when contacting support.
Example response
{
"error": {
"code": "conflict",
"message": "Resource conflict"
},
"request_id": "9f6c4e8a-1d3b-4c8b-9f1e-7a3b1c2d3e4f"
}-
Show fields
-
Stable machine-readable error code from the catalog.
-
Human-readable description suitable for logging.
- details object
Optional, code-specific context (e.g.
errorsarray forvalidation_error,retry_afterforservice_unavailable). Shape depends onerror.code; treat as opaque otherwise.Show fields
Empty object (no properties).
-
- request_id string
Server-generated correlation id for the request. Mirrors the
X-Correlation-IDresponse header. Include this when contacting support.
Example response
{
"error": {
"code": "body_validation_error",
"message": "Request body did not match the expected schema"
},
"request_id": "9f6c4e8a-1d3b-4c8b-9f1e-7a3b1c2d3e4f"
}-
Show fields
-
Stable machine-readable error code from the catalog.
-
Human-readable description suitable for logging.
- details object
Optional, code-specific context (e.g.
errorsarray forvalidation_error,retry_afterforservice_unavailable). Shape depends onerror.code; treat as opaque otherwise.Show fields
Empty object (no properties).
-
- request_id string
Server-generated correlation id for the request. Mirrors the
X-Correlation-IDresponse header. Include this when contacting support.
Example response
{
"error": {
"code": "rate_limit_exceeded",
"message": "Per-minute rate limit exceeded"
},
"request_id": "9f6c4e8a-1d3b-4c8b-9f1e-7a3b1c2d3e4f"
}-
Show fields
-
Stable machine-readable error code from the catalog.
-
Human-readable description suitable for logging.
- details object
Optional, code-specific context (e.g.
errorsarray forvalidation_error,retry_afterforservice_unavailable). Shape depends onerror.code; treat as opaque otherwise.Show fields
Empty object (no properties).
-
- request_id string
Server-generated correlation id for the request. Mirrors the
X-Correlation-IDresponse header. Include this when contacting support.
Example response
{
"error": {
"code": "internal_error",
"message": "An unexpected error occurred"
},
"request_id": "9f6c4e8a-1d3b-4c8b-9f1e-7a3b1c2d3e4f"
}-
Show fields
-
Stable machine-readable error code from the catalog.
-
Human-readable description suitable for logging.
- details object
Optional, code-specific context (e.g.
errorsarray forvalidation_error,retry_afterforservice_unavailable). Shape depends onerror.code; treat as opaque otherwise.Show fields
Empty object (no properties).
-
- request_id string
Server-generated correlation id for the request. Mirrors the
X-Correlation-IDresponse header. Include this when contacting support.
Example response
{
"error": {
"code": "service_unavailable",
"message": "Service temporarily unavailable, please retry"
},
"request_id": "9f6c4e8a-1d3b-4c8b-9f1e-7a3b1c2d3e4f"
}