English
Dashboard
Routes are relative to <PUBLIC_BASE_URL>; request and response bodies are JSON unless stated otherwise. Authentication, scopes, pagination and the error format are described in the REST API guides.
GET /api/v1/dashboard/executions
Dashboard: executions
Volumes, success rate, series by status, most active and most failing workflows, latest failures. scope=org and memberId are reserved to administrators; the series follow the tz of the reader.
Access — Member session or API key with scope dashboard:read.
Parameters
| Name | In | Type | Required |
|---|---|---|---|
scope | query | "me" | "org" | no |
period | query | "24h" | "7d" | "30d" | "custom" | no |
from | query | string (date-time) | no |
to | query | string (date-time) | no |
tz | query | string | no |
mailboxId | query | string (uuid) | no |
workflowId | query | string (uuid) | no |
memberId | query | string (uuid) | no |
Responses
200 — The figures.
| Field | Type | Required |
|---|---|---|
window | object | yes |
current | object | yes |
previous | object | yes |
series | object[] | yes |
topWorkflows | object[] | yes |
failingWorkflows | object[] | yes |
recentFailures | object[] | yes |
JSON Schema
json
{
"type": "object",
"properties": {
"window": {
"type": "object",
"properties": {
"from": { "type": "string" },
"to": { "type": "string" },
"previousFrom": { "type": "string" },
"bucket": { "type": "string", "enum": [ "hour", "day" ] },
"buckets": { "type": "array", "items": { "type": "string" } }
},
"required": [ "from", "to", "previousFrom", "bucket", "buckets" ],
"additionalProperties": false
},
"current": {
"type": "object",
"properties": {
"total": { "type": "integer", "minimum": 0, "maximum": 9007199254740991 },
"byStatus": {
"type": "array",
"items": {
"type": "object",
"properties": {
"status": {
"type": "string",
"enum": [
"queued",
"running",
"waiting",
"succeeded",
"failed",
"cancelled"
]
},
"count": { "type": "integer", "minimum": 0, "maximum": 9007199254740991 }
},
"required": [ "status", "count" ],
"additionalProperties": false
}
},
"successRate": {
"anyOf": [
{ "type": "number", "minimum": 0, "maximum": 1 },
{ "type": "null" }
]
},
"medianDurationMs": { "anyOf": [ { "type": "number", "minimum": 0 }, { "type": "null" } ] }
},
"required": [ "total", "byStatus", "successRate", "medianDurationMs" ],
"additionalProperties": false
},
"previous": {
"type": "object",
"properties": {
"total": { "type": "integer", "minimum": 0, "maximum": 9007199254740991 },
"byStatus": {
"type": "array",
"items": {
"type": "object",
"properties": {
"status": {
"type": "string",
"enum": [
"queued",
"running",
"waiting",
"succeeded",
"failed",
"cancelled"
]
},
"count": { "type": "integer", "minimum": 0, "maximum": 9007199254740991 }
},
"required": [ "status", "count" ],
"additionalProperties": false
}
},
"successRate": {
"anyOf": [
{ "type": "number", "minimum": 0, "maximum": 1 },
{ "type": "null" }
]
},
"medianDurationMs": { "anyOf": [ { "type": "number", "minimum": 0 }, { "type": "null" } ] }
},
"required": [ "total", "byStatus", "successRate", "medianDurationMs" ],
"additionalProperties": false
},
"series": {
"type": "array",
"items": {
"type": "object",
"properties": {
"status": {
"type": "string",
"enum": [
"queued",
"running",
"waiting",
"succeeded",
"failed",
"cancelled"
]
},
"values": {
"type": "array",
"items": { "type": "integer", "minimum": 0, "maximum": 9007199254740991 }
}
},
"required": [ "status", "values" ],
"additionalProperties": false
}
},
"topWorkflows": {
"type": "array",
"items": {
"type": "object",
"properties": {
"workflowId": { "type": "string" },
"name": { "type": "string" },
"memberName": { "anyOf": [ { "type": "string" }, { "type": "null" } ] },
"total": { "type": "integer", "minimum": 0, "maximum": 9007199254740991 },
"succeeded": { "type": "integer", "minimum": 0, "maximum": 9007199254740991 },
"failed": { "type": "integer", "minimum": 0, "maximum": 9007199254740991 },
"lastRunAt": { "anyOf": [ { "type": "string" }, { "type": "null" } ] }
},
"required": [
"workflowId",
"name",
"memberName",
"total",
"succeeded",
"failed",
"lastRunAt"
],
"additionalProperties": false
}
},
"failingWorkflows": {
"type": "array",
"items": {
"type": "object",
"properties": {
"workflowId": { "type": "string" },
"name": { "type": "string" },
"memberName": { "anyOf": [ { "type": "string" }, { "type": "null" } ] },
"total": { "type": "integer", "minimum": 0, "maximum": 9007199254740991 },
"succeeded": { "type": "integer", "minimum": 0, "maximum": 9007199254740991 },
"failed": { "type": "integer", "minimum": 0, "maximum": 9007199254740991 },
"lastRunAt": { "anyOf": [ { "type": "string" }, { "type": "null" } ] }
},
"required": [
"workflowId",
"name",
"memberName",
"total",
"succeeded",
"failed",
"lastRunAt"
],
"additionalProperties": false
}
},
"recentFailures": {
"type": "array",
"items": {
"type": "object",
"properties": {
"executionId": { "type": "string" },
"workflowId": { "type": "string" },
"workflowName": { "type": "string" },
"memberName": { "anyOf": [ { "type": "string" }, { "type": "null" } ] },
"failedAt": { "type": "string" },
"errorCode": { "type": "string" },
"errorSummary": { "type": "string" },
"nodeId": { "anyOf": [ { "type": "string" }, { "type": "null" } ] },
"nodeName": { "anyOf": [ { "type": "string" }, { "type": "null" } ] },
"acknowledged": { "type": "boolean" }
},
"required": [
"executionId",
"workflowId",
"workflowName",
"memberName",
"failedAt",
"errorCode",
"errorSummary",
"nodeId",
"nodeName",
"acknowledged"
],
"additionalProperties": false
}
}
},
"required": [
"window",
"current",
"previous",
"series",
"topWorkflows",
"failingWorkflows",
"recentFailures"
],
"additionalProperties": false
}400 — The request does not match its schema.
401 — No valid session or API key (auth.unauthenticated).
403 — Refused: insufficient role (auth.forbidden), missing scope (api_key.scope_missing, details.required names it) or a route closed to API keys (api_key.session_required).
429 — The API key exceeded its rate limit (api_key.rate_limited); Retry-After says when to retry.
Error codes — dashboard.bad_request, dashboard.forbidden. The common codes (request.bad_request, auth.unauthenticated, api_key.scope_missing, api_key.rate_limited…) apply to every route; see Errors.
GET /api/v1/dashboard/mail
Dashboard: mail
Mails received by outcome, automated, and sent, over the period.
Access — Member session or API key with scope dashboard:read.
Parameters
| Name | In | Type | Required |
|---|---|---|---|
scope | query | "me" | "org" | no |
period | query | "24h" | "7d" | "30d" | "custom" | no |
from | query | string (date-time) | no |
to | query | string (date-time) | no |
tz | query | string | no |
mailboxId | query | string (uuid) | no |
workflowId | query | string (uuid) | no |
memberId | query | string (uuid) | no |
Responses
200 — The figures.
| Field | Type | Required |
|---|---|---|
window | object | yes |
current | object | yes |
previous | object | yes |
series | object | yes |
JSON Schema
json
{
"type": "object",
"properties": {
"window": {
"type": "object",
"properties": {
"from": { "type": "string" },
"to": { "type": "string" },
"previousFrom": { "type": "string" },
"bucket": { "type": "string", "enum": [ "hour", "day" ] },
"buckets": { "type": "array", "items": { "type": "string" } }
},
"required": [ "from", "to", "previousFrom", "bucket", "buckets" ],
"additionalProperties": false
},
"current": {
"type": "object",
"properties": {
"received": { "type": "integer", "minimum": 0, "maximum": 9007199254740991 },
"byOutcome": {
"type": "array",
"items": {
"type": "object",
"properties": {
"outcome": {
"type": "string",
"enum": [
"excluded_org",
"excluded_member",
"guardrail",
"unmatched",
"dispatched"
]
},
"count": { "type": "integer", "minimum": 0, "maximum": 9007199254740991 }
},
"required": [ "outcome", "count" ],
"additionalProperties": false
}
},
"automatedEmails": { "type": "integer", "minimum": 0, "maximum": 9007199254740991 },
"draftsPrepared": { "type": "integer", "minimum": 0, "maximum": 9007199254740991 },
"sentByWorkflows": { "type": "integer", "minimum": 0, "maximum": 9007199254740991 }
},
"required": [
"received",
"byOutcome",
"automatedEmails",
"draftsPrepared",
"sentByWorkflows"
],
"additionalProperties": false
},
"previous": {
"type": "object",
"properties": {
"received": { "type": "integer", "minimum": 0, "maximum": 9007199254740991 },
"byOutcome": {
"type": "array",
"items": {
"type": "object",
"properties": {
"outcome": {
"type": "string",
"enum": [
"excluded_org",
"excluded_member",
"guardrail",
"unmatched",
"dispatched"
]
},
"count": { "type": "integer", "minimum": 0, "maximum": 9007199254740991 }
},
"required": [ "outcome", "count" ],
"additionalProperties": false
}
},
"automatedEmails": { "type": "integer", "minimum": 0, "maximum": 9007199254740991 },
"draftsPrepared": { "type": "integer", "minimum": 0, "maximum": 9007199254740991 },
"sentByWorkflows": { "type": "integer", "minimum": 0, "maximum": 9007199254740991 }
},
"required": [
"received",
"byOutcome",
"automatedEmails",
"draftsPrepared",
"sentByWorkflows"
],
"additionalProperties": false
},
"series": {
"type": "object",
"properties": {
"received": {
"type": "array",
"items": { "type": "integer", "minimum": 0, "maximum": 9007199254740991 }
},
"dispatched": {
"type": "array",
"items": { "type": "integer", "minimum": 0, "maximum": 9007199254740991 }
}
},
"required": [ "received", "dispatched" ],
"additionalProperties": false
}
},
"required": [ "window", "current", "previous", "series" ],
"additionalProperties": false
}400 — The request does not match its schema.
401 — No valid session or API key (auth.unauthenticated).
403 — Refused: insufficient role (auth.forbidden), missing scope (api_key.scope_missing, details.required names it) or a route closed to API keys (api_key.session_required).
429 — The API key exceeded its rate limit (api_key.rate_limited); Retry-After says when to retry.
Error codes — dashboard.bad_request, dashboard.forbidden. The common codes (request.bad_request, auth.unauthenticated, api_key.scope_missing, api_key.rate_limited…) apply to every route; see Errors.
GET /api/v1/dashboard/ai
Dashboard: AI cost
The AI spend, broken down by model, purpose and member.
Access — Member session or API key with scope dashboard:read.
Parameters
| Name | In | Type | Required |
|---|---|---|---|
scope | query | "me" | "org" | no |
period | query | "24h" | "7d" | "30d" | "custom" | no |
from | query | string (date-time) | no |
to | query | string (date-time) | no |
tz | query | string | no |
mailboxId | query | string (uuid) | no |
workflowId | query | string (uuid) | no |
memberId | query | string (uuid) | no |
Responses
200 — The figures.
| Field | Type | Required |
|---|---|---|
window | object | yes |
current | object | yes |
previous | object | yes |
series | number[] | yes |
byModel | object[] | yes |
byPurpose | object[] | yes |
byMember | object[] | null | yes |
JSON Schema
json
{
"type": "object",
"properties": {
"window": {
"type": "object",
"properties": {
"from": { "type": "string" },
"to": { "type": "string" },
"previousFrom": { "type": "string" },
"bucket": { "type": "string", "enum": [ "hour", "day" ] },
"buckets": { "type": "array", "items": { "type": "string" } }
},
"required": [ "from", "to", "previousFrom", "bucket", "buckets" ],
"additionalProperties": false
},
"current": {
"type": "object",
"properties": {
"costUsd": { "type": "number", "minimum": 0 },
"calls": { "type": "integer", "minimum": 0, "maximum": 9007199254740991 },
"tokensIn": { "type": "integer", "minimum": 0, "maximum": 9007199254740991 },
"tokensOut": { "type": "integer", "minimum": 0, "maximum": 9007199254740991 }
},
"required": [ "costUsd", "calls", "tokensIn", "tokensOut" ],
"additionalProperties": false
},
"previous": {
"type": "object",
"properties": {
"costUsd": { "type": "number", "minimum": 0 },
"calls": { "type": "integer", "minimum": 0, "maximum": 9007199254740991 },
"tokensIn": { "type": "integer", "minimum": 0, "maximum": 9007199254740991 },
"tokensOut": { "type": "integer", "minimum": 0, "maximum": 9007199254740991 }
},
"required": [ "costUsd", "calls", "tokensIn", "tokensOut" ],
"additionalProperties": false
},
"series": { "type": "array", "items": { "type": "number", "minimum": 0 } },
"byModel": {
"type": "array",
"items": {
"type": "object",
"properties": {
"key": { "type": "string" },
"label": { "anyOf": [ { "type": "string" }, { "type": "null" } ] },
"provider": { "anyOf": [ { "type": "string" }, { "type": "null" } ] },
"costUsd": { "type": "number", "minimum": 0 },
"calls": { "type": "integer", "minimum": 0, "maximum": 9007199254740991 }
},
"required": [ "key", "label", "provider", "costUsd", "calls" ],
"additionalProperties": false
}
},
"byPurpose": {
"type": "array",
"items": {
"type": "object",
"properties": {
"key": { "type": "string" },
"label": { "anyOf": [ { "type": "string" }, { "type": "null" } ] },
"provider": { "anyOf": [ { "type": "string" }, { "type": "null" } ] },
"costUsd": { "type": "number", "minimum": 0 },
"calls": { "type": "integer", "minimum": 0, "maximum": 9007199254740991 }
},
"required": [ "key", "label", "provider", "costUsd", "calls" ],
"additionalProperties": false
}
},
"byMember": {
"anyOf": [
{
"type": "array",
"items": {
"type": "object",
"properties": {
"key": { "type": "string" },
"label": { "anyOf": [ { "type": "string" }, { "type": "null" } ] },
"provider": { "anyOf": [ { "type": "string" }, { "type": "null" } ] },
"costUsd": { "type": "number", "minimum": 0 },
"calls": { "type": "integer", "minimum": 0, "maximum": 9007199254740991 }
},
"required": [ "key", "label", "provider", "costUsd", "calls" ],
"additionalProperties": false
}
},
{ "type": "null" }
]
}
},
"required": [
"window",
"current",
"previous",
"series",
"byModel",
"byPurpose",
"byMember"
],
"additionalProperties": false
}400 — The request does not match its schema.
401 — No valid session or API key (auth.unauthenticated).
403 — Refused: insufficient role (auth.forbidden), missing scope (api_key.scope_missing, details.required names it) or a route closed to API keys (api_key.session_required).
429 — The API key exceeded its rate limit (api_key.rate_limited); Retry-After says when to retry.
Error codes — dashboard.bad_request, dashboard.forbidden. The common codes (request.bad_request, auth.unauthenticated, api_key.scope_missing, api_key.rate_limited…) apply to every route; see Errors.
GET /api/v1/dashboard/health
Dashboard: health
Mailboxes in error and connections to renew.
Access — Member session or API key with scope dashboard:read.
Parameters
| Name | In | Type | Required |
|---|---|---|---|
scope | query | "me" | "org" | no |
period | query | "24h" | "7d" | "30d" | "custom" | no |
from | query | string (date-time) | no |
to | query | string (date-time) | no |
tz | query | string | no |
mailboxId | query | string (uuid) | no |
workflowId | query | string (uuid) | no |
memberId | query | string (uuid) | no |
Responses
200 — The figures.
| Field | Type | Required |
|---|---|---|
mailboxes | object[] | yes |
connections | object[] | yes |
connectionsToRenew | integer | yes |
JSON Schema
json
{
"type": "object",
"properties": {
"mailboxes": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": { "type": "string" },
"address": { "type": "string" },
"provider": { "type": "string" },
"status": { "type": "string", "enum": [ "active", "disconnected", "error" ] },
"memberName": { "anyOf": [ { "type": "string" }, { "type": "null" } ] },
"errorKind": { "anyOf": [ { "type": "string" }, { "type": "null" } ] },
"errorAt": { "anyOf": [ { "type": "string" }, { "type": "null" } ] },
"backfillDone": { "type": "boolean" }
},
"required": [
"id",
"address",
"provider",
"status",
"memberName",
"errorKind",
"errorAt",
"backfillDone"
],
"additionalProperties": false
}
},
"connections": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": { "type": "string" },
"name": { "type": "string" },
"type": { "type": "string" },
"status": { "type": "string", "enum": [ "expired", "revoked" ] },
"ownerName": { "anyOf": [ { "type": "string" }, { "type": "null" } ] },
"updatedAt": { "type": "string" }
},
"required": [ "id", "name", "type", "status", "ownerName", "updatedAt" ],
"additionalProperties": false
}
},
"connectionsToRenew": { "type": "integer", "minimum": 0, "maximum": 9007199254740991 }
},
"required": [ "mailboxes", "connections", "connectionsToRenew" ],
"additionalProperties": false
}400 — The request does not match its schema.
401 — No valid session or API key (auth.unauthenticated).
403 — Refused: insufficient role (auth.forbidden), missing scope (api_key.scope_missing, details.required names it) or a route closed to API keys (api_key.session_required).
429 — The API key exceeded its rate limit (api_key.rate_limited); Retry-After says when to retry.
Error codes — dashboard.bad_request, dashboard.forbidden. The common codes (request.bad_request, auth.unauthenticated, api_key.scope_missing, api_key.rate_limited…) apply to every route; see Errors.
GET /api/v1/dashboard/members
Dashboard: members
Activity per member. Administrators only, in org scope.
Access — Member session or API key with scope dashboard:read.
Parameters
| Name | In | Type | Required |
|---|---|---|---|
scope | query | "me" | "org" | no |
period | query | "24h" | "7d" | "30d" | "custom" | no |
from | query | string (date-time) | no |
to | query | string (date-time) | no |
tz | query | string | no |
mailboxId | query | string (uuid) | no |
workflowId | query | string (uuid) | no |
memberId | query | string (uuid) | no |
Responses
200 — The figures.
| Field | Type | Required |
|---|---|---|
window | object | yes |
total | integer | yes |
active | integer | yes |
suspended | integer | yes |
items | object[] | yes |
JSON Schema
json
{
"type": "object",
"properties": {
"window": {
"type": "object",
"properties": {
"from": { "type": "string" },
"to": { "type": "string" },
"previousFrom": { "type": "string" },
"bucket": { "type": "string", "enum": [ "hour", "day" ] },
"buckets": { "type": "array", "items": { "type": "string" } }
},
"required": [ "from", "to", "previousFrom", "bucket", "buckets" ],
"additionalProperties": false
},
"total": { "type": "integer", "minimum": 0, "maximum": 9007199254740991 },
"active": { "type": "integer", "minimum": 0, "maximum": 9007199254740991 },
"suspended": { "type": "integer", "minimum": 0, "maximum": 9007199254740991 },
"items": {
"type": "array",
"items": {
"type": "object",
"properties": {
"memberId": { "type": "string" },
"name": { "type": "string" },
"email": { "type": "string" },
"role": { "type": "string", "enum": [ "member", "admin" ] },
"status": { "type": "string", "enum": [ "active", "suspended" ] },
"lastSeenAt": { "anyOf": [ { "type": "string" }, { "type": "null" } ] },
"executions": { "type": "integer", "minimum": 0, "maximum": 9007199254740991 },
"failed": { "type": "integer", "minimum": 0, "maximum": 9007199254740991 },
"costUsd": { "type": "number", "minimum": 0 }
},
"required": [
"memberId",
"name",
"email",
"role",
"status",
"lastSeenAt",
"executions",
"failed",
"costUsd"
],
"additionalProperties": false
}
}
},
"required": [ "window", "total", "active", "suspended", "items" ],
"additionalProperties": false
}400 — The request does not match its schema.
401 — No valid session or API key (auth.unauthenticated).
403 — Refused: insufficient role (auth.forbidden), missing scope (api_key.scope_missing, details.required names it) or a route closed to API keys (api_key.session_required).
429 — The API key exceeded its rate limit (api_key.rate_limited); Retry-After says when to retry.
Error codes — dashboard.bad_request, dashboard.forbidden. The common codes (request.bad_request, auth.unauthenticated, api_key.scope_missing, api_key.rate_limited…) apply to every route; see Errors.
GET /api/v1/dashboard/todo
Dashboard: what awaits me
Pending approvals, drafts to review, open incidents. Always personal: no filter.
Access — Member session or API key with scope dashboard:read.
Responses
200 — The to-do items.
| Field | Type | Required |
|---|---|---|
approvalsPending | integer | yes |
reviewPending | integer | yes |
incidentsUnacknowledged | integer | yes |
items | object[] | yes |
JSON Schema
json
{
"type": "object",
"properties": {
"approvalsPending": { "type": "integer", "minimum": 0, "maximum": 9007199254740991 },
"reviewPending": { "type": "integer", "minimum": 0, "maximum": 9007199254740991 },
"incidentsUnacknowledged": { "type": "integer", "minimum": 0, "maximum": 9007199254740991 },
"items": {
"type": "array",
"items": {
"type": "object",
"properties": {
"kind": { "type": "string", "enum": [ "approval", "review", "incident" ] },
"id": { "type": "string" },
"title": { "type": "string" },
"workflowName": { "anyOf": [ { "type": "string" }, { "type": "null" } ] },
"workflowId": { "anyOf": [ { "type": "string" }, { "type": "null" } ] },
"executionId": { "anyOf": [ { "type": "string" }, { "type": "null" } ] },
"at": { "type": "string" }
},
"required": [
"kind",
"id",
"title",
"workflowName",
"workflowId",
"executionId",
"at"
],
"additionalProperties": false
}
}
},
"required": [ "approvalsPending", "reviewPending", "incidentsUnacknowledged", "items" ],
"additionalProperties": false
}401 — No valid session or API key (auth.unauthenticated).
403 — Refused: insufficient role (auth.forbidden), missing scope (api_key.scope_missing, details.required names it) or a route closed to API keys (api_key.session_required).
429 — The API key exceeded its rate limit (api_key.rate_limited); Retry-After says when to retry.
GET /api/v1/dashboard/options
Dashboard: filter options
The mailboxes, workflows and members a filter may name. members is empty in me scope.
Access — Member session or API key with scope dashboard:read.
Parameters
| Name | In | Type | Required |
|---|---|---|---|
scope | query | "me" | "org" | no |
Responses
200 — The options.
| Field | Type | Required |
|---|---|---|
mailboxes | object[] | yes |
workflows | object[] | yes |
members | object[] | yes |
JSON Schema
json
{
"type": "object",
"properties": {
"mailboxes": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": { "type": "string" },
"label": { "type": "string" },
"memberName": { "anyOf": [ { "type": "string" }, { "type": "null" } ] }
},
"required": [ "id", "label", "memberName" ],
"additionalProperties": false
}
},
"workflows": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": { "type": "string" },
"label": { "type": "string" },
"memberName": { "anyOf": [ { "type": "string" }, { "type": "null" } ] }
},
"required": [ "id", "label", "memberName" ],
"additionalProperties": false
}
},
"members": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": { "type": "string" },
"label": { "type": "string" },
"memberName": { "anyOf": [ { "type": "string" }, { "type": "null" } ] }
},
"required": [ "id", "label", "memberName" ],
"additionalProperties": false
}
}
},
"required": [ "mailboxes", "workflows", "members" ],
"additionalProperties": false
}400 — The request does not match its schema.
401 — No valid session or API key (auth.unauthenticated).
403 — Refused: insufficient role (auth.forbidden), missing scope (api_key.scope_missing, details.required names it) or a route closed to API keys (api_key.session_required).
429 — The API key exceeded its rate limit (api_key.rate_limited); Retry-After says when to retry.
Error codes — dashboard.bad_request, dashboard.forbidden. The common codes (request.bad_request, auth.unauthenticated, api_key.scope_missing, api_key.rate_limited…) apply to every route; see Errors.
GET /api/v1/dashboard/layout
Read my dashboard layout
isDefault is true while the member saved nothing: the layout is then the one of their role.
Access — Member session or API key with scope dashboard:read.
Responses
200 — The layout.
| Field | Type | Required |
|---|---|---|
widgets | object[] | yes |
minutesPerEmail | number | yes |
isDefault | boolean | yes |
JSON Schema
json
{
"type": "object",
"properties": {
"widgets": {
"maxItems": 11,
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "string",
"enum": [
"todo",
"executionsKpis",
"executionsTrend",
"recentFailures",
"topWorkflows",
"mailFlow",
"timeSaved",
"mailboxHealth",
"connections",
"aiCost",
"members"
]
},
"visible": { "type": "boolean" }
},
"required": [ "id", "visible" ],
"additionalProperties": false
}
},
"minutesPerEmail": { "type": "number", "minimum": 0, "maximum": 120 },
"isDefault": { "type": "boolean" }
},
"required": [ "widgets", "minutesPerEmail", "isDefault" ],
"additionalProperties": false
}401 — No valid session or API key (auth.unauthenticated).
403 — Refused: insufficient role (auth.forbidden), missing scope (api_key.scope_missing, details.required names it) or a route closed to API keys (api_key.session_required).
429 — The API key exceeded its rate limit (api_key.rate_limited); Retry-After says when to retry.
PUT /api/v1/dashboard/layout
Save my dashboard layout
Widgets, their order and visibility, and the minutes-per-email assumption. Widgets reserved to administrators are dropped for other members.
Access — Member session or API key with scope dashboard:write.
Request body (application/json)
| Field | Type | Required |
|---|---|---|
widgets | object[] | yes |
minutesPerEmail | number | yes |
JSON Schema
json
{
"type": "object",
"properties": {
"widgets": {
"maxItems": 11,
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "string",
"enum": [
"todo",
"executionsKpis",
"executionsTrend",
"recentFailures",
"topWorkflows",
"mailFlow",
"timeSaved",
"mailboxHealth",
"connections",
"aiCost",
"members"
]
},
"visible": { "type": "boolean" }
},
"required": [ "id", "visible" ]
}
},
"minutesPerEmail": { "type": "number", "minimum": 0, "maximum": 120 }
},
"required": [ "widgets", "minutesPerEmail" ]
}Responses
200 — The layout, saved.
| Field | Type | Required |
|---|---|---|
widgets | object[] | yes |
minutesPerEmail | number | yes |
isDefault | boolean | yes |
Same schema as GET /api/v1/dashboard/layout.
400 — The request does not match its schema.
401 — No valid session or API key (auth.unauthenticated).
403 — Refused: insufficient role (auth.forbidden), missing scope (api_key.scope_missing, details.required names it) or a route closed to API keys (api_key.session_required).
429 — The API key exceeded its rate limit (api_key.rate_limited); Retry-After says when to retry.
Error codes — dashboard.bad_request. The common codes (request.bad_request, auth.unauthenticated, api_key.scope_missing, api_key.rate_limited…) apply to every route; see Errors.
DELETE /api/v1/dashboard/layout
Reset my dashboard layout
Back to the layout of the role. Returns it.
Access — Member session or API key with scope dashboard:write.
Responses
200 — The default layout.
| Field | Type | Required |
|---|---|---|
widgets | object[] | yes |
minutesPerEmail | number | yes |
isDefault | boolean | yes |
Same schema as GET /api/v1/dashboard/layout.
401 — No valid session or API key (auth.unauthenticated).
403 — Refused: insufficient role (auth.forbidden), missing scope (api_key.scope_missing, details.required names it) or a route closed to API keys (api_key.session_required).
429 — The API key exceeded its rate limit (api_key.rate_limited); Retry-After says when to retry.