Status API
API for sending and deleting AI agent status.
Endpoints
POST /api/status
DELETE /api/status?project={project}
/statusis also accepted — a Next.js rewrite (next.config.js) maps it to/api/statuswith the same methods and behavior.
Authentication
All requests require a Bearer token.
Authorization: Bearer <token>
Use a server-issued token with write permission. Create, retrieve, or delete it at /account; unknown, deleted, or revoked tokens return 401. See Monitoring API.
POST /api/status
Stores the current agent status in the canonical source model. createdAt is preserved. updatedAt represents the accepted observation time; equal or older observations do not replace the latest state. Clients query updates over HTTP.
Optional sourceId, observedAt, and account fields support multiple provider accounts and workspaces; see account identity.
Request Headers
| Header | Value | Required |
|---|---|---|
Authorization |
Bearer <token> |
Yes |
Content-Type |
application/json |
Yes |
Request Body
{
"state": "working",
"project": "vibemon",
"character": "clawd",
"tool": "Bash",
"model": "Opus 4.5",
"memory": 45,
"usage5h": 36,
"usageWeek": 37,
"usage5hResetsIn": 154,
"usageWeekResetsIn": 4381,
"usageWeekModel": 12,
"usageWeekModelResetsIn": 6300,
"usageWeekModelLabel": "Fable"
}
Fields
| Field | Type | Required | Length/Range | Description |
|---|---|---|---|---|
state |
string | Yes | One of State Values | Agent state (closed enum, same set as the Desktop app and ESP32) |
project |
string | Yes | 1-128 chars (not whitespace-only) | Project name. Stored after trim + a key is generated from the normalized projectKey |
character |
string | Yes | 1-64 chars | Agent character (see Characters). An unknown name is normalized to the default (vibemon), not rejected |
tool |
string | No | Max 64 chars | Tool currently in use (e.g., Bash, Read, Edit). Omitting or passing an empty string clears the existing value |
model |
string | No | Max 64 chars | Model in use (e.g., Opus 4.5, Sonnet). Omitting or passing an empty string clears the existing value |
memory |
integer | No | 0-100 | Context-window usage. Shares its name with the AgentMemory entity but is a separate concept |
usage5h |
integer | No | 0-100 | 5-hour reset plan usage (statusline /usage). Omitting clears the existing value |
usageWeek |
integer | No | 0-100 | Weekly (all models) reset plan usage. Omitting clears the existing value |
usage5hResetsIn |
integer | No | >= 0 | Minutes until the 5-hour usage window resets, as of send time. Omitting clears the existing value |
usageWeekResetsIn |
integer | No | >= 0 | Minutes until the weekly usage window resets, as of send time. Omitting clears the existing value |
usageWeekModel |
integer | No | 0-100 | Model-scoped weekly reset plan usage (e.g. the Fable weekly limit). Omitting clears the existing value |
usageWeekModelResetsIn |
integer | No | >= 0 | Minutes until the model-scoped weekly window resets, as of send time. Omitting clears the existing value |
usageWeekModelLabel |
string | No | Max 64 chars | Display name of the model the scoped weekly limit applies to (e.g. Fable). Omitting or passing an empty string clears the existing value |
Note on project normalization: The stored
projectis the input aftertrim()(only leading/trailing whitespace removed, internal spaces and case preserved), and full normalization is applied only when generating the legacy source ID (trim().toLowerCase().replace(/\s+/g, '-')). Example:" My Project "→ storedproject="My Project", legacy project keymy-project.
Note on
*ResetsInstaleness:usage5hResetsIn/usageWeekResetsIn/usageWeekModelResetsInare snapshots taken at send time. When reading a stored record, offset these countdowns againstupdatedAt.
Note on optional fields: An upsert that omits
tool,model,memory,usage5h,usageWeek,usage5hResetsIn,usageWeekResetsIn,usageWeekModel,usageWeekModelResetsIn, orusageWeekModelLabelclears the existing value. Fortool/model/usageWeekModelLabel, an empty string ("") is treated the same as omission and clears the existing value (a compatibility measure for clients that always serialize the keys). This is designed so that stale values are not left behind when an agent no longer provides that metadata.
Success (200)
{
"success": true,
"status": {
"createdAt": "2026-02-01T10:00:00.000Z",
"updatedAt": "2026-02-01T11:25:32.609Z",
"state": "working",
"project": "vibemon",
"character": "clawd",
"tool": "Bash",
"model": "Opus 4.5",
"memory": 45,
"usage5h": 36,
"usageWeek": 37
}
}
Note: The response does not include
token, since the caller already holds its own token via the Bearer header.
DELETE /api/status
Deletes the matching agent source. Missing sources return 200. When multiple accounts or workspaces share the project, deletion returns 409; use DELETE /api/v1/sources/{sourceId} to choose the exact source.
Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
project |
string | Yes | Name of the project to delete (1-128 chars, not whitespace-only) |
Success (200)
{
"success": true,
"project": "My Project",
"projectKey": "my-project"
}
The response returns both the original project and the normalized projectKey, for compatibility with project-based clients.
Errors
| Status | Error (example) | Description |
|---|---|---|
| 400 | project must be a string / project must contain non-whitespace characters |
Missing project, type error, or whitespace-only input |
| 400 | project exceeds maximum length of 128 characters |
project length exceeded |
| 400 | state must not be empty / Invalid state: foo. Valid states: ... |
Missing state, type error, or unknown state |
| 400 | character must not be empty / character exceeds maximum length of 64 characters |
Missing character, type error, or length exceeded (an unknown but valid-length name is accepted and normalized, not rejected) |
| 400 | tool must be a string / tool exceeds maximum length of 64 characters |
tool type error or length exceeded |
| 400 | model must be a string / model exceeds maximum length of 64 characters |
model type error or length exceeded |
| 400 | memory must be an integer between 0 and 100 |
memory/usage5h/usageWeek/usageWeekModel type or range error (same format per field name) |
| 400 | usage5hResetsIn must be a non-negative integer |
usage5hResetsIn/usageWeekResetsIn/usageWeekModelResetsIn type or range error |
| 401 | Invalid or expired API token | Missing, unknown, or revoked credential |
| 403 | Token requires write permission | Token lacks write scope |
| 409 | Source conflict | Ambiguous project deletion or identity conflict |
| 429 | Request limit exceeded | Shared owner request budget exceeded |
| 405 | Method not allowed |
Method other than POST/DELETE |
| 503 | Service temporarily unavailable | Storage failure; retry with backoff |
Examples
curl (required fields only)
curl -X POST https://vibemon.io/api/status \
-H "Authorization: Bearer <issued-write-token>" \
-H "Content-Type: application/json" \
-d '{"state":"working","project":"vibemon","character":"clawd"}'
curl (all fields)
curl -X POST https://vibemon.io/api/status \
-H "Authorization: Bearer <issued-write-token>" \
-H "Content-Type: application/json" \
-d '{
"state": "working",
"project": "vibemon",
"character": "clawd",
"tool": "Bash",
"model": "Opus 4.5",
"memory": 45,
"usage5h": 36,
"usageWeek": 37,
"usage5hResetsIn": 154,
"usageWeekResetsIn": 4381,
"usageWeekModel": 12,
"usageWeekModelResetsIn": 6300,
"usageWeekModelLabel": "Fable"
}'
curl (delete)
curl -X DELETE "https://vibemon.io/api/status?project=my-project" \
-H "Authorization: Bearer <issued-write-token>"
Python
import requests
url = "https://vibemon.io/api/status"
headers = {
"Authorization": "Bearer <issued-write-token>",
"Content-Type": "application/json"
}
data = {
"state": "working",
"project": "vibemon",
"character": "clawd",
"tool": "Bash",
"model": "Opus 4.5",
"memory": 45,
}
response = requests.post(url, json=data, headers=headers)
print(response.json())
JavaScript
const response = await fetch('https://vibemon.io/api/status', {
method: 'POST',
headers: {
'Authorization': 'Bearer <issued-write-token>',
'Content-Type': 'application/json',
},
body: JSON.stringify({
state: 'working',
project: 'vibemon',
character: 'clawd',
tool: 'Bash',
model: 'Opus 4.5',
memory: 45,
}),
});
const result = await response.json();
console.log(result);
State Values
| State | Description |
|---|---|
start |
Agent started |
idle |
Agent is waiting |
thinking |
Agent is thinking |
planning |
Agent is planning |
working |
Agent is working |
packing |
Compacting context (token optimization) |
notification |
User attention needed (triggers browser system notification) |
done |
Task completed (triggers browser system notification) |
sleep |
Agent is dormant |
alert |
An error occurred (triggers browser system notification) |
States are defined in App's src/shared/data/states.json; Web loads its pinned copy at public/static/data/states.json. Unknown states are rejected. Publish the App source commit, update Web's app-assets.json, then rebuild Web to change the shared registry.
Characters
| Character | Description |
|---|---|
vibemon |
Default character (VibeMon) |
clawd |
Alternative character (Claude Code) |
codex |
Alternative character (Codex CLI) |
claw |
Alternative character (OpenClaw) |
kiro |
Alternative character (Kiro) |
daangni |
Alternative character (Daangni) |
Characters are defined in public/static/data/characters.json. Unknown names resolve to the registry default.
Environment Variables
Environment variables used by the client:
| Variable | Description | Example |
|---|---|---|
VIBEMON_URL |
VibeMon server URL | https://vibemon.io (endpoint: ${VIBEMON_URL}/api/status) |
Related Documentation
- Statuses API - Query all project statuses for a token (
GET /api/statuses) - Metrics API - Per-project activity metrics (
GET /api/metrics) - Stats API - Owner statistics (
GET /api/stats) - Memory API - Agent key-value memory
- Entity Definitions - AgentStatus data model