Orchestrata Ultimate / Specs / 098-api-standards

098-api-standards: API Standards

This specification defines the API standards, versioning strategy, error codes, rate limiting, and response formats for all orchestrata-ultimate APIs.

At a glance

Item Value
Spec directory specs/098-api-standards/
Status line in the spec Complete
Requirement IDs defined 96
With a @traces citation in src/ 0 (0.0%)
With a @traces citation in tests/ 0 (0.0%)
Tracked files 2
RTM page 098-api-standards

Reading this spec

This spec sets the API standards for every orchestrata-ultimate API: the versioning strategy, error codes, rate limiting and response formats. It exists so that clients see the same conventions whichever component they call, and so that API changes can be judged against one yardstick.

Its functional requirements (FR-001 to FR-018 and beyond) cover version declaration and version responses, backward compatibility, breaking change detection, deprecation notices, the error response structure and error code categories, rate limit headers and the response when a limit is exceeded, request authentication and validation, the response format, pagination, idempotency, cache headers, security headers and request tracing. The terminology table defines terms such as SemVer, burst limit, idempotency and breaking change.

The 96 requirement IDs (REQ-098-NNN) turn these into rules. Every request carries version information in the URL path or a header. Error codes fall into the categories AUTH, AUTHZ, VAL, RES, RATE and SYS, and validation failures return HTTP 422 with a matching VAL code. List endpoints paginate with page and per_page. A request over the limit receives HTTP 429 with a RATE-001 error carrying the limit, window and retry_after details, and a Retry-After header; rate limit headers appear on all responses and tiers vary by user. POST endpoints that create resources accept an optional Idempotency-Key header and store the response for 24 hours. Every response carries an X-Response-Time header. WebSocket endpoints accept token-based authentication through a query parameter. Access control is governed by PAM++ policies with role-based permissions for endpoint groups, and all API access is audit-logged. Contract tests run all endpoints against the OpenAPI spec and detect breaking changes, and CI runs tests on every commit, performance tests nightly, security tests weekly and compliance tests per release.

This is a standards spec, so no code module cites it. The requirements traceability matrix lists every ID. The spec's own status line reads Complete and it tracks 2 files. No src/ symbol cites any of the 96 requirements, so measured trace coverage is 0.0%, and in tests/, 0 requirements are cited by a test-side @traces. All 96 requirements have no citing symbol; untraced means no @traces names the ID, and the behaviour may still exist in code that was never annotated.

Requirements

Checkbox is the state recorded in the requirements checklist; Traced by is the count of src/ symbols whose @traces names the ID.

ID Done Requirement Traced by
REQ-098-001 - All API requests MUST include version information via URL path or header. none
REQ-098-002 - All API responses MUST include version metadata in the response header and body. none
REQ-098-003 - API versions within the same MAJOR version MUST maintain backward compatibility. none
REQ-098-004 - Breaking changes MUST trigger a MAJOR version increment. none
REQ-098-005 - Deprecated API versions MUST include Deprecation and Sunset headers for 90 days minimum. none
REQ-098-006 - All error responses MUST follow the defined JSON error schema with code, message, and details. none
REQ-098-007 - Error codes MUST be categorized: AUTH, AUTHZ, VAL, RES, RATE, SYS. none
REQ-098-008 - All responses MUST include X-RateLimit-Limit, X-RateLimit-Remaining, and X-RateLimit-Reset headers. none
REQ-098-009 - When rate limit is exceeded, API MUST return 429 with Retry-After header. none
REQ-098-010 - All API requests MUST include valid authentication credentials. none
REQ-098-011 - All POST/PUT requests MUST be validated against JSON schema. none
REQ-098-012 - All successful responses MUST include data and metadata objects. none
REQ-098-013 - List endpoints MUST support pagination with page, per_page parameters. none
REQ-098-014 - POST endpoints that create resources MUST support Idempotency-Key header. none
REQ-098-015 - GET responses MAY include ETag and Cache-Control headers. none
REQ-098-016 - All responses MUST include security headers (X-Content-Type-Options, X-Frame-Options). none
REQ-098-017 - All responses MUST include X-Request-ID header for tracing. none
REQ-098-018 - API MUST provide /api/v1/health endpoint for health monitoring. none
REQ-098-019 - WebSocket endpoints MUST support token-based authentication via query parameter. none
REQ-098-020 - WebSocket messages MUST use defined message types: subscribe, unsubscribe, event, error, ping, pong. none
REQ-098-021 - All endpoints MUST be documented with OpenAPI 3.x specification. none
REQ-098-022 - API MUST support CORS for allowed origins. none
REQ-098-023 - Authentication failures MUST return HTTP 401 with the matching AUTH code: AUTH-001 for an invalid API key (ERR-001), AUTH-002 for an expired API key (ERR-002), AUTH-003 for a missing authentication header (ERR-003), and AUTH-004 for a malformed authentication token (ERR-004). none
REQ-098-024 - Authorization failures MUST return HTTP 403 with the matching AUTHZ code: AUTHZ-001 for insufficient permissions for the operation (ERR-005), AUTHZ-002 for an operation blocked by governance policy (ERR-006), and AUTHZ-003 when the user role does not meet the requirement (ERR-007). none
REQ-098-025 - Validation failures MUST return HTTP 422 with the matching VAL code: VAL-001 for a required field missing in the request (ERR-008), VAL-002 when a field type does not match the expected type (ERR-009), VAL-003 for a field value outside the allowed range (ERR-010), and VAL-004 for a failed field format validation (ERR-011). none
REQ-098-026 - Resource failures MUST return the matching RES code and status: 404 with RES-001 when the requested resource is not found (ERR-012), 409 with RES-002 when the resource already exists (ERR-013), 409 with RES-003 on a resource state conflict (ERR-014), and 423 with RES-004 when the resource is locked for modification (ERR-015). none
REQ-098-027 - Rate-limiting failures MUST return HTTP 429 with the matching RATE code: RATE-001 when the tier rate limit is exceeded (ERR-016), RATE-002 when the burst limit is exceeded (ERR-017), and RATE-003 when the daily quota is exceeded (ERR-018). none
REQ-098-028 - System failures MUST return the matching SYS code and status: 500 with SYS-001 for an internal server error (ERR-019), 503 with SYS-002 when the service is temporarily unavailable (ERR-020), 504 with SYS-003 on an upstream dependency timeout (ERR-021), and 503 with SYS-004 when the circuit breaker is preventing requests (ERR-022). none
REQ-098-101 - P95 latency MUST be below 500ms for standard requests. none
REQ-098-102 - P99 latency MUST be below 1000ms for standard requests. none
REQ-098-103 - A response time header MUST be included in all responses. none
REQ-098-104 - The API MUST meet a 99.9% uptime target. none
REQ-098-105 - Rate limit enforcement MUST be provided with configurable tiers. none
REQ-098-106 - A circuit breaker MUST guard dependency failures. none
REQ-098-107 - The API MUST support 10x normal load. none
REQ-098-108 - Rate limiting MUST be enforced per endpoint. none
REQ-098-109 - Burst allowance MUST be handled. none
REQ-098-110 - HTTPS MUST be required for all endpoints. none
REQ-098-111 - API key authentication MUST be mandatory. none
REQ-098-112 - Security headers MUST be present on all responses. none
REQ-098-113 - Input validation MUST be applied to all requests. none
REQ-098-029 - Each integration MUST use the protocol and authentication listed for it: the Neo4j database over Bolt with connection-string auth, the Redis cache over the Redis protocol with password auth, Prometheus metrics over HTTP with no authentication (internal), WebSocket clients over WS/WSS with a token in the query parameter, and external webhooks over HTTPS with an HMAC signature. none
REQ-098-030 - The API MUST expose GET /api/v{version}/resources/{id} to retrieve a specific resource, taking version and id as required path parameters, accepting the Authorization: Bearer {api_key}, Accept: application/json and X-API-Version: {version} headers, returning 200 OK with the resource data in the standard format, and returning 401 (AUTH-003), 403 (AUTHZ-001) or 404 (RES-001) on failure. none
REQ-098-031 - The API MUST expose POST /api/v{version}/resources to create a new resource, taking version as a required path parameter, accepting the Authorization: Bearer {api_key}, Content-Type: application/json, X-API-Version: {version} and optional Idempotency-Key: {uuid} headers with a body matching the resource schema, returning 201 Created with the resource data, and returning 401 (AUTH-003), 403 (AUTHZ-001) or 422 (VAL-*) on failure. none
REQ-098-032 - The API MUST expose GET /api/v{version}/resources to list resources with pagination, taking version as a required path parameter and optional page (default 1) and per_page (default 20, maximum 100) query parameters, accepting the Authorization: Bearer {api_key} and X-API-Version: {version} headers, returning 200 OK with an array of resources and pagination metadata, and returning 401 (AUTH-003) or 403 (AUTHZ-001) on failure. none
REQ-098-033 - The API MUST expose GET /ws/v{version}/agents as a WebSocket connection for real-time agent events over ws:// or wss://, taking version as a required path parameter and token as a required query parameter carrying the API key, upgrading from HTTP with token authentication, and carrying the subscribe, unsubscribe, event, error and ping/pong message types. none
REQ-098-034 - For a client migrating to a new API version, API responses MUST include version information, breaking changes MUST be documented 90 days in advance, old versions MUST remain available during the migration period, and a migration guide MUST be provided for each version change. none
REQ-098-035 - For a developer handling API errors, all errors MUST return a consistent JSON format, error codes MUST map to the AUTH, AUTHZ, VAL, RES, RATE and SYS categories, HTTP status codes MUST align with those error categories, and error messages MUST be actionable for developers. none
REQ-098-036 - For an API user approaching a rate limit, rate limit headers MUST be included in all responses, a Retry-After header MUST be included when the limit is exceeded, rate limit tiers MUST be documented, and burst limits MUST be explained. none
REQ-098-037 - For a WebSocket client maintaining a connection, the message types subscribe, event, error, ping and pong MUST be defined, client-to-server and server-to-client formats MUST be documented, reconnection logic MUST be standardized, and message schemas MUST be validated. none
REQ-098-038 - A successful API response payload MUST be a JSON object carrying the required members data and metadata, where metadata requires request_id (string), timestamp (string, date-time format) and version (string). none
REQ-098-039 - An error response payload MUST be a JSON object carrying the required member error, where error requires code (string) and message (string) and MAY carry a details object. none
REQ-098-040 - The API MUST be built on the declared dependencies at or above the listed versions: fastapi >=0.100 as the API framework providing the OpenAPI 3.x spec, pydantic >=2.0 for request/response validation, httpx >=0.25 as the HTTP client for testing, websockets >=11.0 for WebSocket support, redis >=5.0 as the rate-limiting backend, and prometheus-client >=0.17 for metrics and monitoring. none
REQ-098-041 - API design approval MUST require an OpenAPI 3.x specification for every new endpoint, a major version bump for every breaking change, an API review by the architecture team, and enforcement of the deprecation policy. none
REQ-098-042 - API access control MUST be governed by PAM++ policies, MUST apply role-based permissions to endpoint groups, MUST vary rate limiting by user tier, and MUST write audit logging for all API access. none
REQ-098-043 - API versions MUST follow SemVer (MAJOR.MINOR.PATCH) with 1.0.0 as the current version, MUST maintain backward compatibility within a MINOR version, and MUST confine breaking changes to MAJOR versions. none
REQ-098-044 - The API MUST accept the version indicator either as a URL path segment (/api/v1/resources, /api/v1.1/resources, /api/v2/resources) or as a header (X-API-Version: 1.0 or Accept: application/vnd.orchestrata.v1+json), and MUST default to the latest stable version (1.0.0). none
REQ-098-045 - Deprecation MUST be notified a minimum of 90 days before removal, MUST carry Deprecation and Sunset headers, MUST return 410 Gone with a migration guide after removal, and MUST continue supporting the deprecated version for the notice duration. none
REQ-098-046 - The API version lifecycle MUST consist of the stages Development (version not yet released), Alpha/Beta (limited testing, backward-incompatible changes allowed), GA (stable, backward compatible), Deprecated (will be removed, migration to be planned) and Removed (no longer available). none
REQ-098-047 - The API MUST use the 2xx status codes as listed: 200 OK for a successful GET request, 201 Created when a resource is created successfully, 202 Accepted when a request is accepted for processing, and 204 No Content for a successful DELETE request. none
REQ-098-048 - The API MUST use the 4xx status codes as listed: 400 Bad Request for invalid request syntax, 401 Unauthorized when authentication is required, 403 Forbidden when there is no permission for the resource, 404 Not Found when the resource does not exist, 409 Conflict on a resource state conflict, 422 Unprocessable Entity for valid syntax with a semantic error, 429 Too Many Requests when the rate limit is exceeded, and 451 Unavailable For Legal Reasons when blocked by governance. none
REQ-098-049 - The API MUST use the 5xx status codes as listed: 500 Internal Server Error for an unexpected server error, 502 Bad Gateway for an upstream service error, 503 Service Unavailable when the server is temporarily unavailable, and 504 Gateway Timeout on an upstream timeout. none
REQ-098-050 - Every error response body MUST carry an error object holding code, message, details, request_id and timestamp. none
REQ-098-051 - Error codes MUST be allocated inside their reserved category range: AUTH-001 to AUTH-099 for authentication, AUTHZ-001 to AUTHZ-099 for authorization, VAL-001 to VAL-099 for validation, RES-001 to RES-099 for resource, RATE-001 to RATE-099 for rate limiting, and SYS-001 to SYS-099 for system, carrying the meanings listed in this section. none
REQ-098-052 - Rate limit tiers MUST be enforced as listed: Free at 60 requests/minute with burst 10 and a 10,000 daily limit, Standard at 120 with burst 20 and 50,000, Premium at 600 with burst 100 and 500,000, and Enterprise at custom rate, burst and daily limits. none
REQ-098-053 - Every response MUST include the rate limit headers X-RateLimit-Limit (requests allowed per window), X-RateLimit-Remaining (requests remaining in the current window), X-RateLimit-Reset (Unix timestamp when the window resets), X-RateLimit-Burst (burst requests allowed) and X-RateLimit-Burst-Remaining (burst requests remaining). none
REQ-098-054 - A request that exceeds the rate limit MUST be answered with HTTP/1.1 429 Too Many Requests, an error object carrying code RATE-001 and the details limit, window and retry_after, and the Retry-After, X-RateLimit-Limit, X-RateLimit-Remaining and X-RateLimit-Reset headers. none
REQ-098-055 - Per-endpoint rate limits MUST be enforced as listed: /api/v1/intent at 30/minute with burst 5, /api/v1/agents/* at 60 with burst 10, /api/v1/tasks/* at 120 with burst 20, /api/v1/checkpoint at 20 with burst 3, /api/v1/memory at 40 with burst 5, /api/v1/todoist/* at 30 with burst 5, and /api/v1/webhook/* at 100 with burst 15. none
REQ-098-056 - The API MUST use the content type application/json for JSON payloads, application/problem+json for errors only, and text/plain for text. none
REQ-098-057 - A paginated response MUST carry, alongside the data array, a pagination object holding page, per_page, total, total_pages, has_next and has_prev. none
REQ-098-058 - Every request MUST carry the Authorization: Bearer {api_key}, Content-Type: application/json, Accept: application/json and X-API-Version headers, and MAY carry the optional X-Request-ID and X-Client-Version headers. none
REQ-098-059 - A client-to-server WebSocket message MUST carry type, channel and request_id, and a server-to-client WebSocket message MUST carry type, channel, data, request_id and timestamp. none
REQ-098-060 - POST endpoints that create resources MUST support an optional Idempotency-Key header; when the header is present, the server MUST store the response against that key for 24 hours. none
REQ-098-061 - An idempotent response MUST echo the idempotency_key in its metadata. none
REQ-098-062 - The API MUST use Cache-Control: no-cache, no-store, must-revalidate as its cache-control header, and ETag with If-None-Match as its GET validation headers. none
REQ-098-063 - When a client re-requests a resource with If-None-Match carrying the ETag the server previously issued, the server MUST respond 304 Not Modified. none
REQ-098-064 - Responses MUST carry the standard security headers X-Content-Type-Options: nosniff, X-Frame-Options: DENY, X-XSS-Protection: 1; mode=block, Strict-Transport-Security: max-age=31536000; includeSubDomains and Content-Security-Policy: default-src 'self'. none
REQ-098-065 - Cross-origin requests MUST be answered with the CORS headers Access-Control-Allow-Origin, Access-Control-Allow-Methods: GET, POST, PUT, DELETE, Access-Control-Allow-Headers: Authorization, Content-Type, X-API-Version and Access-Control-Max-Age: 86400. none
REQ-098-066 - Every response MUST carry the X-Response-Time header giving the request duration; responses MAY include the X-Server-Time header giving the server timestamp. none
REQ-098-067 - GET /api/v1/health MUST return status, version, uptime and a checks object reporting the state of the database, redis and neo4j dependencies. none
REQ-098-068 - The API MUST use the HTTP method matching the operation (GET, POST, PUT, DELETE), MUST express resource URLs in the plural form, and MUST express relationships as sub-resources. none
REQ-098-069 - The API MUST apply consistent naming conventions, consistent error handling and consistent response formats. none
REQ-098-070 - The API MUST be secure by default: HTTPS MUST be required, authentication MUST be required, data exposure MUST be minimal, and input validation MUST be mandatory. none
REQ-098-071 - Each API endpoint MUST document its URL and method, required parameters, request body schema, response schema, an example request and response, error codes, rate limits, and the authentication required. none
REQ-098-114 - Contract testing MUST exercise all endpoints against the OpenAPI spec, MUST enforce schema validation, and MUST detect breaking changes. none
REQ-098-115 - Load testing MUST verify the 99.9% uptime target, P95 latency below 500ms, and handling of 10x normal load. none
REQ-098-116 - Chaos testing MUST cover dependency failures, network partitions and cascading failures. none
REQ-098-117 - Component unit tests MUST cover all public interfaces, error conditions and edge cases, data validation and transformation, and performance boundaries. none
REQ-098-118 - Component integration tests MUST cover interactions with dependencies, data flow across boundaries, failure recovery scenarios, and performance under load. none
REQ-098-119 - Load and stress tests MUST run under expected production load, under peak load conditions and under failure conditions, and MUST verify recovery after overload. none
REQ-098-120 - CI/CD integration MUST run the tests on every commit, the performance tests nightly, the security tests weekly, and the compliance tests per release. none
REQ-098-121 - Component logging MUST log all major operations at their log level, MUST include correlation IDs for request tracing, MUST log performance metrics for critical operations, and MUST log errors with full context for debugging. none
REQ-098-122 - Performance metrics MUST include operation duration histograms, request/error rate counters, resource utilization gauges, and the business metrics relevant to the domain. none
REQ-098-123 - Distributed tracing MUST propagate traces across component boundaries, MUST carry span attributes for domain-specific context, and MUST sample traces according to operational needs. none
REQ-098-124 - Critical alerts MUST fire on error rate spikes, performance degradation, resource exhaustion and business metric anomalies. none
REQ-098-125 - The operational dashboard MUST show real-time system health, performance trends, error analysis and resource monitoring. none

Code that traces this spec

No src/ symbol cites a requirement of this spec.

Other tracked files

Full spec text

Verbatim from specs/098-api-standards/spec.md; headings are pushed down two levels.

SPEC-098: API Standards

Metadata


Overview

This specification defines the API standards, versioning strategy, error codes, rate limiting, and response formats for all orchestrata-ultimate APIs.


Terminology

Term Definition
API Application Programming Interface
SemVer Semantic Versioning (MAJOR.MINOR.PATCH)
Rate Limit Maximum number of requests allowed in a time window
Burst Limit Maximum number of concurrent requests allowed
Idempotency Property where making the same request multiple times produces the same result
Backward Compatibility Ability for newer API versions to work with existing client code
Breaking Change Change that requires client code modifications
Deprecation Process of marking an API version for future removal
WebSocket Full-duplex communication protocol over TCP
OpenAPI Specification for building RESTful APIs

Functional Requirements

APPLICABILITY (ruled 2026-08-09). This spec specifies a versioned REST resource API — its Contracts section is GET/POST /api/v{version}/resources. The gateway it governs is JSON-RPC over WebSocket with exactly three HTTP endpoints (gateway/http_surface.py: /health, /ready, /metrics, plus /api/v1/health added for FR-018). There are no REST resource paths, no POST/PUT, and no list endpoints, so thirteen of these requirements have no structural home here.

APPLIED (9): FR-006, FR-007 (error schema + AUTH/AUTHZ/VAL/RES/RATE/SYS taxonomy on JSON-RPC error objects — gateway/error_taxonomy.py), FR-010, FR-019 (token auth — TokenAuthenticator.validate_token verifies the JWT signature), FR-016 (X-Content-Type-Options, X-Frame-Options), FR-017 (X-Request-ID, echoed or minted), FR-018 (/api/v1/health), FR-020 (message types — the mapping is recorded on gateway.models.MessageType), FR-022 (CORS).

NOT APPLICABLE (13): FR-001, FR-002 (version in URL path / response header — no REST paths), FR-003, FR-004 (MAJOR-version compatibility of a REST surface), FR-005 (Deprecation/Sunset headers), FR-008, FR-009 (X-RateLimit-* headers, 429 + Retry-After), FR-011 (POST/PUT JSON-schema validation), FR-012 (data + metadata response envelope — JSON-RPC specifies result/error instead), FR-013 (page/per_page — no list endpoints), FR-014 (Idempotency-Key on POST), FR-015 (ETag/Cache-Control — a MAY in any case), FR-021 (OpenAPI 3.x — nothing REST to document).

Marked N/A rather than silently unmet: the gap is a recorded decision about protocol shape, not an omission. Building the REST surface this spec assumes was the considered alternative and was rejected as a second protocol adapter over ~40 gateway handler modules.

FR-001: Version Declaration

REQ-098-001: All API requests MUST include version information via URL path or header.

FR-002: Version Response

REQ-098-002: All API responses MUST include version metadata in the response header and body.

FR-003: Backward Compatibility

REQ-098-003: API versions within the same MAJOR version MUST maintain backward compatibility.

FR-004: Breaking Change Detection

REQ-098-004: Breaking changes MUST trigger a MAJOR version increment.

FR-005: Deprecation Notice

REQ-098-005: Deprecated API versions MUST include Deprecation and Sunset headers for 90 days minimum.

FR-006: Error Response Structure

REQ-098-006: All error responses MUST follow the defined JSON error schema with code, message, and details.

FR-007: Error Code Categories

REQ-098-007: Error codes MUST be categorized: AUTH, AUTHZ, VAL, RES, RATE, SYS.

FR-008: Rate Limit Headers

REQ-098-008: All responses MUST include X-RateLimit-Limit, X-RateLimit-Remaining, and X-RateLimit-Reset headers.

FR-009: Rate Limit Exceeded Handling

REQ-098-009: When rate limit is exceeded, API MUST return 429 with Retry-After header.

FR-010: Request Authentication

REQ-098-010: All API requests MUST include valid authentication credentials.

FR-011: Request Validation

REQ-098-011: All POST/PUT requests MUST be validated against JSON schema.

FR-012: Response Format

REQ-098-012: All successful responses MUST include data and metadata objects.

FR-013: Pagination Support

REQ-098-013: List endpoints MUST support pagination with page, per_page parameters.

FR-014: Idempotency Support

REQ-098-014: POST endpoints that create resources MUST support Idempotency-Key header.

FR-015: Cache Headers

REQ-098-015: GET responses MAY include ETag and Cache-Control headers.

FR-016: Security Headers

REQ-098-016: All responses MUST include security headers (X-Content-Type-Options, X-Frame-Options).

FR-017: Request Tracing

REQ-098-017: All responses MUST include X-Request-ID header for tracing.

FR-018: Health Check

REQ-098-018: API MUST provide /api/v1/health endpoint for health monitoring.

FR-019: WebSocket Connection

REQ-098-019: WebSocket endpoints MUST support token-based authentication via query parameter.

FR-020: WebSocket Message Types

REQ-098-020: WebSocket messages MUST use defined message types: subscribe, unsubscribe, event, error, ping, pong.

FR-021: Documentation

REQ-098-021: All endpoints MUST be documented with OpenAPI 3.x specification.

FR-022: CORS Support

REQ-098-022: API MUST support CORS for allowed origins.


Error Conditions

ID Condition Handling
ERR-001 Invalid API key provided Return 401 with AUTH-001 code
ERR-002 API key expired Return 401 with AUTH-002 code
ERR-003 Missing authentication header Return 401 with AUTH-003 code
ERR-004 Malformed authentication token Return 401 with AUTH-004 code
ERR-005 Insufficient permissions for operation Return 403 with AUTHZ-001 code
ERR-006 Operation blocked by governance policy Return 403 with AUTHZ-002 code
ERR-007 User role does not meet requirement Return 403 with AUTHZ-003 code
ERR-008 Required field missing in request Return 422 with VAL-001 code
ERR-009 Field type does not match expected type Return 422 with VAL-002 code
ERR-010 Field value outside allowed range Return 422 with VAL-003 code
ERR-011 Field format validation failed Return 422 with VAL-004 code
ERR-012 Requested resource not found Return 404 with RES-001 code
ERR-013 Resource already exists Return 409 with RES-002 code
ERR-014 Resource state conflict Return 409 with RES-003 code
ERR-015 Resource locked for modification Return 423 with RES-004 code
ERR-016 Rate limit exceeded for tier Return 429 with RATE-001 code
ERR-017 Burst limit exceeded Return 429 with RATE-002 code
ERR-018 Daily quota exceeded Return 429 with RATE-003 code
ERR-019 Internal server error occurred Return 500 with SYS-001 code
ERR-020 Service temporarily unavailable Return 503 with SYS-002 code
ERR-021 Upstream dependency timeout Return 504 with SYS-003 code
ERR-022 Circuit breaker preventing requests Return 503 with SYS-004 code

REQ-098-023: Authentication failures MUST return HTTP 401 with the matching AUTH code: AUTH-001 for an invalid API key (ERR-001), AUTH-002 for an expired API key (ERR-002), AUTH-003 for a missing authentication header (ERR-003), and AUTH-004 for a malformed authentication token (ERR-004).

REQ-098-024: Authorization failures MUST return HTTP 403 with the matching AUTHZ code: AUTHZ-001 for insufficient permissions for the operation (ERR-005), AUTHZ-002 for an operation blocked by governance policy (ERR-006), and AUTHZ-003 when the user role does not meet the requirement (ERR-007).

REQ-098-025: Validation failures MUST return HTTP 422 with the matching VAL code: VAL-001 for a required field missing in the request (ERR-008), VAL-002 when a field type does not match the expected type (ERR-009), VAL-003 for a field value outside the allowed range (ERR-010), and VAL-004 for a failed field format validation (ERR-011).

REQ-098-026: Resource failures MUST return the matching RES code and status: 404 with RES-001 when the requested resource is not found (ERR-012), 409 with RES-002 when the resource already exists (ERR-013), 409 with RES-003 on a resource state conflict (ERR-014), and 423 with RES-004 when the resource is locked for modification (ERR-015).

REQ-098-027: Rate-limiting failures MUST return HTTP 429 with the matching RATE code: RATE-001 when the tier rate limit is exceeded (ERR-016), RATE-002 when the burst limit is exceeded (ERR-017), and RATE-003 when the daily quota is exceeded (ERR-018).

REQ-098-028: System failures MUST return the matching SYS code and status: 500 with SYS-001 for an internal server error (ERR-019), 503 with SYS-002 when the service is temporarily unavailable (ERR-020), 504 with SYS-003 on an upstream dependency timeout (ERR-021), and 503 with SYS-004 when the circuit breaker is preventing requests (ERR-022).


Non-Functional Requirements

Performance

REQ-098-101: P95 latency MUST be below 500ms for standard requests.

REQ-098-102: P99 latency MUST be below 1000ms for standard requests.

REQ-098-103: A response time header MUST be included in all responses.

Reliability

REQ-098-104: The API MUST meet a 99.9% uptime target.

REQ-098-105: Rate limit enforcement MUST be provided with configurable tiers.

REQ-098-106: A circuit breaker MUST guard dependency failures.

Scalability

REQ-098-107: The API MUST support 10x normal load.

REQ-098-108: Rate limiting MUST be enforced per endpoint.

REQ-098-109: Burst allowance MUST be handled.

Security

REQ-098-110: HTTPS MUST be required for all endpoints.

REQ-098-111: API key authentication MUST be mandatory.

REQ-098-112: Security headers MUST be present on all responses.

REQ-098-113: Input validation MUST be applied to all requests.


Integration Points

Integration Protocol Authentication
Neo4j Database Bolt Connection string auth
Redis Cache Redis Protocol Password auth
Prometheus Metrics HTTP None (internal)
WebSocket Clients WS/WSS Token in query param
External Webhooks HTTPS HMAC signature

REQ-098-029: Each integration MUST use the protocol and authentication listed for it: the Neo4j database over Bolt with connection-string auth, the Redis cache over the Redis protocol with password auth, Prometheus metrics over HTTP with no authentication (internal), WebSocket clients over WS/WSS with a token in the query parameter, and external webhooks over HTTPS with an HMAC signature.


API Contracts

REST Endpoints
GET /api/v{version}/resources/{id}

REQ-098-030: The API MUST expose GET /api/v{version}/resources/{id} to retrieve a specific resource, taking version and id as required path parameters, accepting the Authorization: Bearer {api_key}, Accept: application/json and X-API-Version: {version} headers, returning 200 OK with the resource data in the standard format, and returning 401 (AUTH-003), 403 (AUTHZ-001) or 404 (RES-001) on failure.

POST /api/v{version}/resources

REQ-098-031: The API MUST expose POST /api/v{version}/resources to create a new resource, taking version as a required path parameter, accepting the Authorization: Bearer {api_key}, Content-Type: application/json, X-API-Version: {version} and optional Idempotency-Key: {uuid} headers with a body matching the resource schema, returning 201 Created with the resource data, and returning 401 (AUTH-003), 403 (AUTHZ-001) or 422 (VAL-*) on failure.

GET /api/v{version}/resources

REQ-098-032: The API MUST expose GET /api/v{version}/resources to list resources with pagination, taking version as a required path parameter and optional page (default 1) and per_page (default 20, maximum 100) query parameters, accepting the Authorization: Bearer {api_key} and X-API-Version: {version} headers, returning 200 OK with an array of resources and pagination metadata, and returning 401 (AUTH-003) or 403 (AUTHZ-001) on failure.

WebSocket Endpoint
GET /ws/v{version}/agents

REQ-098-033: The API MUST expose GET /ws/v{version}/agents as a WebSocket connection for real-time agent events over ws:// or wss://, taking version as a required path parameter and token as a required query parameter carrying the API key, upgrading from HTTP with token authentication, and carrying the subscribe, unsubscribe, event, error and ping/pong message types.


Success Criteria

US-001: Client Migrating to New API Version

As an API client, I want clear versioning so I can migrate to new API versions without breaking my application.

Acceptance Criteria:

REQ-098-034: For a client migrating to a new API version, API responses MUST include version information, breaking changes MUST be documented 90 days in advance, old versions MUST remain available during the migration period, and a migration guide MUST be provided for each version change.

US-002: Developer Handling API Errors

As a developer, I want standardized error codes so I can handle failures consistently across all endpoints.

Acceptance Criteria:

REQ-098-035: For a developer handling API errors, all errors MUST return a consistent JSON format, error codes MUST map to the AUTH, AUTHZ, VAL, RES, RATE and SYS categories, HTTP status codes MUST align with those error categories, and error messages MUST be actionable for developers.

US-003: User Approaching Rate Limit

As an API user, I want clear rate limit information so I can avoid service disruption.

Acceptance Criteria:

REQ-098-036: For an API user approaching a rate limit, rate limit headers MUST be included in all responses, a Retry-After header MUST be included when the limit is exceeded, rate limit tiers MUST be documented, and burst limits MUST be explained.

US-004: WebSocket Client Maintaining Connection

As a WebSocket client, I want clear message formats so I can maintain real-time connections reliably.

Acceptance Criteria:

REQ-098-037: For a WebSocket client maintaining a connection, the message types subscribe, event, error, ping and pong MUST be defined, client-to-server and server-to-client formats MUST be documented, reconnection logic MUST be standardized, and message schemas MUST be validated.


User Scenarios

Scenario 1: Third-Party Integration Using API Keys

A partner company integrates their external system with orchestrata-ultimate using API keys. They need to authenticate all requests, handle rate limits gracefully, and receive clear error messages when something goes wrong.

Flow:

  1. Partner obtains API key from admin dashboard
  2. Partner makes API requests with Authorization: Bearer {api_key} header
  3. API responds with version info in headers and body
  4. If request exceeds rate limit, API returns 429 with Retry-After header
  5. Partner implements exponential backoff based on Retry-After value

Key Requirements: FR-001, FR-002, FR-008, FR-009, FR-010

Scenario 2: Legacy Client Upgrading API Versions

An existing client running older integration needs to upgrade from v1 to v2 without service interruption. They need to understand what changed and migrate gradually.

Flow:

  1. Client receives deprecation notice with 90-day warning
  2. Client reviews migration guide and OpenAPI documentation
  3. Client tests v2 endpoints in staging environment
  4. Client gradually switches production traffic to v2
  5. Old v1 returns 410 Gone after sunset date

Key Requirements: FR-003, FR-004, FR-005, FR-021

Scenario 3: Developer Debugging API Failures

A developer building an application against the API encounters errors and needs to quickly identify the issue, understand what went wrong, and take corrective action.

Flow:

  1. Developer makes API request that fails
  2. API returns error with structured response (code, message, details)
  3. Developer identifies error category from code prefix (AUTH, VAL, RES, etc.)
  4. Developer reviews documentation for error code remediation
  5. Developer fixes request and retries

Key Requirements: FR-006, FR-007, FR-011, FR-012

Data Models

API Response
{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "type": "object",
  "required": ["data", "metadata"],
  "properties": {
    "data": {
      "type": "object"
    },
    "metadata": {
      "type": "object",
      "required": ["request_id", "timestamp", "version"],
      "properties": {
        "request_id": {
          "type": "string"
        },
        "timestamp": {
          "type": "string",
          "format": "date-time"
        },
        "version": {
          "type": "string"
        }
      }
    }
  }
}

REQ-098-038: A successful API response payload MUST be a JSON object carrying the required members data and metadata, where metadata requires request_id (string), timestamp (string, date-time format) and version (string).

Error Response
{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "type": "object",
  "required": ["error"],
  "properties": {
    "error": {
      "type": "object",
      "required": ["code", "message"],
      "properties": {
        "code": {
          "type": "string"
        },
        "message": {
          "type": "string"
        },
        "details": {
          "type": "object"
        }
      }
    }
  }
}

REQ-098-039: An error response payload MUST be a JSON object carrying the required member error, where error requires code (string) and message (string) and MAY carry a details object.


Examples

Versioned API Request Examples
Request with URL Path Versioning
curl -X GET \
  https://api.orchestrata.com/api/v1/resources/T:001 \
  -H "Authorization: Bearer sk_live_abc123def456" \
  -H "Accept: application/json" \
  -H "X-Request-ID: req_789xyz"
Request with Header Versioning
curl -X GET \
  https://api.orchestrata.com/api/resources \
  -H "Authorization: Bearer sk_live_abc123def456" \
  -H "X-API-Version: 1.0" \
  -H "Accept: application/vnd.orchestrata.v1+json"
Authentication Examples
Valid API Key
curl -X POST \
  https://api.orchestrata.com/api/v1/tasks \
  -H "Authorization: Bearer sk_live_abc123def456" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "New Task",
    "priority": 3
  }'
Invalid API Key (401 Unauthorized)
curl -X GET \
  https://api.orchestrata.com/api/v1/resources \
  -H "Authorization: Bearer sk_live_invalid123"

# Response:
HTTP/1.1 401 Unauthorized
Content-Type: application/problem+json

{
  "error": {
    "code": "AUTH-001",
    "message": "Invalid API key provided",
    "request_id": "req_123456789",
    "timestamp": "2026-04-09T10:15:30Z"
  }
}
Success Response Examples
GET Resource Response
{
  "data": {
    "id": "T:001",
    "title": "Review API Documentation",
    "status": "pending",
    "priority": 3,
    "assignee": "U:Cd",
    "created_at": "2026-04-08T14:30:00Z",
    "updated_at": "2026-04-09T09:00:00Z"
  },
  "metadata": {
    "request_id": "req_123456789",
    "timestamp": "2026-04-09T10:15:30Z",
    "version": "1.0.0",
    "response_time_ms": 45
  }
}
POST Create Resource Response
{
  "data": {
    "id": "T:002",
    "title": "Update Documentation",
    "status": "created",
    "created_at": "2026-04-09T10:15:30Z"
  },
  "metadata": {
    "request_id": "req_987654321",
    "timestamp": "2026-04-09T10:15:30Z",
    "version": "1.0.0",
    "idempotency_key": "uuid-1234-5678-9012"
  }
}
List Resources with Pagination
{
  "data": [
    {
      "id": "T:001",
      "title": "Task 1",
      "status": "pending"
    },
    {
      "id": "T:002",
      "title": "Task 2",
      "status": "completed"
    }
  ],
  "pagination": {
    "page": 1,
    "per_page": 20,
    "total": 150,
    "total_pages": 8,
    "has_next": true,
    "has_prev": false
  },
  "metadata": {
    "request_id": "req_456789123",
    "timestamp": "2026-04-09T10:15:30Z",
    "version": "1.0.0"
  }
}
Error Response Examples
Validation Error (422)
{
  "error": {
    "code": "VAL-002",
    "message": "Field type does not match expected type",
    "details": {
      "priority": "Expected integer between 1 and 5, got string",
      "fields": ["priority"]
    },
    "request_id": "req_234567890",
    "timestamp": "2026-04-09T10:15:30Z"
  }
}
Resource Not Found (404)
{
  "error": {
    "code": "RES-001",
    "message": "Requested resource not found",
    "details": {
      "resource_type": "task",
      "resource_id": "T:999"
    },
    "request_id": "req_345678901",
    "timestamp": "2026-04-09T10:15:30Z"
  }
}
Authorization Error (403)
{
  "error": {
    "code": "AUTHZ-001",
    "message": "Insufficient permissions for operation",
    "details": {
      "required_permission": "tasks.write",
      "user_permissions": ["tasks.read"]
    },
    "request_id": "req_456789012",
    "timestamp": "2026-04-09T10:15:30Z"
  }
}
Rate Limiting Examples
Normal Response with Rate Limit Headers
HTTP/1.1 200 OK
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 45
X-RateLimit-Reset: 1712575200
X-RateLimit-Burst: 10
X-RateLimit-Burst-Remaining: 8
Retry-After: 45
Rate Limit Exceeded (429)
{
  "error": {
    "code": "RATE-001",
    "message": "Rate limit exceeded. Try again in 45 seconds.",
    "details": {
      "limit": 60,
      "window": 60,
      "retry_after": 45
    },
    "request_id": "req_567890123",
    "timestamp": "2026-04-09T10:15:30Z"
  }
}

With headers:

HTTP/1.1 429 Too Many Requests
Retry-After: 45
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1712575200
X-RateLimit-Burst: 10
X-RateLimit-Burst-Remaining: 0
WebSocket Examples
Client Subscription Message
{
  "type": "subscribe",
  "channel": "agent_status",
  "request_id": "req_sub_001"
}
Server Event Message
{
  "type": "event",
  "channel": "agent_status",
  "data": {
    "agent_id": "U:Cd",
    "status": "running",
    "message": "Agent started successfully"
  },
  "request_id": "req_sub_001",
  "timestamp": "2026-04-09T10:15:30Z"
}
Error Message
{
  "type": "error",
  "code": "AUTHZ-001",
  "message": "Insufficient permissions for channel",
  "details": {
    "channel": "agent_admin",
    "required_permission": "agents.admin"
  },
  "request_id": "req_err_001",
  "timestamp": "2026-04-09T10:15:30Z"
}
WebSocket Connection
const ws = new WebSocket('wss://api.orchestrata.com/ws/v1/agents?token=«redacted»

ws.onopen = () => {
  console.log('Connected to WebSocket');
  ws.send(JSON.stringify({
    type: 'subscribe',
    channel: 'task_updates',
    request_id: 'req_001'
  }));
};

ws.onmessage = (event) => {
  const message = JSON.parse(event.data);
  console.log('Received:', message);
};

ws.onerror = (error) => {
  console.error('WebSocket error:', error);
};
Idempotency Examples
First Request (Creates Resource)
curl -X POST \
  https://api.orchestrata.com/api/v1/resources \
  -H "Authorization: Bearer sk_live_abc123" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: uuid-1234-5678-9012" \
  -d '{
    "title": "Test Resource"
  }'

# Response: 201 Created
Retry with Same Idempotency Key (Returns First Response)
curl -X POST \
  https://api.orchestrata.com/api/v1/resources \
  -H "Authorization: Bearer sk_live_abc123" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: uuid-1234-5678-9012" \
  -d '{
    "title": "Test Resource"
  }'

# Response: 201 Created (same as first request)
Complete Request/Response Sequence
Full API Flow Example
# 1. Create a task with authentication
curl -X POST \
  https://api.orchestrata.com/api/v1/tasks \
  -H "Authorization: Bearer sk_live_abc123def456" \
  -H "Content-Type: application/json" \
  -H "X-API-Version: 1.0" \
  -H "Idempotency-Key: uuid-5678-9012-3456" \
  -d '{
    "title": "Complete API documentation",
    "priority": 2,
    "assignee": "U:Cd"
  }'

# Response:
# HTTP/1.1 201 Created
# X-RateLimit-Limit: 120
# X-RateLimit-Remaining: 118
# X-RateLimit-Reset: 1712578800
# X-Request-ID: req_123456789
# X-Response-Time: 52ms
# X-Server-Time: 2026-04-09T10:15:30Z
# X-Content-Type-Options: nosniff
# X-Frame-Options: DENY

{
  "data": {
    "id": "T:003",
    "title": "Complete API documentation",
    "status": "pending",
    "priority": 2,
    "assignee": "U:Cd",
    "created_at": "2026-04-09T10:15:30Z"
  },
  "metadata": {
    "request_id": "req_123456789",
    "timestamp": "2026-04-09T10:15:30Z",
    "version": "1.0.0",
    "idempotency_key": "uuid-5678-9012-3456",
    "response_time_ms": 52
  }
}

# 2. Retrieve the created task
curl -X GET \
  https://api.orchestrata.com/api/v1/tasks/T:003 \
  -H "Authorization: Bearer sk_live_abc123def456" \
  -H "Accept: application/json" \
  -H "X-API-Version: 1.0"

# Response:
# HTTP/1.1 200 OK
# ETag: "task_abc123"
# Cache-Control: no-cache
# X-RateLimit-Limit: 120
# X-RateLimit-Remaining: 117
# X-RateLimit-Reset: 1712578800
# X-Request-ID: req_987654321
# X-Response-Time: 38ms
# X-Server-Time: 2026-04-09T10:15:30Z
# X-Content-Type-Options: nosniff
# X-Frame-Options: DENY

{
  "data": {
    "id": "T:003",
    "title": "Complete API documentation",
    "status": "pending",
    "priority": 2,
    "assignee": "U:Cd",
    "created_at": "2026-04-09T10:15:30Z",
    "updated_at": "2026-04-09T10:15:30Z"
  },
  "metadata": {
    "request_id": "req_987654321",
    "timestamp": "2026-04-09T10:15:30Z",
    "version": "1.0.0",
    "response_time_ms": 38
  }
}

# 3. List all tasks with pagination
curl -X GET \
  https://api.orchestrata.com/api/v1/tasks?page=1&per_page=10 \
  -H "Authorization: Bearer sk_live_abc123def456" \
  -H "Accept: application/json" \
  -H "X-API-Version: 1.0"

# Response includes pagination metadata in data array
Health Check Example
curl -X GET \
  https://api.orchestrata.com/api/v1/health \
  -H "Accept: application/json"

# Response:
# HTTP/1.1 200 OK
# Content-Type: application/json

{
  "status": "healthy",
  "version": "1.0.0",
  "uptime": 86400,
  "timestamp": "2026-04-09T10:15:30Z",
  "checks": {
    "database": "ok",
    "redis": "ok",
    "neo4j": "ok",
    "cache": "ok"
  }
}

Visual Architecture

Class Diagram

Diagram source shown as text: Mermaid could not parse it (Error: Parse error on line 239:).

classDiagram
    class MultiAgentEditResult {
        +file_path: str
        +old_string: str
        +new_string: str
        +agent_results: dict[Any]
        +aggregated_result: dict[Any]
        +timestamp: datetime = Field()
        +success: bool = True
    }
    class GovernanceError {
    }
    class OrchestrataKernel {
        +__init__(self): None
        +_initialize_agents(self): None
        +get_agents_by_type(self, agent_type): list[Any]
        +get_agent_by_id(self, agent_id): Any
        +async broadcast_to_type(self, agent_type, message): list[Any]
        +async broadcast_to_all(self, message): list[Any]
        +async send_to_agent(self, agent_id, message, sender): Any
    }
    class UltimateOrchestrator {
        +__init__(self): None
        +async execute_multi_agent_edit(self, file_path, old_string, new_string): MultiAgentEditResult
        +_aggregate_agent_results(self, results): dict[Any]
        +async create_project(self, name, path, template): dict[Any]
        +async shutdown(self): None
    }
    class ThreadPoolTaskStatus {
        +PENDING = 'pending'
        +RUNNING = 'running'
        +COMPLETED = 'completed'
        +FAILED = 'failed'
        +CANCELLED = 'cancelled'
        +TIMEOUT = 'timeout'
    }
    class ThreadPoolTask {
        +task_id: str = field()
        +function: Any = None
        +args: tuple = field()
        +kwargs: dict[Any] = field()
        +status: ThreadPoolTaskStatus = .PENDING
        +created_at: datetime = field()
        +started_at: Any = None
        +completed_at: Any = None
        +result: Any = None
        +error: Any = None
        +traceback: Any = None
        +future: Any = None
        +metadata: dict[Any] = field()
    }
    class ThreadPoolManager {
        +__init__(self, max_workers, thread_name_prefix, initializer, initargs)
        +start(self): None
        +stop(self, wait, cancel_futures): None
        +submit(self, fn, *args, **kwargs): str
        +submit_many(self, functions, args_list, kwargs_list): list[str]
        +async submit_async(self, fn, *args, **kwargs): T
        +async submit_many_async(self, functions, args_list, kwargs_list): list[T]
        +async wait_for_task(self, task_id, timeout): Any
        +get_task_status(self, task_id): ThreadPoolTaskStatus
        +get_task_result(self, task_id, wait): Any
        +cancel_task(self, task_id): bool
        +get_stats(self): dict[Any]
        +_wrap_function(self, task_id, fn, *args, **kwargs): T
        +_update_task_from_future(self, task_id, future): None
        +task_context(self, task_id): Any
        +async async_task_context(self, task_id): Any
    }
    class ParallelTestExecutor {
        +__init__(self, thread_pool, max_workers)
        +run_tests_parallel(self, test_paths, pytest_args, timeout_per_test): dict[Any]
        +_run_single_test(self, test_path, pytest_args, timeout): dict[Any]
        +async run_tests_parallel_async(self, test_paths, pytest_args, timeout_per_test): dict[Any]
    }
    class LogLevel {
        +TRACE = 'TRACE'
        +DEBUG = 'DEBUG'
        +INFO = 'INFO'
        +WARNING = 'WARNING'
        +ERROR = 'ERROR'
        +CRITICAL = 'CRITICAL'
    }
    class LogContext {
        +__init__(self, logger, **context)
        +__enter__(self)
        +__exit__(self, exc_type, exc_val, exc_tb)
    }
    class LoggingContext {
        +request_id: Any = None
        +session_id: Any = None
        +trace_id: Any = None
        +span_id: Any = None
        +user_id: Any = None
        +user_email: Any = None
        +user_role: Any = None
        +component: Any = None
        +operation: Any = None
        +extra: dict[Any] = field()
        +created_at: datetime = field()
        ---
        +to_dict(self): dict[Any]
    }
    class ContextManager {
        +get_current_context(): LoggingContext
        +set_current_context(context): None
        +clear_context(): None
        +update_context(**kwargs): LoggingContext
        +create_child_context(**updates): LoggingContext
    }
    class AsyncContext {
        +__init__(self, **context_updates)
        +async __aenter__(self): LoggingContext
        +async __aexit__(self, exc_type, exc_val, exc_tb)
    }
    class Context {
        +__init__(self, **context_updates)
        +__enter__(self): LoggingContext
        +__exit__(self, exc_type, exc_val, exc_tb)
    }
    class AuditAction {
        +LOGIN = 'login'
        +LOGOUT = 'logout'
        +AUTH_FAILURE = 'auth_failure'
        +PERMISSION_CHECK = 'permission_check'
        +PERMISSION_DENIED = 'permission_denied'
        +READ = 'read'
        +CREATE = 'create'
        +UPDATE = 'update'
        +DELETE = 'delete'
        +EXPORT = 'export'
        +IMPORT = 'import'
        +CONFIG_CHANGE = 'config_change'
        +SERVICE_START = 'service_start'
        +SERVICE_STOP = 'service_stop'
        +BACKUP = 'backup'
        +RESTORE = 'restore'
        +USER_CREATE = 'user_create'
        +USER_UPDATE = 'user_update'
        +USER_DELETE = 'user_delete'
        +ROLE_ASSIGN = 'role_assign'
        +ROLE_REVOKE = 'role_revoke'
        +EXTERNAL_CALL = 'external_call'
        +WEBHOOK_RECEIVED = 'webhook_received'
        +API_CALL = 'api_call'
        +WORKFLOW_START = 'workflow_start'
        +WORKFLOW_COMPLETE = 'workflow_complete'
        +ESCALATION = 'escalation'
        +APPROVAL = 'approval'
        +REJECTION = 'rejection'
    }
    class AuditStatus {
        +SUCCESS = 'success'
        +FAILURE = 'failure'
        +PARTIAL = 'partial'
        +PENDING = 'pending'
    }
    class AuditEvent {
        +action: AuditAction
        +timestamp: datetime = field()
        +status: AuditStatus = .SUCCESS
        +actor_id: Any = None
        +actor_type: str = 'user'
        +actor_ip: Any = None
        +actor_user_agent: Any = None
        +resource_type: Any = None
        +resource_id: Any = None
        +resource_path: Any = None
        +operation_id: Any = None
        +operation_name: Any = None
        +operation_duration_ms: Any = None
        +before_state: Any = None
        +after_state: Any = None
        +changes: Any = None
        +request_id: Any = None
        +session_id: Any = None
        +trace_id: Any = None
        +span_id: Any = None
        +component: Any = None
        +severity: str = 'info'
        +details: Any = None
        +error_message: Any = None
        +error_stack: Any = None
        +event_hash: Any = None
        +previous_hash: Any = None
        ---
        +__post_init__(self)
        +calculate_hash(self): str
        +_json_serializer(self, obj)
        +to_dict(self): dict[Any]
        +verify_hash(self): bool
    }
    class AuditLogger {
        +__init__(self, component)
        +log_event(self, event): str
        +log_action(self, action, status, resource_type, resource_id, before_state, after_state, actor_id, actor_type, details, error_message, operation_duration_ms, severity): str
    }
    class AuditOperation {
        +action: Any
        +resource_type: Any = None
        +resource_id: Any = None
        +before_state: Any = None
        +actor_id: Any = None
        +actor_type: str = 'user'
        +component: Any = None
        +details: Any = None
        ---
        +__enter__(self)
        +__exit__(self, exc_type, exc_val, exc_tb)
    }
    class DomainEntity {
        +entity_id: str = Field()
        +is_active: bool = Field()
        ---
        +__init__(self, **data)
        +mark_inactive(self)
        +to_domain_dict(self): dict[Any]
        +get_business_key(self): str
        +__eq__(self, other): bool
        +__hash__(self): int
        +__repr__(self): str
    }
    class Node {
        +node_id: str = Field()
        +node_type: str = Field()
        +name: str = Field()
        +properties: dict[Any] = Field()
        +created_at: datetime = Field()
        +updated_at: datetime = Field()
        +version: int = Field()
        ---
        +to_graph_dict(self): dict[Any]
        +from_graph_dict(cls, data): Node
        +update_properties(self, **kwargs)
        +__str__(self): str
    }
    class Config {
        +arbitrary_types_allowed = True
        +json_encoders = {}
    }
    class TracingLevel {
        +OFF = 0
        +BASIC = 1
        +DETAILED = 2
        +DEBUG = 3
        ---
        +label(self): str
    }
    class TracingConfig {
        +model_config = ConfigDict()
        +enabled: bool = Field()
        +service_name: str = Field()
        +service_version: str = Field()
        +endpoint: Any = Field()
        +sample_rate: float = Field()
        +console_export: bool = Field()
        +tracing_level: TracingLevel = Field()
        ---
        +clamp_sample_rate(cls, v): float
    }
    class MetricsConfig {
        +__init__(self, enabled, port, host, include_system_metrics, system_metrics_interval)
    }
    class RetryStrategy {
        +__init__(self, max_retries, initial_delay, max_delay, backoff_factor, jitter)
        +calculate_delay(self, attempt): float
    }
    class CircuitState {
        +CLOSED = 'closed'
        +OPEN = 'open'
        +HALF_OPEN = 'half_open'
    }
    class CircuitBreaker {
        +__init__(self, failure_threshold, reset_timeout, half_open_max_requests, name)
        +is_closed(self): bool
        +is_open(self): bool
        +is_half_open(self): bool
        +record_success(self): None
        +record_failure(self): None
        +should_allow_request(self): bool
        +async execute(self, operation): T
    }
    class Bulkhead {
        +__init__(self, max_concurrent, max_queue_size, name)
        +async execute(self, operation): T
    }
    Node <|-- DomainEntity

Dependencies

Dependency Version Purpose
fastapi >=0.100 API framework (OpenAPI 3.x spec)
pydantic >=2.0 Request/response validation
httpx >=0.25 HTTP client for testing
websockets >=11.0 WebSocket support
redis >=5.0 Rate limiting backend
prometheus-client >=0.17 Metrics and monitoring

REQ-098-040: The API MUST be built on the declared dependencies at or above the listed versions: fastapi >=0.100 as the API framework providing the OpenAPI 3.x spec, pydantic >=2.0 for request/response validation, httpx >=0.25 as the HTTP client for testing, websockets >=11.0 for WebSocket support, redis >=5.0 as the rate-limiting backend, and prometheus-client >=0.17 for metrics and monitoring.


Governance

API Design Approval

REQ-098-041: API design approval MUST require an OpenAPI 3.x specification for every new endpoint, a major version bump for every breaking change, an API review by the architecture team, and enforcement of the deprecation policy.

Access Control

REQ-098-042: API access control MUST be governed by PAM++ policies, MUST apply role-based permissions to endpoint groups, MUST vary rate limiting by user tier, and MUST write audit logging for all API access.



Technical Design

API Versioning
1.1 Version Strategy

REQ-098-043: API versions MUST follow SemVer (MAJOR.MINOR.PATCH) with 1.0.0 as the current version, MUST maintain backward compatibility within a MINOR version, and MUST confine breaking changes to MAJOR versions.

1.2 Version Indicators

URL Path Versioning:

GET /api/v1/resources
GET /api/v1.1/resources
GET /api/v2/resources

Header Versioning:

X-API-Version: 1.0
Accept: application/vnd.orchestrata.v1+json

Default Version: Latest stable (1.0.0)

REQ-098-044: The API MUST accept the version indicator either as a URL path segment (/api/v1/resources, /api/v1.1/resources, /api/v2/resources) or as a header (X-API-Version: 1.0 or Accept: application/vnd.orchestrata.v1+json), and MUST default to the latest stable version (1.0.0).

1.3 Deprecation Policy

REQ-098-045: Deprecation MUST be notified a minimum of 90 days before removal, MUST carry Deprecation and Sunset headers, MUST return 410 Gone with a migration guide after removal, and MUST continue supporting the deprecated version for the notice duration.

Example deprecation:

Deprecation: version="1.0.0"
Sunset: Wed, 30 Nov 2026 00:00:00 GMT
Link: <https://docs/api/v2>; rel="successor-version"
1.4 Version Lifecycle
  1. Development: Version not yet released
  2. Alpha/Beta: Limited testing, backward incompatible allowed
  3. GA (General Availability): Stable, backward compatible
  4. Deprecated: Will be removed, plan migration
  5. Removed: No longer available

REQ-098-046: The API version lifecycle MUST consist of the stages Development (version not yet released), Alpha/Beta (limited testing, backward-incompatible changes allowed), GA (stable, backward compatible), Deprecated (will be removed, migration to be planned) and Removed (no longer available).


Error Codes
2.1 HTTP Status Codes
2xx Success
Code Name Usage
200 OK GET request successful
201 Created Resource created successfully
202 Accepted Request accepted for processing
204 No Content DELETE request successful

REQ-098-047: The API MUST use the 2xx status codes as listed: 200 OK for a successful GET request, 201 Created when a resource is created successfully, 202 Accepted when a request is accepted for processing, and 204 No Content for a successful DELETE request.

4xx Client Errors
Code Name Usage
400 Bad Request Invalid request syntax
401 Unauthorized Authentication required
403 Forbidden No permission for resource
404 Not Found Resource doesn't exist
409 Conflict Resource state conflict
422 Unprocessable Entity Valid syntax but semantic error
429 Too Many Requests Rate limit exceeded
451 Unavailable For Legal Reasons Blocked by governance

REQ-098-048: The API MUST use the 4xx status codes as listed: 400 Bad Request for invalid request syntax, 401 Unauthorized when authentication is required, 403 Forbidden when there is no permission for the resource, 404 Not Found when the resource does not exist, 409 Conflict on a resource state conflict, 422 Unprocessable Entity for valid syntax with a semantic error, 429 Too Many Requests when the rate limit is exceeded, and 451 Unavailable For Legal Reasons when blocked by governance.

5xx Server Errors
Code Name Usage
500 Internal Server Error Unexpected server error
502 Bad Gateway Upstream service error
503 Service Unavailable Server temporarily unavailable
504 Gateway Timeout Upstream timeout

REQ-098-049: The API MUST use the 5xx status codes as listed: 500 Internal Server Error for an unexpected server error, 502 Bad Gateway for an upstream service error, 503 Service Unavailable when the server is temporarily unavailable, and 504 Gateway Timeout on an upstream timeout.

2.2 Error Response Format
{
  "error": {
    "code": "ERROR_CODE",
    "message": "Human-readable error message",
    "details": {
      "field": "Validation failed",
      "reason": "Invalid value"
    },
    "request_id": "req_123456789",
    "timestamp": "2026-04-08T14:30:00Z"
  }
}

REQ-098-050: Every error response body MUST carry an error object holding code, message, details, request_id and timestamp.

2.3 Standard Error Codes

REQ-098-051: Error codes MUST be allocated inside their reserved category range: AUTH-001 to AUTH-099 for authentication, AUTHZ-001 to AUTHZ-099 for authorization, VAL-001 to VAL-099 for validation, RES-001 to RES-099 for resource, RATE-001 to RATE-099 for rate limiting, and SYS-001 to SYS-099 for system, carrying the meanings listed in this section.

AUTH-001 to AUTH-099 (Authentication)
AUTHZ-001 to AUTHZ-099 (Authorization)
VAL-001 to VAL-099 (Validation)
RES-001 to RES-099 (Resource)
RATE-001 to RATE-099 (Rate Limiting)
SYS-001 to SYS-099 (System)

Rate Limiting
3.1 Rate Limit Tiers
Tier Requests/Minute Burst Daily Limit
Free 60 10 10,000
Standard 120 20 50,000
Premium 600 100 500,000
Enterprise Custom Custom Custom

REQ-098-052: Rate limit tiers MUST be enforced as listed: Free at 60 requests/minute with burst 10 and a 10,000 daily limit, Standard at 120 with burst 20 and 50,000, Premium at 600 with burst 100 and 500,000, and Enterprise at custom rate, burst and daily limits.

3.2 Rate Limit Headers

Every response includes rate limit information:

X-RateLimit-Limit: 60
X-RateLimit-Remaining: 45
X-RateLimit-Reset: 1712575200
X-RateLimit-Burst: 10
X-RateLimit-Burst-Remaining: 8

Header Meanings:

REQ-098-053: Every response MUST include the rate limit headers X-RateLimit-Limit (requests allowed per window), X-RateLimit-Remaining (requests remaining in the current window), X-RateLimit-Reset (Unix timestamp when the window resets), X-RateLimit-Burst (burst requests allowed) and X-RateLimit-Burst-Remaining (burst requests remaining).

3.3 Rate Limit Exceeded Response
{
  "error": {
    "code": "RATE-001",
    "message": "Rate limit exceeded. Try again in 45 seconds.",
    "details": {
      "limit": 60,
      "window": 60,
      "retry_after": 45
    }
  }
}

Headers:

HTTP/1.1 429 Too Many Requests
Retry-After: 45
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1712575200

REQ-098-054: A request that exceeds the rate limit MUST be answered with HTTP/1.1 429 Too Many Requests, an error object carrying code RATE-001 and the details limit, window and retry_after, and the Retry-After, X-RateLimit-Limit, X-RateLimit-Remaining and X-RateLimit-Reset headers.

3.4 Per-Endpoint Limits
Endpoint Limit/Minute Burst
/api/v1/intent 30 5
/api/v1/agents/* 60 10
/api/v1/tasks/* 120 20
/api/v1/checkpoint 20 3
/api/v1/memory 40 5
/api/v1/todoist/* 30 5
/api/v1/webhook/* 100 15

REQ-098-055: Per-endpoint rate limits MUST be enforced as listed: /api/v1/intent at 30/minute with burst 5, /api/v1/agents/* at 60 with burst 10, /api/v1/tasks/* at 120 with burst 20, /api/v1/checkpoint at 20 with burst 3, /api/v1/memory at 40 with burst 5, /api/v1/todoist/* at 30 with burst 5, and /api/v1/webhook/* at 100 with burst 15.


Response Format Standards
4.1 Content Types

REQ-098-056: The API MUST use the content type application/json for JSON payloads, application/problem+json for errors only, and text/plain for text.

4.2 Success Response Format
{
  "data": {
    "id": "T:001",
    "title": "Task title",
    "status": "pending"
  },
  "metadata": {
    "request_id": "req_123456789",
    "timestamp": "2026-04-08T14:30:00Z",
    "version": "1.0.0"
  }
}
4.3 Pagination Format
{
  "data": [
    { "id": "1", "title": "Task 1" },
    { "id": "2", "title": "Task 2" }
  ],
  "pagination": {
    "page": 1,
    "per_page": 20,
    "total": 100,
    "total_pages": 5,
    "has_next": true,
    "has_prev": false
  }
}

REQ-098-057: A paginated response MUST carry, alongside the data array, a pagination object holding page, per_page, total, total_pages, has_next and has_prev.

Request Format Standards
5.1 Request Headers

Required for all requests:

Authorization: Bearer {api_key}
Content-Type: application/json
Accept: application/json
X-API-Version: 1.0

Optional headers:

X-Request-ID: req_123456789
X-Client-Version: 1.2.3

REQ-098-058: Every request MUST carry the Authorization: Bearer {api_key}, Content-Type: application/json, Accept: application/json and X-API-Version headers, and MAY carry the optional X-Request-ID and X-Client-Version headers.

5.2 Request Body Validation

All POST/PUT requests MUST validate against JSON schema:

{
  "title": "Task title",
  "priority": 1
}

Validation errors return 422:

{
  "error": {
    "code": "VAL-002",
    "message": "Validation failed",
    "details": {
      "priority": "Must be between 1 and 5"
    }
  }
}

WebSocket Standards
6.1 Connection
ws://localhost:8080/ws/v1/agents?token={api_key}
6.2 Message Format

Client to Server:

{
  "type": "subscribe",
  "channel": "agent_status",
  "request_id": "req_123"
}

Server to Client:

{
  "type": "event",
  "channel": "agent_status",
  "data": {
    "agent_id": "U:Cd",
    "status": "running"
  },
  "request_id": "req_123",
  "timestamp": "2026-04-08T14:30:00Z"
}

REQ-098-059: A client-to-server WebSocket message MUST carry type, channel and request_id, and a server-to-client WebSocket message MUST carry type, channel, data, request_id and timestamp.

6.3 Message Types

Idempotency
7.1 Idempotency Headers

For POST requests that create resources:

Idempotency-Key: uuid-1234-5678-9012

Server stores response for 24 hours with this key.

REQ-098-060: POST endpoints that create resources MUST support an optional Idempotency-Key header; when the header is present, the server MUST store the response against that key for 24 hours.

7.2 Idempotent Response
{
  "data": {
    "id": "T:001",
    "status": "created",
    "created_at": "2026-04-08T14:30:00Z"
  },
  "metadata": {
    "idempotency_key": "uuid-1234-5678-9012"
  }
}

REQ-098-061: An idempotent response MUST echo the idempotency_key in its metadata.

Caching
8.1 Cache Headers

Cache-Control:

Cache-Control: no-cache, no-store, must-revalidate

ETag (for GET requests):

ETag: "abc123"
If-None-Match: "abc123"

REQ-098-062: The API MUST use Cache-Control: no-cache, no-store, must-revalidate as its cache-control header, and ETag with If-None-Match as its GET validation headers.

8.2 Cache Validation

Client can validate cached data:

GET /api/v1/resource
200 OK
ETag: "abc123"

Client sends:

GET /api/v1/resource
If-None-Match: "abc123"

Server responds:

304 Not Modified

REQ-098-063: When a client re-requests a resource with If-None-Match carrying the ETag the server previously issued, the server MUST respond 304 Not Modified.


Security Headers
9.1 Standard Headers
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
X-XSS-Protection: 1; mode=block
Strict-Transport-Security: max-age=31536000; includeSubDomains
Content-Security-Policy: default-src 'self'

REQ-098-064: Responses MUST carry the standard security headers X-Content-Type-Options: nosniff, X-Frame-Options: DENY, X-XSS-Protection: 1; mode=block, Strict-Transport-Security: max-age=31536000; includeSubDomains and Content-Security-Policy: default-src 'self'.

9.2 CORS Headers

For cross-origin requests:

Access-Control-Allow-Origin: https://app.orchestrata.com
Access-Control-Allow-Methods: GET, POST, PUT, DELETE
Access-Control-Allow-Headers: Authorization, Content-Type, X-API-Version
Access-Control-Max-Age: 86400

REQ-098-065: Cross-origin requests MUST be answered with the CORS headers Access-Control-Allow-Origin, Access-Control-Allow-Methods: GET, POST, PUT, DELETE, Access-Control-Allow-Headers: Authorization, Content-Type, X-API-Version and Access-Control-Max-Age: 86400.

Monitoring and Observability
10.1 Request Tracing

Every response includes request ID:

X-Request-ID: req_123456789
10.2 Performance Metrics

Response Time Header:

X-Response-Time: 45ms

Server Timestamp:

X-Server-Time: 2026-04-08T14:30:00Z

REQ-098-066: Every response MUST carry the X-Response-Time header giving the request duration; responses MAY include the X-Server-Time header giving the server timestamp.

10.3 Health Check
GET /api/v1/health

Response:
{
  "status": "healthy",
  "version": "1.0.0",
  "uptime": 3600,
  "checks": {
    "database": "ok",
    "redis": "ok",
    "neo4j": "ok"
  }
}

REQ-098-067: GET /api/v1/health MUST return status, version, uptime and a checks object reporting the state of the database, redis and neo4j dependencies.

API Design Principles
11.1 RESTful Design

REQ-098-068: The API MUST use the HTTP method matching the operation (GET, POST, PUT, DELETE), MUST express resource URLs in the plural form, and MUST express relationships as sub-resources.

11.2 Consistency

REQ-098-069: The API MUST apply consistent naming conventions, consistent error handling and consistent response formats.

11.3 Security by Default

REQ-098-070: The API MUST be secure by default: HTTPS MUST be required, authentication MUST be required, data exposure MUST be minimal, and input validation MUST be mandatory.


Documentation Requirements

Each API endpoint MUST document:

REQ-098-071: Each API endpoint MUST document its URL and method, required parameters, request body schema, response schema, an example request and response, error codes, rate limits, and the authentication required.


Testing Requirements
13.1 Contract Testing

REQ-098-114: Contract testing MUST exercise all endpoints against the OpenAPI spec, MUST enforce schema validation, and MUST detect breaking changes.

13.2 Load Testing

REQ-098-115: Load testing MUST verify the 99.9% uptime target, P95 latency below 500ms, and handling of 10x normal load.

13.3 Chaos Testing

REQ-098-116: Chaos testing MUST cover dependency failures, network partitions and cascading failures.


Testing Requirements

Unit Testing Requirements
  1. Component Unit Tests
    • Test all public interfaces
    • Test error conditions and edge cases
    • Test data validation and transformation
    • Test performance boundaries

REQ-098-117: Component unit tests MUST cover all public interfaces, error conditions and edge cases, data validation and transformation, and performance boundaries.

Integration Testing Requirements
  1. Component Integration Tests
    • Test interactions with dependencies
    • Test data flow across boundaries
    • Test failure recovery scenarios
    • Test performance under load

REQ-098-118: Component integration tests MUST cover interactions with dependencies, data flow across boundaries, failure recovery scenarios, and performance under load.

Performance Testing Requirements
  1. Load and Stress Tests
    • Test under expected production load
    • Test under peak load conditions
    • Test under failure conditions
    • Test recovery after overload

REQ-098-119: Load and stress tests MUST run under expected production load, under peak load conditions and under failure conditions, and MUST verify recovery after overload.

Test Automation Requirements
  1. CI/CD Integration
    • Tests run on every commit
    • Performance tests run nightly
    • Security tests run weekly
    • Compliance tests run per release

REQ-098-120: CI/CD integration MUST run the tests on every commit, the performance tests nightly, the security tests weekly, and the compliance tests per release.


Observability

Logging Requirements
  1. Component Logging
    • Log all major operations with appropriate log levels
    • Include correlation IDs for request tracing
    • Log performance metrics for critical operations
    • Log errors with full context for debugging

REQ-098-121: Component logging MUST log all major operations at their log level, MUST include correlation IDs for request tracing, MUST log performance metrics for critical operations, and MUST log errors with full context for debugging.

Metrics Requirements
  1. Performance Metrics
    • Operation duration histograms
    • Request/error rate counters
    • Resource utilization gauges
    • Business metrics relevant to domain

REQ-098-122: Performance metrics MUST include operation duration histograms, request/error rate counters, resource utilization gauges, and the business metrics relevant to the domain.

Tracing Requirements
  1. Distributed Tracing
    • Trace propagation across component boundaries
    • Span attributes for domain-specific context
    • Trace sampling based on operational needs

REQ-098-123: Distributed tracing MUST propagate traces across component boundaries, MUST carry span attributes for domain-specific context, and MUST sample traces according to operational needs.

Alerting Requirements
  1. Critical Alerts
    • Error rate spikes
    • Performance degradation
    • Resource exhaustion
    • Business metric anomalies

REQ-098-124: Critical alerts MUST fire on error rate spikes, performance degradation, resource exhaustion and business metric anomalies.

Dashboard Requirements
  1. Operational Dashboard
    • Real-time system health
    • Performance trends
    • Error analysis
    • Resource monitoring

REQ-098-125: The operational dashboard MUST show real-time system health, performance trends, error analysis and resource monitoring.


Revision History

Version Date Author Changes
1.0.0 2026-04-08 Mohamed Initial specification
1.1.0 2026-04-09 Mohamed Added FR, ERR table, terminology, NFR, integration points, success criteria