From 2dd75a2d2fd371e1f54d87386787c668510558a6 Mon Sep 17 00:00:00 2001 From: Cassio Paes-Leme Date: Wed, 17 Jun 2026 14:11:13 -0500 Subject: [PATCH 1/8] docs: add Enterprise Data API reference and usage reports guide MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add documentation for the Docker Enterprise Data API, which provides programmatic access to organization usage reports (CSV) via api.docker.com/enterprise-data/v1/. - reference/api/enterprise-data/ — OpenAPI 3.0 spec and rendered API reference page for all four endpoints (list types, list reports, download, schema) - manuals/enterprise/reports/ — feature guide with authentication setup (PAT and OAT flows), curl walkthrough, pagination, and troubleshooting Co-Authored-By: Claude Opus 4.6 (1M context) --- content/manuals/enterprise/reports/_index.md | 257 +++++++++ .../reference/api/enterprise-data/api.yaml | 512 ++++++++++++++++++ .../reference/api/enterprise-data/index.md | 9 + 3 files changed, 778 insertions(+) create mode 100644 content/manuals/enterprise/reports/_index.md create mode 100644 content/reference/api/enterprise-data/api.yaml create mode 100644 content/reference/api/enterprise-data/index.md diff --git a/content/manuals/enterprise/reports/_index.md b/content/manuals/enterprise/reports/_index.md new file mode 100644 index 00000000000..839106a6b60 --- /dev/null +++ b/content/manuals/enterprise/reports/_index.md @@ -0,0 +1,257 @@ +--- +title: Usage reports +description: Learn how to retrieve enterprise usage reports for your Docker organization using the Reports API. +keywords: docker, enterprise, reports, usage, pulls, api, csv, personal access token, pat, organization access token, oat +weight: 20 +params: + sidebar: + group: Enterprise +--- + +Docker provides daily usage reports for organizations with a Docker Business +subscription. These reports contain pull activity data for your organization and +are available as CSV downloads through the Reports API. + +Reports are generated automatically. You use the API to list what is available +and download the files you need. + +## Prerequisites + +Before you begin, ensure you have: + +- A [Docker Business subscription](/subscription/core-subscription/details/) +- One of the following: + - Organization owner role + - A custom role that includes the **report-read** permission +- `curl` installed for making API requests +- `jq` installed for JSON parsing (optional, for formatting responses) + +## Authentication + +The Reports API accepts two authentication methods: Personal Access Tokens (PATs) +and Organization Access Tokens (OATs). Both are sent directly as Bearer tokens. + +### Option A: Personal Access Token + +Use a PAT from a user account that has the required role in the organization. + +1. [Create a personal access token](/security/access-tokens/) with + **Read-only** access or broader. + +2. Set your variables: + + ```bash + ORG="" + TOKEN="" + ``` + +3. Test the token: + + ```console + $ curl -s "https://api.docker.com/enterprise-data/v1/orgs/$ORG/reports" \ + -H "Authorization: Bearer $TOKEN" | jq . + ``` + +### Option B: Organization Access Token + +Use an OAT issued to the organization. OATs do not require a specific user +account. + +1. [Create an organization access token](/security/oat/) with + the appropriate permissions. + +2. Set your variables: + + ```bash + ORG="" + TOKEN="" + ``` + +3. Test the token: + + ```console + $ curl -s "https://api.docker.com/enterprise-data/v1/orgs/$ORG/reports" \ + -H "Authorization: Bearer $TOKEN" | jq . + ``` + +You use this `TOKEN` value in the `Authorization: Bearer` header for all +subsequent API calls. + +## List available report types + +Discover which report types and cadences are available for your organization. + +```console +$ curl -s "https://api.docker.com/enterprise-data/v1/orgs/$ORG/reports" \ + -H "Authorization: Bearer $TOKEN" | jq . +``` + +Example response: + +```json +{ + "report_types": [ + { + "ReportType": "usage_pulls", + "Cadence": "daily" + } + ] +} +``` + +Each entry represents a distinct combination of report type and cadence. Use +these values in subsequent calls. + +## List reports + +List available reports for a given type and cadence. Reports are returned in +reverse chronological order (most recent first). + +```console +$ curl -s "https://api.docker.com/enterprise-data/v1/orgs/$ORG/reports/usage_pulls/daily" \ + -H "Authorization: Bearer $TOKEN" | jq . +``` + +Example response: + +```json +{ + "reports": [ + { + "ReportType": "usage_pulls", + "Cadence": "daily", + "Date": "2026-06-16", + "SizeBytes": 48210, + "Key": "my-org/usage_pulls/daily/2026-06-16.csv" + }, + { + "ReportType": "usage_pulls", + "Cadence": "daily", + "Date": "2026-06-15", + "SizeBytes": 51003, + "Key": "my-org/usage_pulls/daily/2026-06-15.csv" + } + ], + "next_page_token": "" +} +``` + +### Pagination + +Results are paginated with a default page size of 30 and a maximum of 100. +Use the `page_size` and `page_token` query parameters to control pagination. + +```console +$ curl -s "https://api.docker.com/enterprise-data/v1/orgs/$ORG/reports/usage_pulls/daily?page_size=10" \ + -H "Authorization: Bearer $TOKEN" | jq . +``` + +When `next_page_token` is non-empty, pass it as `page_token` to fetch the next +page: + +```console +$ curl -s "https://api.docker.com/enterprise-data/v1/orgs/$ORG/reports/usage_pulls/daily?page_size=10&page_token=NEXT_TOKEN" \ + -H "Authorization: Bearer $TOKEN" | jq . +``` + +## Download a report + +Download the CSV file for a specific date. The API responds with a `302` +redirect to a pre-signed URL. With `curl -L`, the redirect is followed +automatically and the file is saved locally. + +```console +$ curl -L -o "usage_pulls_2026-06-16.csv" \ + "https://api.docker.com/enterprise-data/v1/orgs/$ORG/reports/usage_pulls/daily/2026-06-16/download" \ + -H "Authorization: Bearer $TOKEN" +``` + +The pre-signed download URL expires after 15 minutes. If the link expires, +call the endpoint again to get a fresh URL. + +### Download the latest report + +Combine the list and download steps to always fetch the most recent report: + +```bash +DATE=$( + curl -s "https://api.docker.com/enterprise-data/v1/orgs/$ORG/reports/usage_pulls/daily?page_size=1" \ + -H "Authorization: Bearer $TOKEN" \ + | jq -r '.reports[0].Date' +) + +curl -L -o "usage_pulls_${DATE}.csv" \ + "https://api.docker.com/enterprise-data/v1/orgs/$ORG/reports/usage_pulls/daily/${DATE}/download" \ + -H "Authorization: Bearer $TOKEN" +``` + +## Get report schema + +Retrieve the schema for a specific report date. The schema describes the columns +in the CSV file. + +```console +$ curl -s "https://api.docker.com/enterprise-data/v1/orgs/$ORG/reports/usage_pulls/daily/2026-06-16/schema" \ + -H "Authorization: Bearer $TOKEN" | jq . +``` + +Example response: + +```json +{ + "category": "usage_pulls", + "fields": [ + { + "name": "date", + "type": "string", + "description": "The date of the pull event (YYYY-MM-DD)." + }, + { + "name": "repository", + "type": "string", + "description": "The repository that was pulled." + }, + { + "name": "pull_count", + "type": "integer", + "description": "Number of pulls for the repository on this date." + } + ] +} +``` + +Use the schema endpoint to programmatically discover column names and types +before processing a report. + +## API reference + +| Endpoint | Description | +|---|---| +| `GET /enterprise-data/v1/orgs/{org}/reports` | List available report types | +| `GET /enterprise-data/v1/orgs/{org}/reports/{type}/{cadence}` | List reports with pagination | +| `GET /enterprise-data/v1/orgs/{org}/reports/{type}/{cadence}/{date}/download` | Download a report (302 redirect) | +| `GET /enterprise-data/v1/orgs/{org}/reports/{type}/{cadence}/{date}/schema` | Get report column schema | + +For the full API specification, see the +[Enterprise Data API reference](/reference/api/enterprise-data/). + +## Troubleshooting + +### 401 Unauthorized + +Your token is missing or invalid. Verify that you are passing the token as a +Bearer token in the `Authorization` header and that the token has not expired. + +### 403 Forbidden + +The authenticated user or token does not have permission to access reports for +this organization. Verify that: + +- The user has the organization owner role or a custom role with the + **report-read** permission. +- The organization has an active Docker Business subscription. + +### 404 Not Found + +The requested report type, cadence, or date does not exist. Use the list +endpoints to discover available reports before attempting a download. diff --git a/content/reference/api/enterprise-data/api.yaml b/content/reference/api/enterprise-data/api.yaml new file mode 100644 index 00000000000..437824826ac --- /dev/null +++ b/content/reference/api/enterprise-data/api.yaml @@ -0,0 +1,512 @@ +openapi: "3.0.3" + +info: + title: Docker Enterprise Data API + version: "1" + description: | + HTTP+JSON API for accessing Docker Enterprise customer usage reports. + + **Overview.** Docker Enterprise subscribers can retrieve structured usage + reports (CSV) covering product activity within their organization. Reports + are generated on a fixed cadence (for example, daily or weekly) and stored + for a retention period. This API provides programmatic access to discover + available report types, list generated reports, download report files, and + inspect report schemas. + + **Resource model.** An organization has one or more report types, each + produced at a specific cadence. Each report type + cadence combination + contains a series of dated report files (CSV). Every report file has an + accompanying JSON schema describing its columns. + + **Authentication.** All endpoints require a Bearer token: either a Personal + Access Token (PAT) or Organization Access Token (OAT). The caller must have + the `OrganizationReportRead` permission for the target organization. + + **Subscription.** An active Docker Enterprise subscription is required. + Requests from organizations without an eligible subscription receive a + `403 Forbidden` response. + + **Pagination.** The list-reports endpoint supports cursor-based pagination + via `page_size` and `page_token` query parameters. Reports are returned + most-recent-first. + contact: + name: Docker + url: https://www.docker.com/ + +tags: + - name: report-types + description: Discover available report type and cadence combinations. + - name: reports + description: List and download generated report files. + - name: schemas + description: Inspect the column schema for a specific report. + +servers: + - url: https://api.docker.com/enterprise-data/v1 + +security: + - bearerAuth: [] + +paths: + /orgs/{org_name}: + parameters: + - $ref: "#/components/parameters/OrgName" + get: + operationId: listReportTypes + tags: [report-types] + summary: List report types + description: > + Returns the distinct report type and cadence combinations available for + the organization. Each entry represents a category of reports that can + be listed and downloaded. + responses: + "200": + description: Array of report type and cadence combinations. + content: + application/json: + schema: + type: object + required: [report_types] + properties: + report_types: + type: array + items: + $ref: "#/components/schemas/ReportTypeInfo" + examples: + default: + value: + report_types: + - ReportType: usage_pulls + Cadence: daily + - ReportType: usage_pulls + Cadence: weekly + - ReportType: image_access + Cadence: daily + "401": + $ref: "#/components/responses/Unauthenticated" + "403": + $ref: "#/components/responses/Forbidden" + "404": + $ref: "#/components/responses/NotFound" + "500": + $ref: "#/components/responses/InternalError" + + /orgs/{org_name}/{type}/{cadence}: + parameters: + - $ref: "#/components/parameters/OrgName" + - $ref: "#/components/parameters/ReportType" + - $ref: "#/components/parameters/Cadence" + get: + operationId: listReports + tags: [reports] + summary: List reports + description: > + Returns a paginated list of available report files for the given report + type and cadence. Reports are sorted most-recent-first. Use `page_size` + and `page_token` query parameters for pagination. + parameters: + - name: page_size + in: query + required: false + description: > + Number of reports to return per page. Minimum 1, maximum 100. + Defaults to 30. + schema: + type: integer + format: int32 + minimum: 1 + maximum: 100 + default: 30 + examples: + default: + value: 30 + - name: page_token + in: query + required: false + description: > + Opaque cursor returned in `next_page_token` from a previous + response. Omit for the first page. + schema: + type: string + examples: + default: + value: "MjAyNi0wNi0wMQ" + responses: + "200": + description: Paginated list of reports. + content: + application/json: + schema: + type: object + required: [reports, next_page_token] + properties: + reports: + type: array + items: + $ref: "#/components/schemas/Report" + next_page_token: + type: string + description: > + Opaque cursor for fetching the next page. Empty string + when there are no more results. + examples: + default: + value: + reports: + - ReportType: usage_pulls + Cadence: daily + Date: "2026-06-16" + SizeBytes: 524288 + Key: my-org/usage_pulls/daily/2026-06-16.csv + - ReportType: usage_pulls + Cadence: daily + Date: "2026-06-15" + SizeBytes: 498712 + Key: my-org/usage_pulls/daily/2026-06-15.csv + next_page_token: "MjAyNi0wNS0xOA" + "400": + $ref: "#/components/responses/BadRequest" + "401": + $ref: "#/components/responses/Unauthenticated" + "403": + $ref: "#/components/responses/Forbidden" + "404": + $ref: "#/components/responses/NotFound" + "500": + $ref: "#/components/responses/InternalError" + + /orgs/{org_name}/{type}/{cadence}/{date}/download: + parameters: + - $ref: "#/components/parameters/OrgName" + - $ref: "#/components/parameters/ReportType" + - $ref: "#/components/parameters/Cadence" + - $ref: "#/components/parameters/Date" + get: + operationId: getReportDownloadURL + tags: [reports] + summary: Download report + description: > + Returns a `302 Found` redirect to a pre-signed S3 URL for the report + CSV file. The pre-signed URL expires after 15 minutes. Follow the + redirect to download the file directly from S3. + + + Most HTTP clients follow redirects automatically. If your client does + not, read the `Location` header from the 302 response and issue a + separate GET to that URL (no Authorization header needed for the + pre-signed URL). + responses: + "302": + description: > + Redirect to a pre-signed download URL. The `Location` header + contains the S3 pre-signed URL. The URL expires after 15 minutes. + headers: + Location: + description: Pre-signed S3 URL for the CSV report file. + schema: + type: string + format: uri + "400": + $ref: "#/components/responses/BadRequest" + "401": + $ref: "#/components/responses/Unauthenticated" + "403": + $ref: "#/components/responses/Forbidden" + "404": + $ref: "#/components/responses/NotFound" + "500": + $ref: "#/components/responses/InternalError" + + /orgs/{org_name}/{type}/{cadence}/{date}/schema: + parameters: + - $ref: "#/components/parameters/OrgName" + - $ref: "#/components/parameters/ReportType" + - $ref: "#/components/parameters/Cadence" + - $ref: "#/components/parameters/Date" + get: + operationId: getReportSchema + tags: [schemas] + summary: Get report schema + description: > + Returns the JSON schema for the specified report. The schema describes + the columns (fields) present in the CSV file, including each field's + name, data type, and description. Use this to understand the report + structure before or after downloading the CSV. + responses: + "200": + description: Report schema describing the CSV columns. + content: + application/json: + schema: + $ref: "#/components/schemas/ReportSchema" + examples: + default: + value: + category: usage_pulls + fields: + - name: event_date + type: date + description: Date the pull occurred (UTC). + - name: repository + type: string + description: Full repository name including namespace. + - name: tag + type: string + description: Image tag that was pulled. + - name: pull_count + type: integer + description: Number of pulls for this repository and tag on this date. + "400": + $ref: "#/components/responses/BadRequest" + "401": + $ref: "#/components/responses/Unauthenticated" + "403": + $ref: "#/components/responses/Forbidden" + "404": + $ref: "#/components/responses/NotFound" + "500": + $ref: "#/components/responses/InternalError" + +components: + securitySchemes: + bearerAuth: + type: http + scheme: bearer + description: | + A Personal Access Token (PAT) or Organization Access Token (OAT) passed + in the `Authorization: Bearer ` header. + + | Type | Format | Notes | + |------|--------|-------| + | Personal Access Token (PAT) | `dckr_pat_*` | Created under Account Settings. Must belong to an org member with the `OrganizationReportRead` permission. | + | Organization Access Token (OAT) | `dckr_oat_*` | Created under Organization Settings. Must be scoped to include report-read access. | + + The organization must have an active Docker Enterprise subscription. + + parameters: + OrgName: + name: org_name + in: path + required: true + description: Docker organization name (the billing entity). + schema: + type: string + pattern: "^[a-z0-9][a-z0-9_-]*$" + examples: + default: + value: my-org + + ReportType: + name: type + in: path + required: true + description: > + Report type identifier. Only lowercase alphanumeric characters, hyphens, + and underscores are allowed. + schema: + type: string + pattern: "^[a-z0-9][a-z0-9_-]*$" + examples: + default: + value: usage_pulls + + Cadence: + name: cadence + in: path + required: true + description: > + Report cadence (for example, `daily` or `weekly`). Only lowercase + alphanumeric characters, hyphens, and underscores are allowed. + schema: + type: string + pattern: "^[a-z0-9][a-z0-9_-]*$" + examples: + default: + value: daily + + Date: + name: date + in: path + required: true + description: > + Report date in `YYYY-MM-DD` format. Identifies a specific report + within the type and cadence. + schema: + type: string + format: date + examples: + default: + value: "2026-06-16" + + schemas: + ReportTypeInfo: + type: object + description: A distinct report type and cadence combination available for the organization. + required: [ReportType, Cadence] + properties: + ReportType: + type: string + description: Report type identifier (for example, `usage_pulls`). + examples: + - usage_pulls + Cadence: + type: string + description: Report generation cadence (for example, `daily`, `weekly`). + examples: + - daily + + Report: + type: object + description: Metadata for a single generated report file. + required: [ReportType, Cadence, Date, SizeBytes, Key] + properties: + ReportType: + type: string + description: Report type identifier. + examples: + - usage_pulls + Cadence: + type: string + description: Report generation cadence. + examples: + - daily + Date: + type: string + format: date + description: Report date in `YYYY-MM-DD` format. + examples: + - "2026-06-16" + SizeBytes: + type: integer + format: int64 + description: Size of the CSV file in bytes. + examples: + - 524288 + Key: + type: string + description: S3 object key for the report file. + examples: + - my-org/usage_pulls/daily/2026-06-16.csv + + ReportSchema: + type: object + description: Schema describing the columns present in a report CSV file. + required: [category, fields] + properties: + category: + type: string + description: Report category (matches the report type). + examples: + - usage_pulls + fields: + type: array + description: Ordered list of columns in the CSV file. + items: + $ref: "#/components/schemas/SchemaField" + + SchemaField: + type: object + description: A single column definition within a report schema. + required: [name, type, description] + properties: + name: + type: string + description: Column name as it appears in the CSV header row. + examples: + - event_date + type: + type: string + description: > + Data type of the column (for example, `string`, `integer`, `date`, + `timestamp`, `boolean`, `float`). + examples: + - string + description: + type: string + description: Human-readable description of what the column contains. + examples: + - Date the pull occurred (UTC). + + Error: + type: object + description: Error envelope returned on all non-2xx responses. + required: [error] + properties: + error: + type: string + description: Human-readable error message. + examples: + - "not found" + + responses: + BadRequest: + description: > + The request contains invalid parameters. Path segments must match + `^[a-z0-9][a-z0-9_-]*$` and dates must be valid `YYYY-MM-DD` values. + content: + application/json: + schema: + $ref: "#/components/schemas/Error" + examples: + invalid_segment: + summary: Invalid path segment + value: + error: "invalid input: type contains invalid characters" + invalid_date: + summary: Invalid date + value: + error: "invalid input: date must be a valid YYYY-MM-DD date" + invalid_page_token: + summary: Invalid page token + value: + error: "invalid input: invalid page token" + + Unauthenticated: + description: Missing or invalid Bearer token. + content: + application/json: + schema: + $ref: "#/components/schemas/Error" + examples: + default: + value: + error: unauthenticated + + Forbidden: + description: > + The caller lacks the `OrganizationReportRead` permission for this + organization, or the organization does not have an active Docker + Enterprise subscription. + content: + application/json: + schema: + $ref: "#/components/schemas/Error" + examples: + default: + value: + error: permission denied + + NotFound: + description: > + The requested resource does not exist. This may mean the organization + has no reports, the report type or cadence is unknown, or the specific + dated report has not been generated. + content: + application/json: + schema: + $ref: "#/components/schemas/Error" + examples: + default: + value: + error: not found + + InternalError: + description: Unexpected server error. + content: + application/json: + schema: + $ref: "#/components/schemas/Error" + examples: + default: + value: + error: internal error diff --git a/content/reference/api/enterprise-data/index.md b/content/reference/api/enterprise-data/index.md new file mode 100644 index 00000000000..9668a73d3dd --- /dev/null +++ b/content/reference/api/enterprise-data/index.md @@ -0,0 +1,9 @@ +--- +layout: api-reference +title: Docker Enterprise Data API +linkTitle: Enterprise Data +description: HTTP API reference for accessing Docker Enterprise customer usage reports programmatically. +keywords: docker enterprise, data export, usage reports, customer data, REST API, openapi +aliases: + - /admin/organization/usage-reports/api/ +--- From c8fe0a6383a1fecd4194cbf45aa63940ad8c7b2f Mon Sep 17 00:00:00 2001 From: Cassio Paes-Leme Date: Wed, 17 Jun 2026 14:20:31 -0500 Subject: [PATCH 2/8] fix: add missing /reports segment to OpenAPI spec paths The spec paths were missing the /reports segment, making them inconsistent with the curl examples in the guide and the actual REST handler routes. Co-Authored-By: Claude Opus 4.6 (1M context) --- content/reference/api/enterprise-data/api.yaml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/content/reference/api/enterprise-data/api.yaml b/content/reference/api/enterprise-data/api.yaml index 437824826ac..f76a37212dd 100644 --- a/content/reference/api/enterprise-data/api.yaml +++ b/content/reference/api/enterprise-data/api.yaml @@ -48,7 +48,7 @@ security: - bearerAuth: [] paths: - /orgs/{org_name}: + /orgs/{org_name}/reports: parameters: - $ref: "#/components/parameters/OrgName" get: @@ -91,7 +91,7 @@ paths: "500": $ref: "#/components/responses/InternalError" - /orgs/{org_name}/{type}/{cadence}: + /orgs/{org_name}/reports/{type}/{cadence}: parameters: - $ref: "#/components/parameters/OrgName" - $ref: "#/components/parameters/ReportType" @@ -175,7 +175,7 @@ paths: "500": $ref: "#/components/responses/InternalError" - /orgs/{org_name}/{type}/{cadence}/{date}/download: + /orgs/{org_name}/reports/{type}/{cadence}/{date}/download: parameters: - $ref: "#/components/parameters/OrgName" - $ref: "#/components/parameters/ReportType" @@ -217,7 +217,7 @@ paths: "500": $ref: "#/components/responses/InternalError" - /orgs/{org_name}/{type}/{cadence}/{date}/schema: + /orgs/{org_name}/reports/{type}/{cadence}/{date}/schema: parameters: - $ref: "#/components/parameters/OrgName" - $ref: "#/components/parameters/ReportType" From e983461bb73284f3d63641822c03383701b1c826 Mon Sep 17 00:00:00 2001 From: Cassio Paes-Leme Date: Wed, 17 Jun 2026 14:21:38 -0500 Subject: [PATCH 3/8] fix: guard download-latest script against empty reports Use jq's // empty alternative operator so an empty report list produces an empty string instead of the literal "null". Add a shell guard to exit early with a message. Co-Authored-By: Claude Opus 4.6 (1M context) --- content/manuals/enterprise/reports/_index.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/content/manuals/enterprise/reports/_index.md b/content/manuals/enterprise/reports/_index.md index 839106a6b60..77782071e3c 100644 --- a/content/manuals/enterprise/reports/_index.md +++ b/content/manuals/enterprise/reports/_index.md @@ -177,9 +177,14 @@ Combine the list and download steps to always fetch the most recent report: DATE=$( curl -s "https://api.docker.com/enterprise-data/v1/orgs/$ORG/reports/usage_pulls/daily?page_size=1" \ -H "Authorization: Bearer $TOKEN" \ - | jq -r '.reports[0].Date' + | jq -r '.reports[0].Date // empty' ) +if [ -z "$DATE" ]; then + echo "No reports available." + exit 1 +fi + curl -L -o "usage_pulls_${DATE}.csv" \ "https://api.docker.com/enterprise-data/v1/orgs/$ORG/reports/usage_pulls/daily/${DATE}/download" \ -H "Authorization: Bearer $TOKEN" From e335d3c532d1a97314dc3b921bb9b99fc68cab46 Mon Sep 17 00:00:00 2001 From: Cassio Paes-Leme Date: Wed, 17 Jun 2026 14:28:28 -0500 Subject: [PATCH 4/8] fix: match DVP/Hub API structure with Latest/Changelog/Deprecated Restructure the Enterprise Data API reference to match the sidebar pattern used by Docker Hub API and DVP Data API: - _index.md as hidden section index (build: render: never) - latest.md with layout: api pointing to latest.yaml - changelog.md with initial release entry - deprecated.md with empty deprecation table Co-Authored-By: Claude Opus 4.6 (1M context) --- .../reference/api/enterprise-data/_index.md | 5 ++++ .../api/enterprise-data/changelog.md | 22 ++++++++++++++++ .../api/enterprise-data/deprecated.md | 26 +++++++++++++++++++ .../reference/api/enterprise-data/index.md | 9 ------- .../reference/api/enterprise-data/latest.md | 7 +++++ .../enterprise-data/{api.yaml => latest.yaml} | 0 6 files changed, 60 insertions(+), 9 deletions(-) create mode 100644 content/reference/api/enterprise-data/_index.md create mode 100644 content/reference/api/enterprise-data/changelog.md create mode 100644 content/reference/api/enterprise-data/deprecated.md delete mode 100644 content/reference/api/enterprise-data/index.md create mode 100644 content/reference/api/enterprise-data/latest.md rename content/reference/api/enterprise-data/{api.yaml => latest.yaml} (100%) diff --git a/content/reference/api/enterprise-data/_index.md b/content/reference/api/enterprise-data/_index.md new file mode 100644 index 00000000000..ef1625f7873 --- /dev/null +++ b/content/reference/api/enterprise-data/_index.md @@ -0,0 +1,5 @@ +--- +title: Enterprise Data API +build: + render: never +--- diff --git a/content/reference/api/enterprise-data/changelog.md b/content/reference/api/enterprise-data/changelog.md new file mode 100644 index 00000000000..4564ec9c499 --- /dev/null +++ b/content/reference/api/enterprise-data/changelog.md @@ -0,0 +1,22 @@ +--- +description: Docker Enterprise Data API changelog +title: Docker Enterprise Data API changelog +linkTitle: Changelog +keywords: docker enterprise, data api, whats new, release notes, api, changelog +weight: 2 +toc_min: 1 +toc_max: 2 +--- + +Here you can learn about the latest changes, new features, bug fixes, and known +issues for the Docker Enterprise Data API. + +--- + +## 2026-06-17 + +### New + +- Initial release of the Enterprise Data API +- Usage reports endpoints: list report types, list reports, download, schema +- Authentication via Personal Access Tokens (PAT) and Organization Access Tokens (OAT) diff --git a/content/reference/api/enterprise-data/deprecated.md b/content/reference/api/enterprise-data/deprecated.md new file mode 100644 index 00000000000..4fd4227b05b --- /dev/null +++ b/content/reference/api/enterprise-data/deprecated.md @@ -0,0 +1,26 @@ +--- +description: Deprecated Docker Enterprise Data API endpoints +keywords: deprecated +title: Deprecated Docker Enterprise Data API endpoints +linkTitle: Deprecated +weight: 3 +--- + +This page provides an overview of endpoints that are deprecated in the Docker Enterprise Data API. + +## Endpoint deprecation policy + +As changes are made to the Docker Enterprise Data API there may be times when existing endpoints need to be removed or replaced with newer endpoints. Before an existing endpoint is removed it is labeled as "deprecated" within the documentation. After some time it may be removed. + +## Deprecated endpoints + +The following table provides an overview of the current status of deprecated endpoints: + +**Deprecated**: the endpoint is marked "deprecated" and should no longer be used. +The endpoint may be removed, disabled, or change behavior in a future release. + +**Removed**: the endpoint was removed, disabled, or hidden. + +--- + +No endpoints are currently deprecated. diff --git a/content/reference/api/enterprise-data/index.md b/content/reference/api/enterprise-data/index.md deleted file mode 100644 index 9668a73d3dd..00000000000 --- a/content/reference/api/enterprise-data/index.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -layout: api-reference -title: Docker Enterprise Data API -linkTitle: Enterprise Data -description: HTTP API reference for accessing Docker Enterprise customer usage reports programmatically. -keywords: docker enterprise, data export, usage reports, customer data, REST API, openapi -aliases: - - /admin/organization/usage-reports/api/ ---- diff --git a/content/reference/api/enterprise-data/latest.md b/content/reference/api/enterprise-data/latest.md new file mode 100644 index 00000000000..69828067932 --- /dev/null +++ b/content/reference/api/enterprise-data/latest.md @@ -0,0 +1,7 @@ +--- +layout: api +description: Reference documentation and OpenAPI specification for the Docker Enterprise Data API. +title: Docker Enterprise Data API reference +linkTitle: Latest +weight: 1 +--- diff --git a/content/reference/api/enterprise-data/api.yaml b/content/reference/api/enterprise-data/latest.yaml similarity index 100% rename from content/reference/api/enterprise-data/api.yaml rename to content/reference/api/enterprise-data/latest.yaml From 623c41da47d9a92f0ffd42d8600da10e61332924 Mon Sep 17 00:00:00 2001 From: Cassio Paes-Leme Date: Wed, 17 Jun 2026 15:11:10 -0500 Subject: [PATCH 5/8] fix: restrict docs to OAT-only auth, remove PAT references Per IAM team guidance, PATs cannot be scoped outside of registry. OATs are the only supported auth mechanism for the Reports API. Co-Authored-By: Claude Opus 4.6 (1M context) --- content/manuals/enterprise/reports/_index.md | 38 ++++--------------- .../reference/api/enterprise-data/latest.yaml | 16 ++++---- 2 files changed, 14 insertions(+), 40 deletions(-) diff --git a/content/manuals/enterprise/reports/_index.md b/content/manuals/enterprise/reports/_index.md index 77782071e3c..b53d091f3ab 100644 --- a/content/manuals/enterprise/reports/_index.md +++ b/content/manuals/enterprise/reports/_index.md @@ -1,7 +1,7 @@ --- title: Usage reports description: Learn how to retrieve enterprise usage reports for your Docker organization using the Reports API. -keywords: docker, enterprise, reports, usage, pulls, api, csv, personal access token, pat, organization access token, oat +keywords: docker, enterprise, reports, usage, pulls, api, csv, organization access token, oat weight: 20 params: sidebar: @@ -28,37 +28,13 @@ Before you begin, ensure you have: ## Authentication -The Reports API accepts two authentication methods: Personal Access Tokens (PATs) -and Organization Access Tokens (OATs). Both are sent directly as Bearer tokens. +The Reports API requires an Organization Access Token (OAT). OATs are +org-scoped tokens designed for machine-to-machine access, making them +suitable for automated report retrieval workflows. Personal Access Tokens +(PATs) are not supported. -### Option A: Personal Access Token - -Use a PAT from a user account that has the required role in the organization. - -1. [Create a personal access token](/security/access-tokens/) with - **Read-only** access or broader. - -2. Set your variables: - - ```bash - ORG="" - TOKEN="" - ``` - -3. Test the token: - - ```console - $ curl -s "https://api.docker.com/enterprise-data/v1/orgs/$ORG/reports" \ - -H "Authorization: Bearer $TOKEN" | jq . - ``` - -### Option B: Organization Access Token - -Use an OAT issued to the organization. OATs do not require a specific user -account. - -1. [Create an organization access token](/security/oat/) with - the appropriate permissions. +1. [Create an organization access token](/enterprise/security/access-tokens/) + and select the **Report Read** scope under Organization permissions. 2. Set your variables: diff --git a/content/reference/api/enterprise-data/latest.yaml b/content/reference/api/enterprise-data/latest.yaml index f76a37212dd..b9fffef0106 100644 --- a/content/reference/api/enterprise-data/latest.yaml +++ b/content/reference/api/enterprise-data/latest.yaml @@ -18,9 +18,9 @@ info: contains a series of dated report files (CSV). Every report file has an accompanying JSON schema describing its columns. - **Authentication.** All endpoints require a Bearer token: either a Personal - Access Token (PAT) or Organization Access Token (OAT). The caller must have - the `OrganizationReportRead` permission for the target organization. + **Authentication.** All endpoints require a Bearer token: an Organization + Access Token (OAT) with the `Report Read` scope. Personal Access Tokens + (PATs) are not supported. **Subscription.** An active Docker Enterprise subscription is required. Requests from organizations without an eligible subscription receive a @@ -273,13 +273,11 @@ components: type: http scheme: bearer description: | - A Personal Access Token (PAT) or Organization Access Token (OAT) passed - in the `Authorization: Bearer ` header. + An Organization Access Token (OAT) passed in the + `Authorization: Bearer ` header. The OAT must have the + **Report Read** scope selected under Organization permissions. - | Type | Format | Notes | - |------|--------|-------| - | Personal Access Token (PAT) | `dckr_pat_*` | Created under Account Settings. Must belong to an org member with the `OrganizationReportRead` permission. | - | Organization Access Token (OAT) | `dckr_oat_*` | Created under Organization Settings. Must be scoped to include report-read access. | + Personal Access Tokens (PATs) are not supported. The organization must have an active Docker Enterprise subscription. From 15defd539a3cc4aa507b3467102ab8b4e3022293 Mon Sep 17 00:00:00 2001 From: Cassio Paes-Leme Date: Wed, 17 Jun 2026 15:14:40 -0500 Subject: [PATCH 6/8] fix: add example Location header for 302 download response Co-Authored-By: Claude Opus 4.6 (1M context) --- content/reference/api/enterprise-data/latest.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/content/reference/api/enterprise-data/latest.yaml b/content/reference/api/enterprise-data/latest.yaml index b9fffef0106..37388b28737 100644 --- a/content/reference/api/enterprise-data/latest.yaml +++ b/content/reference/api/enterprise-data/latest.yaml @@ -206,6 +206,7 @@ paths: schema: type: string format: uri + example: "https://customer-exports-prod.s3.amazonaws.com/my-org/usage_pulls/daily/2026-06-16.csv?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Expires=900&..." "400": $ref: "#/components/responses/BadRequest" "401": From 85bdbb917a953a071089f41d39f76402bdf7ca68 Mon Sep 17 00:00:00 2001 From: Cassio Paes-Leme Date: Wed, 17 Jun 2026 15:18:35 -0500 Subject: [PATCH 7/8] fix: set contact URL to api.docker.com Co-Authored-By: Claude Opus 4.6 (1M context) --- content/reference/api/enterprise-data/latest.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/reference/api/enterprise-data/latest.yaml b/content/reference/api/enterprise-data/latest.yaml index 37388b28737..f31d4cd05ee 100644 --- a/content/reference/api/enterprise-data/latest.yaml +++ b/content/reference/api/enterprise-data/latest.yaml @@ -31,7 +31,7 @@ info: most-recent-first. contact: name: Docker - url: https://www.docker.com/ + url: https://api.docker.com/ tags: - name: report-types From ca54d60b0ca8db2579755ae54e0eb5ac20203d28 Mon Sep 17 00:00:00 2001 From: Cassio Paes-Leme Date: Wed, 17 Jun 2026 16:10:28 -0500 Subject: [PATCH 8/8] docs: fix broken links in enterprise reports page --- content/manuals/enterprise/reports/_index.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/content/manuals/enterprise/reports/_index.md b/content/manuals/enterprise/reports/_index.md index b53d091f3ab..9660dccdfbc 100644 --- a/content/manuals/enterprise/reports/_index.md +++ b/content/manuals/enterprise/reports/_index.md @@ -19,7 +19,7 @@ and download the files you need. Before you begin, ensure you have: -- A [Docker Business subscription](/subscription/core-subscription/details/) +- A [Docker Business subscription](/subscription/details/) - One of the following: - Organization owner role - A custom role that includes the **report-read** permission @@ -214,7 +214,7 @@ before processing a report. | `GET /enterprise-data/v1/orgs/{org}/reports/{type}/{cadence}/{date}/schema` | Get report column schema | For the full API specification, see the -[Enterprise Data API reference](/reference/api/enterprise-data/). +[Enterprise Data API reference](/reference/api/enterprise-data/latest/). ## Troubleshooting