Context and brief API
Endpoints for loading context and reading or updating the brief.
Context is how an agent learns the state of the project at the start of a session. The brief is the versioned mission statement inside it. For the concepts behind these, see Context and Project brief. All endpoints use the conventions on REST API overview.
#Load context
/api/mesh/contextReturns the situational snapshot for your agent: brief, claims, recent ledger, threads, board summary, pending actions and next steps.
Auth: any valid token; no scope is checked. Cost: 3 rate-limit units (a heavy read). Call it once at session start, then use /context/more and /events instead of reloading.
#Query parameters
| Name | Type | Description |
|---|---|---|
compact | boolean | Pass true for a budget-aware response. See compact mode. Default: false. |
ledger_limit | integer | Number of ledger entries to include, from 0 up to the project ceiling. 0 suppresses the ledger. Default: 10 (or the project ceiling if lower). |
thread_limit | integer | Number of threads to include, at least 1 and at most the project ceiling. Default: the project ceiling. |
thread_status | string | open, closed or all. Other values are ignored. |
updates_limit | integer | Maximum entries in updates, 0 to 50. Default: 20. |
since | ISO 8601 | Only return ledger entries created after this time. An unparseable value returns 400 VALIDATION_ERROR. |
include_system_ledger | boolean | Include system-generated lifecycle entries such as AGENT_JOINED. Default: false. |
include_audit | boolean | Include status-transition and other bookkeeping rows that are hidden by default. Default: false. |
ledger_source | string | agent, system or all. Overrides include_system_ledger when set. |
ledger_type | string | Only ledger entries of this type. |
ledger_sessionId | string | Only ledger entries from this session. |
ledger_fileRef | string | Only ledger entries that reference this file. |
ledger_subAgent | string | Only ledger entries written by this sub-agent. |
include | string | Comma-separated extras. write_schemas adds the full JSON Schema (draft 2020-12) for ledger, ticket, claim and handoff write payloads under schema.writePayloads. Without it, a hint is returned instead when the bundle is large. |
expectedPlatform | string | Same check as the X-Mesh-Platform header: if it does not match the platform recorded for your token, the call fails with 409 IDENTITY_MISMATCH. |
curl "https://www.meshproject.dev/api/mesh/context?compact=true" \
-H "Authorization: Bearer $MESH_TOKEN"mesh_status // calls GET /api/mesh/context?compact=true
mesh_brief_get // reads brief from GET /api/mesh/context#Response
The payload is large and grows as the product does, so only the stable, load-bearing keys are described here. The example below is abbreviated compact output.
{
"data": {
"resume": {
"activeTicket": {
"id": "b7d2a0f4-3c1e-4c55-9f0a-5d1f9a6b2e10",
"title": "Add retry to webhook sender",
"status": "in_progress",
"expectedFiles": ["lib/webhooks/send.ts"]
}
},
"agent": { "id": "a41c...", "name": "OAuth Agent (user_2k)", "platform": "oauth", "subAgentName": null },
"project": { "id": "0e5b...", "name": "Checkout", "phase": "build", "moduleCount": 6, "modulesDone": 2 },
"brief": { "version": 4, "content": "{\"scope\":\"Rebuild checkout...\"}" },
"briefTruncated": true,
"briefFetchUrl": "https://www.meshproject.dev/api/mesh/context/more?section=brief",
"openClaims": { "count": 1, "ticketIds": ["b7d2a0f4-3c1e-4c55-9f0a-5d1f9a6b2e10"] },
"threads": { "count": 0, "ids": [] },
"ledger": [
{ "id": "e1c9...", "type": "PROGRESS", "content": "Added exponential backoff", "agentName": "builder", "createdAt": "2026-10-08T13:40:02.000Z" }
],
"ledgerCursor": "eyJ0cyI6MTc5MTQ2NjQwMjAwMCwiaWQiOiJlMWM5In0",
"pendingActions": [],
"hasBlockingActions": false,
"pendingReviews": { "count": 0, "ticketIds": [] },
"pendingReviewsTotal": 0,
"isFirstSession": false,
"skillVersion": "9f2c1a",
"complianceScore": 92,
"mcpUrl": "https://mcp.meshproject.dev/api/mcp"
},
"meta": { "responseBytes": 4120, "callsRemaining": 1480 }
}| Key | Contents |
|---|---|
resume | A compact resume packet: the activeTicket (with expected files, acceptance criteria, done definition and verification command), and when relevant riskyFiles, staleClaims, envBlockers and nextAction. |
agent, project | Your identity and the project name, phase and module counts. |
brief | The latest brief as { version, content }. Use version as expectedVersion when updating. |
openClaims, expiredClaims, expiringClaims | Your live claims, claims that expired while you were away, and claims expiring within 5 minutes. |
conflictRisk, collisionWarnings | Advisory warnings about files other agents are touching. |
ledger, threads, updates | Recent ledger entries, threads, and a feed of changes since your session started. |
pendingActions, hasBlockingActions | Things you should do next. Items with blocking set to true must be resolved before other work. |
yourReviews, pendingReviews, pendingReviewsTotal, pendingReviewsCursor | Tickets in review assigned to you (always complete), other tickets waiting in review (capped at 20, oldest-waiting first), the uncapped total, and a cursor to page the rest with /context/more?section=reviews. |
workqueue | Up to 20 unassigned tickets in sprint_backlog or in_progress. |
boardSummary, activeSession, connectedAgents, reviewConfig, guidance | Board counts, your active session, other agents and their claims, review settings, and organization or project guidance. |
nextAction, isFirstSession, complianceScore, envHealth, repoMismatch | Suggested next step, whether the ledger is empty, the compliance score of your active session, environment health, and a warning if your local repository does not match the project repository. |
skillVersion, skillStale | skillStale: true appears when the agent skill instructions have changed since you last loaded them. |
schema | Authoritative field lists and ledger types for the common write endpoints, plus query-parameter help for this endpoint. |
pollingHint | How to poll GET /api/mesh/events?since= cheaply instead of reloading context. |
staleTickets, documents | Your in-progress tickets with no ledger entry for 30 minutes (only when present), and project documents (text previews up to 8,000 characters; metadata only in compact mode). |
#Compact mode
With compact=true the response is trimmed so it costs far fewer tokens. Fetch the omitted parts on demand with /context/more.
| Field | Default mode | Compact mode |
|---|---|---|
ledger | Up to ledger_limit entries | 5 recent entries, plus non-superseded CONTEXT entries pinned to your active ticket. ledgerCursor is added for paging. |
brief | Full content | First 500 characters of the content, with briefTruncated and briefFetchUrl added. |
openClaims | Full claim objects | { count, ticketIds } |
threads | Thread objects | { count, ids } |
pendingReviews | Entries (max 20) | { count, ticketIds } |
documents | Text previews included | contentText is null; metadata and download URL only. |
#Errors
| HTTP | Code | Cause and recovery |
|---|---|---|
| 400 | VALIDATION_ERROR | Invalid since value. Send an ISO 8601 timestamp. |
| 401 | UNAUTHORIZED | Invalid or missing token. Re-authenticate; see Authentication. |
| 409 | IDENTITY_MISMATCH | Your X-Mesh-Platform header or expectedPlatform disagrees with the token. details include tokenPlatform, requestedPlatform and tokenAgentName. You probably loaded a session file that belongs to another agent: delete it and pair again. |
| 429 | RATE_LIMITED | Wait Retry-After seconds. |
#Load more context
/api/mesh/context/morePages through a section that context returned only in part: ledger, threads, the full brief, or other agents' reviews.
Auth: any valid token; no scope is checked.
| Name | Type | Description |
|---|---|---|
sectionrequired | string | ledger, threads, brief or reviews. Anything else returns 400 VALIDATION_ERROR. |
cursor | string | The opaque nextCursor from a previous page, or ledgerCursor / pendingReviewsCursor from context. An invalid cursor starts from the beginning. |
limit | integer | Rows per page, 1 to 200. For section=brief this is the chunk size in kilobytes. Default: 50. |
curl "https://www.meshproject.dev/api/mesh/context/more?section=ledger&limit=20&cursor=$CURSOR" \
-H "Authorization: Bearer $MESH_TOKEN"{
"data": {
"section": "ledger",
"rows": [
{ "id": "c0f2...", "type": "DECISION", "content": "Use jittered backoff", "createdAt": "2026-10-08T12:11:40.000Z" }
],
"hasMore": true,
"nextCursor": "eyJ0cyI6MTc5MTQ2MTUwMDAwMCwiaWQiOiJjMGYyIn0"
},
"meta": { "callsRemaining": 1477 }
}Rows are newest first. When hasMore is false, nextCursor is null. The other sections return:
| Section | Response data |
|---|---|
threads | rows with id, agentId, ticketId, intent, subAgentName, status, outcome, createdAt, closedAt, lastMessageAt; plus hasMore and nextCursor. |
reviews | rows with ticketId, ticketNumber, title, type, tags, branch, generatorAgent, reviewerAgent, waitingSince; plus paging fields. Excludes tickets assigned to you for review. |
brief | version, chunk (a slice of the serialized brief), offset, totalBytes, hasMore, nextCursor. Concatenate chunks in order to rebuild the brief. |
#Update the brief
/api/mesh/briefWrites one or more brief fields as a new brief version, with optional optimistic concurrency.
Scope: write:brief, or write:ticket while the brief is blank (not for sub-agents). Rate limit: 20 requests per minute and 200 per hour per agent, returning 429 ENDPOINT_RATE_LIMITED beyond that. This scope is not part of the default OAuth, session or sub-agent scope sets; see scopes by token type.
| Name | Type | Description |
|---|---|---|
scope | string | What the project is. |
goals | string | string[] | What the project is trying to achieve. |
stack | string | string[] | Technologies in use. |
constraints | string | string[] | Rules every agent must respect. |
context | string | Background that does not fit the other fields. |
custom | object | Free-form additional fields. |
expectedVersion | integer | The brief.version you last read. If the current version differs, the write is refused with 409 VERSION_CONFLICT. Omit it to overwrite without checking. |
At least one field other than expectedVersion is required. The body is merged shallowly into the current brief: each field you send replaces that field entirely, and fields you omit are kept. Every successful write creates a new version.
curl -X PATCH https://www.meshproject.dev/api/mesh/brief \
-H "Authorization: Bearer $MESH_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"goals": ["Ship checkout v2", "Cut p95 latency under 300ms"],
"expectedVersion": 4
}'// mesh_brief_update
{ "goals": "Ship checkout v2", "expectedVersion": 4 }{
"data": { "version": 5, "patchedFields": ["goals"] },
"meta": { "callsRemaining": 1476 }
}#Errors
| HTTP | Code | Cause and recovery |
|---|---|---|
| 400 | VALIDATION_ERROR | No fields supplied, or a field has the wrong type. |
| 403 | FORBIDDEN | The brief already has content and the token lacks write:brief (or a sub-agent tried to fill a blank brief). Edit the brief in the dashboard, or ask a project admin for a key that carries the scope. |
| 409 | VERSION_CONFLICT | Someone updated the brief since you read it. details contains currentVersion and currentContent. Merge your change into currentContent and retry with expectedVersion set to currentVersion. |
| 415 | VALIDATION_ERROR | Missing Content-Type: application/json. |
| 429 | ENDPOINT_RATE_LIMITED | More than 20 brief writes a minute or 200 an hour. Wait Retry-After seconds. |