Implements all P0 features per OpenSpec change phase-1-mvp-implementation: - Agent Registry Service (CRUD) — full lifecycle management - OAuth 2.0 Token Service (Client Credentials flow) - Credential Management (generate, rotate, revoke) - Immutable Audit Log Service Tech: Node.js 18+, TypeScript 5.3+ strict, Express 4.18+, PostgreSQL 14+, Redis 7+ Standards: OpenAPI 3.0 specs, DRY/SOLID, zero `any` types Quality: 18 unit test suites, 244 tests passing, 97%+ coverage OpenAPI: 4 complete specs (14 endpoints total) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
817 lines
27 KiB
YAML
817 lines
27 KiB
YAML
openapi: 3.0.3
|
|
|
|
info:
|
|
title: SentryAgent.ai — Agent Registry Service
|
|
version: 1.0.0
|
|
description: |
|
|
The Agent Registry Service provides full lifecycle management for AI agent
|
|
identities on the SentryAgent.ai AgentIdP platform. Every AI agent is treated
|
|
as a first-class non-human identity, aligned with the AGNTCY standard
|
|
(Linux Foundation).
|
|
|
|
Agents receive unique, immutable identifiers (UUIDs), typed capabilities,
|
|
and lifecycle status management. The registry is the authoritative source of
|
|
truth for all registered agent identities.
|
|
|
|
**Free Tier Limits**:
|
|
- Max 100 registered agents per account
|
|
- API rate limit: 100 requests/minute
|
|
|
|
servers:
|
|
- url: http://localhost:3000/api/v1
|
|
description: Local development server
|
|
- url: https://api.sentryagent.ai/v1
|
|
description: Production server
|
|
|
|
tags:
|
|
- name: Agent Registry
|
|
description: CRUD operations for AI agent identities
|
|
|
|
components:
|
|
securitySchemes:
|
|
BearerAuth:
|
|
type: http
|
|
scheme: bearer
|
|
bearerFormat: JWT
|
|
description: |
|
|
JWT access token obtained via the OAuth 2.0 Client Credentials flow
|
|
(`POST /token`). Include in the `Authorization` header as:
|
|
`Authorization: Bearer <token>`
|
|
|
|
schemas:
|
|
AgentType:
|
|
type: string
|
|
description: The functional classification of the AI agent.
|
|
enum:
|
|
- screener
|
|
- classifier
|
|
- orchestrator
|
|
- extractor
|
|
- summarizer
|
|
- router
|
|
- monitor
|
|
- custom
|
|
example: screener
|
|
|
|
DeploymentEnv:
|
|
type: string
|
|
description: The target deployment environment for the agent.
|
|
enum:
|
|
- development
|
|
- staging
|
|
- production
|
|
example: production
|
|
|
|
AgentStatus:
|
|
type: string
|
|
description: |
|
|
Lifecycle status of the agent.
|
|
- `active`: Agent is operational and can authenticate.
|
|
- `suspended`: Agent is temporarily disabled; credentials cannot be used.
|
|
- `decommissioned`: Agent is permanently retired; soft-deleted record remains.
|
|
enum:
|
|
- active
|
|
- suspended
|
|
- decommissioned
|
|
example: active
|
|
|
|
Agent:
|
|
type: object
|
|
description: Full representation of a registered AI agent identity.
|
|
required:
|
|
- agentId
|
|
- email
|
|
- agentType
|
|
- version
|
|
- capabilities
|
|
- owner
|
|
- deploymentEnv
|
|
- status
|
|
- createdAt
|
|
- updatedAt
|
|
properties:
|
|
agentId:
|
|
type: string
|
|
format: uuid
|
|
description: >
|
|
Immutable, system-assigned unique identifier for the agent.
|
|
Assigned at registration and never changes.
|
|
readOnly: true
|
|
example: "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
|
|
email:
|
|
type: string
|
|
format: email
|
|
description: >
|
|
Unique email-format identifier for the agent. Acts as the human-readable
|
|
stable name for this agent identity.
|
|
example: "screener-001@sentryagent.ai"
|
|
agentType:
|
|
$ref: '#/components/schemas/AgentType'
|
|
version:
|
|
type: string
|
|
description: Semantic version string of the agent software.
|
|
pattern: '^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$'
|
|
example: "1.4.2"
|
|
capabilities:
|
|
type: array
|
|
description: >
|
|
List of capability strings representing what this agent is permitted
|
|
to do. Uses a `resource:action` convention.
|
|
items:
|
|
type: string
|
|
pattern: '^[a-z0-9_-]+:[a-z0-9_*-]+$'
|
|
minItems: 1
|
|
example:
|
|
- "resume:read"
|
|
- "email:send"
|
|
- "candidate:score"
|
|
owner:
|
|
type: string
|
|
description: Team or organisation that owns and is responsible for this agent.
|
|
minLength: 1
|
|
maxLength: 128
|
|
example: "talent-acquisition-team"
|
|
deploymentEnv:
|
|
$ref: '#/components/schemas/DeploymentEnv'
|
|
status:
|
|
$ref: '#/components/schemas/AgentStatus'
|
|
createdAt:
|
|
type: string
|
|
format: date-time
|
|
description: ISO 8601 timestamp when the agent was first registered.
|
|
readOnly: true
|
|
example: "2026-03-28T09:00:00.000Z"
|
|
updatedAt:
|
|
type: string
|
|
format: date-time
|
|
description: ISO 8601 timestamp of the most recent update to this agent record.
|
|
readOnly: true
|
|
example: "2026-03-28T11:30:00.000Z"
|
|
|
|
CreateAgentRequest:
|
|
type: object
|
|
description: Request body for registering a new AI agent identity.
|
|
required:
|
|
- email
|
|
- agentType
|
|
- version
|
|
- capabilities
|
|
- owner
|
|
- deploymentEnv
|
|
properties:
|
|
email:
|
|
type: string
|
|
format: email
|
|
description: >
|
|
Unique email-format identifier for the agent.
|
|
Must be unique across all registered agents in the system.
|
|
example: "screener-001@sentryagent.ai"
|
|
agentType:
|
|
$ref: '#/components/schemas/AgentType'
|
|
version:
|
|
type: string
|
|
description: Semantic version string of the agent software.
|
|
pattern: '^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$'
|
|
example: "1.0.0"
|
|
capabilities:
|
|
type: array
|
|
description: List of capability strings for this agent.
|
|
items:
|
|
type: string
|
|
pattern: '^[a-z0-9_-]+:[a-z0-9_*-]+$'
|
|
minItems: 1
|
|
example:
|
|
- "resume:read"
|
|
- "email:send"
|
|
owner:
|
|
type: string
|
|
description: Team or organisation that owns this agent.
|
|
minLength: 1
|
|
maxLength: 128
|
|
example: "talent-acquisition-team"
|
|
deploymentEnv:
|
|
$ref: '#/components/schemas/DeploymentEnv'
|
|
|
|
UpdateAgentRequest:
|
|
type: object
|
|
description: >
|
|
Request body for updating agent metadata. All fields are optional;
|
|
only provided fields are updated. `agentId`, `email`, and `createdAt`
|
|
are immutable and cannot be changed.
|
|
minProperties: 1
|
|
properties:
|
|
agentType:
|
|
$ref: '#/components/schemas/AgentType'
|
|
version:
|
|
type: string
|
|
description: Updated semantic version string.
|
|
pattern: '^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$'
|
|
example: "1.5.0"
|
|
capabilities:
|
|
type: array
|
|
description: Updated list of capability strings. Replaces the full list.
|
|
items:
|
|
type: string
|
|
pattern: '^[a-z0-9_-]+:[a-z0-9_*-]+$'
|
|
minItems: 1
|
|
example:
|
|
- "resume:read"
|
|
- "email:send"
|
|
- "candidate:score"
|
|
- "report:write"
|
|
owner:
|
|
type: string
|
|
description: Updated owner team or organisation.
|
|
minLength: 1
|
|
maxLength: 128
|
|
example: "platform-team"
|
|
deploymentEnv:
|
|
$ref: '#/components/schemas/DeploymentEnv'
|
|
status:
|
|
$ref: '#/components/schemas/AgentStatus'
|
|
|
|
PaginatedAgentsResponse:
|
|
type: object
|
|
description: Paginated list of agent identities.
|
|
required:
|
|
- data
|
|
- total
|
|
- page
|
|
- limit
|
|
properties:
|
|
data:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/Agent'
|
|
total:
|
|
type: integer
|
|
description: Total number of agents matching the query filters.
|
|
example: 47
|
|
page:
|
|
type: integer
|
|
description: Current page number (1-based).
|
|
example: 1
|
|
limit:
|
|
type: integer
|
|
description: Number of items per page.
|
|
example: 20
|
|
|
|
ErrorResponse:
|
|
type: object
|
|
description: Standard error response envelope used across all SentryAgent.ai APIs.
|
|
required:
|
|
- code
|
|
- message
|
|
properties:
|
|
code:
|
|
type: string
|
|
description: >
|
|
Machine-readable error code. Use this field for programmatic error handling.
|
|
example: "AGENT_NOT_FOUND"
|
|
message:
|
|
type: string
|
|
description: Human-readable description of the error.
|
|
example: "Agent with the specified ID was not found."
|
|
details:
|
|
type: object
|
|
description: >
|
|
Optional structured details providing additional context about the error,
|
|
such as field-level validation failures.
|
|
additionalProperties: true
|
|
example:
|
|
field: "email"
|
|
reason: "Email address is already registered to another agent."
|
|
|
|
responses:
|
|
Unauthorized:
|
|
description: Missing or invalid Bearer token.
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/ErrorResponse'
|
|
example:
|
|
code: "UNAUTHORIZED"
|
|
message: "A valid Bearer token is required to access this resource."
|
|
|
|
Forbidden:
|
|
description: Valid token but insufficient permissions.
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/ErrorResponse'
|
|
example:
|
|
code: "FORBIDDEN"
|
|
message: "You do not have permission to perform this action."
|
|
|
|
NotFound:
|
|
description: The requested resource was not found.
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/ErrorResponse'
|
|
example:
|
|
code: "AGENT_NOT_FOUND"
|
|
message: "Agent with the specified ID was not found."
|
|
|
|
TooManyRequests:
|
|
description: Rate limit exceeded. Retry after the reset time.
|
|
headers:
|
|
X-RateLimit-Limit:
|
|
schema:
|
|
type: integer
|
|
description: Maximum number of requests allowed per minute.
|
|
example: 100
|
|
X-RateLimit-Remaining:
|
|
schema:
|
|
type: integer
|
|
description: Number of requests remaining in the current window.
|
|
example: 0
|
|
X-RateLimit-Reset:
|
|
schema:
|
|
type: integer
|
|
description: Unix timestamp (seconds) when the rate limit window resets.
|
|
example: 1743155400
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/ErrorResponse'
|
|
example:
|
|
code: "RATE_LIMIT_EXCEEDED"
|
|
message: "Too many requests. Please retry after the rate limit window resets."
|
|
|
|
InternalServerError:
|
|
description: Unexpected server error. Contact support if the issue persists.
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/ErrorResponse'
|
|
example:
|
|
code: "INTERNAL_SERVER_ERROR"
|
|
message: "An unexpected error occurred. Please try again later."
|
|
|
|
security:
|
|
- BearerAuth: []
|
|
|
|
paths:
|
|
/agents:
|
|
post:
|
|
operationId: registerAgent
|
|
tags:
|
|
- Agent Registry
|
|
summary: Register a new AI agent
|
|
description: |
|
|
Creates a new AI agent identity in the SentryAgent.ai registry.
|
|
|
|
A unique immutable `agentId` (UUID) is system-assigned on creation.
|
|
The `email` must be unique across all registered agents.
|
|
|
|
**Free Tier**: Maximum 100 registered agents per account. Attempting to
|
|
register beyond this limit returns `403 Forbidden` with code `FREE_TIER_LIMIT_EXCEEDED`.
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/CreateAgentRequest'
|
|
example:
|
|
email: "screener-001@sentryagent.ai"
|
|
agentType: "screener"
|
|
version: "1.0.0"
|
|
capabilities:
|
|
- "resume:read"
|
|
- "email:send"
|
|
owner: "talent-acquisition-team"
|
|
deploymentEnv: "production"
|
|
responses:
|
|
'201':
|
|
description: Agent registered successfully.
|
|
headers:
|
|
X-RateLimit-Limit:
|
|
schema:
|
|
type: integer
|
|
example: 100
|
|
X-RateLimit-Remaining:
|
|
schema:
|
|
type: integer
|
|
example: 99
|
|
X-RateLimit-Reset:
|
|
schema:
|
|
type: integer
|
|
example: 1743155400
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/Agent'
|
|
example:
|
|
agentId: "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
|
|
email: "screener-001@sentryagent.ai"
|
|
agentType: "screener"
|
|
version: "1.0.0"
|
|
capabilities:
|
|
- "resume:read"
|
|
- "email:send"
|
|
owner: "talent-acquisition-team"
|
|
deploymentEnv: "production"
|
|
status: "active"
|
|
createdAt: "2026-03-28T09:00:00.000Z"
|
|
updatedAt: "2026-03-28T09:00:00.000Z"
|
|
'400':
|
|
description: Invalid request body. Check `details` for field-level errors.
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/ErrorResponse'
|
|
example:
|
|
code: "VALIDATION_ERROR"
|
|
message: "Request validation failed."
|
|
details:
|
|
field: "email"
|
|
reason: "Must be a valid email address."
|
|
'401':
|
|
$ref: '#/components/responses/Unauthorized'
|
|
'403':
|
|
description: Forbidden. Either insufficient permissions or free tier limit reached.
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/ErrorResponse'
|
|
examples:
|
|
insufficientPermissions:
|
|
summary: Insufficient permissions
|
|
value:
|
|
code: "FORBIDDEN"
|
|
message: "You do not have permission to register agents."
|
|
freeTierLimit:
|
|
summary: Free tier agent limit reached
|
|
value:
|
|
code: "FREE_TIER_LIMIT_EXCEEDED"
|
|
message: "Free tier limit of 100 registered agents has been reached."
|
|
details:
|
|
limit: 100
|
|
current: 100
|
|
'409':
|
|
description: An agent with the provided email address is already registered.
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/ErrorResponse'
|
|
example:
|
|
code: "AGENT_ALREADY_EXISTS"
|
|
message: "An agent with this email address is already registered."
|
|
details:
|
|
email: "screener-001@sentryagent.ai"
|
|
'429':
|
|
$ref: '#/components/responses/TooManyRequests'
|
|
'500':
|
|
$ref: '#/components/responses/InternalServerError'
|
|
|
|
get:
|
|
operationId: listAgents
|
|
tags:
|
|
- Agent Registry
|
|
summary: List registered agents
|
|
description: |
|
|
Returns a paginated list of all registered AI agent identities accessible
|
|
to the authenticated caller.
|
|
|
|
Results can be filtered by `owner`, `agentType`, and/or `status`.
|
|
Results are ordered by `createdAt` descending (most recent first).
|
|
parameters:
|
|
- name: page
|
|
in: query
|
|
description: Page number (1-based). Defaults to `1`.
|
|
required: false
|
|
schema:
|
|
type: integer
|
|
minimum: 1
|
|
default: 1
|
|
example: 1
|
|
- name: limit
|
|
in: query
|
|
description: Number of results per page. Defaults to `20`, maximum `100`.
|
|
required: false
|
|
schema:
|
|
type: integer
|
|
minimum: 1
|
|
maximum: 100
|
|
default: 20
|
|
example: 20
|
|
- name: owner
|
|
in: query
|
|
description: Filter agents by owner name (exact match).
|
|
required: false
|
|
schema:
|
|
type: string
|
|
example: "talent-acquisition-team"
|
|
- name: agentType
|
|
in: query
|
|
description: Filter agents by type.
|
|
required: false
|
|
schema:
|
|
$ref: '#/components/schemas/AgentType'
|
|
- name: status
|
|
in: query
|
|
description: Filter agents by lifecycle status.
|
|
required: false
|
|
schema:
|
|
$ref: '#/components/schemas/AgentStatus'
|
|
responses:
|
|
'200':
|
|
description: Paginated list of agents returned successfully.
|
|
headers:
|
|
X-RateLimit-Limit:
|
|
schema:
|
|
type: integer
|
|
example: 100
|
|
X-RateLimit-Remaining:
|
|
schema:
|
|
type: integer
|
|
example: 95
|
|
X-RateLimit-Reset:
|
|
schema:
|
|
type: integer
|
|
example: 1743155400
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/PaginatedAgentsResponse'
|
|
example:
|
|
data:
|
|
- agentId: "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
|
|
email: "screener-001@sentryagent.ai"
|
|
agentType: "screener"
|
|
version: "1.4.2"
|
|
capabilities:
|
|
- "resume:read"
|
|
- "email:send"
|
|
- "candidate:score"
|
|
owner: "talent-acquisition-team"
|
|
deploymentEnv: "production"
|
|
status: "active"
|
|
createdAt: "2026-03-01T08:00:00.000Z"
|
|
updatedAt: "2026-03-28T09:00:00.000Z"
|
|
- agentId: "b2c3d4e5-f6a7-8901-bcde-f12345678901"
|
|
email: "classifier-002@sentryagent.ai"
|
|
agentType: "classifier"
|
|
version: "2.1.0"
|
|
capabilities:
|
|
- "document:classify"
|
|
- "label:write"
|
|
owner: "talent-acquisition-team"
|
|
deploymentEnv: "staging"
|
|
status: "active"
|
|
createdAt: "2026-03-10T10:00:00.000Z"
|
|
updatedAt: "2026-03-10T10:00:00.000Z"
|
|
total: 47
|
|
page: 1
|
|
limit: 20
|
|
'400':
|
|
description: Invalid query parameters.
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/ErrorResponse'
|
|
example:
|
|
code: "VALIDATION_ERROR"
|
|
message: "Invalid query parameter value."
|
|
details:
|
|
field: "limit"
|
|
reason: "Must be an integer between 1 and 100."
|
|
'401':
|
|
$ref: '#/components/responses/Unauthorized'
|
|
'403':
|
|
$ref: '#/components/responses/Forbidden'
|
|
'429':
|
|
$ref: '#/components/responses/TooManyRequests'
|
|
'500':
|
|
$ref: '#/components/responses/InternalServerError'
|
|
|
|
/agents/{agentId}:
|
|
parameters:
|
|
- name: agentId
|
|
in: path
|
|
description: The unique UUID identifier of the agent.
|
|
required: true
|
|
schema:
|
|
type: string
|
|
format: uuid
|
|
example: "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
|
|
|
|
get:
|
|
operationId: getAgentById
|
|
tags:
|
|
- Agent Registry
|
|
summary: Get agent by ID
|
|
description: |
|
|
Retrieves the full identity record for a single AI agent by its immutable `agentId`.
|
|
responses:
|
|
'200':
|
|
description: Agent record returned successfully.
|
|
headers:
|
|
X-RateLimit-Limit:
|
|
schema:
|
|
type: integer
|
|
example: 100
|
|
X-RateLimit-Remaining:
|
|
schema:
|
|
type: integer
|
|
example: 94
|
|
X-RateLimit-Reset:
|
|
schema:
|
|
type: integer
|
|
example: 1743155400
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/Agent'
|
|
example:
|
|
agentId: "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
|
|
email: "screener-001@sentryagent.ai"
|
|
agentType: "screener"
|
|
version: "1.4.2"
|
|
capabilities:
|
|
- "resume:read"
|
|
- "email:send"
|
|
- "candidate:score"
|
|
owner: "talent-acquisition-team"
|
|
deploymentEnv: "production"
|
|
status: "active"
|
|
createdAt: "2026-03-01T08:00:00.000Z"
|
|
updatedAt: "2026-03-28T09:00:00.000Z"
|
|
'401':
|
|
$ref: '#/components/responses/Unauthorized'
|
|
'403':
|
|
$ref: '#/components/responses/Forbidden'
|
|
'404':
|
|
$ref: '#/components/responses/NotFound'
|
|
'429':
|
|
$ref: '#/components/responses/TooManyRequests'
|
|
'500':
|
|
$ref: '#/components/responses/InternalServerError'
|
|
|
|
patch:
|
|
operationId: updateAgent
|
|
tags:
|
|
- Agent Registry
|
|
summary: Update agent metadata
|
|
description: |
|
|
Partially updates the metadata for an existing agent.
|
|
|
|
Only the fields provided in the request body are updated. Omitted fields
|
|
are left unchanged. The following fields are immutable and cannot be
|
|
updated: `agentId`, `email`, `createdAt`.
|
|
|
|
Setting `status` to `decommissioned` is a one-way operation — a
|
|
decommissioned agent cannot be reactivated.
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/UpdateAgentRequest'
|
|
example:
|
|
version: "1.5.0"
|
|
capabilities:
|
|
- "resume:read"
|
|
- "email:send"
|
|
- "candidate:score"
|
|
- "report:write"
|
|
deploymentEnv: "production"
|
|
responses:
|
|
'200':
|
|
description: Agent updated successfully. Returns the full updated agent record.
|
|
headers:
|
|
X-RateLimit-Limit:
|
|
schema:
|
|
type: integer
|
|
example: 100
|
|
X-RateLimit-Remaining:
|
|
schema:
|
|
type: integer
|
|
example: 93
|
|
X-RateLimit-Reset:
|
|
schema:
|
|
type: integer
|
|
example: 1743155400
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/Agent'
|
|
example:
|
|
agentId: "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
|
|
email: "screener-001@sentryagent.ai"
|
|
agentType: "screener"
|
|
version: "1.5.0"
|
|
capabilities:
|
|
- "resume:read"
|
|
- "email:send"
|
|
- "candidate:score"
|
|
- "report:write"
|
|
owner: "talent-acquisition-team"
|
|
deploymentEnv: "production"
|
|
status: "active"
|
|
createdAt: "2026-03-01T08:00:00.000Z"
|
|
updatedAt: "2026-03-28T11:30:00.000Z"
|
|
'400':
|
|
description: Invalid request body or attempt to modify an immutable field.
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/ErrorResponse'
|
|
examples:
|
|
validationError:
|
|
summary: Validation failure
|
|
value:
|
|
code: "VALIDATION_ERROR"
|
|
message: "Request validation failed."
|
|
details:
|
|
field: "version"
|
|
reason: "Must be a valid semantic version string."
|
|
immutableField:
|
|
summary: Attempt to modify immutable field
|
|
value:
|
|
code: "IMMUTABLE_FIELD"
|
|
message: "The field 'email' cannot be modified after registration."
|
|
details:
|
|
field: "email"
|
|
'401':
|
|
$ref: '#/components/responses/Unauthorized'
|
|
'403':
|
|
description: Forbidden. Insufficient permissions or agent is decommissioned.
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/ErrorResponse'
|
|
examples:
|
|
forbidden:
|
|
summary: Insufficient permissions
|
|
value:
|
|
code: "FORBIDDEN"
|
|
message: "You do not have permission to update this agent."
|
|
decommissioned:
|
|
summary: Agent is decommissioned
|
|
value:
|
|
code: "AGENT_DECOMMISSIONED"
|
|
message: "Decommissioned agents cannot be updated."
|
|
details:
|
|
agentId: "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
|
|
'404':
|
|
$ref: '#/components/responses/NotFound'
|
|
'429':
|
|
$ref: '#/components/responses/TooManyRequests'
|
|
'500':
|
|
$ref: '#/components/responses/InternalServerError'
|
|
|
|
delete:
|
|
operationId: deactivateAgent
|
|
tags:
|
|
- Agent Registry
|
|
summary: Deactivate (soft-delete) an agent
|
|
description: |
|
|
Permanently decommissions an AI agent. This is a **soft delete** — the
|
|
agent record is retained in the database for audit purposes, but the
|
|
agent's status is set to `decommissioned`.
|
|
|
|
**Effects of decommissioning**:
|
|
- All active credentials for this agent are immediately revoked.
|
|
- The agent can no longer authenticate or obtain tokens.
|
|
- The agent record remains visible in the registry with status `decommissioned`.
|
|
- This operation is **irreversible**.
|
|
responses:
|
|
'204':
|
|
description: Agent decommissioned successfully. No response body.
|
|
headers:
|
|
X-RateLimit-Limit:
|
|
schema:
|
|
type: integer
|
|
example: 100
|
|
X-RateLimit-Remaining:
|
|
schema:
|
|
type: integer
|
|
example: 92
|
|
X-RateLimit-Reset:
|
|
schema:
|
|
type: integer
|
|
example: 1743155400
|
|
'401':
|
|
$ref: '#/components/responses/Unauthorized'
|
|
'403':
|
|
$ref: '#/components/responses/Forbidden'
|
|
'404':
|
|
$ref: '#/components/responses/NotFound'
|
|
'409':
|
|
description: Agent is already decommissioned.
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/ErrorResponse'
|
|
example:
|
|
code: "AGENT_ALREADY_DECOMMISSIONED"
|
|
message: "This agent has already been decommissioned."
|
|
details:
|
|
agentId: "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
|
|
'429':
|
|
$ref: '#/components/responses/TooManyRequests'
|
|
'500':
|
|
$ref: '#/components/responses/InternalServerError'
|