Documentation
API Reference
Janus exposes HTTP REST and gRPC APIs. All SDKs communicate through these endpoints.
Base URL
http://localhost:8080
All requests require the X-Tenant-ID header. Authenticated endpoints require an Authorization: Bearer <api_key> header.
REST Endpoints
Health & Readiness
GET/healthz
Liveness probe. Returns 200 when the process is alive.
GET/readyz
Readiness probe. Checks PG, NATS, Redis connectivity. Returns 200 only when all dependencies are reachable.
Mailboxes
POST/v1/tenants/{tenant}/mailboxes
Create a mailbox. Body: { "id": "review-mb", "agent_id": "reviewer", "ack_wait_seconds": 300, "max_deliver": 5 }
GET/v1/tenants/{tenant}/mailboxes/{id}
Get mailbox details and stats.
PATCH/v1/tenants/{tenant}/mailboxes/{id}
Update mailbox config (max_concurrency, ack_wait_seconds, max_deliver, retention_seconds).
Agents
POST/v1/tenants/{tenant}/agents
Register an agent with capabilities. Body: { "id", "display_name", "team", "protocol", "capabilities": [{ "capability", "description" }] }. Capabilities are persisted atomically since v1.1.0.
POST/v1/tenants/{tenant}/agents/{id}/heartbeat
Send heartbeat; keeps the agent online (TTL via JANUS_HB_TTL).
GET/v1/tenants/{tenant}/agents
List registered agents.
Tasks
POST/v1/tenants/{tenant}/tasks
Publish a task. Body: { "id", "source_agent", "target_type", "target_value", "envelope" }. Response: { "id", "status", "task": {...} } — full task object included since v1.1.0.
POST/v1/tenants/{tenant}/mailboxes/{name}/pull
Pull next pending task from a mailbox. Body: { "agent_id": "reviewer" }
POST/v1/tenants/{tenant}/tasks/{id}/start
Start task processing. Body: { "lease_id": "..." }
POST/v1/tenants/{tenant}/tasks/{id}/ack
Acknowledge successful completion. Body: { "lease_id": "...", "result_ref": "..." }
POST/v1/tenants/{tenant}/tasks/{id}/nack
Negative ACK — return to queue or DLQ. Body: { "lease_id": "...", "reason": "..." }
GET/v1/tenants/{tenant}/tasks/{id}
Get task details and current state.
GET/v1/tenants/{tenant}/tasks
List tasks with optional filters (status, mailbox, source).
POST/v1/tenants/{tenant}/tasks/{id}/replay
Replay a task from DLQ back to pending.
Catalog & Intent
GET/v1/tenants/{tenant}/catalog
List online agents with their capabilities (name, description, schema) for client-side matching.
POST/v1/tenants/{tenant}/tasks
Intent routing — publish with target_type: "intent" and a natural-language target_value. Janus resolves it to the best matching capability (LLM if configured via JANUS_LLM_ENABLED, keyword fallback otherwise) before dispatch. There is no separate resolve endpoint.
Artifacts
POST/v1/tenants/{tenant}/artifacts
Upload an artifact. Multipart form with tenant isolation.
GET/v1/tenants/{tenant}/artifacts/{id}
Download an artifact (tenant-scoped access check).
Error Format
All errors return a standard envelope:
{
"error": {
"code": "TENANT_MISMATCH",
"message": "Cross-tenant access denied",
"details": {
"request_tenant": "acme",
"resource_tenant": "evil-corp"
}
}
}
| HTTP Status | Error Code | Description |
| 400 | INVALID_REQUEST | Malformed request body |
| 401 | UNAUTHENTICATED | Missing or invalid API key |
| 403 | TENANT_MISMATCH | Cross-tenant access denied |
| 403 | POLICY_DENIED | Governance policy blocked the operation |
| 404 | NOT_FOUND | Resource not found |
| 409 | LEASE_EXPIRED | Task lease expired, re-pull required |
| 429 | RATE_LIMITED | Budget or concurrency limit exceeded |
| 500 | INTERNAL | Server error |
Authentication
Janus supports two authentication modes:
- API Key (default, enabled) — pass key via
Authorization: Bearer <key> header
- mTLS — mutual TLS with client certificates
API keys are tenant-scoped. Create and revoke keys via the CLI:
janus api-key create --tenant acme
janus api-key revoke --tenant acme --key-id <id>
The full protobuf service definitions and gRPC reflection are available on the server. See the
GitHub repo for proto files.