---
title: "Get the Agency workspace"
method: GET
path: "/api/agent/agency"
tags: ["Agency"]
---

# Get the Agency workspace

`GET /api/agent/agency`

## Request

- Base URL: `https://preuve.ai`
- URL: `https://preuve.ai/api/agent/agency`
- Auth: API key in header `x-preuve-key`

Workspace identity, the caller's role, remaining shared project quota, and one page of the workspace's client reports - dashboard-created ones included, newest first, without report bodies. Consultant and AppSumo Agency accounts only: a key whose account holds no Agency workspace, or whose membership was removed, gets 404 AGENCY_NOT_FOUND on the next call. Membership is resolved live on every request, independently of the key.

## Query parameters

- `limit` integer
- `offset` integer

## Response `200`

Workspace, role, quota, and one page of client reports.

- AgencyContext
  - `agency` object
    - `id` string
    - `name` string
    - `role` string: The calling account's role in the workspace.
  - `quota` AgencyQuota: Shared project quota for the workspace, same pool as the dashboard.
    - `plan` string
    - `isActiveSubscription` boolean
    - `trialLimit` integer
    - `trialUsed` integer
    - `trialExpired` boolean
    - `delinquent` boolean
    - `monthlyLimit` integer
    - `monthlyUsed` integer
    - `monthlyRemaining` integer
    - `topupRemaining` integer
    - `totalRemaining` integer
    - `requiresPaymentSetup` boolean
    - `canScan` boolean
    - `nextResetAt` string, date-time, nullable
  - `canRunScan` boolean: Eligibility, not live availability. True only when the role may run scans, the workspace is approved, billing setup is done, and quota remains. It does not read the service kill switch, the LLM pause or the rate limiters, so a start can still answer 503 or 429 while this is true. None of those refusals spends a project credit.
  - `reports` AgencyReportListItem[]: One page of the workspace's client reports, newest first, including ones created in the Agency dashboard. Same shape and paging as /api/agent/agency/reports.
    - `reportId` string
    - `title` string, nullable
    - `status` string
    - `scanType` 'starter' | 'deep'
    - `createdAt` string, date-time
    - `reportUrl` string, uri
  - `nextOffset` integer, nullable: Offset of the next page of reports, or null on the last page.

## Other responses

- `400`: limit must be 1-50 and offset 0-10000 (INVALID_PAGINATION).
- `401`: Missing x-preuve-key header (MISSING_API_KEY), or a malformed, unknown or revoked key (INVALID_AGENT_KEY - the same envelope for all three, on purpose). Repeated failures are throttled per IP and answer 429.
- `403`: Key does not carry agency:read (INSUFFICIENT_SCOPE) or the account is suspended (ACCOUNT_SUSPENDED). agency:write does not imply it. Keys created before 2026-09-09 predate both Agency scopes and always fail this check - see the AgencyInsufficientScope response for the recovery and the condition on each of its two routes.
- `404`: No Agency workspace on this account, or workspace membership was removed (AGENCY_NOT_FOUND). Membership is resolved live on every call.
- `429`: Rate limited (RATE_LIMITED or DAILY_LIMIT_REACHED). RATE_LIMITED carries a Retry-After header with the seconds until the window resets; the quota-shaped codes clear on a different clock and put resetAt in the body instead.
- `500`: Unexpected server error (INTERNAL_ERROR, or TRIGGER_DISPATCH_FAILED when a deep scan could not be handed to the job runner). Never tell the user their quota is safe: on a deep scan the spend can already have happened when the failure hit, and an ambiguous dispatch deliberately keeps the report and its funding because the job may have been accepted before its response was lost. Treat consumption as unknown and retry with backoff. On an operation that takes a clientRunId, retry with the SAME one - that reconciles the original run, whatever state it reached, instead of starting and charging for a second one. On every other operation there is nothing to reconcile: the read or export simply failed, so a plain backed-off retry is the whole recovery.
- `503`: A dependency was unavailable or deliberately paused (SERVICE_DISABLED, LLM_PAUSED, PROFILE_LOOKUP_FAILED, and the fail-closed answer when the rate-limit backend is down). Any authenticated route can answer this one: authentication meters itself through the same fail-closed limiter, so an outage there refuses the request before the handler runs. Retryable, and no paid quota, tokens, or scans were consumed - a pause that lands mid-run refunds the claim it had already made. Back off and try again rather than falling back to a different endpoint.

---

[API](https://skmtc.dev/preuve/apis/preuve-agent-api.md) · [All operations](https://skmtc.dev/preuve/apis/preuve-agent-api/llms.txt) · [OpenAPI document](https://skmtc.dev/preuve/apis/preuve-agent-api/revisions/b8e99c2a4fc7?raw)
