diff --git a/api-reference/admin-api/get-custom-tag-usage-analytics.mdx b/api-reference/admin-api/get-custom-tag-usage-analytics.mdx new file mode 100644 index 00000000..e93b5cc2 --- /dev/null +++ b/api-reference/admin-api/get-custom-tag-usage-analytics.mdx @@ -0,0 +1,51 @@ +--- +openapi: get /v2/admin/analytics/custom-tags +title: "Get custom tag usage analytics" +--- + +## Date range + +Specify the reporting window using the required `start_date` and `end_date` parameters in ISO 8601 date format (e.g., `2026-05-01`). The maximum date range is 366 days. + +## Aggregation + +The optional `aggregate_by` parameter controls how usage is grouped: + +| **Value** | **Description** | +|:---|:---| +| `period` (default) | Returns total usage per custom tag over the entire date range | +| `day` | Returns usage per custom tag broken down by individual day | + +Use `period` when you need a summary for billing or reporting. Use `day` when you need to analyze usage trends over time. + +## Response structure + +The response contains a `custom_tag_usage_report` object with the following fields: + +| **Field** | **Description** | +|:---|:---| +| `aggregate_by` | The aggregation method used (`period` or `day`) | +| `start_date` | Start of the reporting period (ISO 8601 datetime) | +| `end_date` | End of the reporting period (ISO 8601 datetime) | +| `next_page` | Integer cursor for the next page of results. `null` if there are no further pages | +| `usage` | Array of usage entries, one per custom tag | + +Each entry in `usage` includes: +- `custom_tag`: the tag identifier +- `breakdown`: character counts split by service type + +### Usage breakdown + +| **Field** | **Description** | +|:---|:---| +| `total_characters` | Combined character usage across all services | +| `text_translation_characters` | Characters used for text translation | +| `text_improvement_characters` | Characters used for text improvement (rephrasing) | + + +Custom tag data is supported only for text translation. Support for other request types will be added in a future update. + + +## Pagination + +Results are paginated. If the response includes a non-null `next_page` value, pass it as the `page` parameter in your next request to retrieve the following page. Continue until `next_page` is `null`. diff --git a/api-reference/admin-api/get-usage-analytics.mdx b/api-reference/admin-api/get-usage-analytics.mdx index e844752e..d4027f86 100644 --- a/api-reference/admin-api/get-usage-analytics.mdx +++ b/api-reference/admin-api/get-usage-analytics.mdx @@ -3,3 +3,35 @@ openapi: get /v2/admin/analytics title: "Get usage analytics" --- +## Date range + +Specify the reporting window using the required `start_date` and `end_date` parameters. Both support the following formats (all in UTC): + +| **Format** | **Example** | +|:---|:---| +| `YYYY-MM-DD` | `2025-09-29` | +| `YYYY-MM-DDTHH:MM:SS` | `2025-09-29T14:30:00` | + +The maximum date range is 366 days. + +## Grouping + +The optional `group_by` parameter controls how results are organized: + +| **Value** | **Description** | +|:---|:---| +| (default) | Returns total usage for the entire date range across all API keys | +| `key` | Groups usage by individual API key, showing totals for each key over the date range | +| `key_and_day` | Groups usage by both API key and day, providing daily breakdowns per key | + +## Response structure + +All responses include a breakdown of usage by service type: + +| **Field** | **Description** | +|:---|:---| +| `total_characters` | Combined character usage across all services | +| `text_translation_characters` | Characters used for text translation | +| `document_translation_characters` | Characters used for document translation | +| `text_improvement_characters` | Characters used for text improvement (rephrasing) | +| `speech_to_text_minutes` | Duration of speech-to-text usage in minutes | diff --git a/api-reference/admin-api/organization-usage-analytics.mdx b/api-reference/admin-api/organization-usage-analytics.mdx index 869f5f4d..7ea9514e 100644 --- a/api-reference/admin-api/organization-usage-analytics.mdx +++ b/api-reference/admin-api/organization-usage-analytics.mdx @@ -1,54 +1,38 @@ --- -title: "Accessing organization usage analytics" +title: "Accessing usage analytics" description: "Learn how admins can retrieve and analyze usage data across their organization." public: true --- -The Admin API allows admins to retrieve detailed usage statistics for their organization through the [Get usage analytics](/api-reference/admin-api/get-usage-analytics) endpoint. +The Admin API provides two endpoints for monitoring usage across your organization: -This analytics functionality enables you to: -* Track character usage across your entire organization -* Monitor usage by individual API keys -* Analyze usage patterns over time -* Generate reports for specific date ranges -* Break down usage by service type (text translation, document translation, text improvement) +- [Get usage analytics](/api-reference/admin-api/get-usage-analytics): retrieves total usage statistics, optionally grouped by API key or day +- [Get custom tag usage analytics](/api-reference/admin-api/get-custom-tag-usage-analytics): retrieves usage statistics broken down by custom tags -## Usage statistics endpoint +## Organization usage -The analytics endpoint provides detailed usage information for a specified date range with flexible grouping options. +The [Get usage analytics](/api-reference/admin-api/get-usage-analytics) endpoint returns usage statistics for a specified date range with flexible grouping options. It covers all services: text translation, document translation, text improvement, and speech-to-text. -### Date range queries +## Custom tag usage -Retrieve usage statistics by specifying a start and end date. Both `start_date` and `end_date` parameters are required and support the following formats (all in UTC): -* `YYYY-MM-DD` - Simple date format (e.g., `2025-09-29`) -* `YYYY-MM-DDTHH:MM:SS` - Full datetime format (e.g., `2025-09-29T14:30:00`) +Custom tags are an optional dimension for breaking down usage. If your organization wants to track consumption by team, project, or any other category, you can attach a single tag to individual API requests using the `X-DeepL-Reporting-Tag` header. Each request accepts one tag. -The maximum date range is 366 days. +The [Get custom tag usage analytics](/api-reference/admin-api/get-custom-tag-usage-analytics) endpoint only returns usage from tagged requests. Untagged requests are not included, so the results will reflect a subset of your organization's total usage unless all API requests are tagged. -### Grouping options +```bash +curl --request POST \ + --url https://api.deepl.com/v2/translate \ + --header 'Authorization: DeepL-Auth-Key YOUR_AUTH_KEY' \ + --header 'X-DeepL-Reporting-Tag: your-custom-tag' \ + --header 'Content-Type: application/json' \ + --data '{ + "text": ["Hello, world!"], + "target_lang": "DE" + }' +``` -The optional `group_by` parameter allows you to organize usage data in different ways: - -* **No grouping** (default): Returns total usage for the entire date range across all API keys -* **`key`**: Groups usage by individual API key, showing totals for each key over the entire date range -* **`key_and_day`**: Groups usage by both API key and day, providing daily breakdowns for each key - -### Usage breakdown - -All responses include a breakdown of usage by service type: -* **Total characters**: Combined usage across all services -* **Text translation characters**: Characters used for text translation -* **Document translation characters**: Characters used for document translation -* **Text improvement characters**: Characters used for text improvement (rephrasing) -* **Speech-to-text minutes**: Duration of speech-to-text usage in minutes - -## Use cases - -The account-level analytics endpoint is particularly useful for: - -* **Cost monitoring**: Track usage to stay within budget limits and forecast costs -* **Resource allocation**: Identify which teams or projects (represented by API keys) are using the most resources -* **Usage trends**: Analyze daily or weekly usage patterns to optimize resource planning -* **Compliance and auditing**: Generate detailed usage reports for compliance requirements -* **Performance tracking**: Monitor adoption and usage of different DeepL services within your organization + +Custom tag data is currently supported for text translation. Support for additional request types will be added in a future update. + +Once tags are in place, query [Get custom tag usage analytics](/api-reference/admin-api/get-custom-tag-usage-analytics) to retrieve usage broken down by tag. diff --git a/api-reference/openapi.json b/api-reference/openapi.json index 8eb9b5ad..b2deb4df 100644 --- a/api-reference/openapi.json +++ b/api-reference/openapi.json @@ -8,7 +8,7 @@ "name": "DeepL - Contact us", "url": "https://www.deepl.com/contact-us" }, - "version": "3.9.0" + "version": "3.10.0" }, "externalDocs": { "description": "DeepL Pro - Plans and pricing", @@ -64,6 +64,10 @@ { "name": "VoiceTranslateJob", "description": "**Alpha.** Async voice translation jobs. This API may change without notice." + }, + { + "name": "AdminApi", + "description": "Endpoints for organization administrators to manage API keys and retrieve usage analytics." } ], "x-hideTryItPanel": true, @@ -232,6 +236,183 @@ ] } }, + "/v2/admin/analytics/custom-tags": { + "get": { + "tags": [ + "AdminApi" + ], + "summary": "Get custom tag usage statistics as an admin", + "operationId": "adminGetCustomTagAnalytics", + "description": "Retrieve usage statistics broken down by custom tags within a specified date range.\nOptionally aggregate results by day or over the entire period.\nResults are paginated; use the `page` parameter with the `next_page` value from\na previous response to retrieve subsequent pages.", + "parameters": [ + { + "name": "start_date", + "in": "query", + "required": true, + "description": "Start date for the usage report (ISO 8601 date format).", + "schema": { + "type": "string", + "format": "date" + }, + "example": "2026-05-17" + }, + { + "name": "end_date", + "in": "query", + "required": true, + "description": "End date for the usage report (ISO 8601 date format).", + "schema": { + "type": "string", + "format": "date" + }, + "example": "2026-05-18" + }, + { + "name": "aggregate_by", + "in": "query", + "required": false, + "description": "Optional parameter to control aggregation of usage statistics. Possible values:\n * `period` - Aggregate usage over the entire date range (default)\n * `day` - Group usage by individual day", + "schema": { + "type": "string", + "enum": [ + "period", + "day" + ], + "default": "period" + }, + "example": "day" + }, + { + "name": "page", + "in": "query", + "required": false, + "description": "Page number for pagination. Use the integer value returned in `next_page` from\na previous response to retrieve the next page of results.", + "schema": { + "type": "integer" + }, + "example": 2 + } + ], + "responses": { + "200": { + "description": "The custom tag usage statistics for the specified date range.", + "headers": { + "X-Trace-ID": { + "$ref": "#/components/headers/X-Trace-ID" + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CustomTagUsageReport" + }, + "examples": { + "aggregateByPeriod": { + "summary": "Usage report aggregated over the full period", + "value": { + "custom_tag_usage_report": { + "aggregate_by": "period", + "start_date": "2026-05-03T00:00:00", + "end_date": "2026-05-05T00:00:00", + "next_page": null, + "usage": [ + { + "custom_tag": "example-custom-tag", + "breakdown": { + "total_characters": 380, + "text_translation_characters": 380, + "text_improvement_characters": 0 + } + }, + { + "custom_tag": "example-custom-tag-2", + "breakdown": { + "total_characters": 475, + "text_translation_characters": 475, + "text_improvement_characters": 0 + } + } + ] + } + } + }, + "aggregateByDay": { + "summary": "Usage report aggregated by day", + "value": { + "custom_tag_usage_report": { + "aggregate_by": "day", + "start_date": "2026-05-17T00:00:00", + "end_date": "2026-05-18T00:00:00", + "next_page": 2, + "usage": [ + { + "custom_tag": "example-custom-tag", + "breakdown": { + "total_characters": 190, + "text_translation_characters": 190, + "text_improvement_characters": 0 + } + } + ] + } + } + } + } + } + } + }, + "400": { + "description": "Bad request. Please check error message and your parameters.", + "headers": { + "X-Trace-ID": { + "$ref": "#/components/headers/X-Trace-ID" + } + }, + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "message": { + "type": "string", + "description": "Error message describing the issue." + } + } + }, + "examples": { + "dateRangeExceeded": { + "summary": "Date range exceeds maximum allowed", + "value": { + "message": "Bad request. Reason: Date range cannot exceed 366 days" + } + }, + "invalidAggregateBy": { + "summary": "Invalid aggregate_by parameter value", + "value": { + "message": "Value for 'aggregate_by' not supported. Allowed: '', 'period', 'day'." + } + } + } + } + } + }, + "403": { + "$ref": "#/components/responses/Forbidden" + }, + "404": { + "$ref": "#/components/responses/NotFound" + }, + "500": { + "$ref": "#/components/responses/InternalServerError" + } + }, + "security": [ + { + "auth_header": [] + } + ] + } + }, "/v2/admin/developer-keys": { "post": { "tags": [ @@ -7625,6 +7806,90 @@ } } }, + "CustomTagUsageReport": { + "type": "object", + "description": "The response for admin custom tag usage statistics.", + "properties": { + "custom_tag_usage_report": { + "$ref": "#/components/schemas/CustomTagUsageReportData" + } + } + }, + "CustomTagUsageReportData": { + "type": "object", + "description": "Contains the detailed custom tag usage statistics for the specified date range.", + "properties": { + "aggregate_by": { + "type": "string", + "description": "The aggregation method used.", + "enum": [ + "period", + "day" + ], + "example": "period" + }, + "start_date": { + "type": "string", + "format": "date-time", + "description": "Start date of the usage report period.", + "example": "2026-05-03T00:00:00" + }, + "end_date": { + "type": "string", + "format": "date-time", + "description": "End date of the usage report period.", + "example": "2026-05-05T00:00:00" + }, + "next_page": { + "type": "integer", + "nullable": true, + "description": "Cursor for the next page of results. Null if there are no further pages.", + "example": 2 + }, + "usage": { + "type": "array", + "description": "List of custom tag usage entries.", + "items": { + "$ref": "#/components/schemas/CustomTagUsageItem" + } + } + } + }, + "CustomTagUsageItem": { + "type": "object", + "description": "Usage statistics for a specific custom tag.", + "properties": { + "custom_tag": { + "type": "string", + "description": "The custom tag identifier.", + "example": "example-custom-tag" + }, + "breakdown": { + "$ref": "#/components/schemas/CustomTagBreakdown" + } + } + }, + "CustomTagBreakdown": { + "type": "object", + "description": "Breakdown of character usage by category for a custom tag.", + "properties": { + "total_characters": { + "type": "integer", + "description": "Total number of characters used.", + "example": 380 + }, + "text_translation_characters": { + "type": "integer", + "description": "Number of characters used for text translation.", + "example": 380 + }, + "text_improvement_characters": { + "type": "integer", + "description": "Number of characters used for text improvement.", + "example": 0 + } + } + }, "ErrorResponse": { "type": "object", "required": [ diff --git a/api-reference/openapi.yaml b/api-reference/openapi.yaml index 675f7446..107b8561 100644 --- a/api-reference/openapi.yaml +++ b/api-reference/openapi.yaml @@ -9,7 +9,7 @@ info: contact: name: DeepL - Contact us url: https://www.deepl.com/contact-us - version: 3.9.0 + version: 3.10.0 externalDocs: description: DeepL Pro - Plans and pricing url: https://www.deepl.com/pro#developer @@ -87,6 +87,8 @@ tags: Use a two-step flow: first request a streaming URL via REST, then establish a WebSocket connection for streaming audio and receiving transcriptions. - name: VoiceTranslateJob description: "**Alpha.** Async voice translation jobs. This API may change without notice." +- name: AdminApi + description: Endpoints for organization administrators to manage API keys and retrieve usage analytics. x-hideTryItPanel: true x-codeSamples: false paths: @@ -205,6 +207,131 @@ paths: $ref: '#/components/responses/InternalServerError' security: - auth_header: [ ] + /v2/admin/analytics/custom-tags: + get: + tags: + - AdminApi + summary: Get custom tag usage statistics as an admin + operationId: adminGetCustomTagAnalytics + description: |- + Retrieve usage statistics broken down by custom tags within a specified date range. + Optionally aggregate results by day or over the entire period. + Results are paginated; use the `page` parameter with the `next_page` value from + a previous response to retrieve subsequent pages. + parameters: + - name: start_date + in: query + required: true + description: Start date for the usage report (ISO 8601 date format). + schema: + type: string + format: date + example: "2026-05-17" + - name: end_date + in: query + required: true + description: End date for the usage report (ISO 8601 date format). + schema: + type: string + format: date + example: "2026-05-18" + - name: aggregate_by + in: query + required: false + description: |- + Optional parameter to control aggregation of usage statistics. Possible values: + * `period` - Aggregate usage over the entire date range (default) + * `day` - Group usage by individual day + schema: + type: string + enum: + - period + - day + default: period + example: "day" + - name: page + in: query + required: false + description: |- + Page number for pagination. Use the integer value returned in `next_page` from + a previous response to retrieve the next page of results. + schema: + type: integer + example: 2 + responses: + 200: + description: The custom tag usage statistics for the specified date range. + headers: + X-Trace-ID: + $ref: '#/components/headers/X-Trace-ID' + content: + application/json: + schema: + $ref: '#/components/schemas/CustomTagUsageReport' + examples: + aggregateByPeriod: + summary: Usage report aggregated over the full period + value: + custom_tag_usage_report: + aggregate_by: "period" + start_date: "2026-05-03T00:00:00" + end_date: "2026-05-05T00:00:00" + next_page: null + usage: + - custom_tag: "example-custom-tag" + breakdown: + total_characters: 380 + text_translation_characters: 380 + text_improvement_characters: 0 + - custom_tag: "example-custom-tag-2" + breakdown: + total_characters: 475 + text_translation_characters: 475 + text_improvement_characters: 0 + aggregateByDay: + summary: Usage report aggregated by day + value: + custom_tag_usage_report: + aggregate_by: "day" + start_date: "2026-05-17T00:00:00" + end_date: "2026-05-18T00:00:00" + next_page: 2 + usage: + - custom_tag: "example-custom-tag" + breakdown: + total_characters: 190 + text_translation_characters: 190 + text_improvement_characters: 0 + 400: + description: Bad request. Please check error message and your parameters. + headers: + X-Trace-ID: + $ref: '#/components/headers/X-Trace-ID' + content: + application/json: + schema: + type: object + properties: + message: + type: string + description: Error message describing the issue. + examples: + dateRangeExceeded: + summary: Date range exceeds maximum allowed + value: + message: "Bad request. Reason: Date range cannot exceed 366 days" + invalidAggregateBy: + summary: Invalid aggregate_by parameter value + value: + message: "Value for 'aggregate_by' not supported. Allowed: '', 'period', 'day'." + 403: + $ref: '#/components/responses/Forbidden' + 404: + $ref: '#/components/responses/NotFound' + 500: + $ref: '#/components/responses/InternalServerError' + security: + - auth_header: [ ] /v2/admin/developer-keys: post: tags: @@ -5711,6 +5838,69 @@ components: example: "DeepL API Key Prod" usage: $ref: '#/components/schemas/UsageBreakdown' + CustomTagUsageReport: + type: object + description: The response for admin custom tag usage statistics. + properties: + custom_tag_usage_report: + $ref: '#/components/schemas/CustomTagUsageReportData' + CustomTagUsageReportData: + type: object + description: Contains the detailed custom tag usage statistics for the specified date range. + properties: + aggregate_by: + type: string + description: The aggregation method used. + enum: + - period + - day + example: "period" + start_date: + type: string + format: date-time + description: Start date of the usage report period. + example: "2026-05-03T00:00:00" + end_date: + type: string + format: date-time + description: End date of the usage report period. + example: "2026-05-05T00:00:00" + next_page: + type: integer + nullable: true + description: Cursor for the next page of results. Null if there are no further pages. + example: 2 + usage: + type: array + description: List of custom tag usage entries. + items: + $ref: '#/components/schemas/CustomTagUsageItem' + CustomTagUsageItem: + type: object + description: Usage statistics for a specific custom tag. + properties: + custom_tag: + type: string + description: The custom tag identifier. + example: "example-custom-tag" + breakdown: + $ref: '#/components/schemas/CustomTagBreakdown' + CustomTagBreakdown: + type: object + description: Breakdown of character usage by category for a custom tag. + properties: + total_characters: + type: integer + description: Total number of characters used. + example: 380 + text_translation_characters: + type: integer + description: Number of characters used for text translation. + example: 380 + text_improvement_characters: + type: integer + description: Number of characters used for text improvement. + example: 0 ErrorResponse: type: object required: diff --git a/docs.json b/docs.json index cf0925d2..ab042cb6 100644 --- a/docs.json +++ b/docs.json @@ -303,7 +303,8 @@ "group": "Organization Usage Analytics", "pages": [ "api-reference/admin-api/organization-usage-analytics", - "api-reference/admin-api/get-usage-analytics" + "api-reference/admin-api/get-usage-analytics", + "api-reference/admin-api/get-custom-tag-usage-analytics" ], "drilldown": false } diff --git a/docs/resources/roadmap-and-release-notes.mdx b/docs/resources/roadmap-and-release-notes.mdx index 0480de87..895b8f2a 100644 --- a/docs/resources/roadmap-and-release-notes.mdx +++ b/docs/resources/roadmap-and-release-notes.mdx @@ -7,10 +7,15 @@ rss: true - Support for uploading, modifying, and deleting [translation memories](/docs/learning-how-tos/examples-and-guides/how-to-use-translation-memories) via API - API key-level endpoint restrictions -- Usage reporting by custom tag and language pair +- Usage reporting by language pair +## May 20 - Custom Tag Usage Analytics +- Added [`GET /v2/admin/analytics/custom-tags`](/api-reference/admin-api/organization-usage-analytics) to the Admin API, allowing admins to retrieve usage statistics broken down by custom tags. +- Supports `aggregate_by=period` (default) to aggregate usage over the full date range, or `aggregate_by=day` for daily breakdowns. +- Results are paginated; use the `next_page` integer from the response as the `page` parameter in subsequent requests. + ## May 18 - v3/languages General Availability - [`GET /v3/languages`](/api-reference/languages/retrieve-supported-languages-by-resource) and [`GET /v3/languages/resources`](/api-reference/languages/retrieve-resources) are now generally available. - **`/v2/languages` and `/v2/glossary-language-pairs` are now deprecated.** Migrate to `/v3/languages`. See the [migration guide](/api-reference/languages/migrate-from-v2-languages) for details.