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/classquill-com:classquill-com-pricing-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: ClassQuill Public Pricing API
description: 'REST API for ClassQuill tutoring organisations. Pipe your sessions, invoices, payments, tutor earnings, students, and more into your own tools. Most endpoints are reads; a focused set of writes (each gated by a *:write scope) create or update data, including creating student/tutor/parent accounts.
Authenticate every request with an org API key:
Authorization: Token token=cq_live_...
Mint keys in the ClassQuill app under Settings → Developers.'
version: 1.0.0
security:
- ApiKeyAuth: []
tags:
- name: Pricing
paths:
/v1/rate-cells:
get:
tags:
- Pricing
summary: List Rate Cells
description: 'List the org''s rate-matrix cells — student rates per (band × tier × subject ×
session kind), plus the in-person surcharge.
Scoped directly by `organization_id`. Tutor-pay fields are pay-sensitive and
only included when `include_pay=true`.'
operationId: list_rate_cells_v1_rate_cells_get
parameters:
- name: band_id
in: query
required: false
schema:
anyOf:
- type: string
- type: 'null'
description: Filter by rate band UUID
title: Band Id
description: Filter by rate band UUID
- name: tutor_tier_id
in: query
required: false
schema:
anyOf:
- type: string
- type: 'null'
description: Filter by tutor tier UUID
title: Tutor Tier Id
description: Filter by tutor tier UUID
- name: subject_id
in: query
required: false
schema:
anyOf:
- type: string
- type: 'null'
description: Filter by subject id, e.g. methods_34
title: Subject Id
description: Filter by subject id, e.g. methods_34
- name: session_kind
in: query
required: false
schema:
anyOf:
- type: string
- type: 'null'
description: 1on1_online, 1on1_inperson, group, classroom
title: Session Kind
description: 1on1_online, 1on1_inperson, group, classroom
- name: include_pay
in: query
required: false
schema:
type: boolean
description: Include pay-sensitive tutor-pay fields (tutor_pay_mode, tutor_pay_pct, tutor_flat_rate_cents). Default false.
default: false
title: Include Pay
description: Include pay-sensitive tutor-pay fields (tutor_pay_mode, tutor_pay_pct, tutor_flat_rate_cents). Default false.
- name: cursor
in: query
required: false
schema:
anyOf:
- type: string
- type: 'null'
description: Opaque cursor from a previous response's meta.next_cursor, or the literal 'start' to begin cursor paging from the newest record. When set, offset is ignored and results page by a stable (created_at, id) keyset — recommended for large or incremental syncs.
title: Cursor
description: Opaque cursor from a previous response's meta.next_cursor, or the literal 'start' to begin cursor paging from the newest record. When set, offset is ignored and results page by a stable (created_at, id) keyset — recommended for large or incremental syncs.
- name: limit
in: query
required: false
schema:
type: integer
maximum: 100
minimum: 1
description: Records per page (default 20, max 100)
default: 20
title: Limit
description: Records per page (default 20, max 100)
- name: offset
in: query
required: false
schema:
type: integer
minimum: 0
description: Pagination offset (ignored when cursor is set)
default: 0
title: Offset
description: Pagination offset (ignored when cursor is set)
responses:
'200':
description: Successful Response
content:
application/json:
schema:
$ref: '#/components/schemas/Page_RateCell_'
'422':
description: Validation error — `error.details.errors` lists the fields.
content:
application/json:
schema:
$ref: '#/components/schemas/ApiError'
'401':
description: Missing, malformed, revoked, or expired credentials.
content:
application/json:
schema:
$ref: '#/components/schemas/ApiError'
'403':
description: The credential lacks the scope this endpoint requires.
content:
application/json:
schema:
$ref: '#/components/schemas/ApiError'
'429':
description: Rate limit exceeded — honour Retry-After and the RateLimit-* headers.
content:
application/json:
schema:
$ref: '#/components/schemas/ApiError'
/v1/rate-bands:
get:
tags:
- Pricing
summary: List Rate Bands
description: 'List the org''s named student price bands, in the org''s configured sort order.
Scoped directly by `organization_id`. Pairs with `rate-cells.band_id`.'
operationId: list_rate_bands_v1_rate_bands_get
parameters:
- name: cursor
in: query
required: false
schema:
anyOf:
- type: string
- type: 'null'
description: Opaque cursor from a previous response's meta.next_cursor, or the literal 'start' to begin cursor paging from the newest record. When set, offset is ignored and results page by a stable (created_at, id) keyset — recommended for large or incremental syncs.
title: Cursor
description: Opaque cursor from a previous response's meta.next_cursor, or the literal 'start' to begin cursor paging from the newest record. When set, offset is ignored and results page by a stable (created_at, id) keyset — recommended for large or incremental syncs.
- name: limit
in: query
required: false
schema:
type: integer
maximum: 100
minimum: 1
description: Records per page (default 20, max 100)
default: 20
title: Limit
description: Records per page (default 20, max 100)
- name: offset
in: query
required: false
schema:
type: integer
minimum: 0
description: Pagination offset (ignored when cursor is set)
default: 0
title: Offset
description: Pagination offset (ignored when cursor is set)
responses:
'200':
description: Successful Response
content:
application/json:
schema:
$ref: '#/components/schemas/Page_RateBand_'
'422':
description: Validation error — `error.details.errors` lists the fields.
content:
application/json:
schema:
$ref: '#/components/schemas/ApiError'
'401':
description: Missing, malformed, revoked, or expired credentials.
content:
application/json:
schema:
$ref: '#/components/schemas/ApiError'
'403':
description: The credential lacks the scope this endpoint requires.
content:
application/json:
schema:
$ref: '#/components/schemas/ApiError'
'429':
description: Rate limit exceeded — honour Retry-After and the RateLimit-* headers.
content:
application/json:
schema:
$ref: '#/components/schemas/ApiError'
/v1/tutor-tiers:
get:
tags:
- Pricing
summary: List Tutor Tiers
description: 'List the org''s tutor pay/qualification tiers, in the org''s configured sort
order. Names and labels only — no money.
Scoped directly by `organization_id`. Pairs with `rate-cells.tutor_tier_id`.'
operationId: list_tutor_tiers_v1_tutor_tiers_get
parameters:
- name: cursor
in: query
required: false
schema:
anyOf:
- type: string
- type: 'null'
description: Opaque cursor from a previous response's meta.next_cursor, or the literal 'start' to begin cursor paging from the newest record. When set, offset is ignored and results page by a stable (created_at, id) keyset — recommended for large or incremental syncs.
title: Cursor
description: Opaque cursor from a previous response's meta.next_cursor, or the literal 'start' to begin cursor paging from the newest record. When set, offset is ignored and results page by a stable (created_at, id) keyset — recommended for large or incremental syncs.
- name: limit
in: query
required: false
schema:
type: integer
maximum: 100
minimum: 1
description: Records per page (default 20, max 100)
default: 20
title: Limit
description: Records per page (default 20, max 100)
- name: offset
in: query
required: false
schema:
type: integer
minimum: 0
description: Pagination offset (ignored when cursor is set)
default: 0
title: Offset
description: Pagination offset (ignored when cursor is set)
responses:
'200':
description: Successful Response
content:
application/json:
schema:
$ref: '#/components/schemas/Page_TutorTier_'
'422':
description: Validation error — `error.details.errors` lists the fields.
content:
application/json:
schema:
$ref: '#/components/schemas/ApiError'
'401':
description: Missing, malformed, revoked, or expired credentials.
content:
application/json:
schema:
$ref: '#/components/schemas/ApiError'
'403':
description: The credential lacks the scope this endpoint requires.
content:
application/json:
schema:
$ref: '#/components/schemas/ApiError'
'429':
description: Rate limit exceeded — honour Retry-After and the RateLimit-* headers.
content:
application/json:
schema:
$ref: '#/components/schemas/ApiError'
components:
schemas:
Page_TutorTier_:
properties:
data:
items:
$ref: '#/components/schemas/TutorTier'
type: array
title: Data
meta:
$ref: '#/components/schemas/PageMeta'
type: object
required:
- data
- meta
title: Page[TutorTier]
ApiErrorBody:
description: The `error` object every /v1 error response carries.
properties:
code:
description: 'Stable machine-readable error code: bad_request, unauthorized, forbidden, not_found, conflict, validation_error, rate_limited, or internal_error.'
examples:
- not_found
title: Code
type: string
message:
description: Human-readable explanation, safe to surface to end users.
examples:
- Session not found
title: Message
type: string
status:
description: The HTTP status code, repeated in the body.
examples:
- 404
title: Status
type: integer
details:
additionalProperties: true
description: Error-specific context. 422 carries the field errors under `errors`; 429 carries `retry_after_seconds`.
title: Details
type: object
required:
- code
- message
- status
title: ApiErrorBody
type: object
ApiError:
description: Canonical error envelope for every /v1 error response (4xx/5xx).
properties:
error:
$ref: '#/components/schemas/ApiErrorBody'
required:
- error
title: ApiError
type: object
RateCell:
properties:
id:
type: string
title: Id
band_id:
anyOf:
- type: string
- type: 'null'
title: Band Id
tutor_tier_id:
anyOf:
- type: string
- type: 'null'
title: Tutor Tier Id
subject_id:
anyOf:
- type: string
- type: 'null'
title: Subject Id
session_kind:
anyOf:
- type: string
- type: 'null'
title: Session Kind
student_rate_cents:
anyOf:
- type: integer
- type: 'null'
title: Student Rate Cents
inperson_surcharge_cents:
anyOf:
- type: integer
- type: 'null'
title: Inperson Surcharge Cents
tutor_pay_mode:
anyOf:
- type: string
- type: 'null'
title: Tutor Pay Mode
tutor_pay_pct:
anyOf:
- type: number
- type: 'null'
title: Tutor Pay Pct
tutor_flat_rate_cents:
anyOf:
- type: integer
- type: 'null'
title: Tutor Flat Rate Cents
created_at:
anyOf:
- type: string
- type: 'null'
title: Created At
type: object
required:
- id
title: RateCell
description: 'One cell of the org rate matrix (band × tier × subject × session_kind).
Tutor-pay fields (tutor_pay_mode, tutor_pay_pct, tutor_flat_rate_cents) are
pay-sensitive and only populated when `include_pay=true`.'
RateBand:
properties:
id:
type: string
title: Id
name:
anyOf:
- type: string
- type: 'null'
title: Name
sort_order:
anyOf:
- type: integer
- type: 'null'
title: Sort Order
created_at:
anyOf:
- type: string
- type: 'null'
title: Created At
type: object
required:
- id
title: RateBand
description: A named student price band (Teachworks Services parity).
PageMeta:
properties:
limit:
type: integer
title: Limit
offset:
anyOf:
- type: integer
- type: 'null'
title: Offset
count:
anyOf:
- type: integer
- type: 'null'
title: Count
total:
anyOf:
- type: integer
- type: 'null'
title: Total
next_cursor:
anyOf:
- type: string
- type: 'null'
title: Next Cursor
description: 'Cursor-mode only: pass as ?cursor= to fetch the next page; null when this is the last page.'
type: object
required:
- limit
title: PageMeta
description: 'Pagination envelope metadata. `count` is the size of the returned page;
`total` (when present) is the full result-set size for offset paging.
In cursor mode `offset`/`total` are absent and `next_cursor` carries the
opaque token for the next page (null on the last page).'
Page_RateCell_:
properties:
data:
items:
$ref: '#/components/schemas/RateCell'
type: array
title: Data
meta:
$ref: '#/components/schemas/PageMeta'
type: object
required:
- data
- meta
title: Page[RateCell]
Page_RateBand_:
properties:
data:
items:
$ref: '#/components/schemas/RateBand'
type: array
title: Data
meta:
$ref: '#/components/schemas/PageMeta'
type: object
required:
- data
- meta
title: Page[RateBand]
TutorTier:
properties:
id:
type: string
title: Id
name:
anyOf:
- type: string
- type: 'null'
title: Name
badge_label:
anyOf:
- type: string
- type: 'null'
title: Badge Label
description:
anyOf:
- type: string
- type: 'null'
title: Description
sort_order:
anyOf:
- type: integer
- type: 'null'
title: Sort Order
created_at:
anyOf:
- type: string
- type: 'null'
title: Created At
type: object
required:
- id
title: TutorTier
description: 'A tutor pay/qualification tier (Teachworks Wage Tiers parity). Names and
labels only — no money.'
securitySchemes:
ApiKeyAuth:
type: apiKey
in: header
name: Authorization
description: Org API key as `Token token=cq_live_...`