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.
Call it yourself
curl for this page
This API
curl "https://apis.io/api/v1/apis/sapling:sapling-account-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
openapi: 3.2.0
info:
title: Sapling Account API
version: 1.4.3
contact:
name: Sapling AI
url: https://sapling.ai
termsOfService: https://sapling.ai/terms
description: 'Operations tagged account across 2 of this provider''s published API definitions: api-sapling-openapi.json, sapling-openapi.json. Each path carries the servers of the definition it was published in.'
servers:
- description: The deployment serving this document
url: https://api.sapling.ai
security:
- bearerAuth: []
- oauth2:
- sapling:api
- {}
tags:
- description: API key status, usage and quota reporting.
name: Account
paths:
/api/v1/account/status:
get:
description: 'One-call self-diagnosis for the presented key: whether billable endpoints will serve it, and if not why (`blocked_reason`) and for how long (`retry_after`). Works even when the key is blocked. The same handler is exposed on POST (sapling_account_status_post). Team-scoped keys receive only the verdict and their own quota.'
externalDocs:
url: https://sapling.ai/docs/api/account-status/
operationId: sapling_account_status
parameters:
- in: query
name: return_usage
required: false
schema:
default: false
description: 'When true, a successful JSON-object response additionally carries "usage": {"characters": <n>} — the billable character count this request submitted (0 for unbilled requests; the 2.5x adjustment for logographic languages is included, so CJK requests report more than their raw length). Repeat texts inside the billing deduplication window are still counted here even though they are not re-charged, so the number is an upper bound on the final charge. Responses whose body is not a JSON object (e.g. bare-array response formats) cannot carry the field. An existing usage field (such as account/status or completion token usage) is preserved unchanged.'
type: boolean
responses:
'200':
content:
application/json:
schema:
properties:
api_access:
type: boolean
blocked_reason:
description: Null when api_access is true, else one of key_expired, credits_depleted, subscription_expired, trial_daily_limit, monthly_billing_limit, monthly_quota_exhausted.
credits:
type: object
message:
description: Human-readable reason, or null.
retry_after:
description: Seconds until the block may clear. Present only when blocked.
type: integer
subscription:
type: object
trial:
type: object
usage:
type: object
type: object
description: Access verdict plus credit, subscription, usage and trial details.
headers:
X-RateLimit-Limit:
$ref: '#/components/headers/XRateLimitLimit'
X-RateLimit-Remaining:
$ref: '#/components/headers/XRateLimitRemaining'
X-RateLimit-Reset:
$ref: '#/components/headers/XRateLimitReset'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
description: The public (client-side) API key cannot query account status. MCP OAuth access tokens are not accepted by this operation; send an API key.
'429':
$ref: '#/components/responses/RateLimited'
'500':
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
description: Unexpected server error. Report persistent occurrences to support@sapling.ai.
headers:
X-RateLimit-Limit:
$ref: '#/components/headers/XRateLimitLimit'
X-RateLimit-Remaining:
$ref: '#/components/headers/XRateLimitRemaining'
X-RateLimit-Reset:
$ref: '#/components/headers/XRateLimitReset'
security:
- bearerAuth: []
- apiKeyQuery: []
summary: Check whether this API key can make billable calls
tags:
- Account
post:
description: POST form of GET /api/v1/account/status (sapling_account_status), for clients that credential via a JSON `key` body. Identical behavior and response.
externalDocs:
url: https://sapling.ai/docs/api/account-status/
operationId: sapling_account_status_post
requestBody:
content:
application/json:
schema:
properties:
key:
description: 'Sapling API key. Required when no "Authorization: Bearer <key>" header is sent; when both are sent, the body key takes precedence over the header.'
type: string
return_usage:
default: false
description: 'When true, a successful JSON-object response additionally carries "usage": {"characters": <n>} — the billable character count this request submitted (0 for unbilled requests; the 2.5x adjustment for logographic languages is included, so CJK requests report more than their raw length). Repeat texts inside the billing deduplication window are still counted here even though they are not re-charged, so the number is an upper bound on the final charge. Responses whose body is not a JSON object (e.g. bare-array response formats) cannot carry the field. An existing usage field (such as account/status or completion token usage) is preserved unchanged.'
type: boolean
type: object
required: false
responses:
'200':
content:
application/json:
schema:
properties:
api_access:
type: boolean
blocked_reason:
description: Null when api_access is true, else one of key_expired, credits_depleted, subscription_expired, trial_daily_limit, monthly_billing_limit, monthly_quota_exhausted.
credits:
type: object
message:
description: Human-readable reason, or null.
retry_after:
description: Seconds until the block may clear. Present only when blocked.
type: integer
subscription:
type: object
trial:
type: object
usage:
type: object
type: object
description: Access verdict plus credit, subscription, usage and trial details.
headers:
X-RateLimit-Limit:
$ref: '#/components/headers/XRateLimitLimit'
X-RateLimit-Remaining:
$ref: '#/components/headers/XRateLimitRemaining'
X-RateLimit-Reset:
$ref: '#/components/headers/XRateLimitReset'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
description: The public (client-side) API key cannot query account status. MCP OAuth access tokens are not accepted by this operation; send an API key.
'429':
$ref: '#/components/responses/RateLimited'
'500':
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
description: Unexpected server error. Report persistent occurrences to support@sapling.ai.
headers:
X-RateLimit-Limit:
$ref: '#/components/headers/XRateLimitLimit'
X-RateLimit-Remaining:
$ref: '#/components/headers/XRateLimitRemaining'
X-RateLimit-Reset:
$ref: '#/components/headers/XRateLimitReset'
security:
- bearerAuth: []
- {}
summary: Check whether this API key can make billable calls
tags:
- Account
servers:
- description: The deployment serving this document
url: https://api.sapling.ai
/api/v1/reporting/api_endpoint_usage:
post:
description: Characters per endpoint, bucketed by day, week or month. The body must be a non-empty JSON object.
externalDocs:
url: https://sapling.ai/docs/api/api-reporting/
operationId: sapling_api_endpoint_usage
requestBody:
content:
application/json:
schema:
minProperties: 1
properties:
end_days_back:
default: 0
description: Window end, in days before today.
minimum: 0
type: integer
interval:
default: Daily
enum:
- Daily
- Weekly
- Monthly
type: string
key:
description: 'Sapling API key. Required when no "Authorization: Bearer <key>" header is sent; when both are sent, the body key takes precedence over the header.'
type: string
return_usage:
default: false
description: 'When true, a successful JSON-object response additionally carries "usage": {"characters": <n>} — the billable character count this request submitted (0 for unbilled requests; the 2.5x adjustment for logographic languages is included, so CJK requests report more than their raw length). Repeat texts inside the billing deduplication window are still counted here even though they are not re-charged, so the number is an upper bound on the final charge. Responses whose body is not a JSON object (e.g. bare-array response formats) cannot carry the field. An existing usage field (such as account/status or completion token usage) is preserved unchanged.'
type: boolean
start_days_back:
default: 6
description: Window start, in days before today.
minimum: 0
type: integer
type: object
required: true
responses:
'200':
content:
application/json:
schema:
properties:
data:
type: object
last_updated:
description: ISO timestamp, or null.
usage:
description: 'Present only when the request sent return_usage: true. characters is the billable character count the request submitted; see the return_usage request field for the exact semantics.'
properties:
characters:
type: integer
type: object
type: object
description: '{"data": {endpoint: {bucket: characters}}, "last_updated"}.'
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'402':
$ref: '#/components/responses/PaymentRequired'
'403':
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
description: The requested window reaches further back than the maximum reporting range (about one year). MCP OAuth access tokens are not accepted by this operation; send an API key.
'413':
$ref: '#/components/responses/PayloadTooLarge'
'500':
$ref: '#/components/responses/InternalError'
security:
- bearerAuth: []
- {}
summary: API usage by endpoint over time
tags:
- Account
servers:
- description: The deployment serving this document
url: https://api.sapling.ai
/api/v1/reporting/api_quota_usage:
post:
description: Quota, characters used, and suggestion accept/ignore counts over a window of days. Send a JSON body (it may be `{}`).
externalDocs:
url: https://sapling.ai/docs/api/api-reporting/
operationId: sapling_api_quota_usage
requestBody:
content:
application/json:
schema:
properties:
end_days_back:
default: 0
description: Window end, in days before today.
minimum: 0
type: integer
key:
description: 'Sapling API key. Required when no "Authorization: Bearer <key>" header is sent; when both are sent, the body key takes precedence over the header.'
type: string
return_usage:
default: false
description: 'When true, a successful JSON-object response additionally carries "usage": {"characters": <n>} — the billable character count this request submitted (0 for unbilled requests; the 2.5x adjustment for logographic languages is included, so CJK requests report more than their raw length). Repeat texts inside the billing deduplication window are still counted here even though they are not re-charged, so the number is an upper bound on the final charge. Responses whose body is not a JSON object (e.g. bare-array response formats) cannot carry the field. An existing usage field (such as account/status or completion token usage) is preserved unchanged.'
type: boolean
start_days_back:
default: 1
description: Window start, in days before today.
minimum: 0
type: integer
type: object
required: true
responses:
'200':
content:
application/json:
schema:
properties:
accepts:
type: integer
ignores:
type: integer
last_updated:
description: Unix epoch seconds. Falls back to 24h ago when no aggregation timestamp is cached.
type: number
quota:
type: integer
usage:
type: integer
type: object
description: Quota summary.
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'402':
$ref: '#/components/responses/PaymentRequired'
'403':
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
description: The requested window reaches further back than the maximum reporting range (about one year). MCP OAuth access tokens are not accepted by this operation; send an API key.
'500':
$ref: '#/components/responses/InternalError'
security:
- bearerAuth: []
- {}
summary: Quota and usage summary
tags:
- Account
servers:
- description: The deployment serving this document
url: https://api.sapling.ai
/api/v1/reporting/api_usage:
post:
description: Characters and cost over a window of days, broken down by API key, endpoint, day and month. The body is optional.
externalDocs:
url: https://sapling.ai/docs/api/api-reporting/
operationId: sapling_api_usage
requestBody:
content:
application/json:
schema:
properties:
end_days_back:
default: 0
description: Window end, in days before today.
minimum: 0
type: integer
key:
description: 'Sapling API key. Required when no "Authorization: Bearer <key>" header is sent; when both are sent, the body key takes precedence over the header.'
type: string
return_usage:
default: false
description: 'When true, a successful JSON-object response additionally carries "usage": {"characters": <n>} — the billable character count this request submitted (0 for unbilled requests; the 2.5x adjustment for logographic languages is included, so CJK requests report more than their raw length). Repeat texts inside the billing deduplication window are still counted here even though they are not re-charged, so the number is an upper bound on the final charge. Responses whose body is not a JSON object (e.g. bare-array response formats) cannot carry the field. An existing usage field (such as account/status or completion token usage) is preserved unchanged.'
type: boolean
start_days_back:
description: Window start, in days before today. Defaults to the first of this month.
minimum: 0
type: integer
type: object
required: false
responses:
'200':
content:
application/json:
schema:
properties:
by_api_key:
type: object
by_endpoint:
type: object
currency:
type: string
daily_usage:
description: Characters per day.
end_date:
type: string
last_updated:
description: When usage was last aggregated.
monthly_usage:
description: Characters per month.
start_date:
type: string
total_characters:
type: integer
total_cost_usd:
type: number
usage:
description: 'Present only when the request sent return_usage: true. characters is the billable character count the request submitted; see the return_usage request field for the exact semantics.'
properties:
characters:
type: integer
type: object
type: object
description: Usage report.
'400':
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
description: Non-integer or negative day offsets, or start before end.
'401':
$ref: '#/components/responses/Unauthorized'
'402':
$ref: '#/components/responses/PaymentRequired'
'403':
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
description: The requested window reaches further back than the maximum reporting range (about one year). MCP OAuth access tokens are not accepted by this operation; send an API key.
'500':
$ref: '#/components/responses/InternalError'
security:
- bearerAuth: []
- {}
summary: API usage and cost report
tags:
- Account
servers:
- description: The deployment serving this document
url: https://api.sapling.ai
/api/v1/reporting/api_user_activity:
post:
description: Edits shown, accepted and ignored, plus active-user counts (logged-in and anonymous), over a window of days. Send a non-empty JSON body (unlike /api/v1/reporting/api_usage this handler rejects an absent or empty `{}` body with 400); the window defaults to the last 6 days when a field is omitted.
externalDocs:
url: https://sapling.ai/docs/api/api-reporting/
operationId: sapling_api_user_activity
requestBody:
content:
application/json:
schema:
minProperties: 1
properties:
end_days_back:
default: 0
description: Window end, in days before today.
minimum: 0
type: integer
key:
description: 'Sapling API key. Required when no "Authorization: Bearer <key>" header is sent; when both are sent, the body key takes precedence over the header.'
type: string
return_usage:
default: false
description: 'When true, a successful JSON-object response additionally carries "usage": {"characters": <n>} — the billable character count this request submitted (0 for unbilled requests; the 2.5x adjustment for logographic languages is included, so CJK requests report more than their raw length). Repeat texts inside the billing deduplication window are still counted here even though they are not re-charged, so the number is an upper bound on the final charge. Responses whose body is not a JSON object (e.g. bare-array response formats) cannot carry the field. An existing usage field (such as account/status or completion token usage) is preserved unchanged.'
type: boolean
start_days_back:
default: 6
description: Window start, in days before today.
minimum: 0
type: integer
type: object
required: true
responses:
'200':
content:
application/json:
schema:
properties:
active_users:
properties:
anonymous:
type: integer
logged_in:
type: integer
type: object
edits_accepted:
type: integer
edits_ignored:
type: integer
edits_shown:
type: integer
usage:
description: 'Present only when the request sent return_usage: true. characters is the billable character count the request submitted; see the return_usage request field for the exact semantics.'
properties:
characters:
type: integer
type: object
type: object
description: Activity summary.
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'402':
$ref: '#/components/responses/PaymentRequired'
'403':
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
description: The requested window reaches further back than the maximum reporting range (about one year). MCP OAuth access tokens are not accepted by this operation; send an API key.
'413':
$ref: '#/components/responses/PayloadTooLarge'
'500':
$ref: '#/components/responses/InternalError'
security:
- bearerAuth: []
- {}
summary: Suggestion activity and active-user report
tags:
- Account
servers:
- description: The deployment serving this document
url: https://api.sapling.ai
components:
headers:
XRateLimitLimit:
description: Total capacity of the caller's rate-limit bucket.
schema:
type: integer
RetryAfter:
description: Seconds to wait before retrying.
schema:
type: integer
XRateLimitRemaining:
description: Tokens remaining in the caller's rate-limit bucket.
schema:
type: integer
XRateLimitReset:
description: Seconds until the bucket is full again (a delta, not an epoch timestamp).
schema:
type: integer
responses:
Unauthorized:
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
description: Missing or invalid API key or OAuth access token. (An EXPIRED key or subscription answers 402, not 401.)
InternalError:
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
description: Unexpected server error. Report persistent occurrences to support@sapling.ai.
BadRequest:
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
description: Invalid request (malformed JSON, a missing or invalid argument, or an endpoint-level check such as a size limit or empty text). Validator rejections prefix `msg` with "400 Bad Request:".
RateLimited:
content:
application/json:
schema:
allOf:
- $ref: '#/components/schemas/Error'
- properties:
retry_after:
description: Seconds until the request would fit the bucket. Absent when it never can.
type: number
type: object
description: Rate limited. Wait retry_after seconds (also in the Retry-After header) and retry. If retry_after is absent, the request exceeds the bucket capacity and can never succeed unchanged.
headers:
Retry-After:
$ref: '#/components/headers/RetryAfter'
X-RateLimit-Limit:
$ref: '#/components/headers/XRateLimitLimit'
X-RateLimit-Remaining:
$ref: '#/components/headers/XRateLimitRemaining'
X-RateLimit-Reset:
$ref: '#/components/headers/XRateLimitReset'
PayloadTooLarge:
content:
application/json:
schema:
properties:
message:
type: string
result:
type: string
type: object
description: Request body over 4MB. Note the body uses `message` and `result` keys, not the usual `msg`. Applies to requests authenticated via the Authorization header; a body-key-only request over the limit fails authentication instead (401), because the key cannot be read from the oversized body.
PaymentRequired:
content:
application/json:
schema:
allOf:
- $ref: '#/components/schemas/Error'
- properties:
retry_after:
description: Seconds until the trial daily cap resets (next UTC midnight). Present only for the temporary trial-cap case.
type: integer
type: object
description: 'Payment required. Two distinct cases share this status. (1) A PERMANENT block — an expired API key or subscription, or exhausted quota/prepaid credits: renew or top up at https://sapling.ai/api_settings, as re-authenticating or retrying will not help; its `Retry-After` is a conservative backoff hint. (2) A TEMPORARY free-trial block — a trial-only key that hit its daily character cap: this clears on its own when the cap resets at the next UTC midnight, its `Retry-After` states that actual reset, and the body carries a matching numeric `retry_after` field (whose presence also distinguishes the two cases).'
headers:
Retry-After:
$ref: '#/components/headers/RetryAfter'
schemas:
Error:
properties:
msg:
description: Human-readable error message.
type: string
required:
- msg
type: object
securitySchemes:
apiKeyQuery:
description: Sapling API key passed as the `key` query parameter, an alternative to the Authorization bearer header.
in: query
name: key
type: apiKey
bearerAuth:
description: Sapling API key. Language-tool operations also accept an OAuth access token from the Sapling authorization server — see the oauth2 scheme. The key may instead be sent as a `key` field in the JSON body, which takes precedence when both are present.
scheme: bearer
type: http
oauth2:
description: 'OAuth 2.1 authorization code flow with PKCE (S256). Clients may register dynamically (RFC 7591) at https://api.sapling.ai/oauth/register; server metadata is at https://api.sapling.ai/.well-known/oauth-authorization-server. The access token is sent as an `Authorization: Bearer` header and is accepted only on the language-tool operations that advertise OAuth security. Other authenticated operations require an API key.'
flows:
authorizationCode:
authorizationUrl: https://api.sapling.ai/oauth/authorize
refreshUrl: https://api.sapling.ai/oauth/token
scopes:
offline_access: Receive a refresh token so access survives the 24-hour access-token lifetime.
sapling:api: Call the Sapling language-tool endpoints in this document on behalf of the user, billed to the API key they choose at consent.
tokenUrl: https://api.sapling.ai/oauth/token
type: oauth2
externalDocs:
description: API documentation
url: https://sapling.ai/docs/api
x-refined-from:
- api-sapling-openapi.json
- sapling-openapi.json