Files
sentryagent-idp/docs/developers/api-reference.md
SentryAgent.ai Developer 61ea975c79 docs: bedroom developer documentation — complete docs/developers/ set
Adds the full bedroom-developer-docs OpenSpec change implementation:

- docs/developers/README.md — index page
- docs/developers/quick-start.md — bootstrap to working token in 7 steps
- docs/developers/concepts.md — AgentIdP, AGNTCY, lifecycle, OAuth 2.0, free tier
- docs/developers/guides/README.md — guide index
- docs/developers/guides/register-an-agent.md — all fields, validation, common errors
- docs/developers/guides/manage-credentials.md — generate, list, rotate, revoke
- docs/developers/guides/issue-and-revoke-tokens.md — OAuth 2.0 flow, introspect, revoke
- docs/developers/guides/query-audit-logs.md — filters, pagination, 90-day retention
- docs/developers/api-reference.md — all 14 endpoints, all error codes, curl examples

Also commits deferred OpenSpec housekeeping from previous session:
- Archives phase-1-mvp-implementation change to openspec/changes/archive/
- Adds bedroom-developer-docs change artifacts (30/30 tasks complete)
- Syncs 4 delta specs to openspec/specs/

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-28 14:13:03 +00:00

16 KiB
Raw Permalink Blame History

API Reference

Complete reference for all 14 endpoints across the four SentryAgent.ai AgentIdP services.

Base URL

http://localhost:3000/api/v1

The port is configured via the PORT environment variable (default: 3000).

All endpoints are currently unversioned within the path prefix /api/v1. API versioning will be introduced in Phase 2.

Authentication

All endpoints require a JWT Bearer token in the Authorization header:

Authorization: Bearer <access_token>

Obtain a token via POST /token using your agent's client_id and client_secret.

Table of Contents


Errors

All error responses use this envelope:

{
  "code": "ERROR_CODE",
  "message": "Human-readable description.",
  "details": {}
}

The details field is optional and provides additional context (e.g. which field failed validation).

Error codes

Code HTTP Status Description
VALIDATION_ERROR 400 Request body or query parameter failed validation
UNAUTHORIZED 401 Missing, expired, or invalid Bearer token
FORBIDDEN 403 Valid token but insufficient scope
AGENT_NOT_FOUND 404 Agent with the given agentId does not exist
CREDENTIAL_NOT_FOUND 404 Credential with the given credentialId does not exist
AUDIT_EVENT_NOT_FOUND 404 Audit event with the given eventId does not exist (or outside retention window)
AGENT_ALREADY_EXISTS 409 An agent with this email is already registered
AGENT_ALREADY_DECOMMISSIONED 409 Agent has already been decommissioned
CREDENTIAL_ALREADY_REVOKED 409 Credential has already been revoked
RATE_LIMIT_EXCEEDED 429 100 req/min limit exceeded
FREE_TIER_LIMIT_EXCEEDED 403 Free tier resource limit reached
INSUFFICIENT_SCOPE 403 Token is missing a required scope
IMMUTABLE_FIELD 400 Attempt to modify a field that cannot be changed
AGENT_NOT_ACTIVE 403 Operation requires agent to be in active status
AGENT_DECOMMISSIONED 403 Cannot modify a decommissioned agent
RETENTION_WINDOW_EXCEEDED 400 Requested audit date is outside the 90-day retention window
INTERNAL_SERVER_ERROR 500 Unexpected server error

Rate limit headers

Every response includes rate limit headers:

Header Description
X-RateLimit-Limit Maximum requests per minute (100)
X-RateLimit-Remaining Requests remaining in current window
X-RateLimit-Reset Unix timestamp when the window resets

On 429 responses, wait until X-RateLimit-Reset before retrying.


Agent Registry

POST /agents — Register a new agent

Creates a new AI agent identity. The agentId is system-assigned.

Auth: Bearer token with agents:write scope.

Request body (application/json):

Field Type Required Description
email string Yes Unique email-format identifier
agentType enum Yes screener | classifier | orchestrator | extractor | summarizer | router | monitor | custom
version string Yes Semantic version (e.g. 1.0.0)
capabilities string[] Yes resource:action strings, min 1
owner string Yes Owning team/org, 1128 chars
deploymentEnv enum Yes development | staging | production

Response codes:

Code Meaning
201 Agent registered successfully
400 Validation error
401 Invalid token
403 Insufficient scope or free tier limit reached
409 Email already registered
429 Rate limit exceeded

Example:

curl -s -X POST http://localhost:3000/api/v1/agents \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "email": "screener-001@talent.ai",
    "agentType": "screener",
    "version": "1.0.0",
    "capabilities": ["resume:read", "email:send"],
    "owner": "talent-team",
    "deploymentEnv": "production"
  }' | jq .

GET /agents — List agents

Returns a paginated list of registered agents.

Auth: Bearer token with agents:read scope.

Query parameters:

Parameter Type Default Description
page integer 1 Page number (1-based)
limit integer 20 Results per page (max 100)
owner string Filter by owner (exact match)
agentType enum Filter by agent type
status enum Filter by status

Response codes:

Code Meaning
200 List returned
400 Invalid query parameters
401 Invalid token
403 Insufficient scope
429 Rate limit exceeded

Example:

curl -s "http://localhost:3000/api/v1/agents?page=1&limit=20&status=active" \
  -H "Authorization: Bearer $TOKEN" | jq .

GET /agents/{agentId} — Get agent by ID

Returns the full identity record for a single agent.

Auth: Bearer token with agents:read scope.

Path parameters:

Parameter Type Description
agentId UUID The agent's immutable identifier

Response codes:

Code Meaning
200 Agent record returned
401 Invalid token
403 Insufficient scope
404 Agent not found
429 Rate limit exceeded

Example:

curl -s "http://localhost:3000/api/v1/agents/$AGENT_ID" \
  -H "Authorization: Bearer $TOKEN" | jq .

PATCH /agents/{agentId} — Update agent metadata

Partially updates agent metadata. Only provided fields are changed. Immutable fields (agentId, email, createdAt) cannot be updated.

Auth: Bearer token with agents:write scope.

Request body (application/json) — all fields optional:

Field Type Description
agentType enum Updated agent type
version string Updated semantic version
capabilities string[] Updated capabilities (replaces the full list)
owner string Updated owner
deploymentEnv enum Updated deployment environment
status enum Updated status (active | suspended | decommissioned)

Setting status to decommissioned is irreversible. The agent cannot be reactivated.

Response codes:

Code Meaning
200 Agent updated, full record returned
400 Validation error or attempt to modify immutable field
401 Invalid token
403 Insufficient scope or agent is decommissioned
404 Agent not found
429 Rate limit exceeded

Example:

curl -s -X PATCH "http://localhost:3000/api/v1/agents/$AGENT_ID" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "version": "1.5.0", "status": "suspended" }' | jq .

DELETE /agents/{agentId} — Decommission an agent

Permanently decommissions an agent (soft delete). All active credentials are immediately revoked. This operation is irreversible.

Auth: Bearer token with agents:write scope.

Response codes:

Code Meaning
204 Agent decommissioned (no body)
401 Invalid token
403 Insufficient scope
404 Agent not found
409 Agent already decommissioned
429 Rate limit exceeded

Example:

curl -s -X DELETE "http://localhost:3000/api/v1/agents/$AGENT_ID" \
  -H "Authorization: Bearer $TOKEN" \
  -o /dev/null -w "%{http_code}\n"

OAuth 2.0 Tokens

POST /token — Issue an access token

Issues a signed RS256 JWT via the OAuth 2.0 Client Credentials grant.

Auth: Client credentials in the request body (no Bearer token required for this endpoint).

Content-Type: This endpoint uses application/x-www-form-urlencoded, not JSON.

Request fields (form-encoded):

Field Required Description
grant_type Yes Must be client_credentials
client_id Yes Your agent's agentId (UUID)
client_secret Yes The credential secret
scope No Space-separated scopes. If omitted, all scopes are granted.

Response codes:

Code Meaning
200 Token issued
400 Malformed request, invalid scope, or unsupported grant type
401 Invalid client_id or client_secret
403 Agent suspended or monthly token limit reached
429 Rate limit exceeded

Note on 429: The X-RateLimit-* headers are returned on all responses, including 429.

Example:

curl -s -X POST http://localhost:3000/api/v1/token \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "grant_type=client_credentials" \
  -d "client_id=$CLIENT_ID" \
  -d "client_secret=$CLIENT_SECRET" \
  -d "scope=agents:read agents:write" | jq .

POST /token/introspect — Introspect a token

Checks whether a token is active. Returns { "active": false } for expired or revoked tokens — always 200 OK.

Auth: Bearer token with tokens:read scope.

Content-Type: application/x-www-form-urlencoded

Request fields:

Field Required Description
token Yes The JWT to introspect
token_type_hint No Optional hint — access_token

Response codes:

Code Meaning
200 Result returned (check active field)
400 Missing token parameter
401 Caller's Bearer token is invalid
403 Caller's token lacks tokens:read scope
429 Rate limit exceeded

Example:

curl -s -X POST http://localhost:3000/api/v1/token/introspect \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "token=$TOKEN_TO_CHECK" | jq .

POST /token/revoke — Revoke a token

Immediately invalidates a token. Idempotent — revoking an already-revoked token returns 200.

Auth: Bearer token (agent can revoke its own tokens).

Content-Type: application/x-www-form-urlencoded

Request fields:

Field Required Description
token Yes The JWT to revoke
token_type_hint No Optional hint — access_token

Response codes:

Code Meaning
200 Token revoked (or was already inactive)
400 Missing token parameter
401 Caller's Bearer token is invalid
403 Insufficient permissions to revoke this token
429 Rate limit exceeded

Example:

curl -s -X POST http://localhost:3000/api/v1/token/revoke \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "token=$TOKEN_TO_REVOKE" | jq .

Credential Management

POST /agents/{agentId}/credentials — Generate credentials

Creates a new client_id + client_secret pair. The clientSecret is returned once only.

Auth: Bearer token with agents:write scope.

Request body (application/json) — optional:

Field Type Required Description
expiresAt ISO 8601 No Optional expiry date. Must be a future date. If omitted, credential does not expire.

Response codes:

Code Meaning
201 Credential created — save clientSecret now
400 Invalid expiresAt
401 Invalid token
403 Insufficient scope or agent not active
404 Agent not found
429 Rate limit exceeded

Example:

curl -s -X POST "http://localhost:3000/api/v1/agents/$AGENT_ID/credentials" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "expiresAt": "2027-01-01T00:00:00.000Z" }' | jq .

GET /agents/{agentId}/credentials — List credentials

Returns all credentials (active and revoked). The clientSecret is never returned.

Auth: Bearer token with agents:read scope.

Query parameters:

Parameter Type Default Description
page integer 1 Page number
limit integer 20 Results per page (max 100)
status enum Filter by active or revoked

Response codes:

Code Meaning
200 List returned
400 Invalid query parameters
401 Invalid token
403 Insufficient scope
404 Agent not found
429 Rate limit exceeded

Example:

curl -s "http://localhost:3000/api/v1/agents/$AGENT_ID/credentials?status=active" \
  -H "Authorization: Bearer $TOKEN" | jq .

POST /agents/{agentId}/credentials/{credentialId}/rotate — Rotate a credential

Replaces the clientSecret for the same credentialId. The old secret is immediately invalidated.

Auth: Bearer token with agents:write scope.

Request body (application/json) — optional:

Field Type Required Description
expiresAt ISO 8601 No New expiry for the rotated credential

Response codes:

Code Meaning
200 Credential rotated — save new clientSecret now
400 Invalid expiresAt
401 Invalid token
403 Insufficient scope
404 Agent or credential not found
409 Credential is already revoked
429 Rate limit exceeded

Example:

curl -s -X POST \
  "http://localhost:3000/api/v1/agents/$AGENT_ID/credentials/$CREDENTIAL_ID/rotate" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{}' | jq .

DELETE /agents/{agentId}/credentials/{credentialId} — Revoke a credential

Permanently revokes a credential. The credential can no longer obtain tokens. Irreversible.

Auth: Bearer token with agents:write scope.

Response codes:

Code Meaning
204 Credential revoked (no body)
401 Invalid token
403 Insufficient scope
404 Agent or credential not found
409 Credential already revoked
429 Rate limit exceeded

Example:

curl -s -X DELETE \
  "http://localhost:3000/api/v1/agents/$AGENT_ID/credentials/$CREDENTIAL_ID" \
  -H "Authorization: Bearer $TOKEN" \
  -o /dev/null -w "%{http_code}\n"

Audit Log

GET /audit — Query audit log

Returns a paginated, filtered list of audit events (most recent first).

Auth: Bearer token with audit:read scope.

Query parameters:

Parameter Type Default Description
page integer 1 Page number
limit integer 50 Results per page (max 200)
agentId UUID Filter by agent
action enum Filter by action type (see Audit Log guide)
outcome enum success or failure
fromDate ISO 8601 Events at or after this timestamp (max 90 days ago)
toDate ISO 8601 Events at or before this timestamp

Response codes:

Code Meaning
200 Events returned
400 Invalid parameters or date outside retention window
401 Invalid token
403 Token lacks audit:read scope
429 Rate limit exceeded

Example:

curl -s "http://localhost:3000/api/v1/audit?agentId=$AGENT_ID&action=token.issued&limit=50" \
  -H "Authorization: Bearer $TOKEN" | jq .

GET /audit/{eventId} — Get audit event by ID

Returns a single audit event by its immutable eventId.

Auth: Bearer token with audit:read scope.

Path parameters:

Parameter Type Description
eventId UUID The audit event's identifier

Response codes:

Code Meaning
200 Audit event returned
401 Invalid token
403 Token lacks audit:read scope
404 Event not found or outside 90-day retention window
429 Rate limit exceeded

Example:

curl -s "http://localhost:3000/api/v1/audit/$EVENT_ID" \
  -H "Authorization: Bearer $TOKEN" | jq .