Docs·Reports
/api/v1/spreelytics/reports/:reportIdUpdate a report
Changes a saved report. Send only what changes: name, config (a whole new one, checked as on create), dashboardId (another dashboard in this audience to move it to) or layout (null lets the app place it). Moving or resizing a card on a dashboard in the app saves its layout this way.
A report always sits on one dashboard, so it cannot be taken off every dashboard: "dashboardId": null or an empty one answers 400. To get rid of a report, delete it.
It answers 404 when the id is not a report in this audience. Needs the Editor or Admin role in the workspace that owns the audience. A Viewer gets 403.
Keys: an account key. Getting started explains both kinds.
Parameters
| Prop | In | Type | Notes |
|---|---|---|---|
reportId | path | string | The report id. |
contactListId | query | string | The audience id, a UUID. With an audience key it must be that key's own audience. |
Request body
| Prop | Type | Notes |
|---|---|---|
name? | string | Optional. Trimmed, and a blank name answers 400. |
config? | SpreelyticsSavedReportConfig | Optional. A whole new config, which replaces the old one and is checked as on create. |
dashboardId? | string | Optional. Another dashboard in this audience to move the report to. |
layout? | object | Optional. A new grid slot { x, y, w, h }, or null to let the app place the card. |
Response
| Prop | Type | Notes |
|---|---|---|
id | string | The report id. |
name | string | The report name. |
dashboardId | string | The dashboard it sits on. Every report sits on one. |
config | SpreelyticsSavedReportConfig | The saved settings, exactly as they were sent. POST /reports describes them. |
layout | object | Its slot on the dashboard grid as { x, y, w, h }, or null when the app places it. |
createdAt | string | When it was created. Only the create call answers in ISO 8601 (2026-09-30T09:00:00.000Z). Every other call returns the database form (2026-09-30 09:00:00+00), so parse both. |
updatedAt | string | When it last changed. Create and update calls answer in ISO 8601, lists and reads in the database form, as with createdAt. |
Request
curl -X PUT 'https://app.spreelytics.com/api/v1/spreelytics/reports/:reportId?contactListId=…' \
-H 'Authorization: Bearer YOUR_API_KEY' \
-H 'Content-Type: application/json' \
-d '{ … }'
const res = await fetch('https://app.spreelytics.com/api/v1/spreelytics/reports/:reportId', {
method: 'PUT',
headers: {
Authorization: 'Bearer YOUR_API_KEY',
'Content-Type': 'application/json',
},
body: JSON.stringify({ /* see Request body above */ }),
});
const data = await res.json();
import requests
res = requests.put(
"https://app.spreelytics.com/api/v1/spreelytics/reports/:reportId",
headers={"Authorization": "Bearer YOUR_API_KEY"},
json={}, # see Request body above
)
data = res.json()
Response
{
"id": "string",
"name": "string",
"dashboardId": "string",
"config": {
"kind": "chart",
"chartType": "line",
"interval": "minute",
"range": "30min",
"startDate": "string",
"endDate": "string",
"series": [
{
"id": "string",
"type": "event",
"event": "string",
"events": [
null
],
"eventLabels": {},
"stepsBefore": 0,
"stepsAfter": 0,
"displayName": "string",
"segment": "event",
"property": "string",
"cohortId": "string",
"filters": [
null
],
"formula": "string",
"hideSeries": [
null
]
}
],
"breakdowns": [
"string"
],
"breakdown": "string",
"globalFilters": [
{
"id": "string",
"name": "string",
"operator": "is",
"value": [
null
],
"event": "string"
}
],
"previous": true,
"customDays": 0,
"limit": 0,
"funnelWindowSeconds": 0,
"funnelStrictOrder": true,
"retentionCriteria": "on",
"sankeyExclude": [
"string"
],
"stacked": true,
"tabKeys": [
"string"
],
"metrics": [
"string"
],
"showChart": true
},
"layout": "string",
"createdAt": "string",
"updatedAt": "string"
}