feat: add group AI spend endpoint (#27568)

## Description

Adds `GET /api/v2/groups/{group}/ai/spend`, returning the AI spend limit
and aggregate spend for a single group over the current budget period.
The period is derived from the deployment's configured budget period
rather than being caller-specified, matching the other AI spend
endpoints.

## Changes

- Add the `groupAISpend` handler and route, gated by the
`aigateway-cost-control` experiment and the `AIBridge` feature.
- Reuse the existing `GetOrganizationGroupsAISpend` query with a single
group ID, so no new query or authorization path is introduced.
- Add the `GroupAISpend` codersdk type and client method.

Closes
https://linear.app/codercom/issue/AIGOV-475/implement-apiv2groupsgroupaispend

> [!NOTE]
> Initially generated by Claude Opus 4.7, modified and reviewed by
@ssncferreira
This commit is contained in:
Susana Ferreira
2026-07-28 11:32:51 +01:00
committed by GitHub
parent e83f018f5f
commit ed37483ff7
9 changed files with 526 additions and 0 deletions
+63
View File
@@ -3400,6 +3400,42 @@ const docTemplate = `{
]
}
},
"/api/v2/groups/{group}/ai/spend": {
"get": {
"description": "Returns the AI spend limit and aggregate spend for the group.",
"produces": [
"application/json"
],
"tags": [
"Enterprise"
],
"summary": "Get group AI spend",
"operationId": "get-group-ai-spend",
"parameters": [
{
"type": "string",
"format": "uuid",
"description": "Group ID",
"name": "group",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/codersdk.GroupAISpend"
}
}
},
"security": [
{
"CoderSessionToken": []
}
]
}
},
"/api/v2/groups/{group}/members": {
"get": {
"produces": [
@@ -20642,6 +20678,33 @@ const docTemplate = `{
}
}
},
"codersdk.GroupAISpend": {
"type": "object",
"properties": {
"current_spend_micros": {
"description": "CurrentSpendMicros is the group's spend over the current budget\nperiod.",
"type": "integer"
},
"group_id": {
"type": "string",
"format": "uuid"
},
"period_end": {
"description": "PeriodEnd is the exclusive upper bound of the current budget\nperiod.",
"type": "string",
"format": "date-time"
},
"period_start": {
"description": "PeriodStart is the inclusive lower bound of the current budget\nperiod.",
"type": "string",
"format": "date-time"
},
"spend_limit_micros": {
"description": "SpendLimitMicros is the group's configured AI spend limit. Null when\nthe group has no configured budget.",
"type": "integer"
}
}
},
"codersdk.GroupMemberAISpend": {
"type": "object",
"properties": {
+59
View File
@@ -2999,6 +2999,38 @@
]
}
},
"/api/v2/groups/{group}/ai/spend": {
"get": {
"description": "Returns the AI spend limit and aggregate spend for the group.",
"produces": ["application/json"],
"tags": ["Enterprise"],
"summary": "Get group AI spend",
"operationId": "get-group-ai-spend",
"parameters": [
{
"type": "string",
"format": "uuid",
"description": "Group ID",
"name": "group",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/codersdk.GroupAISpend"
}
}
},
"security": [
{
"CoderSessionToken": []
}
]
}
},
"/api/v2/groups/{group}/members": {
"get": {
"produces": ["application/json"],
@@ -18790,6 +18822,33 @@
}
}
},
"codersdk.GroupAISpend": {
"type": "object",
"properties": {
"current_spend_micros": {
"description": "CurrentSpendMicros is the group's spend over the current budget\nperiod.",
"type": "integer"
},
"group_id": {
"type": "string",
"format": "uuid"
},
"period_end": {
"description": "PeriodEnd is the exclusive upper bound of the current budget\nperiod.",
"type": "string",
"format": "date-time"
},
"period_start": {
"description": "PeriodStart is the inclusive lower bound of the current budget\nperiod.",
"type": "string",
"format": "date-time"
},
"spend_limit_micros": {
"description": "SpendLimitMicros is the group's configured AI spend limit. Null when\nthe group has no configured budget.",
"type": "integer"
}
}
},
"codersdk.GroupMemberAISpend": {
"type": "object",
"properties": {