> For the complete documentation index, see [llms.txt](https://docs.cortecs.ai/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.cortecs.ai/api/management-api.md).

# Management API

## List API Keys

> Returns all API keys belonging to the authenticated user. Requires a management API key for authentication.<br>

```json
{"openapi":"3.1.0","info":{"title":"Cortecs Management API","version":"1.0.0"},"servers":[{"url":"https://api.cortecs.ai/v1"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT","description":"A management API key must be used as the Bearer token."}},"schemas":{"ApiKey":{"type":"object","properties":{"name":{"type":"string","maxLength":50,"pattern":"^[A-Za-z0-9_\\s-]+$","description":"The unique name of the API key."},"team_id":{"type":"string","description":"The team assigned to the API key."},"created_at":{"type":"integer","description":"Unix timestamp (seconds) of when the key was created."},"is_management_key":{"type":"boolean","description":"Whether this key has management permissions."}}},"ErrorResponse":{"type":"object","properties":{"error":{"type":"string","description":"A human-readable error message."},"detail":{"type":"string","description":"A human-readable error detail message."}}}}},"paths":{"/manage/api-keys":{"get":{"summary":"List API Keys","tags":["API Keys"],"description":"Returns all API keys belonging to the authenticated user. Requires a management API key for authentication.\n","responses":{"200":{"description":"Successfully returned the list of API keys.","content":{"application/json":{"schema":{"type":"object","properties":{"api_keys":{"type":"array","items":{"$ref":"#/components/schemas/ApiKey"}}}}}}},"401":{"description":"Unauthorized – Missing or invalid token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden – The provided API key is not a management key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal server error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}}}}
```

## Create API Key

> Creates a new API key for the authenticated user. Requires a management API key for authentication.<br>

```json
{"openapi":"3.1.0","info":{"title":"Cortecs Management API","version":"1.0.0"},"servers":[{"url":"https://api.cortecs.ai/v1"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT","description":"A management API key must be used as the Bearer token."}},"schemas":{"ErrorResponse":{"type":"object","properties":{"error":{"type":"string","description":"A human-readable error message."},"detail":{"type":"string","description":"A human-readable error detail message."}}}}},"paths":{"/manage/api-keys":{"post":{"summary":"Create API Key","tags":["API Keys"],"description":"Creates a new API key for the authenticated user. Requires a management API key for authentication.\n","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["name"],"properties":{"name":{"type":"string","maxLength":50,"pattern":"^[A-Za-z0-9_\\s-]+$","description":"A unique name for the new API key. Only letters, numbers, hyphens, underscores, and whitespace are allowed."},"team_id":{"type":"string","description":"A team currently assigned to the authenticated user. Defaults to the team assigned to the management API key used for this request when omitted or blank. Legacy management keys without a team resolve to the system-managed Default team."},"is_management_key":{"type":"boolean","description":"Whether the new key should have management permissions.","default":false}}}}}},"responses":{"201":{"description":"API key created successfully. The `api_key` value is only shown once.","content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","description":"The name of the created key."},"team_id":{"type":"string","description":"The team assigned to the created key."},"is_management_key":{"type":"boolean","description":"Whether the key has management permissions."},"api_key":{"type":"string","description":"The API key token. Store it securely — it cannot be retrieved again."}}}}}},"400":{"description":"Bad request – Invalid input, duplicate name, or key limit reached.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized – Missing or invalid token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden – The provided API key is not a management key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}}}}
```

## Delete API Key

> Deletes an API key by name. Also removes any associated budget configurations. You cannot delete the management key currently being used to authenticate. Requires a management API key for authentication.<br>

```json
{"openapi":"3.1.0","info":{"title":"Cortecs Management API","version":"1.0.0"},"servers":[{"url":"https://api.cortecs.ai/v1"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT","description":"A management API key must be used as the Bearer token."}},"schemas":{"ErrorResponse":{"type":"object","properties":{"error":{"type":"string","description":"A human-readable error message."},"detail":{"type":"string","description":"A human-readable error detail message."}}}}},"paths":{"/manage/api-keys":{"delete":{"summary":"Delete API Key","tags":["API Keys"],"description":"Deletes an API key by name. Also removes any associated budget configurations. You cannot delete the management key currently being used to authenticate. Requires a management API key for authentication.\n","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["name"],"properties":{"name":{"type":"string","description":"The name of the API key to delete."}}}}}},"responses":{"200":{"description":"API key deleted successfully.","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"deleted":{"type":"string","description":"The name of the deleted key."}}}}}},"400":{"description":"Bad request – Invalid input or attempting to delete the key in use.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized – Missing or invalid token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden – The provided API key is not a management key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found – The specified API key does not exist.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal server error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}}}}
```

## Retrieve Current Project Settings

> Retrieves effective settings for one team. Admins may retrieve any team in the project. Members may retrieve only teams they are assigned to. Any user may provide team\_id; when omitted, it defaults to the team assigned to the management API key. Legacy keys without a team use Default. Default always resolves to the global project configuration. Other teams without an explicit override use the global project configuration.<br>

```json
{"openapi":"3.1.0","info":{"title":"Cortecs Management API","version":"1.0.0"},"servers":[{"url":"https://api.cortecs.ai/v1"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT","description":"A management API key must be used as the Bearer token."}},"schemas":{"EffectiveProjectConfig":{"allOf":[{"$ref":"#/components/schemas/ProjectConfigUpdateRequest"},{"type":"object","required":["team_id"],"properties":{"team_id":{"type":"string","description":"Selected team. Legacy API keys without a team use Default."}}}]},"ProjectConfigUpdateRequest":{"type":"object","description":"Settings for one team. The optional team_id query parameter selects the team; when omitted, the team is derived from the authenticated API key, or Default for a legacy key without a team.\n","required":["inference_config"],"properties":{"inference_config":{"type":"object","description":"The inference configuration for the project.","properties":{"allowed_providers":{"type":"array","description":"List of allowed providers.","items":{"type":"string"}},"eu_native":{"type":"boolean","description":"Whether to consider only providers based and regulated within the EU. Even when false, all our endpoints are GDPR compliant."},"allow_quantization":{"type":"boolean","description":"Whether to allow quantized endpoints."},"max_tokens":{"type":"integer","description":"Maximum tokens allowed in output.","nullable":true},"preference":{"type":"string","description":"Preference for handling the request.","enum":["speed","cost","balanced"],"nullable":true},"allow_zero_data_retention":{"type":"boolean","description":"Whether to use only ZDR providers."},"enable_model_fallback":{"type":"boolean","description":"Whether to allow model fallback when a model is currently unavailable."}}},"allow_overwrite":{"type":"boolean","description":"Allow individual API calls to define their own inference configurations. If disabled, the selected team's settings will be enforced for all requests.\n"}}},"ErrorResponse":{"type":"object","properties":{"error":{"type":"string","description":"A human-readable error message."},"detail":{"type":"string","description":"A human-readable error detail message."}}}}},"paths":{"/manage/project-configs":{"get":{"summary":"Retrieve Current Project Settings","tags":["Project Config"],"description":"Retrieves effective settings for one team. Admins may retrieve any team in the project. Members may retrieve only teams they are assigned to. Any user may provide team_id; when omitted, it defaults to the team assigned to the management API key. Legacy keys without a team use Default. Default always resolves to the global project configuration. Other teams without an explicit override use the global project configuration.\n","parameters":[{"name":"team_id","in":"query","required":false,"description":"Team to retrieve. Default selects the global project configuration. Members must be assigned to the requested team. Omit to use the team assigned to the authenticated management API key, or Default for a legacy key without a team.","schema":{"type":"string"}}],"responses":{"200":{"description":"Successfully returned the current project settings.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EffectiveProjectConfig"}}}},"401":{"description":"Unauthorized – Missing or invalid token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden – The provided API key is not a management key, or a member requested a team they are not assigned to.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found – Project configuration or requested team not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal server error."}}}}}}
```

## Update Current Project Settings

> Updates one team's project configuration. Pass team\_id to select a team, or omit it to use the team assigned to the management API key. Default updates the global project configuration. Legacy keys without a team use Default. Restricted to project admins. Requires a management API key for authentication.<br>

```json
{"openapi":"3.1.0","info":{"title":"Cortecs Management API","version":"1.0.0"},"servers":[{"url":"https://api.cortecs.ai/v1"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT","description":"A management API key must be used as the Bearer token."}},"schemas":{"ProjectConfigUpdateRequest":{"type":"object","description":"Settings for one team. The optional team_id query parameter selects the team; when omitted, the team is derived from the authenticated API key, or Default for a legacy key without a team.\n","required":["inference_config"],"properties":{"inference_config":{"type":"object","description":"The inference configuration for the project.","properties":{"allowed_providers":{"type":"array","description":"List of allowed providers.","items":{"type":"string"}},"eu_native":{"type":"boolean","description":"Whether to consider only providers based and regulated within the EU. Even when false, all our endpoints are GDPR compliant."},"allow_quantization":{"type":"boolean","description":"Whether to allow quantized endpoints."},"max_tokens":{"type":"integer","description":"Maximum tokens allowed in output.","nullable":true},"preference":{"type":"string","description":"Preference for handling the request.","enum":["speed","cost","balanced"],"nullable":true},"allow_zero_data_retention":{"type":"boolean","description":"Whether to use only ZDR providers."},"enable_model_fallback":{"type":"boolean","description":"Whether to allow model fallback when a model is currently unavailable."}}},"allow_overwrite":{"type":"boolean","description":"Allow individual API calls to define their own inference configurations. If disabled, the selected team's settings will be enforced for all requests.\n"}}},"SuccessResponse":{"type":"object","properties":{"success":{"type":"boolean"}},"description":"Indicates whether the operation was successful."},"ErrorResponse":{"type":"object","properties":{"error":{"type":"string","description":"A human-readable error message."},"detail":{"type":"string","description":"A human-readable error detail message."}}}}},"paths":{"/manage/project-configs":{"put":{"summary":"Update Current Project Settings","tags":["Project Config"],"description":"Updates one team's project configuration. Pass team_id to select a team, or omit it to use the team assigned to the management API key. Default updates the global project configuration. Legacy keys without a team use Default. Restricted to project admins. Requires a management API key for authentication.\n","parameters":[{"name":"team_id","in":"query","required":false,"description":"Team override to update. Default updates the global project configuration. Omit to use the team assigned to the authenticated management API key, or Default for a legacy key without a team.","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectConfigUpdateRequest"}}}},"responses":{"200":{"description":"Project configuration updated successfully.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SuccessResponse"}}}},"400":{"description":"Bad Request – Invalid configuration or registry validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized – Missing or invalid token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden – Not a management key or user is not an admin.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found – Project configuration not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal server error."}}}}}}
```

## Remove Team Project Settings Override

> Removes a team's explicit settings so it uses the Default team configuration. The Default team configuration cannot be removed. Restricted to project admins. Requires a management API key for authentication.<br>

```json
{"openapi":"3.1.0","info":{"title":"Cortecs Management API","version":"1.0.0"},"servers":[{"url":"https://api.cortecs.ai/v1"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT","description":"A management API key must be used as the Bearer token."}},"schemas":{"SuccessResponse":{"type":"object","properties":{"success":{"type":"boolean"}},"description":"Indicates whether the operation was successful."}}},"paths":{"/manage/project-configs":{"delete":{"summary":"Remove Team Project Settings Override","tags":["Project Config"],"description":"Removes a team's explicit settings so it uses the Default team configuration. The Default team configuration cannot be removed. Restricted to project admins. Requires a management API key for authentication.\n","parameters":[{"name":"team_id","in":"query","required":false,"description":"Team override to remove. Default is the global project configuration and cannot be removed. Omit to use the team assigned to the authenticated management API key, or Default for a legacy key without a team.","schema":{"type":"string"}}],"responses":{"200":{"description":"Team override removed successfully.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SuccessResponse"}}}},"400":{"description":"Invalid team_id."},"401":{"description":"Unauthorized – Missing or invalid token."},"403":{"description":"Forbidden – Not a management key or user is not an admin."},"404":{"description":"Project configuration not found."}}}}}}
```

## List Budgets

> Lists budget rules for the authenticated project. Non-admin management key holders receive only their effective rules. For each period, a specific user rule overrides a selected-team per-user rule, which overrides the all-users rule. Project admins receive all stored rules, including overridden generic rules. Results can be filtered by scope, period, team\_id, user\_id, and key\_name.<br>

```json
{"openapi":"3.1.0","info":{"title":"Cortecs Management API","version":"1.0.0"},"servers":[{"url":"https://api.cortecs.ai/v1"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT","description":"A management API key must be used as the Bearer token."}},"schemas":{"BudgetsResponse":{"type":"object","required":["budgets"],"properties":{"budgets":{"type":"array","items":{"$ref":"#/components/schemas/Budget"}}}},"Budget":{"type":"object","required":["scope","period","amount","team_id","user_id","key_name"],"properties":{"scope":{"type":"string","enum":["project","team","user","api-key"],"description":"Budget scope."},"period":{"type":"string","enum":["daily","weekly","monthly"],"description":"Budget period."},"amount":{"type":"number","format":"double","minimum":0,"multipleOf":0.01,"description":"Budget amount in EUR, with up to two decimal places."},"team_id":{"type":["string","null"],"description":"Team name for team-scoped budgets. For user scope, a specific team means the budget is applied separately to every user in that team. `*` represents the default budget applied separately to each team."},"user_id":{"type":["string","null"],"description":"User identifier for user and api-key scoped budgets. `*` identifies an all-users rule, optionally within the selected team."},"key_name":{"type":["string","null"],"description":"API key name for api-key scoped budgets."}}},"ErrorResponse":{"type":"object","properties":{"error":{"type":"string","description":"A human-readable error message."},"detail":{"type":"string","description":"A human-readable error detail message."}}}}},"paths":{"/manage/budgets":{"get":{"summary":"List Budgets","tags":["Budgets"],"description":"Lists budget rules for the authenticated project. Non-admin management key holders receive only their effective rules. For each period, a specific user rule overrides a selected-team per-user rule, which overrides the all-users rule. Project admins receive all stored rules, including overridden generic rules. Results can be filtered by scope, period, team_id, user_id, and key_name.\n","parameters":[{"name":"scope","in":"query","required":false,"schema":{"type":"string","enum":["project","team","user","api-key"]}},{"name":"period","in":"query","required":false,"schema":{"type":"string","enum":["daily","weekly","monthly"]}},{"name":"user_id","in":"query","required":false,"schema":{"type":"string"}},{"name":"team_id","in":"query","required":false,"schema":{"type":"string"}},{"name":"key_name","in":"query","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"Successfully returned budgets.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BudgetsResponse"}}}},"400":{"description":"Invalid filter.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized - Missing or invalid token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden - The provided API key is not a management key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found - Project configuration not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal server error."}}}}}}
```

## Upsert Budget

> Creates or updates a budget period for the authenticated project. Restricted to project admins using a management API key. For user scope, a concrete team\_id with an omitted or \`\*\` user\_id creates a separate budget counter for every user in that team. PUT is also supported with the same body.<br>

```json
{"openapi":"3.1.0","info":{"title":"Cortecs Management API","version":"1.0.0"},"servers":[{"url":"https://api.cortecs.ai/v1"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT","description":"A management API key must be used as the Bearer token."}},"schemas":{"BudgetUpsertRequest":{"type":"object","required":["scope","period","amount"],"properties":{"scope":{"type":"string","enum":["project","team","user","api-key"]},"period":{"type":"string","enum":["daily","weekly","monthly"]},"team_id":{"type":["string","null"],"description":"Required for team scope. For user scope, select a specific team to apply the budget separately to every user in it; omit it or use `*` for all teams.","default":null},"user_id":{"type":["string","null"],"description":"Required for user and concrete api-key budgets. When user scope has a specific team_id, omit this field or use `*` because the rule applies to all users in that team. Must be null or omitted when key_name is '*' for api-key scope.","default":null},"key_name":{"type":["string","null"],"description":"Required for api-key scope. Use '*' with user_id null for the default per-api-key budget; otherwise user_id is required and the key must belong to that user.","default":null},"amount":{"type":"number","format":"double","minimum":0,"multipleOf":0.01,"description":"Budget amount in EUR, with up to two decimal places."}}},"SuccessResponse":{"type":"object","properties":{"success":{"type":"boolean"}},"description":"Indicates whether the operation was successful."},"ErrorResponse":{"type":"object","properties":{"error":{"type":"string","description":"A human-readable error message."},"detail":{"type":"string","description":"A human-readable error detail message."}}}}},"paths":{"/manage/budgets":{"post":{"summary":"Upsert Budget","tags":["Budgets"],"description":"Creates or updates a budget period for the authenticated project. Restricted to project admins using a management API key. For user scope, a concrete team_id with an omitted or `*` user_id creates a separate budget counter for every user in that team. PUT is also supported with the same body.\n","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BudgetUpsertRequest"}}}},"responses":{"200":{"description":"Budget saved successfully.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SuccessResponse"}}}},"400":{"description":"Invalid budget request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized - Missing or invalid token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden - Not a management key or user is not an admin.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found - Project configuration not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal server error."}}}}}}
```

## Upsert Budget

> Same behavior as POST /manage/budgets.

```json
{"openapi":"3.1.0","info":{"title":"Cortecs Management API","version":"1.0.0"},"servers":[{"url":"https://api.cortecs.ai/v1"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT","description":"A management API key must be used as the Bearer token."}},"schemas":{"BudgetUpsertRequest":{"type":"object","required":["scope","period","amount"],"properties":{"scope":{"type":"string","enum":["project","team","user","api-key"]},"period":{"type":"string","enum":["daily","weekly","monthly"]},"team_id":{"type":["string","null"],"description":"Required for team scope. For user scope, select a specific team to apply the budget separately to every user in it; omit it or use `*` for all teams.","default":null},"user_id":{"type":["string","null"],"description":"Required for user and concrete api-key budgets. When user scope has a specific team_id, omit this field or use `*` because the rule applies to all users in that team. Must be null or omitted when key_name is '*' for api-key scope.","default":null},"key_name":{"type":["string","null"],"description":"Required for api-key scope. Use '*' with user_id null for the default per-api-key budget; otherwise user_id is required and the key must belong to that user.","default":null},"amount":{"type":"number","format":"double","minimum":0,"multipleOf":0.01,"description":"Budget amount in EUR, with up to two decimal places."}}},"SuccessResponse":{"type":"object","properties":{"success":{"type":"boolean"}},"description":"Indicates whether the operation was successful."}}},"paths":{"/manage/budgets":{"put":{"summary":"Upsert Budget","tags":["Budgets"],"description":"Same behavior as POST /manage/budgets.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BudgetUpsertRequest"}}}},"responses":{"200":{"description":"Budget saved successfully.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SuccessResponse"}}}},"400":{"description":"Invalid budget request."},"401":{"description":"Unauthorized - Missing or invalid token."},"403":{"description":"Forbidden - Not a management key or user is not an admin."},"404":{"description":"Not Found - Project configuration not found."},"500":{"description":"Internal server error."}}}}}}
```

## Delete Budget

> Deletes a single budget period for the provided scope. Restricted to project admins using a management API key. The request body may be JSON, or the same fields may be provided as query parameters.<br>

```json
{"openapi":"3.1.0","info":{"title":"Cortecs Management API","version":"1.0.0"},"servers":[{"url":"https://api.cortecs.ai/v1"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT","description":"A management API key must be used as the Bearer token."}},"schemas":{"BudgetDeleteRequest":{"type":"object","required":["scope","period"],"properties":{"scope":{"type":"string","enum":["project","team","user","api-key"]},"period":{"type":"string","enum":["daily","weekly","monthly"]},"team_id":{"type":["string","null"],"description":"Required for team scope. For user scope, select a specific team to address its per-user budget; omit it or use `*` for all teams.","default":null},"user_id":{"type":["string","null"],"description":"Required for user and concrete api-key budgets. When user scope has a specific team_id, omit this field or use `*`. Must be null or omitted when key_name is '*' for api-key scope.","default":null},"key_name":{"type":["string","null"],"description":"Required for api-key scope. Use '*' with user_id null for the default per-api-key budget; otherwise user_id is required and the key must belong to that user.","default":null}}},"SuccessResponse":{"type":"object","properties":{"success":{"type":"boolean"}},"description":"Indicates whether the operation was successful."}}},"paths":{"/manage/budgets":{"delete":{"summary":"Delete Budget","tags":["Budgets"],"description":"Deletes a single budget period for the provided scope. Restricted to project admins using a management API key. The request body may be JSON, or the same fields may be provided as query parameters.\n","requestBody":{"required":false,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BudgetDeleteRequest"}}}},"responses":{"200":{"description":"Budget deleted successfully.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SuccessResponse"}}}},"400":{"description":"Invalid budget delete request."},"401":{"description":"Unauthorized - Missing or invalid token."},"403":{"description":"Forbidden - Not a management key or user is not an admin."},"404":{"description":"Not Found - Project configuration not found."},"500":{"description":"Internal server error."}}}}}}
```

## Retrieve Project Balance

> Retrieves the current balance information of the authenticated project. Requires a management API key belonging to a project admin.<br>

```json
{"openapi":"3.1.0","info":{"title":"Cortecs Management API","version":"1.0.0"},"servers":[{"url":"https://api.cortecs.ai/v1"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT","description":"A management API key must be used as the Bearer token."}},"schemas":{"UserBalance":{"type":"object","properties":{"current_balance":{"type":"number","format":"float","description":"The current balance of the user."},"currency":{"type":"string","description":"The currency in which the balance is expressed."}}},"ErrorResponse":{"type":"object","properties":{"error":{"type":"string","description":"A human-readable error message."},"detail":{"type":"string","description":"A human-readable error detail message."}}}}},"paths":{"/manage/balance":{"get":{"summary":"Retrieve Project Balance","tags":["Balance"],"description":"Retrieves the current balance information of the authenticated project. Requires a management API key belonging to a project admin.\n","responses":{"200":{"description":"Successfully retrieved project balance.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserBalance"}}}},"401":{"description":"Unauthorized – Missing or invalid token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden – Not a management key or user is not an admin.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found – Project configuration not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal server error."}}}}}}
```

## List Project Members

> Returns all members of the authenticated project. Requires a management API key belonging to a project admin.<br>

```json
{"openapi":"3.1.0","info":{"title":"Cortecs Management API","version":"1.0.0"},"servers":[{"url":"https://api.cortecs.ai/v1"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT","description":"A management API key must be used as the Bearer token."}},"schemas":{"ProjectMembersResponse":{"type":"object","required":["members"],"properties":{"members":{"type":"array","items":{"$ref":"#/components/schemas/ProjectMember"}}}},"ProjectMember":{"type":"object","required":["id","name","email","role"],"properties":{"id":{"type":"string","description":"The Auth0 user identifier of the project member."},"name":{"type":"string","description":"The display name of the project member."},"email":{"type":"string","format":"email","description":"The email address of the project member."},"role":{"type":["string","null"],"description":"The project role of the member."}}},"ErrorResponse":{"type":"object","properties":{"error":{"type":"string","description":"A human-readable error message."},"detail":{"type":"string","description":"A human-readable error detail message."}}}}},"paths":{"/manage/project-members":{"get":{"summary":"List Project Members","tags":["Project"],"description":"Returns all members of the authenticated project. Requires a management API key belonging to a project admin.\n","responses":{"200":{"description":"Successfully returned the project members.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectMembersResponse"}}}},"401":{"description":"Unauthorized - Missing or invalid token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden - Not a management key or user is not an admin.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found - Project configuration not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal server error."}}}}}}
```

## Invite Project Members

> Invites one or more email addresses to the authenticated project with either the member or admin role. Up to 50 unique addresses can be supplied in one request. Requires a management API key belonging to a project admin.<br>

```json
{"openapi":"3.1.0","info":{"title":"Cortecs Management API","version":"1.0.0"},"servers":[{"url":"https://api.cortecs.ai/v1"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT","description":"A management API key must be used as the Bearer token."}},"schemas":{"ProjectInvitationsRequest":{"type":"object","required":["emails"],"properties":{"emails":{"type":"array","minItems":1,"maxItems":50,"items":{"type":"string","format":"email"},"description":"Email addresses to invite. Duplicate addresses are ignored case-insensitively. Addresses that already belong to project members or have an existing invitation are reported as failures and are not invited.\n"},"role":{"type":"string","enum":["member","admin"],"default":"member","description":"Organization role granted to every invitee when the invitation is accepted."}}},"ProjectInvitationsResponse":{"type":"object","required":["invitations","failures"],"properties":{"invitations":{"type":"array","items":{"$ref":"#/components/schemas/ProjectInvitation"}},"failures":{"type":"array","items":{"$ref":"#/components/schemas/ProjectInvitationFailure"}}}},"ProjectInvitation":{"type":"object","required":["id","email"],"properties":{"id":{"type":"string","description":"The Auth0 invitation identifier."},"email":{"type":"string","format":"email"}}},"ProjectInvitationFailure":{"type":"object","required":["email","error"],"properties":{"email":{"type":"string","format":"email"},"error":{"type":"string"}}},"ErrorResponse":{"type":"object","properties":{"error":{"type":"string","description":"A human-readable error message."},"detail":{"type":"string","description":"A human-readable error detail message."}}}}},"paths":{"/manage/project-members":{"post":{"summary":"Invite Project Members","tags":["Project"],"description":"Invites one or more email addresses to the authenticated project with either the member or admin role. Up to 50 unique addresses can be supplied in one request. Requires a management API key belonging to a project admin.\n","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectInvitationsRequest"}}}},"responses":{"201":{"description":"All invitations were created successfully.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectInvitationsResponse"}}}},"207":{"description":"One or more invitations could not be created.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectInvitationsResponse"}}}},"400":{"description":"Missing or invalid email addresses.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized - Missing or invalid token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden - Not a management key or user is not an admin.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found - Project configuration not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal server error."}}}}}}
```

## List Teams

> Returns the named teams for the authenticated project, including the system-managed \`Default\` team. Requires a management API key belonging to a project admin.

```json
{"openapi":"3.1.0","info":{"title":"Cortecs Management API","version":"1.0.0"},"servers":[{"url":"https://api.cortecs.ai/v1"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT","description":"A management API key must be used as the Bearer token."}},"schemas":{"TeamsResponse":{"type":"object","required":["teams"],"properties":{"teams":{"type":"array","items":{"type":"string"}}}}}},"paths":{"/manage/teams":{"get":{"summary":"List Teams","tags":["Project"],"description":"Returns the named teams for the authenticated project, including the system-managed `Default` team. Requires a management API key belonging to a project admin.","responses":{"200":{"description":"Successfully returned the project teams.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TeamsResponse"}}}},"401":{"description":"Unauthorized - Missing or invalid token."},"403":{"description":"Forbidden - Not a management key or user is not an admin."},"404":{"description":"Project not found."},"500":{"description":"Internal server error."}}}}}}
```

## Create Team

> Adds a unique custom team name to the authenticated project. \`Default\` is reserved. Requires a management API key belonging to a project admin.

```json
{"openapi":"3.1.0","info":{"title":"Cortecs Management API","version":"1.0.0"},"servers":[{"url":"https://api.cortecs.ai/v1"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT","description":"A management API key must be used as the Bearer token."}},"schemas":{"TeamMutationRequest":{"type":"object","required":["team_id"],"properties":{"team_id":{"type":"string","minLength":1,"maxLength":50,"pattern":"^[A-Za-z0-9_\\s-]+$","description":"The team name. Only letters, numbers, hyphens, underscores, and whitespace are allowed. Leading and trailing whitespace is removed. `Default` is reserved for the system-managed fallback team."}}},"TeamResponse":{"type":"object","required":["team_id"],"properties":{"team_id":{"type":"string"}}}}},"paths":{"/manage/teams":{"post":{"summary":"Create Team","tags":["Project"],"description":"Adds a unique custom team name to the authenticated project. `Default` is reserved. Requires a management API key belonging to a project admin.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TeamMutationRequest"}}}},"responses":{"201":{"description":"Team created successfully.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TeamResponse"}}}},"400":{"description":"Invalid JSON or team name."},"401":{"description":"Unauthorized - Missing or invalid token."},"403":{"description":"Forbidden - Not a management key or user is not an admin."},"404":{"description":"Project not found."},"409":{"description":"A team with the same name already exists or the reserved `Default` name was used."},"500":{"description":"Internal server error."}}}}}}
```

## Delete Team

> Removes a custom team from the authenticated project. The system-managed \`Default\` team cannot be deleted. Members left without a team are assigned to \`Default\`. Requires a management API key belonging to a project admin.

```json
{"openapi":"3.1.0","info":{"title":"Cortecs Management API","version":"1.0.0"},"servers":[{"url":"https://api.cortecs.ai/v1"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT","description":"A management API key must be used as the Bearer token."}},"schemas":{"TeamMutationRequest":{"type":"object","required":["team_id"],"properties":{"team_id":{"type":"string","minLength":1,"maxLength":50,"pattern":"^[A-Za-z0-9_\\s-]+$","description":"The team name. Only letters, numbers, hyphens, underscores, and whitespace are allowed. Leading and trailing whitespace is removed. `Default` is reserved for the system-managed fallback team."}}}}},"paths":{"/manage/teams":{"delete":{"summary":"Delete Team","tags":["Project"],"description":"Removes a custom team from the authenticated project. The system-managed `Default` team cannot be deleted. Members left without a team are assigned to `Default`. Requires a management API key belonging to a project admin.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TeamMutationRequest"}}}},"responses":{"200":{"description":"Team deleted successfully.","content":{"application/json":{"schema":{"type":"object","required":["success","deleted"],"properties":{"success":{"type":"boolean","const":true},"deleted":{"type":"string"}}}}}},"400":{"description":"Invalid JSON or team name, or an attempt to delete `Default`."},"401":{"description":"Unauthorized - Missing or invalid token."},"403":{"description":"Forbidden - Not a management key or user is not an admin."},"404":{"description":"Team not found."},"500":{"description":"Internal server error."}}}}}}
```

## List Team Members

> Returns the project members assigned to a team. Requires a management API key belonging to a project admin.

```json
{"openapi":"3.1.0","info":{"title":"Cortecs Management API","version":"1.0.0"},"servers":[{"url":"https://api.cortecs.ai/v1"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT","description":"A management API key must be used as the Bearer token."}},"schemas":{"TeamMembersResponse":{"type":"object","required":["team_id","user_ids"],"properties":{"team_id":{"type":"string"},"user_ids":{"type":"array","items":{"type":"string"}}}}}},"paths":{"/manage/teams/members":{"get":{"summary":"List Team Members","tags":["Project"],"description":"Returns the project members assigned to a team. Requires a management API key belonging to a project admin.","parameters":[{"in":"query","name":"team_id","required":true,"schema":{"type":"string","minLength":1,"maxLength":50}}],"responses":{"200":{"description":"Team membership returned successfully.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TeamMembersResponse"}}}},"400":{"description":"Missing or invalid team name."},"401":{"description":"Unauthorized - Missing or invalid token."},"403":{"description":"Forbidden - Not a management key or user is not an admin."},"404":{"description":"Team not found."},"500":{"description":"Internal server error."}}}}}}
```

## Assign Team Members

> Assigns any number of project members to a team in one request. Existing assignments, including \`Default\`, are unchanged.

```json
{"openapi":"3.1.0","info":{"title":"Cortecs Management API","version":"1.0.0"},"servers":[{"url":"https://api.cortecs.ai/v1"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT","description":"A management API key must be used as the Bearer token."}},"schemas":{"TeamMembersMutationRequest":{"type":"object","required":["team_id","user_ids"],"properties":{"team_id":{"type":"string","minLength":1,"maxLength":50},"user_ids":{"type":"array","minItems":1,"uniqueItems":true,"items":{"type":"string"}}}}}},"paths":{"/manage/teams/members":{"post":{"summary":"Assign Team Members","tags":["Project"],"description":"Assigns any number of project members to a team in one request. Existing assignments, including `Default`, are unchanged.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TeamMembersMutationRequest"}}}},"responses":{"200":{"description":"Project members assigned successfully.","content":{"application/json":{"schema":{"type":"object","required":["team_id","assigned"],"properties":{"team_id":{"type":"string"},"assigned":{"type":"array","items":{"type":"string"}}}}}}},"400":{"description":"Invalid team, user IDs, or a user does not belong to this project."},"401":{"description":"Unauthorized - Missing or invalid token."},"403":{"description":"Forbidden - Not a management key or user is not an admin."},"404":{"description":"Team not found."},"500":{"description":"Internal server error."}}}}}}
```

## Unassign Team Members

> Unassigns any number of project members from a team in one request. Removing \`Default\` requires every affected member to belong to another team. Removing a custom team restores \`Default\` for members who would otherwise have no team.

```json
{"openapi":"3.1.0","info":{"title":"Cortecs Management API","version":"1.0.0"},"servers":[{"url":"https://api.cortecs.ai/v1"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT","description":"A management API key must be used as the Bearer token."}},"schemas":{"TeamMembersMutationRequest":{"type":"object","required":["team_id","user_ids"],"properties":{"team_id":{"type":"string","minLength":1,"maxLength":50},"user_ids":{"type":"array","minItems":1,"uniqueItems":true,"items":{"type":"string"}}}}}},"paths":{"/manage/teams/members":{"delete":{"summary":"Unassign Team Members","tags":["Project"],"description":"Unassigns any number of project members from a team in one request. Removing `Default` requires every affected member to belong to another team. Removing a custom team restores `Default` for members who would otherwise have no team.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TeamMembersMutationRequest"}}}},"responses":{"200":{"description":"Project members unassigned successfully.","content":{"application/json":{"schema":{"type":"object","required":["team_id","unassigned"],"properties":{"team_id":{"type":"string"},"unassigned":{"type":"array","items":{"type":"string"}}}}}}},"400":{"description":"Invalid team or user IDs, a user does not belong to this project, or removing `Default` would leave a member without a team."},"401":{"description":"Unauthorized - Missing or invalid token."},"403":{"description":"Forbidden - Not a management key or user is not an admin."},"404":{"description":"Team not found."},"500":{"description":"Internal server error."}}}}}}
```

## Usage / Accounting

> Returns aggregated token and cost metrics bucketed by time and optionally by\
> team, user, API key, model, or provider.\
> \
> \*\*Time range\*\*\
> \- \`from\` defaults to the start of the current calendar day (UTC).\
> \- \`until\` defaults to the current moment (UTC).\
> \
> \*\*Bucket sizes\*\* (\`bucket\` parameter)\
> \
> \| Value  | Meaning          |\
> \|--------|------------------|\
> \| \`1h\`   | 1 hour           |\
> \| \`1d\`   | 1 day (default)  |\
> \| \`1w\`   | 1 week           |\
> \| \`1M\`   | 1 month          |\
> \| \`1Y\`   | 1 year           |\
> \
> \*\*Grouping\*\* (\`group\_by\` parameter)\
> \
> Comma-separated list of fields to group by (in addition to the time bucket).\
> Valid fields: \`team\_id\`, \`user\_id\`, \`key\_name\`, \`model\`, \`provider\`.\
> \
> \| Example value            | GROUP BY columns                            |\
> \|--------------------------|---------------------------------------------|\
> \| \*(omitted)\*              | bucket only (default)                       |\
> \| \`team\_id\`                | bucket + \`team\_id\`                          |\
> \| \`team\_id,model\`          | bucket + \`team\_id\` + \`model\`                |\
> \| \`user\_id\`                | bucket + \`user\_id\`                          |\
> \| \`user\_id,key\_name\`       | bucket + \`user\_id\` + \`key\_name\`             |\
> \| \`user\_id,model\`          | bucket + \`user\_id\` + \`model\`                |\
> \| \`model\`                  | bucket + \`model\`                            |\
> \| \`provider\`               | bucket + \`provider\`                         |\
> \| \`user\_id,key\_name,model\` | bucket + \`user\_id\` + \`key\_name\` + \`model\`   |<br>

```json
{"openapi":"3.1.0","info":{"title":"Cortecs Management API","version":"1.0.0"},"servers":[{"url":"https://api.cortecs.ai/v1"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT","description":"A management API key must be used as the Bearer token."}},"schemas":{"UsageResponse":{"type":"object","required":["from","until","bucket","group_by","byok","rows"],"properties":{"from":{"type":"string","format":"date-time","description":"Resolved inclusive start of the queried range (UTC)."},"until":{"type":"string","format":"date-time","description":"Resolved exclusive end of the queried range (UTC)."},"bucket":{"type":"string","enum":["1h","1d","1w","1M","1Y"],"description":"The bucket interval used for aggregation."},"group_by":{"type":["string","null"],"description":"The comma-separated group_by fields that were applied.\n`null` when no grouping was requested.\n"},"team_id":{"type":["string","null"],"description":"The `team_id` filter that was applied, if any."},"user_id":{"type":["string","null"],"description":"The `user_id` filter that was applied, if any."},"key_name":{"type":["string","null"],"description":"The `key_name` filter that was applied, if any."},"model":{"type":["string","null"],"description":"The `model` filter that was applied, if any."},"provider":{"type":["string","null"],"description":"The `provider` filter that was applied, if any."},"byok":{"type":["boolean","null"],"description":"The BYOK filter that was applied. `null` means all usage."},"rows":{"type":"array","items":{"$ref":"#/components/schemas/UsageRow"},"description":"Aggregated rows ordered by `bucket_start ASC`, then `team_id ASC`, then `user_id ASC`,\nthen `key_name ASC`, then `model ASC`, then `provider ASC` (where applicable).\n"}}},"UsageRow":{"type":"object","required":["bucket_start","bucket_end","request_count","input_tokens","output_tokens","total_tokens","audio_duration","input_price","output_price","audio_price","cache_read_price","cache_write_price","speech_price","total_price","cache_read_tokens","cache_write_tokens","character_count"],"properties":{"bucket_start":{"type":"string","format":"date-time","description":"Inclusive start of the aggregation bucket (UTC)."},"bucket_end":{"type":"string","format":"date-time","description":"Exclusive end of the aggregation bucket (UTC).\nEqual to `bucket_start + bucket_interval`.\n"},"team_id":{"type":["string","null"],"description":"Present when `group_by` includes `team_id`.\n`null` for legacy requests that had no team context.\n"},"user_id":{"type":["string","null"],"description":"Present when `group_by` includes `user_id`.\n`null` for requests that had no user context.\n"},"user_email":{"type":["string","null"],"description":"Resolved email address of the user. Present when `group_by` includes\n`user_id` and the user could be found in the team.\n`null` if the user is not a current project member.\n"},"user_name":{"type":["string","null"],"description":"Resolved display name of the user. Present when `group_by` includes\n`user_id` and the user could be found in the team.\n`null` if the user has no name set or is not a current project member.\n"},"key_name":{"type":["string","null"],"description":"Present when `group_by` includes `key_name`.\n`null` for requests with no named API key.\n"},"model":{"type":["string","null"],"description":"Present when `group_by` includes `model`.\n`null` for requests where the model was not recorded.\n"},"provider":{"type":["string","null"],"description":"Present when `group_by` includes `provider`.\n`null` for requests where the provider was not recorded.\n"},"request_count":{"type":"integer","format":"int64","description":"Number of individual inference requests in this bucket."},"input_tokens":{"type":"integer","format":"int64","description":"Total prompt / input tokens consumed, including cache-read and cache-write tokens.\n"},"output_tokens":{"type":"integer","format":"int64","description":"Total completion / output tokens generated."},"total_tokens":{"type":"integer","format":"int64","description":"`input_tokens + output_tokens`"},"audio_duration":{"type":"number","format":"double","description":"Total audio duration in seconds (STT/TTS workloads)."},"input_price":{"type":"number","format":"double","description":"Aggregated cost for input tokens in EUR."},"output_price":{"type":"number","format":"double","description":"Aggregated cost for output tokens in EUR."},"audio_price":{"type":"number","format":"double","description":"Aggregated cost for audio processing in EUR."},"cache_read_price":{"type":"number","format":"double","description":"Aggregated cost for cache-read tokens in EUR."},"cache_write_price":{"type":"number","format":"double","description":"Aggregated cost for cache-write tokens in EUR."},"speech_price":{"type":"number","format":"double","description":"Aggregated cost for speech synthesis (TTS) in EUR."},"image_price":{"type":"number","format":"double","description":"Aggregated cost for images generated in EUR."},"total_price":{"type":"number","format":"double","description":"`input_price + output_price + audio_price + cache_read_price + cache_write_price + speech_price`\n"},"cache_read_tokens":{"type":"integer","format":"int64","description":"Tokens served from prompt cache (subset of `input_tokens`)."},"cache_write_tokens":{"type":"integer","format":"int64","description":"Tokens written to prompt cache (subset of `input_tokens`)."},"character_count":{"type":"integer","format":"int64","description":"Total character count across all requests in this bucket."}}},"ErrorResponse":{"type":"object","properties":{"error":{"type":"string","description":"A human-readable error message."},"detail":{"type":"string","description":"A human-readable error detail message."}}},"ValidationErrorResponse":{"type":"object","required":["detail"],"properties":{"detail":{"type":"array","items":{"type":"object","required":["loc","msg","type"],"properties":{"loc":{"type":"array","items":{"oneOf":[{"type":"string"},{"type":"integer"}]},"description":"Location of the offending field."},"msg":{"type":"string","description":"Validation error message."},"type":{"type":"string","description":"Pydantic error type code."}}}}}}}},"paths":{"/manage/usage":{"get":{"operationId":"getUsage","summary":"Usage / Accounting","tags":["Usage"],"description":"Returns aggregated token and cost metrics bucketed by time and optionally by\nteam, user, API key, model, or provider.\n\n**Time range**\n- `from` defaults to the start of the current calendar day (UTC).\n- `until` defaults to the current moment (UTC).\n\n**Bucket sizes** (`bucket` parameter)\n\n| Value  | Meaning          |\n|--------|------------------|\n| `1h`   | 1 hour           |\n| `1d`   | 1 day (default)  |\n| `1w`   | 1 week           |\n| `1M`   | 1 month          |\n| `1Y`   | 1 year           |\n\n**Grouping** (`group_by` parameter)\n\nComma-separated list of fields to group by (in addition to the time bucket).\nValid fields: `team_id`, `user_id`, `key_name`, `model`, `provider`.\n\n| Example value            | GROUP BY columns                            |\n|--------------------------|---------------------------------------------|\n| *(omitted)*              | bucket only (default)                       |\n| `team_id`                | bucket + `team_id`                          |\n| `team_id,model`          | bucket + `team_id` + `model`                |\n| `user_id`                | bucket + `user_id`                          |\n| `user_id,key_name`       | bucket + `user_id` + `key_name`             |\n| `user_id,model`          | bucket + `user_id` + `model`                |\n| `model`                  | bucket + `model`                            |\n| `provider`               | bucket + `provider`                         |\n| `user_id,key_name,model` | bucket + `user_id` + `key_name` + `model`   |\n","parameters":[{"name":"from","in":"query","required":false,"description":"Inclusive start of the time range (ISO 8601 / RFC 3339).\nDefaults to the start of the current UTC day.\n","schema":{"type":"string","format":"date-time"}},{"name":"until","in":"query","required":false,"description":"Exclusive end of the time range (ISO 8601 / RFC 3339).\nDefaults to the current UTC moment.\n","schema":{"type":"string","format":"date-time"}},{"name":"bucket","in":"query","required":false,"description":"TimescaleDB `time_bucket` interval for aggregation.","schema":{"type":"string","enum":["1h","1d","1w","1M","1Y"]}},{"name":"group_by","in":"query","required":false,"description":"Comma-separated list of fields to group by, in addition to the time bucket.\nValid fields: `team_id`, `user_id`, `key_name`, `model`, `provider`.\nExamples: `team_id`, `team_id,model`, `user_id,key_name,provider`.\n","schema":{"type":"string"}},{"name":"team_id","in":"query","required":false,"description":"Filter results to a single team.","schema":{"type":"string"}},{"name":"user_id","in":"query","required":false,"description":"Filter results to a single user.","schema":{"type":"string"}},{"name":"key_name","in":"query","required":false,"description":"Filter results to a specific API key name.\nOnly effective when `group_by` includes `key_name` or used as a standalone filter.\n","schema":{"type":"string"}},{"name":"model","in":"query","required":false,"description":"Filter results to a single model name.","schema":{"type":"string"}},{"name":"provider","in":"query","required":false,"description":"Filter results to a single provider.","schema":{"type":"string"}},{"name":"byok","in":"query","required":false,"description":"Filter by whether the request used the project's own provider key.\n`true` returns only BYOK usage, `false` excludes BYOK usage, and\n`null` or omission returns all usage.\n","schema":{"type":["boolean","null"]}}],"responses":{"200":{"description":"Usage rows matching the requested filters and grouping.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UsageResponse"}}}},"400":{"description":"Invalid query parameters.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Missing or invalid Bearer token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Token does not have permission to access this resource.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation error (missing required parameters or wrong type).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationErrorResponse"}}}},"500":{"description":"Internal server error (DB unreachable, query timeout, etc.).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}}}}
```

## List Notification Rules

> Lists the predefined notification rule catalog with settings for the authenticated project. Rules are returned even before settings have been persisted.

```json
{"openapi":"3.1.0","info":{"title":"Cortecs Management API","version":"1.0.0"},"servers":[{"url":"https://api.cortecs.ai/v1"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT","description":"A management API key must be used as the Bearer token."}},"schemas":{"NotificationRulesResponse":{"type":"object","required":["rules"],"properties":{"rules":{"type":"array","items":{"$ref":"#/components/schemas/NotificationRule"}}}},"NotificationRule":{"allOf":[{"$ref":"#/components/schemas/NotificationRuleEditable"},{"type":"object","required":["id","category","type","title","subtitle","status"],"properties":{"id":{"type":"string"},"category":{"type":"string"},"type":{"type":"string"},"operators":{"type":"array","minItems":1,"uniqueItems":true,"items":{"type":"string","enum":["less_than","less_than_or_equal","greater_than","greater_than_or_equal"]}},"title":{"type":"string"},"subtitle":{"type":"string"},"status":{"type":"string","enum":["pending","normal","triggered","failed"]}}}]},"NotificationRuleEditable":{"type":"object","additionalProperties":false,"required":["enabled","targets"],"properties":{"enabled":{"type":"boolean"},"operator":{"type":"string","description":"Selected comparison operator. Only accepted when the catalog rule defines operators.","enum":["less_than","less_than_or_equal","greater_than","greater_than_or_equal"]},"threshold":{"$ref":"#/components/schemas/NotificationThreshold","description":"Required for threshold-based catalog rules and omitted for custom rules."},"targets":{"type":"array","uniqueItems":true,"description":"At least one target is required when the rule is enabled.","items":{"$ref":"#/components/schemas/NotificationTarget"}}}},"NotificationThreshold":{"type":"number","format":"double","exclusiveMinimum":0,"multipleOf":0.01,"description":"Threshold amount in EUR, with up to two decimal places."},"NotificationTarget":{"oneOf":[{"$ref":"#/components/schemas/BillingContactNotificationTarget"},{"$ref":"#/components/schemas/ProjectMemberNotificationTarget"}],"discriminator":{"propertyName":"kind"}},"BillingContactNotificationTarget":{"type":"object","additionalProperties":false,"required":["kind"],"properties":{"kind":{"type":"string","const":"billing_contact"}}},"ProjectMemberNotificationTarget":{"type":"object","additionalProperties":false,"required":["kind","user_id"],"properties":{"kind":{"type":"string","const":"project_member"},"user_id":{"type":"string","minLength":1}}}}},"paths":{"/manage/notifications":{"get":{"summary":"List Notification Rules","tags":["Notifications"],"description":"Lists the predefined notification rule catalog with settings for the authenticated project. Rules are returned even before settings have been persisted.","responses":{"200":{"description":"Notification rules returned successfully.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotificationRulesResponse"}}}},"401":{"description":"Missing or invalid management API key."},"403":{"description":"The management API key owner is not a project admin."},"500":{"description":"Internal server error."}}}}}}
```

## GET /manage/notifications/{rule\_id}

> Retrieve Notification Rule

```json
{"openapi":"3.1.0","info":{"title":"Cortecs Management API","version":"1.0.0"},"servers":[{"url":"https://api.cortecs.ai/v1"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT","description":"A management API key must be used as the Bearer token."}},"schemas":{"NotificationRuleResponse":{"type":"object","required":["rule"],"properties":{"rule":{"$ref":"#/components/schemas/NotificationRule"}}},"NotificationRule":{"allOf":[{"$ref":"#/components/schemas/NotificationRuleEditable"},{"type":"object","required":["id","category","type","title","subtitle","status"],"properties":{"id":{"type":"string"},"category":{"type":"string"},"type":{"type":"string"},"operators":{"type":"array","minItems":1,"uniqueItems":true,"items":{"type":"string","enum":["less_than","less_than_or_equal","greater_than","greater_than_or_equal"]}},"title":{"type":"string"},"subtitle":{"type":"string"},"status":{"type":"string","enum":["pending","normal","triggered","failed"]}}}]},"NotificationRuleEditable":{"type":"object","additionalProperties":false,"required":["enabled","targets"],"properties":{"enabled":{"type":"boolean"},"operator":{"type":"string","description":"Selected comparison operator. Only accepted when the catalog rule defines operators.","enum":["less_than","less_than_or_equal","greater_than","greater_than_or_equal"]},"threshold":{"$ref":"#/components/schemas/NotificationThreshold","description":"Required for threshold-based catalog rules and omitted for custom rules."},"targets":{"type":"array","uniqueItems":true,"description":"At least one target is required when the rule is enabled.","items":{"$ref":"#/components/schemas/NotificationTarget"}}}},"NotificationThreshold":{"type":"number","format":"double","exclusiveMinimum":0,"multipleOf":0.01,"description":"Threshold amount in EUR, with up to two decimal places."},"NotificationTarget":{"oneOf":[{"$ref":"#/components/schemas/BillingContactNotificationTarget"},{"$ref":"#/components/schemas/ProjectMemberNotificationTarget"}],"discriminator":{"propertyName":"kind"}},"BillingContactNotificationTarget":{"type":"object","additionalProperties":false,"required":["kind"],"properties":{"kind":{"type":"string","const":"billing_contact"}}},"ProjectMemberNotificationTarget":{"type":"object","additionalProperties":false,"required":["kind","user_id"],"properties":{"kind":{"type":"string","const":"project_member"},"user_id":{"type":"string","minLength":1}}}}},"paths":{"/manage/notifications/{rule_id}":{"get":{"summary":"Retrieve Notification Rule","tags":["Notifications"],"responses":{"200":{"description":"Notification rule returned successfully.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotificationRuleResponse"}}}},"401":{"description":"Missing or invalid management API key."},"403":{"description":"The management API key owner is not a project admin."},"404":{"description":"Notification rule not found."},"500":{"description":"Internal server error."}}}}}}
```

## Configure Notification Rule

> Upserts project-specific settings for a notification rule from the catalog.

```json
{"openapi":"3.1.0","info":{"title":"Cortecs Management API","version":"1.0.0"},"servers":[{"url":"https://api.cortecs.ai/v1"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT","description":"A management API key must be used as the Bearer token."}},"schemas":{"NotificationRuleEditable":{"type":"object","additionalProperties":false,"required":["enabled","targets"],"properties":{"enabled":{"type":"boolean"},"operator":{"type":"string","description":"Selected comparison operator. Only accepted when the catalog rule defines operators.","enum":["less_than","less_than_or_equal","greater_than","greater_than_or_equal"]},"threshold":{"$ref":"#/components/schemas/NotificationThreshold","description":"Required for threshold-based catalog rules and omitted for custom rules."},"targets":{"type":"array","uniqueItems":true,"description":"At least one target is required when the rule is enabled.","items":{"$ref":"#/components/schemas/NotificationTarget"}}}},"NotificationThreshold":{"type":"number","format":"double","exclusiveMinimum":0,"multipleOf":0.01,"description":"Threshold amount in EUR, with up to two decimal places."},"NotificationTarget":{"oneOf":[{"$ref":"#/components/schemas/BillingContactNotificationTarget"},{"$ref":"#/components/schemas/ProjectMemberNotificationTarget"}],"discriminator":{"propertyName":"kind"}},"BillingContactNotificationTarget":{"type":"object","additionalProperties":false,"required":["kind"],"properties":{"kind":{"type":"string","const":"billing_contact"}}},"ProjectMemberNotificationTarget":{"type":"object","additionalProperties":false,"required":["kind","user_id"],"properties":{"kind":{"type":"string","const":"project_member"},"user_id":{"type":"string","minLength":1}}},"NotificationRuleResponse":{"type":"object","required":["rule"],"properties":{"rule":{"$ref":"#/components/schemas/NotificationRule"}}},"NotificationRule":{"allOf":[{"$ref":"#/components/schemas/NotificationRuleEditable"},{"type":"object","required":["id","category","type","title","subtitle","status"],"properties":{"id":{"type":"string"},"category":{"type":"string"},"type":{"type":"string"},"operators":{"type":"array","minItems":1,"uniqueItems":true,"items":{"type":"string","enum":["less_than","less_than_or_equal","greater_than","greater_than_or_equal"]}},"title":{"type":"string"},"subtitle":{"type":"string"},"status":{"type":"string","enum":["pending","normal","triggered","failed"]}}}]}}},"paths":{"/manage/notifications/{rule_id}":{"put":{"summary":"Configure Notification Rule","tags":["Notifications"],"description":"Upserts project-specific settings for a notification rule from the catalog.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotificationRuleEditable"}}}},"responses":{"200":{"description":"Notification rule updated successfully.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotificationRuleResponse"}}}},"400":{"description":"Invalid rule or recipient selection."},"401":{"description":"Missing or invalid management API key."},"403":{"description":"The management API key owner is not a project admin."},"404":{"description":"Notification rule not found."},"500":{"description":"Internal server error."}}}}}}
```
