> ## Documentation Index
> Fetch the complete documentation index at: https://docs.costory.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Run a cost query

> 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.



## OpenAPI

````yaml POST /queries/run
openapi: 3.0.0
info:
  title: Costory
  version: '1.0'
  description: API Documentation
servers:
  - url: ''
    description: Production server
security: []
paths:
  /queries/run:
    post:
      tags:
        - Query Costs
      summary: Run a cost query
      description: >-
        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.
      operationId: runQuery
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/QueryRequest'
      responses:
        '200':
          description: Query result, discriminated by `kind`
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/QueryResponse'
        '400':
          description: >-
            Invalid query (strict CEL contract, formula refs, period, group-by,
            or other request rules)
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/InvalidQueryError'
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Unauthorized'
        '403':
          description: Hourly granularity requires Copilot Pro
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HourlyGranularityForbiddenError'
        '404':
          description: >-
            Scope or external-metric integration absent or not visible to this
            organization
          content:
            application/json:
              schema:
                anyOf:
                  - $ref: '#/components/schemas/ScopeNotFoundOrForbiddenError'
                  - $ref: >-
                      #/components/schemas/ExternalMetricIntegrationNotFoundError
        '500':
          description: Unexpected server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/InternalServerError'
      security:
        - bearerAuth: []
components:
  schemas:
    QueryRequest:
      type: object
      properties:
        queries:
          type: array
          items:
            oneOf:
              - type: object
                properties:
                  type:
                    type: string
                    enum:
                      - cost
                    description: >-
                      Required series discriminator — always set explicitly,
                      never omit. One of: "cost" | "metric" | "usage" |
                      "formula" | "budget" | "externalMetric".
                  groupBy:
                    anyOf:
                      - type: string
                      - type: array
                        items:
                          type: string
                          minLength: 1
                      - nullable: true
                        type: string
                        enum:
                          - null
                  rollingAggregation:
                    type: object
                    properties:
                      aggregator:
                        type: string
                        enum:
                          - SUM
                          - AVG
                          - MAX
                          - MIN
                      window:
                        type: object
                        properties:
                          preset:
                            type: string
                            enum:
                              - MONTH
                              - WEEK
                          relativeDays:
                            type: integer
                            minimum: 1
                    required:
                      - aggregator
                      - window
                  name:
                    type: string
                    pattern: ^[a-z]$
                    description: >-
                      Required single-letter query identifier (a, b, c…). Never
                      use a descriptive phrase here — put human labels in alias
                      instead. Formula queries reference other queries by this
                      letter (e.g. formula: "a / b").
                  alias:
                    type: string
                    minLength: 1
                    maxLength: 50
                    description: >-
                      Optional human-readable label (e.g. "Cost by environment",
                      "AWS spend"). Use name for the single letter required by
                      formulas; never put descriptive text in name.
                  filterCel:
                    type: string
                    nullable: true
                    description: >-
                      Optional scope filter as CEL (Common Expression Language).
                      Examples: cos_service_name in ["AmazonEC2"]; cos_provider
                      in ["AWS"] && cos_environment in ["prod"]. Label
                      dimensions use the cos_ prefix; native provider fields
                      omit it. Unlabelled/untagged resources have null values;
                      use == null to match them (e.g. cos_environment == null)
                      and != null to exclude them. Omit or pass empty string for
                      no filter.
                  metricId:
                    type: string
                    enum:
                      - cost
                      - effective_cost
                      - list_cost
                      - contracted_cost
                      - unblended_cost
                      - net_unblended_cost
                      - amortized_cost
                      - net_amortized_cost
                    default: cost
                    description: >-
                      Cost column to query (e.g. "cost", "effective_cost",
                      "amortized_cost"). Defaults to "cost".
                  currency:
                    type: string
                    enum:
                      - USD
                      - EUR
                      - GBP
                      - CNY
                    default: USD
                    description: >-
                      Currency for cost values (USD, EUR, GBP). Defaults to
                      "USD".
                  chartType:
                    type: string
                    enum:
                      - BAR
                      - LINE
                      - AREA
                      - WATERFALL
                      - TABLE
                    description: >-
                      Explorer chart for this series: BAR, LINE, AREA,
                      WATERFALL, or TABLE. Omit to use LINE.
                  aggregator:
                    type: string
                    enum:
                      - SUM
                      - AVG
                      - MAX
                      - MIN
                    description: Aggregation over the bucket. Defaults to SUM.
                  reducer:
                    type: string
                    enum:
                      - SUM
                      - AVG
                      - MAX
                      - MIN
                  shiftAmount:
                    type: integer
                  shiftUnit:
                    type: string
                    enum:
                      - DAY
                      - WEEK
                      - MONTH
                required:
                  - type
                  - name
                additionalProperties: false
              - type: object
                properties:
                  type:
                    type: string
                    enum:
                      - metric
                    description: >-
                      Required series discriminator — always set explicitly,
                      never omit. One of: "cost" | "metric" | "usage" |
                      "formula" | "budget" | "externalMetric".
                  groupBy:
                    anyOf:
                      - type: string
                      - type: array
                        items:
                          type: string
                          minLength: 1
                      - nullable: true
                        type: string
                        enum:
                          - null
                  metricId:
                    type: string
                    description: >-
                      Saved Costory metric id from list_metrics metrics[].id.
                      This is the query identity — not list_metrics
                      `datasourceId` (that filter only returns groupBy
                      dimensions for telemetry).
                  name:
                    type: string
                    pattern: ^[a-z]$
                    description: >-
                      Required single-letter query identifier (a, b, c…). Never
                      use a descriptive phrase here — put human labels in alias
                      instead. Formula queries reference other queries by this
                      letter (e.g. formula: "a / b").
                  alias:
                    type: string
                    minLength: 1
                    maxLength: 50
                    description: >-
                      Optional human-readable label (e.g. "Cost by environment",
                      "AWS spend"). Use name for the single letter required by
                      formulas; never put descriptive text in name.
                  chartType:
                    type: string
                    enum:
                      - BAR
                      - LINE
                      - AREA
                      - WATERFALL
                      - TABLE
                    description: >-
                      Explorer chart for this series: BAR, LINE, AREA,
                      WATERFALL, or TABLE. Omit to use LINE.
                  aggregator:
                    type: string
                    enum:
                      - SUM
                      - AVG
                      - MAX
                      - MIN
                    description: Aggregation over the bucket. Defaults to SUM.
                  reducer:
                    type: string
                    enum:
                      - SUM
                      - AVG
                      - MAX
                      - MIN
                  shiftAmount:
                    type: integer
                  shiftUnit:
                    type: string
                    enum:
                      - DAY
                      - WEEK
                      - MONTH
                  rollingAggregation:
                    type: object
                    properties:
                      aggregator:
                        type: string
                        enum:
                          - SUM
                          - AVG
                          - MAX
                          - MIN
                      window:
                        type: object
                        properties:
                          preset:
                            type: string
                            enum:
                              - MONTH
                              - WEEK
                          relativeDays:
                            type: integer
                            minimum: 1
                    required:
                      - aggregator
                      - window
                  rawMetric:
                    type: string
                  unitOverride:
                    type: string
                required:
                  - type
                  - metricId
                  - name
                additionalProperties: false
              - type: object
                properties:
                  type:
                    type: string
                    enum:
                      - usage
                    description: >-
                      Required series discriminator — always set explicitly,
                      never omit. One of: "cost" | "metric" | "usage" |
                      "formula" | "budget" | "externalMetric".
                  groupBy:
                    anyOf:
                      - type: string
                      - type: array
                        items:
                          type: string
                          minLength: 1
                      - nullable: true
                        type: string
                        enum:
                          - null
                  metricId:
                    type: string
                    description: >-
                      Usage metric id (from suggest_usage_metrics). Distinct
                      from cost metricId and from list_metrics datasourceId.
                  name:
                    type: string
                    pattern: ^[a-z]$
                    description: >-
                      Required single-letter query identifier (a, b, c…). Never
                      use a descriptive phrase here — put human labels in alias
                      instead. Formula queries reference other queries by this
                      letter (e.g. formula: "a / b").
                  alias:
                    type: string
                    minLength: 1
                    maxLength: 50
                    description: >-
                      Optional human-readable label (e.g. "Cost by environment",
                      "AWS spend"). Use name for the single letter required by
                      formulas; never put descriptive text in name.
                  filterCel:
                    type: string
                    nullable: true
                    description: >-
                      Optional scope filter as CEL (Common Expression Language).
                      Examples: cos_service_name in ["AmazonEC2"]; cos_provider
                      in ["AWS"] && cos_environment in ["prod"]. Label
                      dimensions use the cos_ prefix; native provider fields
                      omit it. Unlabelled/untagged resources have null values;
                      use == null to match them (e.g. cos_environment == null)
                      and != null to exclude them. Omit or pass empty string for
                      no filter.
                  chartType:
                    type: string
                    enum:
                      - BAR
                      - LINE
                      - AREA
                      - WATERFALL
                      - TABLE
                    description: >-
                      Explorer chart for this series: BAR, LINE, AREA,
                      WATERFALL, or TABLE. Omit to use LINE.
                  aggregator:
                    type: string
                    enum:
                      - SUM
                      - AVG
                      - MAX
                      - MIN
                    description: Aggregation over the bucket. Defaults to SUM.
                  reducer:
                    type: string
                    enum:
                      - SUM
                      - AVG
                      - MAX
                      - MIN
                  shiftAmount:
                    type: integer
                  shiftUnit:
                    type: string
                    enum:
                      - DAY
                      - WEEK
                      - MONTH
                  rollingAggregation:
                    type: object
                    properties:
                      aggregator:
                        type: string
                        enum:
                          - SUM
                          - AVG
                          - MAX
                          - MIN
                      window:
                        type: object
                        properties:
                          preset:
                            type: string
                            enum:
                              - MONTH
                              - WEEK
                          relativeDays:
                            type: integer
                            minimum: 1
                    required:
                      - aggregator
                      - window
                required:
                  - type
                  - metricId
                  - name
                additionalProperties: false
              - type: object
                properties:
                  type:
                    type: string
                    enum:
                      - formula
                    description: >-
                      Required series discriminator — always set explicitly,
                      never omit. One of: "cost" | "metric" | "usage" |
                      "formula" | "budget" | "externalMetric".
                  formula:
                    type: string
                  name:
                    type: string
                    pattern: ^[a-z]$
                    description: >-
                      Required single-letter query identifier (a, b, c…). Never
                      use a descriptive phrase here — put human labels in alias
                      instead. Formula queries reference other queries by this
                      letter (e.g. formula: "a / b").
                  alias:
                    type: string
                    minLength: 1
                    maxLength: 50
                    description: >-
                      Optional human-readable label (e.g. "Cost by environment",
                      "AWS spend"). Use name for the single letter required by
                      formulas; never put descriptive text in name.
                  chartType:
                    type: string
                    enum:
                      - BAR
                      - LINE
                      - AREA
                      - WATERFALL
                      - TABLE
                    description: >-
                      Explorer chart for this series: BAR, LINE, AREA,
                      WATERFALL, or TABLE. Omit to use LINE.
                  shiftAmount:
                    type: integer
                  shiftUnit:
                    type: string
                    enum:
                      - DAY
                      - WEEK
                      - MONTH
                  rollingAggregation:
                    type: object
                    properties:
                      aggregator:
                        type: string
                        enum:
                          - SUM
                          - AVG
                          - MAX
                          - MIN
                      window:
                        type: object
                        properties:
                          preset:
                            type: string
                            enum:
                              - MONTH
                              - WEEK
                          relativeDays:
                            type: integer
                            minimum: 1
                    required:
                      - aggregator
                      - window
                required:
                  - type
                  - formula
                  - name
                additionalProperties: false
              - type: object
                properties:
                  type:
                    type: string
                    enum:
                      - budget
                    description: >-
                      Required series discriminator — always set explicitly,
                      never omit. One of: "cost" | "metric" | "usage" |
                      "formula" | "budget" | "externalMetric".
                  budgetId:
                    type: string
                  virtualDimensionValue:
                    type: string
                  rollingAggregation:
                    type: object
                    properties:
                      aggregator:
                        type: string
                        enum:
                          - SUM
                          - AVG
                          - MAX
                          - MIN
                      window:
                        type: object
                        properties:
                          preset:
                            type: string
                            enum:
                              - MONTH
                              - WEEK
                          relativeDays:
                            type: integer
                            minimum: 1
                    required:
                      - aggregator
                      - window
                  name:
                    type: string
                    pattern: ^[a-z]$
                    description: >-
                      Required single-letter query identifier (a, b, c…). Never
                      use a descriptive phrase here — put human labels in alias
                      instead. Formula queries reference other queries by this
                      letter (e.g. formula: "a / b").
                  alias:
                    type: string
                    minLength: 1
                    maxLength: 50
                    description: >-
                      Optional human-readable label (e.g. "Cost by environment",
                      "AWS spend"). Use name for the single letter required by
                      formulas; never put descriptive text in name.
                  chartType:
                    type: string
                    enum:
                      - BAR
                      - LINE
                      - AREA
                      - WATERFALL
                      - TABLE
                    description: >-
                      Explorer chart for this series: BAR, LINE, AREA,
                      WATERFALL, or TABLE. Omit to use LINE.
                required:
                  - type
                  - budgetId
                  - name
                additionalProperties: false
              - type: object
                properties:
                  type:
                    type: string
                    enum:
                      - externalMetric
                    description: >-
                      Required series discriminator — always set explicitly,
                      never omit. One of: "cost" | "metric" | "usage" |
                      "formula" | "budget" | "externalMetric".
                  integrationId:
                    type: string
                    minLength: 1
                    description: >-
                      External metric integration ID from
                      list_metrics(includeExternal: true).
                  metricName:
                    type: string
                    minLength: 1
                  aggregator:
                    type: string
                    enum:
                      - SUM
                      - AVG
                      - MAX
                      - MIN
                  groupByFields:
                    type: array
                    items:
                      type: string
                      minLength: 1
                    maxItems: 7
                    default: []
                  conditions:
                    type: string
                  dateColumn:
                    type: string
                    minLength: 1
                  metricColumn:
                    type: string
                    minLength: 1
                  gapFillingMethod:
                    type: string
                    enum:
                      - ZERO
                      - FORWARD_FILL
                      - LINEAR_INTERPOLATION
                      - SPREAD
                  rollingAggregation:
                    type: object
                    properties:
                      aggregator:
                        type: string
                        enum:
                          - SUM
                          - AVG
                          - MAX
                          - MIN
                      window:
                        type: object
                        properties:
                          preset:
                            type: string
                            enum:
                              - MONTH
                              - WEEK
                          relativeDays:
                            type: integer
                            minimum: 1
                    required:
                      - aggregator
                      - window
                  provider:
                    type: string
                    enum:
                      - tsuga
                      - bigquery
                      - datadog
                      - cloudwatch
                    default: tsuga
                    description: >-
                      External metric provider. Defaults to "tsuga" when omitted
                      for backward compatibility with existing Tsuga MCP
                      clients.
                  name:
                    type: string
                    pattern: ^[a-z]$
                    description: >-
                      Required single-letter query identifier (a, b, c…). Never
                      use a descriptive phrase here — put human labels in alias
                      instead. Formula queries reference other queries by this
                      letter (e.g. formula: "a / b").
                  alias:
                    type: string
                    minLength: 1
                    maxLength: 50
                    description: >-
                      Optional human-readable label (e.g. "Cost by environment",
                      "AWS spend"). Use name for the single letter required by
                      formulas; never put descriptive text in name.
                  chartType:
                    type: string
                    enum:
                      - BAR
                      - LINE
                      - AREA
                      - WATERFALL
                      - TABLE
                    description: >-
                      Explorer chart for this series: BAR, LINE, AREA,
                      WATERFALL, or TABLE. Omit to use LINE.
                required:
                  - type
                  - integrationId
                  - metricName
                  - aggregator
                  - name
                additionalProperties: false
            discriminator:
              propertyName: type
          minItems: 1
          maxItems: 26
        datePreset:
          type: string
          enum:
            - TRAILING_90_DAYS
            - TRAILING_30_DAYS
            - TRAILING_45_DAYS
            - TRAILING_7_DAYS
            - TRAILING_3_DAYS
            - TRAILING_14_WEEKS
            - MTD
            - QTD
            - YTD
            - LAST_WEEK
            - LAST_MONTH
            - LAST_6_MONTHS
            - LAST_12_MONTHS
            - LAST_4_YEARS
            - LAST_3_MONTHS
            - LAST_INVOICE_MONTH
        from:
          type: string
          pattern: ^\d{4}-\d{2}-\d{2}$
        to:
          type: string
          pattern: ^\d{4}-\d{2}-\d{2}$
        aggBy:
          type: string
          enum:
            - Hour
            - Day
            - Week
            - Month
            - Period
          default: Month
        forecastDays:
          type: integer
          minimum: 0
        compare:
          type: object
          properties:
            enabled:
              type: boolean
              default: true
            from:
              type: string
              pattern: ^\d{4}-\d{2}-\d{2}$
            to:
              type: string
              pattern: ^\d{4}-\d{2}-\d{2}$
            chartType:
              type: string
              enum:
                - WATERFALL
                - TABLE
                - KPI_BREAKDOWN
              default: WATERFALL
          additionalProperties: false
        limit:
          type: integer
          minimum: 1
          maximum: 1000
        scopeId:
          type: string
          nullable: true
      required:
        - queries
      additionalProperties: false
    QueryResponse:
      oneOf:
        - type: object
          properties:
            kind:
              type: string
              enum:
                - series
            data:
              type: object
              properties:
                outputData:
                  type: array
                  items:
                    type: object
                    properties:
                      date:
                        type: string
                        nullable: true
                        format: date-time
                      values:
                        type: array
                        items:
                          type: object
                          properties:
                            groupByValue:
                              type: string
                            queryName:
                              type: string
                            value:
                              type: number
                          required:
                            - groupByValue
                            - queryName
                            - value
                    required:
                      - date
                      - values
                series:
                  type: array
                  items:
                    type: object
                    properties:
                      queryName:
                        type: string
                      groupByValue:
                        type: string
                      totals:
                        type: number
                      unit:
                        type: string
                    required:
                      - queryName
                      - groupByValue
                      - totals
                      - unit
                aggBy:
                  type: string
                  enum:
                    - Hour
                    - Day
                    - Week
                    - Month
                    - Period
              required:
                - outputData
                - series
                - aggBy
          required:
            - kind
            - data
        - type: object
          properties:
            kind:
              type: string
              enum:
                - comparison
            data:
              type: object
              properties:
                outputData:
                  type: array
                  items:
                    type: object
                    properties:
                      comparisonPeriodValue:
                        type: number
                      selectedPeriodValue:
                        type: number
                      difference:
                        type: number
                      percentageChange:
                        type: number
                      queryName:
                        type: string
                      groupByValue:
                        type: string
                    required:
                      - comparisonPeriodValue
                      - selectedPeriodValue
                      - difference
                      - percentageChange
                      - queryName
                      - groupByValue
                series:
                  type: array
                  items:
                    type: object
                    properties:
                      queryName:
                        type: string
                      groupByValue:
                        type: string
                      unit:
                        type: string
                    required:
                      - queryName
                      - groupByValue
                      - unit
                totals:
                  type: array
                  items:
                    type: object
                    properties:
                      totalPrevious:
                        type: number
                      totalCurrent:
                        type: number
                      queryName:
                        type: string
                    required:
                      - totalPrevious
                      - totalCurrent
                      - queryName
              required:
                - outputData
                - series
                - totals
          required:
            - kind
            - data
      discriminator:
        propertyName: kind
    InvalidQueryError:
      type: object
      properties:
        error:
          type: string
          enum:
            - INVALID_QUERY
        reason:
          type: string
        details:
          type: array
          items:
            type: object
            properties:
              path:
                type: array
                items:
                  anyOf:
                    - type: string
                    - type: number
              message:
                type: string
              code:
                type: string
            required:
              - path
              - message
              - code
            additionalProperties: false
      required:
        - error
      additionalProperties: false
    Unauthorized:
      type: object
      properties:
        error:
          type: string
          description: Unauthorized error message
      required:
        - error
    HourlyGranularityForbiddenError:
      type: object
      properties:
        error:
          type: string
          enum:
            - HOURLY_GRANULARITY_FORBIDDEN
      required:
        - error
      additionalProperties: false
    ScopeNotFoundOrForbiddenError:
      type: object
      properties:
        error:
          type: string
          enum:
            - SCOPE_NOT_FOUND_OR_FORBIDDEN
      required:
        - error
      additionalProperties: false
    ExternalMetricIntegrationNotFoundError:
      type: object
      properties:
        error:
          type: string
          enum:
            - EXTERNAL_METRIC_INTEGRATION_NOT_FOUND
      required:
        - error
      additionalProperties: false
    InternalServerError:
      type: object
      properties:
        error:
          type: string
          enum:
            - INTERNAL_SERVER_ERROR
      required:
        - error
      additionalProperties: false
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT or Clerk ak_* API key
      description: >-
        Send `Authorization: Bearer <credential>` using either a Clerk session
        JWT or a Clerk API key (`ak_*`). API keys may identify a user (`user_*`)
        or organization (`org_*`) principal and are generated in the Clerk
        Dashboard under API keys.

````