From eb40c4989ca2dc7c9355287627e903ac915c183b Mon Sep 17 00:00:00 2001 From: "chris.lee" Date: Wed, 24 Jun 2026 14:40:16 -0400 Subject: [PATCH 1/3] docs(usage-api): add Usage API reference under the Admin API section Vendors the Usage API OpenAPI spec (GET /v1/usage/summary, POST /v1/usage/time-series) into src/openapi/usage-api and wires it into the Admin API nav section as "Usage API Endpoints", mirroring how the Admin API ("Apps API") endpoints are surfaced. The spec is vendored locally for now because usage-api.alchemy.com is not yet serving its /openapi.yaml publicly; once it is, this can switch to a content/remote-specs.json entry (like admin-api) for auto-sync. Co-Authored-By: Claude Opus 4.8 --- content/docs.yml | 3 + src/openapi/usage-api/usage-api.yaml | 472 +++++++++++++++++++++++++++ 2 files changed, 475 insertions(+) create mode 100644 src/openapi/usage-api/usage-api.yaml diff --git a/content/docs.yml b/content/docs.yml index 3a10e5d9d..cc40a2f18 100644 --- a/content/docs.yml +++ b/content/docs.yml @@ -125,6 +125,9 @@ navigation: - api: Admin API Endpoints api-name: admin-api flattened: true + - api: Usage API Endpoints + api-name: usage-api + flattened: true - section: Activity Log hidden: true contents: diff --git a/src/openapi/usage-api/usage-api.yaml b/src/openapi/usage-api/usage-api.yaml new file mode 100644 index 000000000..01ac497fe --- /dev/null +++ b/src/openapi/usage-api/usage-api.yaml @@ -0,0 +1,472 @@ +openapi: 3.0.0 +components: + examples: {} + headers: {} + parameters: {} + requestBodies: {} + responses: {} + schemas: + UsageAmount: + properties: + amount: + type: string + description: Product-native amount in the associated MoneyUnit. + unit: + type: string + description: Billing service MoneyUnit enum name. + example: ALCHEMY_COMPUTE_UNIT + usd: + type: string + description: Estimated fiat equivalent in USD. + required: + - amount + - unit + type: object + additionalProperties: false + UsageLimitUnit: + enum: + - CU + - USD + type: string + UsageLimit: + properties: + unit: + $ref: "#/components/schemas/UsageLimitUnit" + limit: + type: string + used: + type: string + remaining: + type: string + percentUsed: + type: number + format: double + required: + - unit + - limit + - used + type: object + additionalProperties: false + UsageUpdateCadence.Minute: + enum: + - minute + type: string + UsageFreshness: + properties: + dataThrough: + type: string + containsPartialToday: + type: boolean + updateCadence: + $ref: "#/components/schemas/UsageUpdateCadence.Minute" + required: + - dataThrough + - containsPartialToday + - updateCadence + type: object + additionalProperties: false + UsageSummaryResponse: + properties: + billingPeriod: + properties: + endTime: + type: string + startTime: + type: string + required: + - endTime + - startTime + type: object + totals: + properties: + last30Days: + $ref: "#/components/schemas/UsageAmount" + last7Days: + $ref: "#/components/schemas/UsageAmount" + monthToDate: + $ref: "#/components/schemas/UsageAmount" + required: + - last30Days + - last7Days + - monthToDate + type: object + usageLimit: + $ref: "#/components/schemas/UsageLimit" + freshness: + $ref: "#/components/schemas/UsageFreshness" + required: + - billingPeriod + - totals + - freshness + type: object + additionalProperties: false + StandardResponse_UsageSummaryResponse_: + description: |- + Standard API response wrapper. + All API responses are wrapped in this format for consistency. + properties: + data: + $ref: "#/components/schemas/UsageSummaryResponse" + required: + - data + type: object + additionalProperties: false + ErrorCode: + enum: + - 500 + - 400 + - 401 + - 403 + - 404 + - 200 + - 201 + - 1000 + type: number + ErrorContext: + description: |- + Additional context information for error responses. + Contains key-value pairs with details about what caused the error. + properties: {} + type: object + additionalProperties: {} + ErrorResponse: + properties: + message: + type: string + code: + anyOf: + - type: integer + format: int32 + - $ref: "#/components/schemas/ErrorCode" + status: + type: integer + format: int32 + context: + $ref: "#/components/schemas/ErrorContext" + description: Additional information about the error specific to the endpoint. + required: + - message + - code + - status + type: object + additionalProperties: false + StandardErrorResponse: + description: |- + Standard error response wrapper. + All error responses are wrapped in this format for consistency. + properties: + error: + $ref: "#/components/schemas/ErrorResponse" + required: + - error + type: object + additionalProperties: false + UsageGranularity: + enum: + - hour + - day + type: string + UsageMetric: + enum: + - amount + - usd + type: string + UsageTimeSeriesFilters: + properties: + appIds: + items: + type: string + type: array + networks: + items: + type: string + type: array + methods: + items: + type: string + type: array + requestTypes: + items: + type: string + type: array + type: object + additionalProperties: false + UsageGroupBy: + enum: + - requestType + - app + - network + - method + type: string + UsageTimeSeriesQuery: + properties: + startTime: + type: string + endTime: + type: string + granularity: + $ref: "#/components/schemas/UsageGranularity" + products: + items: + type: string + type: array + metrics: + items: + $ref: "#/components/schemas/UsageMetric" + type: array + filters: + $ref: "#/components/schemas/UsageTimeSeriesFilters" + groupBy: + items: + $ref: "#/components/schemas/UsageGroupBy" + type: array + required: + - startTime + - endTime + - granularity + - products + - metrics + - groupBy + type: object + additionalProperties: false + UsagePointDimensions: + properties: + requestType: + type: string + app: + type: string + network: + type: string + method: + type: string + type: object + additionalProperties: false + UsageTimeSeriesPoint: + properties: + startTime: + type: string + endTime: + type: string + isPartial: + type: boolean + dimensions: + $ref: "#/components/schemas/UsagePointDimensions" + amount: + type: string + unit: + type: string + usd: + type: string + required: + - startTime + - endTime + - isPartial + - dimensions + type: object + additionalProperties: false + UsageTimeSeriesResponse: + properties: + query: + $ref: "#/components/schemas/UsageTimeSeriesQuery" + freshness: + $ref: "#/components/schemas/UsageFreshness" + data: + items: + $ref: "#/components/schemas/UsageTimeSeriesPoint" + type: array + required: + - query + - freshness + - data + type: object + additionalProperties: false + StandardResponse_UsageTimeSeriesResponse_: + description: |- + Standard API response wrapper. + All API responses are wrapped in this format for consistency. + properties: + data: + $ref: "#/components/schemas/UsageTimeSeriesResponse" + required: + - data + type: object + additionalProperties: false + UsageTimeSeriesRequest: + properties: + startTime: + type: string + endTime: + type: string + description: Defaults to now when omitted. + products: + items: + type: string + type: array + description: BillingProduct enum names. + example: + - SUPERNODE_CU + metrics: + items: + $ref: "#/components/schemas/UsageMetric" + type: array + filters: + $ref: "#/components/schemas/UsageTimeSeriesFilters" + groupBy: + items: + $ref: "#/components/schemas/UsageGroupBy" + type: array + granularity: + $ref: "#/components/schemas/UsageGranularity" + required: + - startTime + type: object + additionalProperties: false + securitySchemes: + user_auth: + type: http + scheme: bearer +info: + title: Usage API + version: 1.0.0 + description: Alchemy API to inspect usage for your team + contact: {} +paths: + /v1/usage/summary: + get: + operationId: GetUsageSummary + responses: + "200": + description: Retrieved usage summary successfully + content: + application/json: + schema: + $ref: "#/components/schemas/StandardResponse_UsageSummaryResponse_" + "401": + description: Requires authentication + content: + application/json: + schema: + $ref: "#/components/schemas/StandardErrorResponse" + examples: + Example 1: + value: + error: + code: 401 + status: 401 + message: Requires authentication + "403": + description: Forbidden + content: + application/json: + schema: + $ref: "#/components/schemas/StandardErrorResponse" + examples: + Example 1: + value: + error: + code: 403 + status: 403 + message: Forbidden + "404": + description: Not found + content: + application/json: + schema: + $ref: "#/components/schemas/StandardErrorResponse" + examples: + Example 1: + value: + error: + code: 404 + status: 404 + message: Path not found + description: + Retrieves usage totals for the current billing period and recent + rolling windows. + summary: Get usage summary + security: + - user_auth: + - viewer + - developer + - admin + parameters: [] + /v1/usage/time-series: + post: + operationId: GetUsageTimeSeries + responses: + "200": + description: Retrieved usage time series successfully + content: + application/json: + schema: + $ref: "#/components/schemas/StandardResponse_UsageTimeSeriesResponse_" + "400": + description: Invalid input + content: + application/json: + schema: + $ref: "#/components/schemas/StandardErrorResponse" + examples: + Example 1: + value: + error: + code: 400 + status: 400 + message: Invalid input + "401": + description: Requires authentication + content: + application/json: + schema: + $ref: "#/components/schemas/StandardErrorResponse" + examples: + Example 1: + value: + error: + code: 401 + status: 401 + message: Requires authentication + "403": + description: Forbidden + content: + application/json: + schema: + $ref: "#/components/schemas/StandardErrorResponse" + examples: + Example 1: + value: + error: + code: 403 + status: 403 + message: Forbidden + "404": + description: Not found + content: + application/json: + schema: + $ref: "#/components/schemas/StandardErrorResponse" + examples: + Example 1: + value: + error: + code: 404 + status: 404 + message: Path not found + description: + Retrieves daily usage over time with optional product, metric, + filter, and dimension controls. + summary: Get usage time series + security: + - user_auth: + - viewer + - developer + - admin + parameters: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: "#/components/schemas/UsageTimeSeriesRequest" +servers: + - url: https://usage-api.alchemy.com From 60b74dfc86d113715be7104fab3094109731b2d8 Mon Sep 17 00:00:00 2001 From: "chris.lee" Date: Wed, 24 Jun 2026 14:44:50 -0400 Subject: [PATCH 2/3] docs(usage-api): use admin-api.alchemy.com as the server The Usage API is path-routed (`/v1/usage*`) through the Apps API ALB at admin-api.alchemy.com (see terraform aws_alb_listener_rule.admin_api_usage), not served directly at usage-api.alchemy.com. Match the public host (and the sibling admin-api spec's server) so the reference shows the correct base URL. Co-Authored-By: Claude Opus 4.8 --- src/openapi/usage-api/usage-api.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/openapi/usage-api/usage-api.yaml b/src/openapi/usage-api/usage-api.yaml index 01ac497fe..f25c3f6a7 100644 --- a/src/openapi/usage-api/usage-api.yaml +++ b/src/openapi/usage-api/usage-api.yaml @@ -469,4 +469,4 @@ paths: schema: $ref: "#/components/schemas/UsageTimeSeriesRequest" servers: - - url: https://usage-api.alchemy.com + - url: https://admin-api.alchemy.com From 03ea226521d9792bea35fca22b2cc91c81b507f4 Mon Sep 17 00:00:00 2001 From: "chris.lee" Date: Wed, 24 Jun 2026 18:17:56 -0400 Subject: [PATCH 3/3] docs(usage-api): use remote spec instead of vendored copy MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Per the sync-docs-as-code pattern, register the Usage API spec as a remote entry (served at https://admin-api.alchemy.com/v1/usage/openapi.json) and remove the vendored src/openapi/usage-api/ copy. content/docs.yml already references api-name: usage-api; the remote entry now supplies it. Blocked: merge only after the dashboard change serving the spec at that URL deploys (OMGWINNING/dashboard#8050) — CI lints the live URL. Co-Authored-By: Claude Opus 4.8 --- content/remote-specs.json | 4 + src/openapi/usage-api/usage-api.yaml | 472 --------------------------- 2 files changed, 4 insertions(+), 472 deletions(-) delete mode 100644 src/openapi/usage-api/usage-api.yaml diff --git a/content/remote-specs.json b/content/remote-specs.json index 001001da2..b67b56294 100644 --- a/content/remote-specs.json +++ b/content/remote-specs.json @@ -3,6 +3,10 @@ "name": "admin-api", "url": "https://admin-api.alchemy.com/openapi.yaml" }, + { + "name": "usage-api", + "url": "https://admin-api.alchemy.com/v1/usage/openapi.json" + }, { "name": "wallet-api", "url": "https://txe-api-specs.docs.alchemy.com/wallet/openrpc.yaml", diff --git a/src/openapi/usage-api/usage-api.yaml b/src/openapi/usage-api/usage-api.yaml deleted file mode 100644 index f25c3f6a7..000000000 --- a/src/openapi/usage-api/usage-api.yaml +++ /dev/null @@ -1,472 +0,0 @@ -openapi: 3.0.0 -components: - examples: {} - headers: {} - parameters: {} - requestBodies: {} - responses: {} - schemas: - UsageAmount: - properties: - amount: - type: string - description: Product-native amount in the associated MoneyUnit. - unit: - type: string - description: Billing service MoneyUnit enum name. - example: ALCHEMY_COMPUTE_UNIT - usd: - type: string - description: Estimated fiat equivalent in USD. - required: - - amount - - unit - type: object - additionalProperties: false - UsageLimitUnit: - enum: - - CU - - USD - type: string - UsageLimit: - properties: - unit: - $ref: "#/components/schemas/UsageLimitUnit" - limit: - type: string - used: - type: string - remaining: - type: string - percentUsed: - type: number - format: double - required: - - unit - - limit - - used - type: object - additionalProperties: false - UsageUpdateCadence.Minute: - enum: - - minute - type: string - UsageFreshness: - properties: - dataThrough: - type: string - containsPartialToday: - type: boolean - updateCadence: - $ref: "#/components/schemas/UsageUpdateCadence.Minute" - required: - - dataThrough - - containsPartialToday - - updateCadence - type: object - additionalProperties: false - UsageSummaryResponse: - properties: - billingPeriod: - properties: - endTime: - type: string - startTime: - type: string - required: - - endTime - - startTime - type: object - totals: - properties: - last30Days: - $ref: "#/components/schemas/UsageAmount" - last7Days: - $ref: "#/components/schemas/UsageAmount" - monthToDate: - $ref: "#/components/schemas/UsageAmount" - required: - - last30Days - - last7Days - - monthToDate - type: object - usageLimit: - $ref: "#/components/schemas/UsageLimit" - freshness: - $ref: "#/components/schemas/UsageFreshness" - required: - - billingPeriod - - totals - - freshness - type: object - additionalProperties: false - StandardResponse_UsageSummaryResponse_: - description: |- - Standard API response wrapper. - All API responses are wrapped in this format for consistency. - properties: - data: - $ref: "#/components/schemas/UsageSummaryResponse" - required: - - data - type: object - additionalProperties: false - ErrorCode: - enum: - - 500 - - 400 - - 401 - - 403 - - 404 - - 200 - - 201 - - 1000 - type: number - ErrorContext: - description: |- - Additional context information for error responses. - Contains key-value pairs with details about what caused the error. - properties: {} - type: object - additionalProperties: {} - ErrorResponse: - properties: - message: - type: string - code: - anyOf: - - type: integer - format: int32 - - $ref: "#/components/schemas/ErrorCode" - status: - type: integer - format: int32 - context: - $ref: "#/components/schemas/ErrorContext" - description: Additional information about the error specific to the endpoint. - required: - - message - - code - - status - type: object - additionalProperties: false - StandardErrorResponse: - description: |- - Standard error response wrapper. - All error responses are wrapped in this format for consistency. - properties: - error: - $ref: "#/components/schemas/ErrorResponse" - required: - - error - type: object - additionalProperties: false - UsageGranularity: - enum: - - hour - - day - type: string - UsageMetric: - enum: - - amount - - usd - type: string - UsageTimeSeriesFilters: - properties: - appIds: - items: - type: string - type: array - networks: - items: - type: string - type: array - methods: - items: - type: string - type: array - requestTypes: - items: - type: string - type: array - type: object - additionalProperties: false - UsageGroupBy: - enum: - - requestType - - app - - network - - method - type: string - UsageTimeSeriesQuery: - properties: - startTime: - type: string - endTime: - type: string - granularity: - $ref: "#/components/schemas/UsageGranularity" - products: - items: - type: string - type: array - metrics: - items: - $ref: "#/components/schemas/UsageMetric" - type: array - filters: - $ref: "#/components/schemas/UsageTimeSeriesFilters" - groupBy: - items: - $ref: "#/components/schemas/UsageGroupBy" - type: array - required: - - startTime - - endTime - - granularity - - products - - metrics - - groupBy - type: object - additionalProperties: false - UsagePointDimensions: - properties: - requestType: - type: string - app: - type: string - network: - type: string - method: - type: string - type: object - additionalProperties: false - UsageTimeSeriesPoint: - properties: - startTime: - type: string - endTime: - type: string - isPartial: - type: boolean - dimensions: - $ref: "#/components/schemas/UsagePointDimensions" - amount: - type: string - unit: - type: string - usd: - type: string - required: - - startTime - - endTime - - isPartial - - dimensions - type: object - additionalProperties: false - UsageTimeSeriesResponse: - properties: - query: - $ref: "#/components/schemas/UsageTimeSeriesQuery" - freshness: - $ref: "#/components/schemas/UsageFreshness" - data: - items: - $ref: "#/components/schemas/UsageTimeSeriesPoint" - type: array - required: - - query - - freshness - - data - type: object - additionalProperties: false - StandardResponse_UsageTimeSeriesResponse_: - description: |- - Standard API response wrapper. - All API responses are wrapped in this format for consistency. - properties: - data: - $ref: "#/components/schemas/UsageTimeSeriesResponse" - required: - - data - type: object - additionalProperties: false - UsageTimeSeriesRequest: - properties: - startTime: - type: string - endTime: - type: string - description: Defaults to now when omitted. - products: - items: - type: string - type: array - description: BillingProduct enum names. - example: - - SUPERNODE_CU - metrics: - items: - $ref: "#/components/schemas/UsageMetric" - type: array - filters: - $ref: "#/components/schemas/UsageTimeSeriesFilters" - groupBy: - items: - $ref: "#/components/schemas/UsageGroupBy" - type: array - granularity: - $ref: "#/components/schemas/UsageGranularity" - required: - - startTime - type: object - additionalProperties: false - securitySchemes: - user_auth: - type: http - scheme: bearer -info: - title: Usage API - version: 1.0.0 - description: Alchemy API to inspect usage for your team - contact: {} -paths: - /v1/usage/summary: - get: - operationId: GetUsageSummary - responses: - "200": - description: Retrieved usage summary successfully - content: - application/json: - schema: - $ref: "#/components/schemas/StandardResponse_UsageSummaryResponse_" - "401": - description: Requires authentication - content: - application/json: - schema: - $ref: "#/components/schemas/StandardErrorResponse" - examples: - Example 1: - value: - error: - code: 401 - status: 401 - message: Requires authentication - "403": - description: Forbidden - content: - application/json: - schema: - $ref: "#/components/schemas/StandardErrorResponse" - examples: - Example 1: - value: - error: - code: 403 - status: 403 - message: Forbidden - "404": - description: Not found - content: - application/json: - schema: - $ref: "#/components/schemas/StandardErrorResponse" - examples: - Example 1: - value: - error: - code: 404 - status: 404 - message: Path not found - description: - Retrieves usage totals for the current billing period and recent - rolling windows. - summary: Get usage summary - security: - - user_auth: - - viewer - - developer - - admin - parameters: [] - /v1/usage/time-series: - post: - operationId: GetUsageTimeSeries - responses: - "200": - description: Retrieved usage time series successfully - content: - application/json: - schema: - $ref: "#/components/schemas/StandardResponse_UsageTimeSeriesResponse_" - "400": - description: Invalid input - content: - application/json: - schema: - $ref: "#/components/schemas/StandardErrorResponse" - examples: - Example 1: - value: - error: - code: 400 - status: 400 - message: Invalid input - "401": - description: Requires authentication - content: - application/json: - schema: - $ref: "#/components/schemas/StandardErrorResponse" - examples: - Example 1: - value: - error: - code: 401 - status: 401 - message: Requires authentication - "403": - description: Forbidden - content: - application/json: - schema: - $ref: "#/components/schemas/StandardErrorResponse" - examples: - Example 1: - value: - error: - code: 403 - status: 403 - message: Forbidden - "404": - description: Not found - content: - application/json: - schema: - $ref: "#/components/schemas/StandardErrorResponse" - examples: - Example 1: - value: - error: - code: 404 - status: 404 - message: Path not found - description: - Retrieves daily usage over time with optional product, metric, - filter, and dimension controls. - summary: Get usage time series - security: - - user_auth: - - viewer - - developer - - admin - parameters: [] - requestBody: - required: true - content: - application/json: - schema: - $ref: "#/components/schemas/UsageTimeSeriesRequest" -servers: - - url: https://admin-api.alchemy.com