Orq.ai Budgets API

Budgets govern spend, token usage, and request rate across six scopes: workspace, project, identity, API key, provider, and model. Every applicable budget is enforced, and the most restrictive limit applies per dimension.

Operations 6

GET /v2/budgets List budgets #
POST /v2/budgets Create a new budget #
GET /v2/budgets/{budget_id} Retrieve a budget #
DELETE /v2/budgets/{budget_id} Delete a budget #
PATCH /v2/budgets/{budget_id} Update a budget #
POST /v2/budgets/{budget_id}/reset-consumption Reset budget consumption #

Work with this as data

Every API here is available over the APIs.io API and to AI agents over MCP.

MCP server

One button, every client — Claude, Cursor, VS Code and the rest.

https://apis.io/mcp

Tools for apis

7 MCP tools reach this
  • find_apisBrowse and filter every API in the catalog.
  • get_api_artifactsOne API's artifacts, grouped by type.
  • get_openapiThe primary OpenAPI for this API.
  • find_similar_apisAPIs that look like this one.
  • apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.
  • resolveTurn a domain, URL or GitHub org into the provider it belongs to.
  • find_cohortsEvery scored population of providers in the catalog.
All 92 tools →

Call it yourself

curl for this page
This API
curl "https://apis.io/api/v1/apis/orq:orq-budgets-api"
All apis
curl "https://apis.io/api/v1/apis?limit=25"

Discovery needs no key. Ratings and market analysis are Pro.

Get an API key

Free tier, no form to fill in. Signing in shares your email address with us — we store it to create your key and to recognise you if you sign in with another provider. See our Privacy Policy and Terms.

A second provider on the same verified email joins the account you already have.

OpenAPI Specification

orq-budgets-api-openapi.yml Raw ↑
openapi: 3.2.0
info:
  title: orq.ai Budgets API
  version: '2.0'
  description: orq.ai API documentation
servers:
- url: https://my.orq.ai
security:
- ApiKey: []
tags:
- name: Budgets
  description: 'Budgets govern spend, token usage, and request rate across six scopes: workspace, project, identity, API key, provider, and model. Every applicable budget is enforced, and the most restrictive limit applies per dimension.'
paths:
  /v2/budgets:
    get:
      tags:
      - Budgets
      summary: List budgets
      description: Returns budgets visible to the current workspace, ordered by most recently updated with the newest first. Supports filtering by scope kind, scope target id, period, and active state, plus an optional free-text query that matches scope target names and ids. Requires a Management Key with the Budgets permission; project-scoped API keys cannot manage budgets.
      operationId: BudgetList
      parameters:
      - name: limit
        in: query
        description: Page size, 1–200. Unset uses the server default (25).
        schema:
          type: integer
          format: int32
      - name: starting_after
        in: query
        description: "Cursor for forward pagination. Set to the `budget_id` of the last\n item from the previous page."
        schema:
          type: string
      - name: ending_before
        in: query
        description: "Cursor for backward pagination. Set to the `budget_id` of the\n first item from the previous page."
        schema:
          type: string
      - name: scope_kind
        in: query
        description: "Optional filter: only return budgets whose scope kind matches one\n of the listed values. Empty means no scope-kind filter."
        schema:
          type: array
          items:
            $ref: '#/components/schemas/BudgetScopeKind'
      - name: scope_target_id
        in: query
        description: 'Optional filter: only return budgets whose scope target id matches.'
        schema:
          type: string
      - name: is_active
        in: query
        description: 'Optional filter: only return budgets with this active state.'
        schema:
          type: boolean
      - name: period
        in: query
        description: "Optional filter: only return budgets whose limits.period matches\n one of the listed values. Empty means no period filter."
        schema:
          type: array
          items:
            $ref: '#/components/schemas/BudgetPeriod'
      - name: query
        in: query
        description: "Optional free-text query matched against a budget's scope target\n name and id."
        schema:
          type: string
      - name: sort_by
        in: query
        description: Field used to order the list. Unset orders by most-recently-updated.
        schema:
          $ref: '#/components/schemas/BudgetSortField'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ListBudgetsResponse'
        '401':
          description: Authentication required. See https://docs.orq.ai/reference/errors for the error codes.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
      x-speakeasy-group: budgets
      x-speakeasy-name-override: list
    post:
      tags:
      - Budgets
      summary: Create a new budget
      description: Creates a new budget in the workspace. Exactly one scope variant must be set (workspace / project / identity / api_key / provider / model). At least one of `limits.amount`, `limits.token_limit`, or `rate_limit.requests_per_minute` MUST be provided. Uniqueness is enforced across (workspace_id, scope_kind, scope_target_id). Requires a Management Key with the Budgets permission; project-scoped API keys cannot manage budgets.
      operationId: BudgetCreate
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateBudgetRequest'
        required: true
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CreateBudgetResponse'
        '401':
          description: Authentication required. See https://docs.orq.ai/reference/errors for the error codes.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
      x-speakeasy-group: budgets
      x-speakeasy-name-override: create
      x-code-samples:
      - lang: typescript
        label: Node.js
        source: 'await orq.budgets.create({ scope: { kind: "workspace" }, limits: { period: "MONTHLY", amount: 1000 } });

          '
  /v2/budgets/{budget_id}:
    get:
      tags:
      - Budgets
      summary: Retrieve a budget
      description: Retrieves the metadata for an existing budget by its unique identifier. Returns `NotFound` when the budget does not exist in the caller's workspace. Requires a Management Key with the Budgets permission; project-scoped API keys cannot manage budgets.
      operationId: BudgetGet
      parameters:
      - name: budget_id
        in: path
        description: Budget id to retrieve.
        required: true
        schema:
          type: string
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GetBudgetResponse'
        '401':
          description: Authentication required. See https://docs.orq.ai/reference/errors for the error codes.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '403':
          description: Not permitted for this key, project or workspace. See https://docs.orq.ai/reference/errors for the error codes.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
      x-speakeasy-group: budgets
      x-speakeasy-name-override: get
    delete:
      tags:
      - Budgets
      summary: Delete a budget
      description: Permanently deletes a budget. Its consumption counters are cleared immediately. The response body is empty on success. Requires a Management Key with the Budgets permission; project-scoped API keys cannot manage budgets.
      operationId: BudgetDelete
      parameters:
      - name: budget_id
        in: path
        description: Budget id to delete.
        required: true
        schema:
          type: string
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DeleteBudgetResponse'
        '401':
          description: Authentication required. See https://docs.orq.ai/reference/errors for the error codes.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
      x-speakeasy-group: budgets
      x-speakeasy-name-override: delete
    patch:
      tags:
      - Budgets
      summary: Update a budget
      description: 'Updates mutable fields of a budget: limits, rate limit, activation, and expiration. The scope is immutable — to change a budget''s target, delete and recreate it. Omitted fields keep their current values. Requires a Management Key with the Budgets permission; project-scoped API keys cannot manage budgets.'
      operationId: BudgetUpdate
      parameters:
      - name: budget_id
        in: path
        description: Budget id to update.
        required: true
        schema:
          type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UpdateBudgetRequest'
        required: true
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UpdateBudgetResponse'
        '401':
          description: Authentication required. See https://docs.orq.ai/reference/errors for the error codes.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
      x-speakeasy-group: budgets
      x-speakeasy-name-override: update
  /v2/budgets/{budget_id}/reset-consumption:
    post:
      tags:
      - Budgets
      summary: Reset budget consumption
      description: Clears the current-period cost, token, and request counters for the budget. The budget record itself is preserved. Requires a Management Key with the Budgets permission; project-scoped API keys cannot manage budgets.
      operationId: BudgetResetConsumption
      parameters:
      - name: budget_id
        in: path
        description: Budget id whose current-period counters should be cleared.
        required: true
        schema:
          type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ResetBudgetConsumptionRequest'
        required: true
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ResetBudgetConsumptionResponse'
        '401':
          description: Authentication required. See https://docs.orq.ai/reference/errors for the error codes.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
      x-speakeasy-group: budgets
      x-speakeasy-name-override: resetConsumption
components:
  schemas:
    ListBudgetsResponse:
      required:
      - object
      - data
      type: object
      properties:
        object:
          type: string
          description: Object discriminator for list responses; always `list`.
        data:
          type: array
          items:
            $ref: '#/components/schemas/BudgetRestResponse'
          description: Page of budgets, ordered newest first.
        hasMore:
          type: boolean
          description: "Whether more budgets are available in the selected pagination\n direction."
          default: false
    BudgetPeriod:
      type: string
      enum:
      - BUDGET_PERIOD_DAILY
      - BUDGET_PERIOD_WEEKLY
      - BUDGET_PERIOD_MONTHLY
      - BUDGET_PERIOD_YEARLY
      - BUDGET_PERIOD_ONE_TIME
    IdentityBudgetScopeRestResponse:
      type: object
      properties:
        identityExternalId:
          type: string
      description: "Per-identity cap. Keyed by the contact's external identifier so the\n scope is stable across imports."
    ProviderBudgetScope:
      type: object
      properties:
        provider:
          type: string
      description: "Per-provider cap. The value is the provider enum string (e.g.\n \"openai\", \"anthropic\") drawn from ModelIntegrationIdentifier."
    ApiKeyBudgetScope:
      type: object
      properties:
        api_key_id:
          type: string
      description: "Per-api-key cap. Replaces the legacy embedded `constraints.budget`\n associated with an API key."
    CreateBudgetRequest:
      type: object
      properties:
        scope:
          allOf:
          - $ref: '#/components/schemas/BudgetScope'
          description: "Structured scope. Mutually exclusive with `match`: provide a scope\n for the six canonical kinds (the server derives the matching CEL),\n or provide `match` for a dynamic budget. Exactly one of the two\n must be set."
        match:
          allOf:
          - $ref: '#/components/schemas/BudgetMatch'
          description: "Raw CEL matching expression for dynamic budgets (e.g.\n `metadata.team == \"ml\" && provider == \"openai\"`). Validated via\n CEL parse at write time. Mutually exclusive with `scope`."
        limits:
          allOf:
          - $ref: '#/components/schemas/BudgetLimits'
          description: "At least one of amount / token_limit / rate_limit.requests_per_minute\n must be provided on the budget."
        rate_limit:
          allOf:
          - $ref: '#/components/schemas/RateLimit'
          description: Optional rate limit.
        is_active:
          type: boolean
          description: "Whether the budget should be active immediately. Defaults to true\n when omitted (handler enforces)."
        expires_at:
          type: string
          description: "Optional expiration. When set in combination with is_active=true,\n the value MUST be in the future; the handler rejects past values."
          format: date-time
        alerts:
          type: array
          items:
            $ref: '#/components/schemas/BudgetAlert'
          description: "Optional threshold notifications. Ids are assigned by the server, so\n `alerts[].id` must be omitted here; supplying one is rejected."
    ErrorResponse:
      type: object
      properties:
        message:
          type: string
          description: Human-readable error message.
        code:
          type: integer
          description: gRPC status code, when the service reports one.
        details:
          type: array
          items: {}
          description: Additional error details, when the service reports any.
      required:
      - message
    ModelBudgetScope:
      required:
      - model_id
      type: object
      properties:
        model_id:
          type: string
      description: "Per-model cap. The value is the FULL model reference as callers send\n it (\"openai/gpt-4o\", or \"workspaceKey@openai/gpt-4o\" for private\n models)."
    ResetBudgetConsumptionResponse:
      type: object
      properties:
        budget:
          allOf:
          - $ref: '#/components/schemas/BudgetRestResponse'
          description: "Budget after reset. The record itself is unchanged; only counters\n were cleared."
    BudgetScope:
      type: object
      properties:
        workspace:
          $ref: '#/components/schemas/WorkspaceBudgetScope'
        project:
          $ref: '#/components/schemas/ProjectBudgetScope'
        identity:
          $ref: '#/components/schemas/IdentityBudgetScope'
        api_key:
          $ref: '#/components/schemas/ApiKeyBudgetScope'
        provider:
          $ref: '#/components/schemas/ProviderBudgetScope'
        model:
          $ref: '#/components/schemas/ModelBudgetScope'
      description: Closed oneof of workspace, project, identity, api_key, provider, or model. Exactly one variant must be set.
    ApiKeyBudgetScopeRestResponse:
      type: object
      properties:
        apiKeyId:
          type: string
      description: "Per-api-key cap. Replaces the legacy embedded `constraints.budget`\n associated with an API key."
    WorkspaceBudgetScope:
      type: object
      properties: {}
      description: Workspace-wide ceiling. The implicit target is the caller's workspace.
    BudgetUsage:
      type: object
      properties:
        amount:
          type: number
          format: double
        tokens:
          type: number
          description: "Carried as a double (not int64) so it serializes as a JSON number\n rather than a quoted string, matching limits.token_limit."
          format: double
        requests:
          type: integer
          format: int32
      description: "BudgetUsage is the latest available current-period consumption used\n for budget enforcement, not an exact billing ledger. Each dimension is\n the consumed side of the matching limit dimension: `amount` is the\n accumulated cost in USD (vs limits.amount), `tokens` is the accumulated\n token count (vs limits.token_limit), and `requests` is the count in the\n rolling 60-second window (vs rate_limit.requests_per_minute). All three\n are explicit-presence so the triple is always emitted in full, zeros\n included — a never-spent budget serializes {amount:0, tokens:0,\n requests:0} rather than dropping its zero dimensions."
    UpdateBudgetRequest:
      type: object
      properties:
        limits:
          allOf:
          - $ref: '#/components/schemas/BudgetLimits'
          description: New limits. Omit to keep current.
        rate_limit:
          allOf:
          - $ref: '#/components/schemas/RateLimit'
          description: New rate limit. Omit to keep current.
        is_active:
          type: boolean
          description: New active state. Omit to keep current.
        expires_at:
          type: string
          description: "New expiration. Omit to keep current. Set `clear_expires_at = true`\n to remove an existing expiration."
          format: date-time
        clear_expires_at:
          type: boolean
          description: Force-clear the expiration. Mutually exclusive with `expires_at`.
        match:
          allOf:
          - $ref: '#/components/schemas/BudgetMatch'
          description: "New matching expression. Only valid for dynamic budgets (no\n structured scope) — the scope of a scoped budget is immutable, so\n its derived expression is too. Validated via CEL parse."
        alerts:
          type: array
          items:
            $ref: '#/components/schemas/BudgetAlert'
          description: "Replaces the alert list wholesale. Omit to keep the current alerts.\n An entry with a known `id` is edited in place; one with no id is minted."
        clear_alerts:
          type: boolean
          description: Force-clear every alert. Mutually exclusive with a non-empty `alerts`.
    ResetBudgetConsumptionRequest:
      type: object
      properties: {}
    BudgetScopeKind:
      type: string
      enum:
      - BUDGET_SCOPE_KIND_WORKSPACE
      - BUDGET_SCOPE_KIND_PROJECT
      - BUDGET_SCOPE_KIND_IDENTITY
      - BUDGET_SCOPE_KIND_API_KEY
      - BUDGET_SCOPE_KIND_PROVIDER
      - BUDGET_SCOPE_KIND_MODEL
    RateLimit:
      type: object
      properties:
        requests_per_minute:
          type: integer
          format: int32
      description: "Per-minute request ceiling applied to the requests this budget\n matches."
    ProjectBudgetScope:
      type: object
      properties:
        project_id:
          type: string
      description: Per-project cap.
    BudgetLimits:
      type: object
      properties:
        period:
          $ref: '#/components/schemas/BudgetPeriod'
        amount:
          type: number
          format: double
        token_limit:
          type: number
          description: "Token ceiling for the budget period. Token counts are whole numbers\n and stored as integers."
          format: double
      description: "BudgetLimits is the per-period spend and token ceiling. At least one\n of `amount`, `token_limit`, or RateLimit.requests_per_minute MUST be\n set on a Budget; that invariant is enforced by the handler."
    CreateBudgetResponse:
      required:
      - budget
      type: object
      properties:
        budget:
          allOf:
          - $ref: '#/components/schemas/BudgetRestResponse'
          description: Newly created budget.
    RateLimitRestResponse:
      type: object
      properties:
        requestsPerMinute:
          type: integer
          format: int32
      description: "Per-minute request ceiling applied to the requests this budget\n matches."
    BudgetAlert:
      required:
      - threshold_percent
      - notifier_ids
      type: object
      properties:
        id:
          type: string
          description: Assigned by ORQ. Supply an existing id to edit that alert in place.
        threshold_percent:
          type: integer
          description: Percentage of the dimension's limit at which the alert fires, 1–100.
          format: uint32
        notifier_ids:
          type: array
          items:
            type: string
          description: Must be workspace-scoped; project-scoped notifiers are rejected.
        dimension:
          description: Defaults to COST when unset.
          $ref: '#/components/schemas/BudgetAlertDimension'
      description: "Notifies every listed notifier once current-period consumption on\n `dimension` reaches `threshold_percent` of the matching limit. Each alert\n fires at most once per period, re-arming on rollover or a limit change.\n The dimension must have a limit set, or the write is rejected. A TOKENS alert is rejected."
    BudgetScopeRestResponse:
      type: object
      properties:
        workspace:
          $ref: '#/components/schemas/WorkspaceBudgetScope'
        project:
          $ref: '#/components/schemas/ProjectBudgetScopeRestResponse'
        identity:
          $ref: '#/components/schemas/IdentityBudgetScopeRestResponse'
        apiKey:
          $ref: '#/components/schemas/ApiKeyBudgetScopeRestResponse'
        provider:
          $ref: '#/components/schemas/ProviderBudgetScope'
        model:
          $ref: '#/components/schemas/ModelBudgetScopeRestResponse'
      description: Closed oneof of workspace, project, identity, api_key, provider, or model. Exactly one variant must be set.
    UpdateBudgetResponse:
      required:
      - budget
      type: object
      properties:
        budget:
          allOf:
          - $ref: '#/components/schemas/BudgetRestResponse'
          description: Updated budget.
    BudgetSortField:
      type: string
      enum:
      - BUDGET_SORT_FIELD_EXPIRES_AT
      - BUDGET_SORT_FIELD_CREATED_AT
      - BUDGET_SORT_FIELD_UPDATED_AT
    BudgetLimitsRestResponse:
      type: object
      properties:
        period:
          $ref: '#/components/schemas/BudgetPeriod'
        amount:
          type: number
          format: double
        tokenLimit:
          type: number
          description: "Token ceiling for the budget period. Token counts are whole numbers\n and stored as integers."
          format: double
      description: "BudgetLimits is the per-period spend and token ceiling. At least one\n of `amount`, `token_limit`, or RateLimit.requests_per_minute MUST be\n set on a Budget; that invariant is enforced by the handler."
    BudgetAlertRestResponse:
      required:
      - thresholdPercent
      - notifierIds
      type: object
      properties:
        id:
          type: string
          description: Assigned by ORQ. Supply an existing id to edit that alert in place.
        thresholdPercent:
          type: integer
          description: Percentage of the dimension's limit at which the alert fires, 1–100.
          format: uint32
        notifierIds:
          type: array
          items:
            type: string
          description: Must be workspace-scoped; project-scoped notifiers are rejected.
        dimension:
          description: Defaults to COST when unset.
          $ref: '#/components/schemas/BudgetAlertDimension'
      description: "Notifies every listed notifier once current-period consumption on\n `dimension` reaches `threshold_percent` of the matching limit. Each alert\n fires at most once per period, re-arming on rollover or a limit change.\n The dimension must have a limit set, or the write is rejected. A TOKENS alert is rejected."
    GetBudgetResponse:
      required:
      - budget
      type: object
      properties:
        budget:
          allOf:
          - $ref: '#/components/schemas/BudgetRestResponse'
          description: Requested budget.
    DeleteBudgetResponse:
      type: object
      properties: {}
    ProjectBudgetScopeRestResponse:
      type: object
      properties:
        projectId:
          type: string
      description: Per-project cap.
    BudgetAlertDimension:
      type: string
      enum:
      - BUDGET_ALERT_DIMENSION_COST
      - BUDGET_ALERT_DIMENSION_TOKENS
    BudgetRestResponse:
      required:
      - budgetId
      - limits
      - createdAt
      - updatedAt
      type: object
      properties:
        budgetId:
          type: string
        scope:
          allOf:
          - $ref: '#/components/schemas/BudgetScopeRestResponse'
          description: "Scope the budget was created for, used to group and filter budgets in\n the console. Not used for matching: the `match` expression decides\n which requests a budget applies to. Unset for budgets created from a\n raw CEL expression (\"custom\")."
        match:
          allOf:
          - $ref: '#/components/schemas/BudgetMatch'
          description: "The matching semantics of the budget. A budget applies to a request\n when `match.cel` evaluates to true against the request context.\n Creating a budget for a scope derives the expression for that scope\n (e.g. `provider == \"openai\"`); an empty expression matches every\n request in the workspace."
        limits:
          $ref: '#/components/schemas/BudgetLimitsRestResponse'
        rateLimit:
          $ref: '#/components/schemas/RateLimitRestResponse'
        isActive:
          type: boolean
          default: false
        expiresAt:
          type: string
          format: date-time
        createdAt:
          type: string
          format: date-time
        updatedAt:
          type: string
          format: date-time
        usage:
          allOf:
          - $ref: '#/components/schemas/BudgetUsage'
          description: "Latest available consumption used for enforcement in the current\n period. This is not an exact billing ledger. Populated by read paths\n (Get / List); omitted on write responses (Create / Update / Reset)\n where it carries no signal. Absent or all-zero for a budget that\n has not been spent against in the current period."
        alerts:
          type: array
          items:
            $ref: '#/components/schemas/BudgetAlertRestResponse'
          description: Threshold notifications. Absent when the budget has none.
      description: Budget defines limits and matching rules used to govern consumption.
    IdentityBudgetScope:
      type: object
      properties:
        identity_external_id:
          type: string
      description: "Per-identity cap. Keyed by the contact's external identifier so the\n scope is stable across imports."
    ModelBudgetScopeRestResponse:
      required:
      - modelId
      type: object
      properties:
        modelId:
          type: string
      description: "Per-model cap. The value is the FULL model reference as callers send\n it (\"openai/gpt-4o\", or \"workspaceKey@openai/gpt-4o\" for private\n models)."
    BudgetMatch:
      type: object
      properties:
        cel:
          type: string
      description: 'CEL expression that decides whether a budget applies to a request. Available variables: `model`, `provider`, `model_id`, `api_key`, `identity`, `project`, `metadata` (map), `headers` (map, lowercase keys). An empty expression always matches. Expressions are syntax-validated at write time.'
  securitySchemes:
    ApiKey:
      type: http
      scheme: bearer
      bearerFormat: JWT
externalDocs:
  url: https://docs.orq.ai
  description: orq.ai Documentation
x-speakeasy-timeout: 600000