{"openapi":"3.0.0","info":{"title":"PlatPhorm Keys API","description":"Canonical public-safe PLATPHORM_API_KEY issuer, lifecycle manager, validator, rotation/revocation service, scoped-access policy layer, and audit/telemetry hub for the PlatPhormNews web mesh.","version":"0.5.1","contact":{"name":"PlatPhorm Support","url":"https://keys.platphormnews.com"},"license":{"name":"MIT"}},"servers":[{"url":"https://keys.platphormnews.com","description":"Production"},{"url":"http://localhost:3000","description":"Development"}],"tags":[{"name":"Health","description":"System health and status"},{"name":"Provisioning","description":"Protected, bounded key provisioning"},{"name":"Keys","description":"API Key management operations"},{"name":"Telemetry","description":"Observability and monitoring"}],"paths":{"/api/health":{"get":{"tags":["Health"],"summary":"Health Check Alias","description":"Canonical unversioned alias for the public-safe Keys health envelope.","operationId":"getHealthAlias","responses":{"200":{"description":"System is healthy or honestly degraded"},"503":{"description":"System is unhealthy"}}}},"/api/v1/certification/lifecycle":{"post":{"tags":["Telemetry","Keys"],"summary":"Run a bounded production lifecycle certification","description":"Creates, reads, rotates, and revokes one certification key; verifies durable audit events; exports a redacted trace; and never returns key material. Requires PLATPHORM_API_KEY or the configured Vercel cron credential.","operationId":"certifyKeyLifecycle","security":[{"platphormBearer":[]},{"platphormHeader":[]}],"responses":{"200":{"description":"Lifecycle, audit readback, trace export, and propagation certified"},"401":{"$ref":"#/components/responses/Unauthorized"},"502":{"description":"Lifecycle completed and key was revoked, but trace export failed"},"503":{"description":"Certification failed and revocation cleanup was attempted"}}}},"/api/v1/keys/bbs/issue":{"post":{"tags":["Keys"],"summary":"Issue BBS Member Key","description":"Protected integration endpoint for bbs.platphormnews.com. Returns a signed, scoped BBS credential exactly once; the credential is not stored or recoverable and does not require email confirmation.","security":[{"platphormBearer":[]},{"platphormHeader":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["email","username","sourceSite"],"properties":{"email":{"type":"string","format":"email"},"username":{"type":"string"},"userId":{"type":"string"},"sourceSite":{"type":"string","enum":["bbs.platphormnews.com"]}}}}}},"responses":{"201":{"description":"Signed BBS key issued and shown once"},"401":{"description":"PLATPHORM_API_KEY required"},"503":{"description":"BBS key signing unavailable; no key issued"}}}},"/api/v1/keys/bbs/verify":{"post":{"tags":["Keys"],"summary":"Verify BBS Member Key","description":"Protected integration endpoint that validates the bbs scope and returns an opaque member subject without returning the key.","security":[{"platphormBearer":[]},{"platphormHeader":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["key","sourceSite"],"properties":{"key":{"type":"string","writeOnly":true},"sourceSite":{"type":"string","enum":["bbs.platphormnews.com"]}}}}}},"responses":{"200":{"description":"Validity, opaque subject, and scopes"},"401":{"description":"PLATPHORM_API_KEY required"}}}},"/api/v1/health":{"get":{"tags":["Health"],"summary":"Health Check","description":"Check the health status of the API","operationId":"getHealth","responses":{"200":{"description":"System is healthy","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["healthy","degraded","unhealthy"]},"timestamp":{"type":"string","format":"date-time"},"version":{"type":"string"},"traceExportConfigured":{"type":"boolean"},"traceExportEnabled":{"type":"boolean","description":"True only when shared auth is configured and durable certification evidence is current."},"traceCertificationStatus":{"type":"string","enum":["current","stale","missing"]},"traceCertificationAgeSeconds":{"type":"number","nullable":true},"traceCertificationMaxAgeSeconds":{"type":"number"},"traceDeliveryMode":{"type":"string","enum":["dynamodb-outbox"]},"traceOutbox":{"type":"object","properties":{"pending":{"type":"number"},"retrying":{"type":"number"},"deadLetters":{"type":"number"},"inspected":{"type":"number"},"bounded":{"type":"boolean"}}},"rateLimit":{"type":"object","description":"Atomic fixed-window counters in same-account DynamoDB; identifiers are SHA-256 hashed and storage failure denies closed."},"monitorDelivery":{"type":"object","description":"Public-safe durable acknowledgement from the most recent controlled Keys-to-Monitor delivery certification."},"lastTraceExportAt":{"type":"string","format":"date-time","nullable":true},"lastTraceId":{"type":"string","nullable":true},"checks":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string"},"status":{"type":"string","enum":["pass","fail"]},"message":{"type":"string"},"latency_ms":{"type":"number"}}}}}}}}},"503":{"description":"System is unhealthy"}}}},"/api/v1/keys/provision":{"post":{"tags":["Provisioning"],"summary":"Self-Service Key Provisioning","description":"Protected, bounded, rate-limited key provisioning. Generated PLATPHORM_API_KEY secrets are shown once.","operationId":"provisionKey","security":[{"platphormBearer":[]},{"platphormHeader":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["name"],"properties":{"name":{"type":"string","description":"Human-readable name for the key","example":"My Production Key"},"scopes":{"type":"array","items":{"type":"string","enum":["read","write","mcp","trace"]},"default":["read"],"description":"Permission scopes for the key"},"clientMetadata":{"type":"object","description":"Optional custom metadata"}}}}}},"responses":{"201":{"description":"API key provisioned successfully","content":{"application/json":{"schema":{"type":"object","properties":{"keyId":{"type":"string"},"key":{"type":"string","description":"Full generated key secret. Shown only once and never returned by list/get/validate/discovery endpoints."},"keyPrefix":{"type":"string"},"name":{"type":"string"},"scopes":{"type":"array","items":{"type":"string"}},"clientUUID":{"type":"string","description":"Auto-generated client identifier"},"fingerprint":{"type":"string","description":"Browser/device fingerprint"},"traceId":{"type":"string","description":"OpenTelemetry trace ID"},"geo":{"type":"object","properties":{"country":{"type":"string"},"region":{"type":"string"},"city":{"type":"string"}}}}}}},"headers":{"X-Client-UUID":{"schema":{"type":"string"},"description":"Client UUID"},"X-Fingerprint":{"schema":{"type":"string"},"description":"Device fingerprint"},"X-Trace-Id":{"schema":{"type":"string"},"description":"Trace ID"},"X-PlatPhorm-Trace-Export":{"schema":{"type":"string","enum":["queued","exported","failed","rejected","disabled"]},"description":"Observed durable Trace delivery state. Routine operations enqueue before responding."}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/api/v1/telemetry":{"get":{"tags":["Telemetry"],"summary":"Get Telemetry Data","description":"Retrieve public-safe telemetry summary. Sensitive spans and metrics require PLATPHORM_API_KEY when requested.","operationId":"getTelemetry","parameters":[{"name":"spans","in":"query","description":"Include recent spans","schema":{"type":"boolean","default":false}},{"name":"metrics","in":"query","description":"Include recent metrics","schema":{"type":"boolean","default":false}},{"name":"limit","in":"query","description":"Maximum number of items to return","schema":{"type":"integer","default":100,"maximum":500}}],"responses":{"200":{"description":"Telemetry data","content":{"application/json":{"schema":{"type":"object","properties":{"summary":{"type":"object","properties":{"activeSpans":{"type":"integer"},"completedSpans":{"type":"integer"},"totalMetrics":{"type":"integer"},"operations":{"type":"object"}}},"timestamp":{"type":"string","format":"date-time"},"spans":{"type":"array","items":{"type":"object"}},"metrics":{"type":"array","items":{"type":"object"}}}}}}}}}},"/api/v1/keys":{"get":{"tags":["Keys"],"summary":"List API Keys","description":"List key metadata for the authenticated tenant. Unauthenticated requests are rejected without returning fake key rows.","operationId":"listKeys","security":[{"platphormBearer":[]},{"platphormHeader":[]}],"parameters":[{"name":"status","in":"query","description":"Filter by key status","required":false,"schema":{"type":"string","enum":["active","rotated","revoked"]}},{"name":"limit","in":"query","description":"Maximum number of results (default: 50)","required":false,"schema":{"type":"integer","minimum":1,"maximum":100}},{"name":"cursor","in":"query","description":"Pagination cursor","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"List of API keys","content":{"application/json":{"schema":{"type":"object","properties":{"keys":{"type":"array","items":{"$ref":"#/components/schemas/ApiKey"}},"cursor":{"type":"string"},"hasMore":{"type":"boolean"}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"429":{"$ref":"#/components/responses/RateLimited"}}},"post":{"tags":["Keys"],"summary":"Create API Key","description":"Protected key creation for an authenticated tenant. Bounded operator provisioning is available at /api/v1/keys/provision.","operationId":"createKey","security":[{"platphormBearer":[]},{"platphormHeader":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["name"],"properties":{"name":{"type":"string","description":"Human-readable name for the key"},"description":{"type":"string","description":"Optional description"},"expiresIn":{"type":"integer","description":"Expiration time in seconds (optional)"}}}}}},"responses":{"201":{"description":"API key created successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiKeyCreated"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/api/v1/keys/{keyId}":{"get":{"tags":["Keys"],"summary":"Get API Key","description":"Retrieve details of a specific API key","operationId":"getKey","security":[{"platphormBearer":[]},{"platphormHeader":[]}],"parameters":[{"name":"keyId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"API key details","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiKey"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}}},"patch":{"tags":["Keys"],"summary":"Update API Key","description":"Update API key metadata","operationId":"updateKey","security":[{"platphormBearer":[]},{"platphormHeader":[]}],"parameters":[{"name":"keyId","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string"},"description":{"type":"string"}}}}}},"responses":{"200":{"description":"Key updated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiKey"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}}},"delete":{"tags":["Keys"],"summary":"Revoke API Key","description":"Revoke an API key","operationId":"revokeKey","security":[{"platphormBearer":[]},{"platphormHeader":[]}],"parameters":[{"name":"keyId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"204":{"description":"Key revoked successfully"},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/api/v1/keys/{keyId}/rotate":{"post":{"tags":["Keys"],"summary":"Rotate API Key","description":"Rotate an existing API key and generate a new secret","operationId":"rotateKey","security":[{"platphormBearer":[]},{"platphormHeader":[]}],"parameters":[{"name":"keyId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Key rotated successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiKeyCreated"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/api/v1/keys/validate":{"post":{"tags":["Keys"],"summary":"Validate API Key","description":"Validate a PLATPHORM_API_KEY candidate without revealing the secret. Responses never include raw key material.","operationId":"validateKey","security":[{"platphormBearer":[]},{"platphormHeader":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["key"],"properties":{"key":{"type":"string","description":"API key to validate"}}}}}},"responses":{"200":{"description":"Validation result","content":{"application/json":{"schema":{"type":"object","properties":{"valid":{"type":"boolean"},"keyId":{"type":"string"},"keyPrefix":{"type":"string"},"status":{"type":"string","enum":["active","rotated","revoked"]}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}}},"/api/mcp":{"get":{"tags":["Telemetry"],"summary":"Read MCP endpoint metadata","description":"Public-safe JSON-RPC usage and method metadata. Successful metadata reads are intentionally not collected as traces.","responses":{"200":{"description":"MCP metadata and usage"}}},"post":{"tags":["Telemetry","Keys"],"summary":"Execute MCP JSON-RPC 2.0 requests","description":"Accepts a JSON-RPC object or batch. Meaningful tool calls and failures are traced truthfully; successful initialize, ping, and registry-list introspection are not collected. Arguments and key material are never exported.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"description":"JSON-RPC response or batch response"},"400":{"description":"JSON-RPC parse error"}}}},"/api/cron/refresh":{"get":{"tags":["Telemetry"],"summary":"Run scheduled read-only platform certification","description":"Checks the fixed trusted Base route-compliance endpoint and reads the last certified Trace. Returns HTTP 503 to signal a regression. Requires PLATPHORM_API_KEY or the configured Vercel cron credential.","security":[{"platphormBearer":[]},{"platphormHeader":[]}],"responses":{"200":{"description":"Base and Trace certification passed"},"401":{"$ref":"#/components/responses/Unauthorized"},"503":{"description":"Certification regression; HTTP status is the alert signal"}}}},"/api/cron/trace-outbox":{"get":{"tags":["Telemetry"],"summary":"Drain the bounded Trace delivery outbox","description":"Delivers up to 25 due DynamoDB-backed events, retries failures with exponential backoff, retains exhausted events as dead-letter evidence, and creates a Monitor incident on the transition to dead-letter.","security":[{"platphormBearer":[]},{"platphormHeader":[]}],"responses":{"200":{"description":"Due events processed without dead letters"},"401":{"$ref":"#/components/responses/Unauthorized"},"503":{"description":"Dead-letter evidence exists; Monitor notification is included in protected details"}}}},"/api/v1/certification/monitor":{"get":{"tags":["Telemetry"],"summary":"Read public-safe Monitor delivery certification","responses":{"200":{"description":"Last durable Monitor acknowledgement or an honest missing state"}}},"post":{"tags":["Telemetry"],"summary":"Run a controlled Monitor delivery drill","description":"Creates an explicitly labeled low-severity certification incident and persists only its acknowledgement evidence. Requires PLATPHORM_API_KEY or the configured Vercel cron credential.","security":[{"platphormBearer":[]},{"platphormHeader":[]}],"responses":{"200":{"description":"Monitor acknowledged the certification incident and evidence was persisted"},"401":{"$ref":"#/components/responses/Unauthorized"},"502":{"description":"Monitor did not acknowledge delivery"}}}}},"components":{"schemas":{"ApiKey":{"type":"object","properties":{"id":{"type":"string"},"keyPrefix":{"type":"string","description":"Public prefix of the key"},"name":{"type":"string"},"description":{"type":"string"},"status":{"type":"string","enum":["active","rotated","revoked"]},"createdAt":{"type":"string","format":"date-time"},"expiresAt":{"type":"string","format":"date-time"},"lastUsedAt":{"type":"string","format":"date-time"}}},"ApiKeyCreated":{"type":"object","properties":{"id":{"type":"string"},"key":{"type":"string","description":"Full API key (only shown once)"},"keyPrefix":{"type":"string"},"name":{"type":"string"},"createdAt":{"type":"string","format":"date-time"}}},"Error":{"type":"object","required":["error","code"],"properties":{"error":{"type":"string"},"code":{"type":"string"},"details":{"type":"object"},"requestId":{"type":"string"}}}},"responses":{"BadRequest":{"description":"Invalid request parameters","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"Unauthorized":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"NotFound":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"RateLimited":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"securitySchemes":{"platphormBearer":{"type":"http","scheme":"bearer","bearerFormat":"PLATPHORM_API_KEY","description":"Use Authorization: Bearer $PLATPHORM_API_KEY. Issued secrets are shown once and authorize permitted protected actions."},"platphormHeader":{"type":"apiKey","in":"header","name":"X-PlatPhorm-API-Key","description":"Use X-PlatPhorm-API-Key: $PLATPHORM_API_KEY for protected key-management and future platform actions."}}}}