Documentation Pages
Documentation
API Reference
The Vigil API lets you manage watchers, threads, memory, and custom tools programmatically. All endpoints return JSON and require an Authorization header.
Authentication
Use either a JWT access token (from login) or an API key from the Developer page.
Authorization: Bearer vk_your_api_key_hereAPI keys use the prefix vk_. The full key is never stored — only a SHA-256 hash.
Base URL
https://api.vigil.run/apiAuth
/auth/registerCreate a new account.
Request body
| email* | string | Valid email address (max 254 chars) |
| password* | string | Min 8 characters |
| name | string | Display name |
Response 201
{
"user": { "user_id": "abc123", "email": "you@example.com" },
"tokens": {
"access_token": "eyJ...",
"refresh_token": "eyJ...",
"expires_in": 900
}
}/auth/loginSign in and receive tokens.
Request body
| email* | string | |
| password* | string |
Response 200
{
"user": { "user_id": "abc123", "email": "you@example.com" },
"tokens": { "access_token": "...", "refresh_token": "...", "expires_in": 900 }
}/auth/refreshExchange a refresh token for a new access token.
Request body
| refresh_token* | string | Also accepts refreshToken |
Response 200
{
"tokens": { "access_token": "...", "refresh_token": "...", "expires_in": 900 }
}/auth/meGet the current authenticated user.
Response 200
{
"user": { "user_id": "abc123", "account_id": "abc123", "email": "you@example.com", "role": "owner" }
}Watchers
/watchersList all watchers for the account.
Response 200
{
"watchers": [
{
"id": "w_123", "name": "Work Email", "ingest_token": "tok_...",
"ingestion_address": "work-tok_...@vigil.run", "status": "active", ...
}
]
}/watchersCreate a new watcher.
Request body
| name* | string | Display name for the watcher |
| system_prompt* | string | Instructions for the agent |
| tools | string[] | Enabled tools. Default: ["send_alert"] |
| silence_hours | number | Hours before silence alert. Default: 48 |
| tick_interval | number | Scheduled check interval in minutes. Default: 60 |
| model | string | LLM model. Default: "gpt-4.1-mini" |
| template_id | string | Watcher template to use |
Response 201
{ "watcher": { "id": "w_123", "name": "Work Email", ... } }/watchers/:idGet a single watcher by ID.
/watchers/:idUpdate watcher settings. All fields optional, at least one required.
Request body
| name | string | |
| system_prompt | string | |
| tools | string[] | |
| silence_hours | number | |
| tick_interval | number | |
| model | string | |
| status | string | "active" or "paused" |
| reactivity | number | Agent reactivity level |
| memory_sensitivity | number | Memory storage sensitivity |
/watchers/:idSoft-delete a watcher and all associated data.
/watchers/:id/invokeManually invoke the agent. All fields optional.
Request body
| message | string | Chat mode — natural language response. Mutually exclusive with query. |
| query | string | Query mode — structured JSON response. Defaults to reviewing active threads if neither field is set. |
Response 200
// Chat mode
{ "response": "You have 3 active threads..." }
// Query mode
{ "actions": [...], "thread_updates": [...], "email_analysis": {...} }/watchers/:id/digestTrigger a digest email for this watcher. No request body.
Threads
/watchers/:watcherId/threadsList threads. Filter with ?status=active, ?status=watching, etc.
Response 200
{
"threads": [
{ "id": "t_123", "subject": "Invoice #4521", "status": "active", "summary": "...", ... }
]
}/watchers/:watcherId/threads/:threadIdGet a single thread with full details.
/watchers/:watcherId/threads/:threadIdUpdate thread status or metadata. All fields optional, at least one required.
Request body
| status | string | "active" | "watching" | "resolved" | "ignored" |
| summary | string | Thread summary text |
| flags | object | Custom flags as key-value pairs |
/watchers/:watcherId/threads/:threadIdDelete a thread.
/watchers/:watcherId/threads/:threadId/closeMark a thread as resolved. No request body. Returns 400 if already resolved or ignored.
Memory
/watchers/:id/memoryList all non-obsolete memories for a watcher.
Response 200
{
"memories": [
{ "id": "m_123", "content": "User's rent is $1,450/mo", "importance": 4, "obsolete": false, "created_at": "..." }
]
}/watchers/:id/memoryManually create a memory.
Request body
| content* | string | Memory text. Must be non-empty. |
| importance | number | 1-5 scale. Default: 3 |
Response 201
{ "memory": { "id": "m_123", "content": "...", "importance": 4 } }/watchers/:id/memory/:memoryIdUpdate a memory. All fields optional, at least one required.
Request body
| content | string | Updated memory text |
| importance | number | 1-5 scale |
| obsolete | boolean | Mark memory as obsolete |
/watchers/:id/memory/:memoryIdDelete a memory.
Actions
/watchers/:id/actionsList agent actions (invocations, alerts, tool calls). Supports ?limit=N and ?thread_id=X.
Response 200
{
"actions": [
{
"id": "a_123", "trigger_type": "email_received", "tool": "send_alert",
"result": "...", "cost_usd": 0.003, "created_at": "..."
}
]
}Custom Tools
Custom tools are webhook-backed extensions the agent can call. Configured per watcher.
/watchers/:id/toolsList custom tools for a watcher.
/watchers/:id/toolsCreate a custom tool.
Request body
| name* | string | Tool name (e.g. "notify_slack") |
| description* | string | What the tool does — shown to the agent |
| webhook_url* | string | URL to POST to when the agent calls the tool |
| headers | object | Custom headers sent with the webhook. Default: {} |
| parameter_schema | object | JSON schema for the tool parameters. Default: {} |
Response 201
{
"tool": {
"id": "ct_123", "name": "notify_slack",
"description": "Send a message to Slack",
"webhook_url": "https://hooks.slack.com/...",
"headers": {},
"parameter_schema": { "message": { "type": "string", "description": "The alert message" } },
"enabled": true
}
}/watchers/:id/tools/:toolIdUpdate a custom tool. All fields optional, at least one required.
Request body
| name | string | |
| description | string | |
| webhook_url | string | |
| headers | object | |
| parameter_schema | object | |
| enabled | boolean | Enable or disable the tool |
/watchers/:id/tools/:toolIdDelete a custom tool.
/watchers/:id/tools/:toolId/testFire a test webhook with a sample payload. No request body.
Response 200
{ "success": true, "status": 200, "response_body": "ok" }Channels
Channels control where alerts are delivered.
/watchers/:id/channelsList alert channels.
/watchers/:id/channelsAdd an alert channel.
Request body
| type* | string | "email" or "webhook" |
| destination* | string | Email address or webhook URL |
Response 201
{ "channel": { "id": "ch_123", "type": "email", "destination": "me@example.com", "enabled": true } }/watchers/:id/channels/:channelIdUpdate a channel. All fields optional, at least one required.
Request body
| destination | string | New email address or webhook URL |
| enabled | boolean | Enable or disable the channel |
/watchers/:id/channels/:channelIdRemove a channel.
API Keys
/keysList your API keys. The full key is never returned.
Response 200
{
"keys": [
{ "id": "k_123", "name": "my-integration", "key_prefix": "vk_a1b2c3d", "usage_count": 42, "created_at": "..." }
]
}/keysCreate a new API key. The full key is returned only once.
Request body
| name* | string | Label for the key |
| permissions | string[] | Permission scopes. Default: ["read"] |
Response 201
{
"key": {
"id": "k_123", "name": "my-integration",
"key_prefix": "vk_a1b2c3d", "full_key": "vk_a1b2c3d4e5f6..."
}
}/keys/:idRevoke an API key.
Usage
/usageGet usage and cost data for your account.
Response 200
{
"usage": {
"total_cost": 0.42,
"total_invocations": 312,
"total_alerts": 28,
"total_emails": 156,
"current_month": { "cost": 0.08, "invocations": 45 },
"watchers": [
{ "watcher_id": "w_123", "watcher_name": "Work Email", "cost": 0.25, "invocations": 200, "alerts": 15, "emails": 100 }
]
}
}Errors
All errors return a JSON body with an error field:
{ "error": "Watcher not found" }400Bad request — missing or invalid fields401Missing or invalid authentication404Resource not found or not owned by your account429Rate limited