diff --git a/docs/reference/openapi.yaml b/docs/reference/openapi.yaml index faa3b50d07..9394ac5b68 100644 --- a/docs/reference/openapi.yaml +++ b/docs/reference/openapi.yaml @@ -2617,15 +2617,350 @@ paths: get: tags: [System] summary: Get compliance audit log + description: > + Returns paginated audit log entries. Use `level=high` to filter to + high-level actions only (powers the Activity feed). Use `level=all` + (default) for full compliance table. + security: + - bearerAuth: [] parameters: + - name: level + in: query + schema: + type: string + enum: [high, all] + default: all + description: "high = Activity feed events only; all = all audit events" + - name: action + in: query + schema: + type: string + description: Filter by exact action string (e.g. "provider.added") + - name: actor + in: query + schema: + type: string + description: Filter by actor identifier - name: limit in: query schema: type: integer - default: 100 + default: 50 + maximum: 500 + - name: offset + in: query + schema: + type: integer + default: 0 responses: "200": description: Audit log entries + "401": + description: Unauthorized + "500": + description: Internal server error + + # ─── Quota Sharing (Group B, plan 22) ──────────────────────────── + + /api/quota/pools: + get: + tags: [Quota] + summary: List quota pools + security: + - bearerAuth: [] + responses: + "200": + description: Array of QuotaPool objects + content: + application/json: + schema: + type: array + items: + $ref: "#/components/schemas/QuotaPool" + "401": + description: Unauthorized + "500": + description: Internal server error + post: + tags: [Quota] + summary: Create quota pool + security: + - bearerAuth: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: "#/components/schemas/PoolCreate" + responses: + "201": + description: Pool created + content: + application/json: + schema: + $ref: "#/components/schemas/QuotaPool" + "400": + description: Validation error (Zod) + "401": + description: Unauthorized + "500": + description: Internal server error + + /api/quota/pools/{id}: + get: + tags: [Quota] + summary: Get quota pool by ID + security: + - bearerAuth: [] + parameters: + - name: id + in: path + required: true + schema: + type: string + responses: + "200": + description: QuotaPool object + content: + application/json: + schema: + $ref: "#/components/schemas/QuotaPool" + "401": + description: Unauthorized + "404": + description: Pool not found + "500": + description: Internal server error + patch: + tags: [Quota] + summary: Update quota pool (name or allocations) + security: + - bearerAuth: [] + parameters: + - name: id + in: path + required: true + schema: + type: string + requestBody: + required: true + content: + application/json: + schema: + $ref: "#/components/schemas/PoolUpdate" + responses: + "200": + description: Updated pool + "400": + description: Validation error + "401": + description: Unauthorized + "404": + description: Pool not found + "500": + description: Internal server error + delete: + tags: [Quota] + summary: Delete quota pool + security: + - bearerAuth: [] + parameters: + - name: id + in: path + required: true + schema: + type: string + responses: + "204": + description: Deleted + "401": + description: Unauthorized + "404": + description: Pool not found + "500": + description: Internal server error + + /api/quota/pools/{id}/usage: + get: + tags: [Quota] + summary: Get pool usage snapshot (per-key consumption + burn rate) + security: + - bearerAuth: [] + parameters: + - name: id + in: path + required: true + schema: + type: string + responses: + "200": + description: PoolUsageSnapshot + content: + application/json: + schema: + $ref: "#/components/schemas/PoolUsageSnapshot" + "401": + description: Unauthorized + "404": + description: Pool not found + "500": + description: Internal server error + + /api/quota/plans: + get: + tags: [Quota] + summary: List resolved provider plans (catalog + manual overrides) + security: + - bearerAuth: [] + responses: + "200": + description: Array of ProviderPlan + "401": + description: Unauthorized + "500": + description: Internal server error + + /api/quota/plans/{connectionId}: + get: + tags: [Quota] + summary: Get resolved plan for a connection + security: + - bearerAuth: [] + parameters: + - name: connectionId + in: path + required: true + schema: + type: string + responses: + "200": + description: ProviderPlan (source = auto | manual) + "401": + description: Unauthorized + "404": + description: Connection not found + "500": + description: Internal server error + put: + tags: [Quota] + summary: Upsert manual plan override for a connection + security: + - bearerAuth: [] + parameters: + - name: connectionId + in: path + required: true + schema: + type: string + requestBody: + required: true + content: + application/json: + schema: + $ref: "#/components/schemas/PlanUpsert" + responses: + "200": + description: Updated plan + "400": + description: Validation error (Zod) + "401": + description: Unauthorized + "500": + description: Internal server error + delete: + tags: [Quota] + summary: Delete manual plan override (reverts to catalog/auto) + security: + - bearerAuth: [] + parameters: + - name: connectionId + in: path + required: true + schema: + type: string + responses: + "204": + description: Override deleted + "401": + description: Unauthorized + "404": + description: Override not found + "500": + description: Internal server error + + /api/quota/preview: + get: + tags: [Quota] + summary: Dry-run quota enforcement check (preview only, no consumption recorded) + security: + - bearerAuth: [] + parameters: + - name: apiKeyId + in: query + required: true + schema: + type: string + - name: poolId + in: query + required: true + schema: + type: string + - name: estimatedTokens + in: query + schema: + type: number + - name: estimatedUsd + in: query + schema: + type: number + - name: estimatedRequests + in: query + schema: + type: integer + responses: + "200": + description: EnforceDecision (allow/block + reason) + "400": + description: Validation error (Zod) + "401": + description: Unauthorized + "500": + description: Internal server error + + /api/settings/quota-store: + get: + tags: [Settings] + summary: Get current quota store driver settings + description: Redis URL is masked in the response (shows only scheme+host). + security: + - bearerAuth: [] + responses: + "200": + description: QuotaStoreSettings (driver + masked redisUrl) + "401": + description: Unauthorized + "500": + description: Internal server error + put: + tags: [Settings] + summary: Update quota store driver settings + security: + - bearerAuth: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: "#/components/schemas/QuotaStoreSettings" + responses: + "200": + description: Settings updated + "400": + description: Validation error (Zod) — e.g. driver=redis without valid URL + "401": + description: Unauthorized + "500": + description: Internal server error # ─── v1beta (Gemini-Compatible) ───────────────────────────────── @@ -2791,6 +3126,161 @@ components: $ref: "#/components/schemas/ValidationErrorResponse" schemas: + QuotaPool: + type: object + description: A quota sharing pool — binds a provider connection to allocation rules. + required: [id, connectionId, name, createdAt, allocations] + properties: + id: + type: string + connectionId: + type: string + name: + type: string + createdAt: + type: string + format: date-time + allocations: + type: array + items: + $ref: "#/components/schemas/PoolAllocation" + + PoolAllocation: + type: object + required: [apiKeyId, weight, policy] + properties: + apiKeyId: + type: string + weight: + type: number + minimum: 0 + maximum: 100 + description: Share percentage (0–100) + capValue: + type: number + nullable: true + description: Absolute cap value (optional) + capUnit: + type: string + enum: [percent, requests, tokens, usd] + nullable: true + policy: + type: string + enum: [hard, soft, burst] + + PoolCreate: + type: object + required: [connectionId, name] + properties: + connectionId: + type: string + name: + type: string + maxLength: 120 + allocations: + type: array + items: + $ref: "#/components/schemas/PoolAllocation" + default: [] + + PoolUpdate: + type: object + properties: + name: + type: string + maxLength: 120 + allocations: + type: array + items: + $ref: "#/components/schemas/PoolAllocation" + + PoolUsageSnapshot: + type: object + required: [poolId, generatedAt, dimensions] + properties: + poolId: + type: string + generatedAt: + type: string + format: date-time + dimensions: + type: array + items: + type: object + properties: + unit: + type: string + enum: [percent, requests, tokens, usd] + window: + type: string + enum: ["5h", hourly, daily, weekly, monthly] + limit: + type: number + consumedTotal: + type: number + perKey: + type: array + items: + type: object + properties: + apiKeyId: + type: string + consumed: + type: number + fairShare: + type: number + deficit: + type: number + description: "Negative = surplus; positive = over-allocation" + borrowing: + type: boolean + burnRate: + type: object + nullable: true + properties: + tokensPerSecond: + type: number + timeToExhaustionMs: + type: number + nullable: true + + QuotaDimension: + type: object + required: [unit, window, limit] + properties: + unit: + type: string + enum: [percent, requests, tokens, usd] + window: + type: string + enum: ["5h", hourly, daily, weekly, monthly] + limit: + type: number + minimum: 0 + + PlanUpsert: + type: object + required: [dimensions] + properties: + dimensions: + type: array + minItems: 1 + items: + $ref: "#/components/schemas/QuotaDimension" + + QuotaStoreSettings: + type: object + required: [driver] + properties: + driver: + type: string + enum: [sqlite, redis] + redisUrl: + type: string + format: uri + nullable: true + description: Redis connection URL (write-only; masked in GET responses) + ServiceStatus: type: object description: Live supervisor state for an embedded service