Skip to main content
Two read surfaces expose the write-only alert sinks that were previously only visible in tests.

Team admin alerts

Team owners can list unresolved operational alerts for their team. These carry diagnostic payloads — they are JWT-only and cannot be read by a mio_sk_ API key.
GET /api/v1/teams/{team_id}/admin-alerts
Auth: team-owner JWT session. API keys are rejected. Query parameters:
ParameterDefaultNotes
filter[status]openOnly open is accepted in v1. Any other value returns 422.
page[size]501–100.
page[after]Cursor from the previous page’s links.next.
Response shape:
{
  "data": [
    {
      "id": "0197...",
      "type": "admin_alerts",
      "attributes": {
        "source_module": "checkout",
        "alert_type": "stripe_sync_drift",
        "hub_id": "hub_abc",
        "payload": { "order_id": "ord_123", "gap_seconds": 420 },
        "created_at": "2026-06-09T14:00:00Z",
        "resolved_at": null,
        "resolved_by": null
      }
    }
  ],
  "meta": { "has_more": false }
}
Results are ordered most-recent first. The list returns unresolved alerts only.

Platform admin alerts

Platform admins can list unresolved cross-tenant alerts (abuse signals, infrastructure events).
GET /api/v1/admin/platform-alerts
Auth: platform_admin role required. Query parameters:
ParameterDefaultNotes
filter[status]openOnly open is accepted in v1.
filter[severity]One of info, warning, or critical. Omit to return all severities. Any other value returns 422.
page[size]501–100.
page[after]Pagination cursor.
Response shape:
{
  "data": [
    {
      "id": "0197...",
      "type": "platform_alerts",
      "attributes": {
        "alert_type": "rate_limit_surge",
        "severity": "warning",
        "payload": { "ip": "198.51.100.1", "route": "/api/v1/hub/{hub_id}/checkout" },
        "created_at": "2026-06-09T15:00:00Z",
        "resolved_at": null,
        "resolved_by": null
      }
    }
  ],
  "meta": { "has_more": false }
}
Results are ordered most-recent first.

Role permissions

Platform admins can assign and remove permissions from roles without rebuilding the role.
POST   /api/v1/roles/{role_id}/permissions
DELETE /api/v1/roles/{role_id}/permissions/{permission_slug}
Auth: JWT session. API keys are rejected.

Assign a permission

curl -X POST "$MIO_BASE_URL/api/v1/roles/$ROLE_ID/permissions" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/vnd.api+json" \
  -d '{"slug": "content:read"}'
Returns 201 with the updated role resource. Re-assigning a permission the role already holds is a no-op that still returns 201.

Remove a permission

curl -X DELETE "$MIO_BASE_URL/api/v1/roles/$ROLE_ID/permissions/content:read" \
  -H "Authorization: Bearer $TOKEN"
Returns 204 No Content. Removing a permission the role does not hold is a no-op that still returns 204. Returns 404 if the role itself does not exist.