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 StatusError CodeDescription
400INVALID_REQUESTMalformed request body
401UNAUTHENTICATEDMissing or invalid API key
403TENANT_MISMATCHCross-tenant access denied
403POLICY_DENIEDGovernance policy blocked the operation
404NOT_FOUNDResource not found
409LEASE_EXPIREDTask lease expired, re-pull required
429RATE_LIMITEDBudget or concurrency limit exceeded
500INTERNALServer error

Authentication

Janus supports two authentication modes:

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.