# Archive a billing datasource Source: https://docs.costory.io/api-reference/admin-billing-datasources/archive-a-billing-datasource /api-reference/openapi.json delete /terraform/billingDatasources/{id} # Create a billing datasource Source: https://docs.costory.io/api-reference/admin-billing-datasources/create-a-billing-datasource /api-reference/openapi.json post /terraform/billingDatasources # Get a billing datasource Source: https://docs.costory.io/api-reference/admin-billing-datasources/get-a-billing-datasource /api-reference/openapi.json get /terraform/billingDatasources/{id} # Validate billing datasource configuration Source: https://docs.costory.io/api-reference/admin-billing-datasources/validate-billing-datasource-configuration /api-reference/openapi.json post /terraform/billingDatasources/validate # Archive a metrics datasource Source: https://docs.costory.io/api-reference/admin-metrics-datasources/archive-a-metrics-datasource /api-reference/openapi.json delete /terraform/metricsDatasources/{id} # Create a metrics datasource Source: https://docs.costory.io/api-reference/admin-metrics-datasources/create-a-metrics-datasource /api-reference/openapi.json post /terraform/metricsDatasources # Get a metrics datasource Source: https://docs.costory.io/api-reference/admin-metrics-datasources/get-a-metrics-datasource /api-reference/openapi.json get /terraform/metricsDatasources/{id} # Update an AWS S3 v2 metrics datasource definition Source: https://docs.costory.io/api-reference/admin-metrics-datasources/update-an-aws-s3-v2-metrics-datasource-definition /api-reference/openapi.json patch /terraform/metricsDatasources/{id} # Validate metrics datasource configuration Source: https://docs.costory.io/api-reference/admin-metrics-datasources/validate-metrics-datasource-configuration /api-reference/openapi.json post /terraform/metricsDatasources/validate # Add a member to a team via Admin API Source: https://docs.costory.io/api-reference/admin-teams/add-a-member-to-a-team-via-admin-api /api-reference/openapi.json post /terraform/teams/{id}/members The path parameter may be the team id or the team name (case-insensitive). # Archive a team via Admin API Source: https://docs.costory.io/api-reference/admin-teams/archive-a-team-via-admin-api /api-reference/openapi.json delete /terraform/teams/{id} The path parameter may be the team id or the team name (case-insensitive). # Create a team via Admin API Source: https://docs.costory.io/api-reference/admin-teams/create-a-team-via-admin-api /api-reference/openapi.json post /terraform/teams # Get a team via Admin API Source: https://docs.costory.io/api-reference/admin-teams/get-a-team-via-admin-api /api-reference/openapi.json get /terraform/teams/{id} The path parameter may be the team id or the team name (case-insensitive). Returns full team detail including members (with user) and pending invites. # List teams in the organization via Admin API Source: https://docs.costory.io/api-reference/admin-teams/list-teams-in-the-organization-via-admin-api /api-reference/openapi.json get /terraform/teams Returns all non-archived teams for the authenticated organization (admin IAM — same list service as SPA `/teams`). # Remove a member from a team via Admin API Source: https://docs.costory.io/api-reference/admin-teams/remove-a-member-from-a-team-via-admin-api /api-reference/openapi.json delete /terraform/teams/{id}/members/{userId} The path parameter may be the team id or the team name (case-insensitive). # Sync all members of a team via Admin API Source: https://docs.costory.io/api-reference/admin-teams/sync-all-members-of-a-team-via-admin-api /api-reference/openapi.json post /terraform/teams/{id}/SYNC Replaces the full member list of a team. Existing members not in the payload are removed, new ones are added or invited. The path parameter may be the team id or the team name (case-insensitive). # Update a team via Admin API Source: https://docs.costory.io/api-reference/admin-teams/update-a-team-via-admin-api /api-reference/openapi.json patch /terraform/teams/{id} The path parameter may be the team id or the team name (case-insensitive). # Get service account details Source: https://docs.costory.io/api-reference/admin/get-service-account-details /api-reference/openapi.json get /terraform Returns service account information for the Admin API. # Archive an alert Source: https://docs.costory.io/api-reference/alerts-v2/archive-an-alert /api-reference/openapi.json post /alerts-v2/{alertId}/archive # Create a budget alert Source: https://docs.costory.io/api-reference/alerts-v2/create-a-budget-alert /api-reference/openapi.json post /alerts-v2/budgetAlerts Creates an alert for budget lines visible to the caller. Threshold percentages are ordered from highest severity to lowest. # Create a cost alert Source: https://docs.costory.io/api-reference/alerts-v2/create-a-cost-alert /api-reference/openapi.json post /alerts-v2/costAlerts Creates either a condition-based alert (`condition` plus `dedup`) or a legacy threshold-based alert. The example monitors production AWS compute spend using Costory dimensions. # Delete an archived alert Source: https://docs.costory.io/api-reference/alerts-v2/delete-an-archived-alert /api-reference/openapi.json delete /alerts-v2/{alertId} # Get an alert template Source: https://docs.costory.io/api-reference/alerts-v2/get-an-alert-template /api-reference/openapi.json get /alerts-v2/templates/{templateId} # Get budget alert destination options Source: https://docs.costory.io/api-reference/alerts-v2/get-budget-alert-destination-options /api-reference/openapi.json get /alerts-v2/budgetAlerts/configurationFormData # Get cost alert destination options Source: https://docs.costory.io/api-reference/alerts-v2/get-cost-alert-destination-options /api-reference/openapi.json get /alerts-v2/costAlerts/configurationFormData # Get cost alert editor data Source: https://docs.costory.io/api-reference/alerts-v2/get-cost-alert-editor-data /api-reference/openapi.json get /alerts-v2/costAlerts/{id}/edit # Get cost alert firing history Source: https://docs.costory.io/api-reference/alerts-v2/get-cost-alert-firing-history /api-reference/openapi.json get /alerts-v2/costAlerts/{id}/history # Get cost alert widget data Source: https://docs.costory.io/api-reference/alerts-v2/get-cost-alert-widget-data /api-reference/openapi.json get /alerts-v2/costAlerts/{id}/widgetData # List alert templates Source: https://docs.costory.io/api-reference/alerts-v2/list-alert-templates /api-reference/openapi.json get /alerts-v2/templates # List budgets eligible for alerts Source: https://docs.costory.io/api-reference/alerts-v2/list-budgets-eligible-for-alerts /api-reference/openapi.json get /alerts-v2/budgets-with-alert-status # List cost alerts Source: https://docs.costory.io/api-reference/alerts-v2/list-cost-alerts /api-reference/openapi.json get /alerts-v2/costAlerts # List cost and budget alerts Source: https://docs.costory.io/api-reference/alerts-v2/list-cost-and-budget-alerts /api-reference/openapi.json get /alerts-v2 Returns the current Alerts V2 table payload. This camelCase route is the supported application contract; canonical public resource naming is a separate follow-up. # Restore an alert Source: https://docs.costory.io/api-reference/alerts-v2/restore-an-alert /api-reference/openapi.json post /alerts-v2/{alertId}/restore # Send a budget alert test notification Source: https://docs.costory.io/api-reference/alerts-v2/send-a-budget-alert-test-notification /api-reference/openapi.json post /alerts-v2/budgetAlerts/sendTest # Send a cost alert test notification Source: https://docs.costory.io/api-reference/alerts-v2/send-a-cost-alert-test-notification /api-reference/openapi.json post /alerts-v2/costAlerts/test # Snooze an alert Source: https://docs.costory.io/api-reference/alerts-v2/snooze-an-alert /api-reference/openapi.json post /alerts-v2/{alertId}/snooze # Unsnooze an alert Source: https://docs.costory.io/api-reference/alerts-v2/unsnooze-an-alert /api-reference/openapi.json post /alerts-v2/{alertId}/unsnooze # Update a budget alert Source: https://docs.costory.io/api-reference/alerts-v2/update-a-budget-alert /api-reference/openapi.json put /alerts-v2/budgetAlerts/{budgetAlertId} # Update a cost alert Source: https://docs.costory.io/api-reference/alerts-v2/update-a-cost-alert /api-reference/openapi.json put /alerts-v2/costAlerts/{id} # Get published label transformations Source: https://docs.costory.io/api-reference/dimensions/get-published-label-transformations /api-reference/openapi.json get /dimensions/labels The currently published label configuration: which source columns are merged into each engineered dimension and how their values are mapped. This is the live configuration, not a draft — the client holds label edits until it calls `POST /dimensions/publish`. # List label keys that could become dimensions Source: https://docs.costory.io/api-reference/dimensions/list-label-keys-that-could-become-dimensions /api-reference/openapi.json get /dimensions/candidates Label keys found in the billing data with the cost-allocation stats used to judge whether promoting them is worthwhile: the share of cost carrying the key, its values, a per-month cost series, and the month-over-month change. Property names are snake_case because they come straight from the billing export. `ingested: true` means the key is already promoted. # List queryable dimensions Source: https://docs.costory.io/api-reference/dimensions/list-queryable-dimensions /api-reference/openapi.json get /dimensions Returns every dimension available to filter and group by today, with its values and supported operators. Served from the cached dimension list refreshed by the compute pipeline, so a dimension published moments ago may not appear yet. # Publish pending dimension changes Source: https://docs.costory.io/api-reference/dimensions/publish-pending-dimension-changes /api-reference/openapi.json post /dimensions/publish Promotes pending dimension changes: the label configuration supplied inline in `labels`, and every pending virtual-dimension draft in the organization. `scope` narrows the publish to labels or virtual dimensions only. Each draft is validated on its own and the valid set is promoted atomically. A `200` therefore does not mean everything was published: `unpublished[]` lists the drafts that failed validation, with per-draft error messages, while `publishedLabels` and `publishedVdimIds` report what did go live. A `400` means the request as a whole was rejected and nothing was promoted. A successful publish enqueues an asynchronous BigQuery refresh (a full feature-engineering refresh when labels changed, a lighter update otherwise), so newly published dimensions are not immediately queryable. # Search dimension values Source: https://docs.costory.io/api-reference/dimensions/search-dimension-values /api-reference/openapi.json get /dimensions/search Full-text search across dimension names and their values. Unlike `GET /dimensions` this queries the billing warehouse live, so it is slower and costlier — use it for type-ahead, not to enumerate dimensions. # Aggregate events Source: https://docs.costory.io/api-reference/events/aggregate-events /api-reference/openapi.json post /events/aggregate # Create a new event Source: https://docs.costory.io/api-reference/events/create-a-new-event /api-reference/openapi.json post /public/events Endpoint to create a new event using public API. # Create a new event Source: https://docs.costory.io/api-reference/events/create-a-new-event-1 /api-reference/openapi.json post /events Endpoint to create a new event from the internal API. # Delete an event Source: https://docs.costory.io/api-reference/events/delete-an-event /api-reference/openapi.json delete /events/{id} # Get an event by ID Source: https://docs.costory.io/api-reference/events/get-an-event-by-id /api-reference/openapi.json get /events/{id} # Get event tags Source: https://docs.costory.io/api-reference/events/get-event-tags /api-reference/openapi.json get /events/tags # Update an event Source: https://docs.costory.io/api-reference/events/update-an-event /api-reference/openapi.json put /events/{id} # List usage metrics Source: https://docs.costory.io/api-reference/metrics/list-usage-metrics /api-reference/openapi.json get /usage-metrics Consumed units available for usage-based queries, with the services that report each unit. # API overview Source: https://docs.costory.io/api-reference/overview Authenticate and call the Costory HTTP API. Use a bearer token from the Costory app for every request. The Costory API exposes the same endpoints the app uses over HTTP. Base URL: ```bash theme={null} https://app-api.costory.io ``` Start with the [Query Costs API](/api-reference/queries/overview) to run Explorer queries from your own tools, or the [Reports API](/api-reference/reports/overview) to create and schedule cost reports. To ingest hourly custom metrics, use [Custom Metrics Push](/setup/usage-metrics/custom-metrics-push) (`POST /integrations/:id/metrics/points` with an organization API key). More resources (Events, Teams, and others) are listed in this API Reference tab as they ship. ## Authentication All requests use a bearer token in the `Authorization` header. Create a user-scoped token or an organization-scoped token (admins only) in the [Costory app](https://app.costory.io/). ```bash theme={null} Authorization: Bearer ``` Create a user scoped token in Costory settings # List business metrics Source: https://docs.costory.io/api-reference/queries/list-business-metrics GET /queries/metrics Business `metricId` values accepted by `metric` series, grouped by datasource. `status` is a stored value and is not refreshed on read for API-key callers. # List queryable dimensions Source: https://docs.costory.io/api-reference/queries/list-queryable-dimensions GET /queries/dimensions Group-by axes and their values accepted by `groupBy` on cost/usage/metric series. Strict public shape — no react-querybuilder filter-widget fields. # List usage metrics Source: https://docs.costory.io/api-reference/queries/list-usage-metrics GET /queries/usage-metrics Usage `metricId` values (and units) accepted by `usage` series. # Query Costs API Source: https://docs.costory.io/api-reference/queries/overview Run Costory Explorer cost queries over HTTP. Filter with CEL, group by dimensions, compare periods, and pull the same series the app and MCP use. The Query Costs API runs the same cost, usage, metric, formula, and budget series you build in [Explorer](/features/cost-explorer). Call `POST /queries/run` from your own scripts, CI jobs, or internal tools with a bearer token from the [API overview](/api-reference/overview). This is the HTTP surface behind the [Costory MCP](/features/mcp) `query` tool and the Explorer UI. A query that works in chat or in the app works here with the same request body. ## What you can query Each item in `queries` is a series. Every series needs a `type` and a single-letter `name` (`a`, `b`, `c`, …). Put human labels in `alias`, not in `name`. | `type` | Use for | | ---------------- | ------------------------------------------------------------------------ | | `cost` | Cloud spend (`metricId`: `cost`, `contracted_cost`, `effective_cost`, …) | | `usage` | Infra usage units (CPU hours, K8s waste, …) | | `metric` | Saved business metrics from your datasources | | `externalMetric` | Live Tsuga or BigQuery metrics | | `formula` | Ratios and derived series (`a / b`, `a - b`) | | `budget` | Budget burn against a budget version id | **Scope vs split:** * `filterCel` scopes which rows to include (for example EC2 only). * `groupBy` splits the result into series or rows (for example per environment). Label dimensions use the `cos_` prefix (`cos_service_name`, `cos_environment`). Untagged resources are CEL `null` (`cos_environment == null`). ## A query in one call Prefer a `datePreset` when one matches. Pass `from` and `to` only for custom ranges. Do not combine a preset with explicit dates. ```bash theme={null} curl -X POST https://app-api.costory.io/queries/run \ -H "Authorization: Bearer " \ -H "Content-Type: application/json" \ -d '{ "queries": [{ "type": "cost", "name": "a", "alias": "AWS by service", "metricId": "cost", "currency": "USD", "groupBy": "cos_service_name", "filterCel": "cos_provider in [\"AWS\"]", "chartType": "BAR" }], "datePreset": "TRAILING_90_DAYS", "aggBy": "Period" }' ``` Period-over-period comparison uses the same endpoint. Add `compare: {}` (or `{ "enabled": true }`) and Costory derives the preceding period from your preset: ```json theme={null} { "queries": [{ "type": "cost", "name": "a", "metricId": "cost", "currency": "USD" }], "datePreset": "LAST_MONTH", "compare": {} } ``` The response is either a time series (`kind: series`) or a comparison (`kind: comparison`) when compare is enabled. ## Discover dimensions and metrics first Before you invent CEL field names or metric ids, call the companion list endpoints: * [List queryable dimensions](/api-reference/queries/list-queryable-dimensions) for `groupBy` and `filterCel` fields * [List business metrics](/api-reference/queries/list-business-metrics) for saved `metric` series ids * [List usage metrics](/api-reference/queries/list-usage-metrics) for `usage` series ids ## Diff tree for cost changes When you need a rollup tree of what moved between two periods (not a flat Explorer comparison), use [Run a cost-change diff tree](/api-reference/queries/run-a-cost-change-diff-tree). It requires an enabled comparison, a non-hourly `aggBy`, and at least one `groupBy` on a single `cost` or `usage` series. ## Endpoints Use the pages in this section for the full schema and to try each call. # Run a cost-change diff tree Source: https://docs.costory.io/api-reference/queries/run-a-cost-change-diff-tree POST /queries/diff-tree Returns a `GROUP BY ROLLUP` tree of current vs previous cost per node for exactly one `cost` or `usage` series. Requires an enabled comparison period, a non-hourly `aggBy`, and at least one `groupBy` axis on that series. Pre-condition failures return `400 INVALID_QUERY` with today's message in `reason`. There is no Hour entitlement gate — hourly is rejected for every organization. # Run a cost query Source: https://docs.costory.io/api-reference/queries/run-a-cost-query POST /queries/run Executes a CEL query and returns either a time series (`kind: series`) or a period-over-period comparison (`kind: comparison`) when `compare.enabled` is true. Organization comes from the authenticated principal (Clerk session JWT or `ak_*` API key). When `datePreset` is sent alongside `from`/`to`, the preset wins. An omitted `limit` is server-chosen (currently between 10 and 200 depending on the chart shape), not a flat default of 100. # List business metrics Source: https://docs.costory.io/api-reference/query-costs/list-business-metrics /api-reference/openapi.json get /queries/metrics Business `metricId` values accepted by `metric` series, grouped by datasource. `status` is a stored value and is not refreshed on read for API-key callers. # List queryable dimensions Source: https://docs.costory.io/api-reference/query-costs/list-queryable-dimensions /api-reference/openapi.json get /queries/dimensions Group-by axes and their values accepted by `groupBy` on cost/usage/metric series. Strict public shape — no react-querybuilder filter-widget fields. # List usage metrics Source: https://docs.costory.io/api-reference/query-costs/list-usage-metrics /api-reference/openapi.json get /queries/usage-metrics Usage `metricId` values (and units) accepted by `usage` series. # Run a cost-change diff tree Source: https://docs.costory.io/api-reference/query-costs/run-a-cost-change-diff-tree /api-reference/openapi.json post /queries/diff-tree Returns a `GROUP BY ROLLUP` tree of current vs previous cost per node for exactly one `cost` or `usage` series. Requires an enabled comparison period, a non-hourly `aggBy`, and at least one `groupBy` axis on that series. Pre-condition failures return `400 INVALID_QUERY` with today's message in `reason`. There is no Hour entitlement gate — hourly is rejected for every organization. # Run a cost query Source: https://docs.costory.io/api-reference/query-costs/run-a-cost-query /api-reference/openapi.json post /queries/run Executes a CEL query and returns either a time series (`kind: series`) or a period-over-period comparison (`kind: comparison`) when `compare.enabled` is true. Organization comes from the authenticated principal (Clerk session JWT or `ak_*` API key). When `datePreset` is sent alongside `from`/`to`, the preset wins. An omitted `limit` is server-chosen (currently between 10 and 200 depending on the chart shape), not a flat default of 100. # Archive a report Source: https://docs.costory.io/api-reference/reports/archive-a-report DELETE /reports/{id} Soft-archives the report (sets `archivedAt`). # Create a report Source: https://docs.costory.io/api-reference/reports/create-a-report POST /reports Creates a report. Rules not captured by the field types: at least one `destinations` entry is required; when `scheduledPeriod` is `WEEKLY`, `scheduledWeekday` (0=Sunday…6=Saturday) is required; EMAIL destinations must be a valid address (or `ALL_ACTIVE_USERS`); and a DIGEST widget rendered as a `table` supports at most two group-by dimensions (report `context.groupBy` plus `additionalGroupBy`). # Duplicate a report Source: https://docs.costory.io/api-reference/reports/duplicate-a-report POST /reports/{id}/duplicate # Get a report Source: https://docs.costory.io/api-reference/reports/get-a-report GET /reports/{id} # Get a report execution Source: https://docs.costory.io/api-reference/reports/get-a-report-execution /api-reference/openapi.json get /report-executions/{executionId} # List reports Source: https://docs.costory.io/api-reference/reports/list-reports GET /reports Returns reports visible to the authenticated user. Optional `recentExecutionsLimit` embeds recent execution rows per report. # Reports API Source: https://docs.costory.io/api-reference/reports/overview Create, schedule, preview, and run Costory cost reports over HTTP. The same API powers scheduling from the UI and from chat via the Costory MCP. The Reports API creates and schedules the cost reports described in [Cost Reports](/features/slack-reports). Every report you build in the UI or ask the [Costory MCP](/features/mcp) to create resolves to a call against these endpoints, so anything you can schedule by hand you can automate here. Authenticate with a bearer token as described in the [API overview](/api-reference/overview). ## A report in one call A report ties together a scope, one or more widgets, a cadence, and the channels it goes to. [Create a report](/api-reference/reports/create-a-report) accepts all of it in a single `POST /reports` body: * `context` sets the shared scope, group-by, and period the widgets inherit. * `widgets` holds the trend graph, the top and bottom ranking, or the Digest breakdown to render. * `scheduledPeriod` and `scheduledWeekday` set the cadence (or `null` for an on-demand report you trigger yourself). * `destinations` lists the Slack, Microsoft Teams, or email targets the report fans out to on every run. Before scheduling, [preview a widget](/api-reference/reports/preview-a-report-widget) or [send a test delivery](/api-reference/reports/send-a-test-report) to check the format and data. ## Endpoints Use the pages in this section to see the full schema and try each call against staging. # Preview a report widget Source: https://docs.costory.io/api-reference/reports/preview-a-report-widget POST /report-previews/widgets # Preview digest summary markdown Source: https://docs.costory.io/api-reference/reports/preview-digest-summary-markdown /api-reference/openapi.json post /report-previews/digest-summary # Retry a failed report execution Source: https://docs.costory.io/api-reference/reports/retry-a-failed-report-execution /api-reference/openapi.json post /report-executions/{executionId}/retry # Run a report now Source: https://docs.costory.io/api-reference/reports/run-a-report-now POST /reports/{reportId}/executions Enqueues and synchronously runs pending executions for every destination. # Send a test report Source: https://docs.costory.io/api-reference/reports/send-a-test-report POST /report-previews/deliveries # Send a test report delivery Source: https://docs.costory.io/api-reference/reports/send-a-test-report-delivery /api-reference/openapi.json post /report-previews/deliveries # Transfer a rendered execution to new destinations Source: https://docs.costory.io/api-reference/reports/transfer-a-rendered-execution-to-new-destinations /api-reference/openapi.json post /report-executions/{executionId}/transfers # Update a report Source: https://docs.costory.io/api-reference/reports/update-a-report PATCH /reports/{id} Partially updates a report; omitted fields are left unchanged. `widgets` and `destinations`, when provided, replace the existing lists wholesale. Same conditional rules as create apply: a WEEKLY cadence needs a `scheduledWeekday` (from this body or already stored), EMAIL destinations must be valid addresses, and a `table` DIGEST widget allows at most two group-by dimensions. Archived reports cannot be updated (409). # Decentralize FinOps with Per-Team Cost Reports Source: https://docs.costory.io/automate-reporting/decentralize-finops Scale cost visibility across engineering teams by scoping automated reports to each squad. Deliver cloud cost insights via Slack, Teams, or email, no billing console access needed. When FinOps sits with one person, every other team is blind to its own cloud spend. Cost-saving work is hard to track, teams can't see the impact of their changes, and the FinOps owner becomes a bottleneck. This guide scopes automated cost reports to each team using Costory's [Slack, Teams, and email reports](/features/slack-reports), so every squad sees its own costs.