ImageStep Usage API

What this account spent over a window — credits, jobs, items and synchronous calls — grouped by op, API key or day: the number an agent holds a budget against

GitHub OpenAPI

Operations 1

GET /api/v1/usage Usage over a window, grouped #

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/imagestep-dev:imagestep-dev-usage-api"
All apis
curl "https://apis.io/api/v1/apis?limit=25"

Calls without X-API-Key need no key. Calls with it need a paid plan — get a key.

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

imagestep-dev-usage-api-openapi.yml Raw ↑
openapi: 3.2.0
info:
  title: ImageStep Usage API
  description: 'The image step for your automations. Store images as assets, run an op or a preset on them as a job — priced first with `?dryRun=true`, then read, waited on or delivered to a webhook — or transform one image synchronously while you wait. Send `Authorization: ApiKey `; the op catalogue (`/api/v1/ops`) needs no credential.


    **Idempotency:** Endpoints that accept an `Idempotency-Key` header support optional deduplication. Supply a unique key (e.g. a UUID) per logical request. Repeating the same key with the same body replays the stored response (`Idempotency-Replayed: true`) without re-running anything; repeating it with a different body is a 409 `idempotency_key_reuse`. Omitting the header processes the request normally. Keys are retained for 24 hours.


    **Errors** all share one shape: `{"error": {"code", "message", "retryable", "param", "details", "requestId"}}`. Branch on `code`, and let `retryable` — not the status code — decide whether to come back.


    **Rate limits** are published on every response as `RateLimit-Limit`, `RateLimit-Remaining` and `RateLimit-Reset` (seconds). A 429 adds `Retry-After`.


    **A paged list** takes `page` (from 0) and `perPage`, and every page answers `meta.nextCursor`; send it back as `cursor` to read on without counting.


    **Every response carries `X-Request-Id`** — yours if you sent one, ours otherwise — and a failure repeats it as `error.requestId`. It is what finds the request in our logs.


    The error-code table, idempotency, limits and pagination are at https://imagestep.dev/docs/errors; the webhook events at https://imagestep.dev/docs/webhooks; what may change inside v1, and the changelog, at https://imagestep.dev/docs/changelog.'
  contact:
    name: ImageStep Team
    url: https://imagestep.dev/support
  license:
    name: Proprietary
    url: https://imagestep.dev/terms
  version: v1
servers:
- url: https://api.imagestep.dev
  description: Production server
tags:
- name: Usage
  description: 'What this account spent over a window — credits, jobs, items and synchronous calls — grouped by op, API key or day: the number an agent holds a budget against'
paths:
  /api/v1/usage:
    get:
      tags:
      - Usage
      summary: Usage over a window, grouped
      description: 'What was spent over a time window, grouped by atomic op, by API key, or by UTC day, with the

        window''s `total` beside the groups:


        - `jobs` — jobs created in the window

        - `credits` and `items` — what those jobs were charged and how many of their items settled, so far

        - `sync` — synchronous calls (`/images/transform`, `/images/render`) that succeeded and so cost an op from the allowance; never counted in `jobs`. `/images/metadata` is free and not counted


        A job submitted as a raw `type` groups under that type; a console session, which has no key, groups

        under `console`. Days are UTC. Usage lives as long as the job records it comes from, so a window

        older than the plan''s retention reads short.


        USE THIS WHEN:

        - An agent has a budget and needs to know what it has spent, and on what

        - Attributing cost across several keys (one key per agent is the usual shape)


        DO NOT USE WHEN:

        - You need one job''s own cost → `GET /api/v1/jobs/{id}` (`actualCredits`, and `credits` per item)

        - You need every credit movement, top-ups and refunds included → the credit ledger, which a signed-in console session reads and an API key cannot'
      operationId: usage
      parameters:
      - name: from
        in: query
        description: Start of the window, inclusive. `YYYY-MM-DD` (UTC midnight) or an ISO-8601 instant. Defaults to 30 days before `to`; the window may span at most 366 days.
        required: false
        schema:
          type: string
        example: '2026-09-01'
      - name: to
        in: query
        description: End of the window, exclusive — `2026-10-01` ends with the last instant of 30 September. Same formats. Defaults to now.
        required: false
        schema:
          type: string
        example: '2026-10-01'
      - name: groupBy
        in: query
        description: 'What a group is: an op (`op`), an API key (`key`) or a UTC day (`day`)'
        required: false
        schema:
          type: string
          default: op
          enum:
          - op
          - key
          - day
      responses:
        '200':
          description: The window, its total and its groups
          headers:
            RateLimit-Limit:
              description: Requests allowed in the current window
              schema:
                type: integer
                format: int32
            RateLimit-Remaining:
              description: Requests left in the current window
              schema:
                type: integer
                format: int32
            RateLimit-Reset:
              description: Seconds until the window resets
              schema:
                type: integer
                format: int32
            X-Request-Id:
              description: This request's id — echoed from your own `X-Request-Id` when you send one. Identical to `error.requestId` on a failure; quote it when reporting one.
              schema:
                type: string
          content:
            '*/*':
              schema:
                $ref: '#/components/schemas/ApiResponseUsage'
        '400':
          description: '- `invalid_param` on `groupBy` — not `op`, `key` or `day`

            - `invalid_param` on `from` / `to` — neither `YYYY-MM-DD` nor an ISO-8601 instant

            - `invalid_param` on `from` — not before `to`, or the window spans more than 366 days'
          headers:
            RateLimit-Limit:
              description: Requests allowed in the current window
              schema:
                type: integer
                format: int32
            RateLimit-Remaining:
              description: Requests left in the current window
              schema:
                type: integer
                format: int32
            RateLimit-Reset:
              description: Seconds until the window resets
              schema:
                type: integer
                format: int32
            X-Request-Id:
              description: This request's id — echoed from your own `X-Request-Id` when you send one. Identical to `error.requestId` on a failure; quote it when reporting one.
              schema:
                type: string
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '429':
          description: Rate limited — `error.code` is `rate_limited` and `retryable` is true. `Retry-After` says how many seconds to wait.
          headers:
            Retry-After:
              description: Seconds to wait before retrying
              schema:
                type: integer
                format: int32
            RateLimit-Limit:
              description: Requests allowed in the current window
              schema:
                type: integer
                format: int32
            RateLimit-Remaining:
              description: Requests left in the current window
              schema:
                type: integer
                format: int32
            RateLimit-Reset:
              description: Seconds until the window resets
              schema:
                type: integer
                format: int32
            X-Request-Id:
              description: This request's id — echoed from your own `X-Request-Id` when you send one. Identical to `error.requestId` on a failure; quote it when reporting one.
              schema:
                type: string
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
      security:
      - apiKeyAuth: []
components:
  schemas:
    ApiError:
      type: object
      description: Structured error. Present on every 4xx/5xx response, absent on success.
      properties:
        code:
          type: string
          description: Machine-readable error code from a closed set
          example: invalid_param
        message:
          type: string
          description: Human-readable explanation. Never parse this — parse `code`.
          example: 'format must be one of: jpeg, png, webp'
        retryable:
          type: boolean
          description: Whether repeating the same request unchanged could succeed. The whole reason this field exists is that an agent cannot infer it from the status code.
          example: false
        param:
          type: string
          description: Which request parameter the error is about, when it is about one
          example: format
        details:
          type: object
          additionalProperties: {}
          description: Extra machine-readable context, e.g. per-field validation messages
        requestId:
          type: string
          description: 'The id of this request, identical to the `X-Request-Id` response header. Quote it when reporting a failure: it is what finds the request in our logs.'
          example: 9f0c1c2e-6f2a-4f6b-9d3e-0a1b2c3d4e5f
      required:
      - retryable
    Usage:
      type: object
      description: 'Usage over one window: its bounds, the grouping, the total and one bucket per group'
      properties:
        from:
          type: string
          format: date-time
          description: Start of the window, inclusive
        to:
          type: string
          format: date-time
          description: End of the window, exclusive
        groupBy:
          type: string
          description: What each group is
          enum:
          - op
          - key
          - day
        total:
          $ref: '#/components/schemas/Bucket'
          description: The window's totals — the sum of the groups
        groups:
          type: array
          description: One bucket per op, key or day that has any usage, ordered by `key`
          items:
            $ref: '#/components/schemas/Bucket'
    Bucket:
      type: object
      description: What was spent in one group, or in the whole window
      properties:
        key:
          type: string
          description: 'The group: an op name (or the raw type of a job submitted without one), an API key id or `console`, or a UTC date `YYYY-MM-DD`. Absent on the total'
        credits:
          type: integer
          format: int64
          description: Credits charged, for the jobs created in the window
        jobs:
          type: integer
          format: int64
          description: Jobs created in the window
        items:
          type: integer
          format: int64
          description: Items of those jobs that settled
        sync:
          type: integer
          format: int64
          description: Synchronous calls that succeeded and counted against the processing allowance
      required:
      - credits
      - items
      - jobs
      - sync
    ErrorResponse:
      type: object
      description: 'The answer to every failed request: `error` says what went wrong and whether to retry, and nothing else rides beside it — no `data`, no `meta`.'
      properties:
        success:
          type: boolean
          description: Always `false` on a failure
        error:
          $ref: '#/components/schemas/ApiError'
        timestamp:
          type: string
          format: date-time
          description: When the response was generated
      required:
      - error
      - success
    ApiResponseUsage:
      type: object
      description: Standard API response wrapper containing status, message, data and timestamp
      properties:
        success:
          type: boolean
          description: Indicates if the request was successful
          example: true
        message:
          type: string
          description: Human-readable message about the response
          example: Operation completed successfully
        data:
          $ref: '#/components/schemas/Usage'
          description: The response data payload
        timestamp:
          type: string
          format: date-time
          description: Timestamp when the response was generated
          example: '2024-01-15T10:30:45.123Z'
        error:
          $ref: '#/components/schemas/ApiError'
          description: Structured error; present exactly when the request failed
        meta:
          $ref: '#/components/schemas/PageMeta'
          description: Pagination metadata for list responses
      required:
      - data
      - success
    PageMeta:
      type: object
      properties:
        total:
          type: integer
          format: int64
          description: 'Rows matching the filter. Page mode only: a cursor request counts nothing'
        page:
          type: integer
          format: int32
          description: The page served, from 0. Page mode only
        perPage:
          type: integer
          format: int32
          description: Rows per page actually used (out of range is clamped)
        hasMore:
          type: boolean
          description: Whether there is another page
        nextCursor:
          type:
          - string
          - 'null'
          description: Pass back as `cursor` for the rows after this page; null on the last page. Opaque — send it unchanged, with the same filters
  securitySchemes:
    apiKeyAuth:
      type: apiKey
      description: 'API Key authentication. Format: ''ApiKey <your-api-key>''. Note: Only allowlisted endpoints accept API key authentication.'
      name: Authorization
      in: header