OpenAPI Discovery (.well-known/openapi)
How to discover the OpenAPI documents that Stella Ops services expose at /.well-known/openapi, and how the Router Gateway aggregates those documents into a single unified specification.
Audience: SDK generators, API client integrators, and tooling authors that need to locate and consume service specs.
The platform exposes OpenAPI discovery at /.well-known/openapi. There are two distinct implementations with different response shapes; the { "spec": "/stella.yaml", "version": ..., "extensions": ... } body documented in earlier drafts of this page does not exist in the codebase and has been removed.
Per-service implementation (Authority, Concelier/Excititor, Export Center, …)
Most services return their OpenAPI document directly from /.well-known/openapi (JSON or YAML negotiated via the Accept header — application/openapi+json / application/openapi+yaml), with metadata carried in response headers rather than a JSON wrapper. See StellaOps.Authority/OpenApi/OpenApiDiscoveryEndpointExtensions.cs.
Response headers (Authority):
| Header | Value / meaning |
|---|---|
Content-Type | application/openapi+json; charset=utf-8 (or application/openapi+yaml) |
ETag | Content hash; supports If-None-Match → 304 Not Modified |
Last-Modified | RFC 1123 timestamp of the spec |
Cache-Control | public, max-age=300 |
Vary | Accept |
X-StellaOps-Service | Service name |
X-StellaOps-Api-Version | API version |
X-StellaOps-Build-Version | Build version |
X-StellaOps-OAuth-Grants | Space-separated grant types (when present) |
X-StellaOps-OAuth-Scopes | Space-separated scopes (when present) |
The Notifier (StellaOps.Notifier.WebService) similarly serves YAML directly with an X-OpenAPI-Scope: notify header.
The
OAS-63work item family referenced in earlier drafts corresponds to deprecation-header and OpenAPI-surfacing work (e.g.CONCELIER-WEB-OAS-63-001), not to astella.yamldiscovery-wrapper contract.
Gateway OpenAPI Aggregation
The Router Gateway dynamically aggregates OpenAPI documentation from connected microservices. This provides a unified API specification that updates automatically as services connect and disconnect.
Discovery Endpoint
GET /.well-known/openapi
Response (StellaOps.Gateway.WebService, OpenApiAggregatorEndpoints):
{
"openapi_json": "/openapi.json",
"openapi_yaml": "/openapi.yaml",
"aggregate_json": "/api/openapi/aggregate",
"etag": "\"5d41402abc4b2a76b9719d911017c592\"",
"generated_at": "2025-01-15T10:30:00.0000000Z"
}
The alternate gateway library (StellaOps.Router.Gateway, OpenApiEndpoints) returns the same body without the aggregate_json key: { "openapi_json", "openapi_yaml", "etag", "generated_at" }. Both serve Cache-Control: public, max-age=60 (not max-age=300); generated_at is an ISO-8601 round-trip (O) UTC timestamp.
OpenAPI Endpoints
| Endpoint | Format | Content-Type |
|---|---|---|
GET /openapi.json | JSON | application/json; charset=utf-8 |
GET /openapi.yaml | YAML | application/yaml; charset=utf-8 |
GET /api/openapi/aggregate | JSON (per-service status + specs) | application/json; charset=utf-8 |
HTTP Caching
OpenAPI endpoints support conditional requests and caching:
| Endpoint(s) | Cache-Control | Notes |
|---|---|---|
/.well-known/openapi, /openapi.json, /openapi.yaml | public, max-age=60 | ETag content hash; If-None-Match → 304 Not Modified |
/api/openapi/aggregate | public, max-age=30 | Fan-out status document |
Conditional Request:
GET /openapi.json
If-None-Match: "5d41402abc4b2a76b9719d911017c592"
Returns 304 Not Modified if content unchanged.
Security Schemes
The Gateway generates two security schemes from endpoint claim requirements:
BearerAuth
{
"type": "http",
"scheme": "bearer",
"bearerFormat": "JWT",
"description": "JWT Bearer token authentication"
}
OAuth2 (when endpoints have claims)
{
"type": "oauth2",
"flows": {
"clientCredentials": {
"tokenUrl": "/auth/token",
"scopes": {
"billing:write": "Access scope: billing:write",
"inventory:read": "Access scope: inventory:read"
}
}
}
}
Schema Prefixing
Schemas are prefixed with the service name to avoid collisions:
billingservice +CreateInvoiceRequesttype =billing_CreateInvoiceRequest
Configuration
See OpenAPI Aggregation for Gateway configuration options.
Related Documentation
- API Overview — shared conventions (auth, tenancy, pagination, error envelope)
- Schema Validation — JSON Schema validation in microservices
- OpenAPI Aggregation — Gateway aggregation configuration and implementation architecture
