Skip to content

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

NameInTypeRequired
scopequery"me" | "org"no
periodquery"24h" | "7d" | "30d" | "custom"no
fromquerystring (date-time)no
toquerystring (date-time)no
tzquerystringno
mailboxIdquerystring (uuid)no
workflowIdquerystring (uuid)no
memberIdquerystring (uuid)no

Responses

200 — The figures.

FieldTypeRequired
windowobjectyes
currentobjectyes
previousobjectyes
seriesobject[]yes
topWorkflowsobject[]yes
failingWorkflowsobject[]yes
recentFailuresobject[]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

NameInTypeRequired
scopequery"me" | "org"no
periodquery"24h" | "7d" | "30d" | "custom"no
fromquerystring (date-time)no
toquerystring (date-time)no
tzquerystringno
mailboxIdquerystring (uuid)no
workflowIdquerystring (uuid)no
memberIdquerystring (uuid)no

Responses

200 — The figures.

FieldTypeRequired
windowobjectyes
currentobjectyes
previousobjectyes
seriesobjectyes
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

NameInTypeRequired
scopequery"me" | "org"no
periodquery"24h" | "7d" | "30d" | "custom"no
fromquerystring (date-time)no
toquerystring (date-time)no
tzquerystringno
mailboxIdquerystring (uuid)no
workflowIdquerystring (uuid)no
memberIdquerystring (uuid)no

Responses

200 — The figures.

FieldTypeRequired
windowobjectyes
currentobjectyes
previousobjectyes
seriesnumber[]yes
byModelobject[]yes
byPurposeobject[]yes
byMemberobject[] | nullyes
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

NameInTypeRequired
scopequery"me" | "org"no
periodquery"24h" | "7d" | "30d" | "custom"no
fromquerystring (date-time)no
toquerystring (date-time)no
tzquerystringno
mailboxIdquerystring (uuid)no
workflowIdquerystring (uuid)no
memberIdquerystring (uuid)no

Responses

200 — The figures.

FieldTypeRequired
mailboxesobject[]yes
connectionsobject[]yes
connectionsToRenewintegeryes
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

NameInTypeRequired
scopequery"me" | "org"no
periodquery"24h" | "7d" | "30d" | "custom"no
fromquerystring (date-time)no
toquerystring (date-time)no
tzquerystringno
mailboxIdquerystring (uuid)no
workflowIdquerystring (uuid)no
memberIdquerystring (uuid)no

Responses

200 — The figures.

FieldTypeRequired
windowobjectyes
totalintegeryes
activeintegeryes
suspendedintegeryes
itemsobject[]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.

FieldTypeRequired
approvalsPendingintegeryes
reviewPendingintegeryes
incidentsUnacknowledgedintegeryes
itemsobject[]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

NameInTypeRequired
scopequery"me" | "org"no

Responses

200 — The options.

FieldTypeRequired
mailboxesobject[]yes
workflowsobject[]yes
membersobject[]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.

FieldTypeRequired
widgetsobject[]yes
minutesPerEmailnumberyes
isDefaultbooleanyes
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)

FieldTypeRequired
widgetsobject[]yes
minutesPerEmailnumberyes
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.

FieldTypeRequired
widgetsobject[]yes
minutesPerEmailnumberyes
isDefaultbooleanyes

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.

FieldTypeRequired
widgetsobject[]yes
minutesPerEmailnumberyes
isDefaultbooleanyes

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.