Atrium
platform docsAgentCase contract

Atrium platform docs

AgentCase contract

Expose workspace-scoped work summaries and actions for the cross-app Home inbox.

Updated 2026-09-22

Represent a unit of work

An AgentCase summarizes one job, application, report, or other unit of work. Home displays this summary and links to your app for the complete workflow. Return useful status information rather than a chat transcript or private record contents.

type AgentCaseStatus = "open" | "blocked" | "done" | "failed";

interface AgentCase {
  id: string;
  title: string;
  status: AgentCaseStatus;
  status_label?: string;
  updated_at: string;
  url: string;
}

IDs must be stable within your app. Use an ISO timestamp for updated_at and an HTTPS deep link for url. An optional label such as "Awaiting your review" explains the app-specific stage while status enables cross-app filtering.

Home treats blocked and failed as needing attention. See Home and the case inbox.

List cases

Implement GET /api/cases on the app's visitor-facing domain. Return a JSON array:

[
  {
    "id": "application-123",
    "title": "Software engineer application",
    "status": "blocked",
    "status_label": "Awaiting your review",
    "updated_at": "2026-09-22T12:00:00Z",
    "url": "https://my-agent.atrium.st/app/applications/application-123"
  }
]

Authenticate the request and return only records the user can access in the selected workspace. Gateway access does not replace your app's record-level authorization.

Return an empty array for a successful read with no cases. If your app does not implement this contract or the request fails, Home can show the installed app without a case summary.

Create cases

Implement POST /api/cases if your app supports creation through this contract:

{
  "params": {
    "url": "https://example.com/job"
  },
  "idempotency_key": "application-request-123"
}

Your app defines and validates params. Enforce permissions and deduplicate retries with the same idempotency key so that one customer action does not create several jobs.

Optional fields and actions

An envelope can accompany cases with a shared schema and capability names:

interface AgentCaseEnvelope {
  cases: AgentCase[] | null;
  schema: AgentCaseSchema | null;
  capabilities: string[];
  unsupported?: boolean;
}

interface AgentCaseSchema {
  version?: number;
  fields?: AgentCaseFieldSchema[];
}

interface AgentCaseFieldSchema {
  name: string;
  label?: string;
  type?: string;
  options?: Array<{ value: string; label: string }>;
}

interface AgentCaseAction {
  id: string;
  label: string;
  method?: "GET" | "POST" | "PATCH" | "PUT" | "DELETE";
  href?: string;
  body?: unknown;
  intent?: string;
}

A case may additionally include fields: Record<string, unknown>, schema: AgentCaseSchema, and actions: AgentCaseAction[]. Use brief display fields; the host need not render every field or support every interaction. Keep essential workflows reachable through the case's main URL.

Supply actions only when implemented. Your app must validate action paths, methods, bodies, permissions, and the current case state on every request. An action rendered by Home is not an authorization grant.

For example, this envelope adds a company field and a review link:

{
  "cases": [
    {
      "id": "application-123",
      "title": "Software engineer application",
      "status": "blocked",
      "status_label": "Awaiting your review",
      "updated_at": "2026-09-22T12:00:00Z",
      "url": "https://my-agent.atrium.st/app/applications/application-123",
      "fields": {"company": "Example Company"},
      "actions": [
        {
          "id": "review",
          "label": "Review application",
          "method": "GET",
          "href": "https://my-agent.atrium.st/app/applications/application-123"
        }
      ]
    }
  ],
  "schema": {
    "version": 1,
    "fields": [{"name": "company", "label": "Company", "type": "string"}]
  },
  "capabilities": []
}

Host integration

The Atrium web app uses same-origin host routes for case requests:

GET    /api/agent-cases?slug=my-agent
POST   /api/agent-cases?slug=my-agent
PATCH  /api/agent-cases/<case-id>?slug=my-agent
POST   /api/agent-cases/<case-id>?slug=my-agent
PUT    /api/agent-cases/<case-id>?slug=my-agent
DELETE /api/agent-cases/<case-id>?slug=my-agent

These are browser integration routes on the Atrium host, not endpoints on api.atrium.st/v0. Implement the corresponding app-side case endpoints and retain authentication checks. Do not add permissive cross-origin rules just to make Home's case inbox work.

Test your integration

Verify an empty list, all four statuses, valid deep links, creation retries, and an unavailable endpoint. Test with two workspaces to confirm one cannot read or mutate the other's cases. Test unauthorized actions even if the UI normally hides them.

For a deployed example, see Otto.