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