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-files-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 Files API
version: 1.4.3
contact:
name: Sapling AI
url: https://sapling.ai
termsOfService: https://sapling.ai/terms
description: 'Operations tagged files 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: PDF/Word text extraction and text chunking.
name: Files
paths:
/api/v1/ingest/chunk_html:
post:
description: Like chunk_text, for HTML input. Not billed.
externalDocs:
url: https://sapling.ai/docs/api/chunk/
operationId: sapling_chunk_html
requestBody:
content:
application/json:
schema:
properties:
html:
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
max_length:
description: 'Maximum chunk length in characters. Required in practice: omitting it answers 400.'
minimum: 1
type: integer
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
step_size:
default: 0
description: Characters to advance between chunk starts; 0 means 10% of max_length.
minimum: 0
type: integer
required:
- html
- max_length
type: object
required: true
responses:
'200':
content:
application/json:
schema:
properties:
chunks:
items:
type: string
type: array
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: Chunks in document order.
'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: 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: Split HTML into chunks
tags:
- Files
servers:
- description: The deployment serving this document
url: https://api.sapling.ai
/api/v1/ingest/chunk_text:
post:
description: Split long text into overlapping chunks no longer than `max_length`, preferring sentence and whitespace boundaries. Not billed.
externalDocs:
url: https://sapling.ai/docs/api/chunk/
operationId: sapling_chunk_text
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
max_length:
description: 'Maximum chunk length in characters. Required in practice: omitting it answers 400.'
minimum: 1
type: integer
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
step_size:
default: 0
description: Characters to advance between chunk starts; 0 means 10% of max_length.
minimum: 0
type: integer
text:
type: string
required:
- text
- max_length
type: object
required: true
responses:
'200':
content:
application/json:
schema:
properties:
chunks:
items:
type: string
type: array
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: Chunks in document order.
'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: 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: Split text into chunks
tags:
- Files
servers:
- description: The deployment serving this document
url: https://api.sapling.ai
/api/v1/ingest/docx_to_text:
post:
description: Upload a .docx and receive its text, tables included in document order. Not billed.
externalDocs:
url: https://sapling.ai/docs/api/files/
operationId: sapling_docx_to_text
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
- description: 'Sapling API key, as an alternative to the "Authorization: Bearer <key>" header.'
in: query
name: key
required: false
schema:
type: string
requestBody:
content:
multipart/form-data:
schema:
properties:
file:
description: The document to upload.
format: binary
type: string
jsonParams:
description: 'Optional part carrying a JSON object, e.g. {"key": "<API key>", "return_usage": true}, as an alternative to the query or header credential. Send it as a file part.'
format: binary
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
required:
- file
type: object
required: true
responses:
'200':
content:
application/json:
schema:
properties:
text:
type: string
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: Extracted text.
'400':
content:
application/json:
schema:
properties:
error:
type: string
type: object
description: 'Missing `file` part, unsupported extension, or the document could not be read (empty, encrypted, corrupt, or no extractable text). Body: {"error": "<reason>"}. A request with no API key at all also answers 400 {"error": "Unauthenticated"}.'
'401':
$ref: '#/components/responses/Unauthorized'
'402':
$ref: '#/components/responses/PaymentRequired'
'403':
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
description: MCP OAuth access tokens are not accepted by this operation; send an API key.
'413':
content:
application/json:
schema:
properties:
error:
type: string
type: object
description: 'The uploaded file is over 30MB. Body: {"error": "<reason>"}.'
'429':
$ref: '#/components/responses/UploadRateLimited'
'500':
$ref: '#/components/responses/InternalError'
security:
- bearerAuth: []
- {}
summary: Extract text from a Word document
tags:
- Files
servers:
- description: The deployment serving this document
url: https://api.sapling.ai
/api/v1/ingest/pdf_to_text:
post:
description: Upload a PDF and receive its text, with layout line breaks and hyphenation repaired. Owner-locked PDFs are decrypted transparently; image-only PDFs answer 400. Not billed.
externalDocs:
url: https://sapling.ai/docs/api/files/
operationId: sapling_pdf_to_text
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
- description: 'Sapling API key, as an alternative to the "Authorization: Bearer <key>" header.'
in: query
name: key
required: false
schema:
type: string
requestBody:
content:
multipart/form-data:
schema:
properties:
file:
description: The document to upload.
format: binary
type: string
jsonParams:
description: 'Optional part carrying a JSON object, e.g. {"key": "<API key>", "return_usage": true}, as an alternative to the query or header credential. Send it as a file part.'
format: binary
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
required:
- file
type: object
required: true
responses:
'200':
content:
application/json:
schema:
properties:
text:
type: string
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: Extracted text.
'400':
content:
application/json:
schema:
properties:
error:
type: string
type: object
description: 'Missing `file` part, unsupported extension, or the document could not be read (empty, encrypted, corrupt, or no extractable text). Body: {"error": "<reason>"}. A request with no API key at all also answers 400 {"error": "Unauthenticated"}.'
'401':
$ref: '#/components/responses/Unauthorized'
'402':
$ref: '#/components/responses/PaymentRequired'
'403':
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
description: MCP OAuth access tokens are not accepted by this operation; send an API key.
'413':
content:
application/json:
schema:
properties:
error:
type: string
type: object
description: 'The uploaded file is over 30MB. Body: {"error": "<reason>"}.'
'429':
$ref: '#/components/responses/UploadRateLimited'
'500':
$ref: '#/components/responses/InternalError'
security:
- bearerAuth: []
- {}
summary: Extract text from a PDF
tags:
- Files
servers:
- description: The deployment serving this document
url: https://api.sapling.ai
components:
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.
UploadRateLimited:
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
description: Too many uploads in the last minute. No Retry-After or rate-limit headers are sent; back off and retry.
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:".
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'
headers:
RetryAfter:
description: Seconds to wait before retrying.
schema:
type: integer
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