Summarize API
The summarize endpoint condenses a longer document — an article, call transcript, meeting notes, a whole webpage or an email thread — into a prose summary plus a list of key points. Input may be plain text or HTML: markup is stripped so you can pass a page body as-is.
Good summarization balances two factors: coverage (the salient points of the source must
survive) and compression (the output must be significantly more digestible than the input).
The length option lets you pick where on that trade-off the summary should sit.
You can test the summarize endpoint here.
Sample Code
- cURL
- JavaScript
- Python
curl -X POST https://api.sapling.ai/api/v1/summarize \
-H "Content-Type: application/json" \
-d '{"key":"<api-key>", "text":"Hi, I was charged twice for my order this month. The first charge posted on the 3rd and a second identical charge posted on the 5th. Please refund the duplicate charge to my original payment method.", "length":"short"}'
import axios from 'axios';
async function run(text) {
try {
const response = await axios.post(
'https://api.sapling.ai/api/v1/summarize',
{
key: '<api-key>',
text,
length: 'short',
},
);
const {status, data} = response;
console.log({status});
console.log(JSON.stringify(data, null, 4));
} catch (err) {
const msg = err.response?.data?.msg || err.message;
console.log({err: msg});
}
}
run('Hi, I was charged twice for my order this month. The first charge posted on the 3rd and a second identical charge posted on the 5th. Please refund the duplicate charge to my original payment method.');
import requests
from pprint import pprint
response = requests.post(
"https://api.sapling.ai/api/v1/summarize",
json={
"key": "<api-key>",
"text": "Hi, I was charged twice for my order this month. The first charge posted on the 3rd and a second identical charge posted on the 5th. Please refund the duplicate charge to my original payment method.",
"length": "short"
}
)
if 200 <= response.status_code < 300:
pprint(response.json())
else:
print('Error: ', response.status_code, response.text)
Sample Response
{
"summary": "A customer was charged twice for one order and asks for the duplicate charge to be refunded.",
"key_points": [
"Two identical charges posted for a single order, on the 3rd and the 5th.",
"The customer requests a refund of the duplicate to the original payment method."
],
"length": "short",
"result": "A customer was charged twice for one order and asks for the duplicate charge to be refunded."
}
Batch Requests
To summarize several documents — a queue of support tickets, a folder of meeting notes — in one
request, send texts (a list of 1–10 strings) instead of text. The same length option applies
to every item, and the combined length of all items may be up to 20,000 characters (the same cap as
a single text). Exactly one of text and texts must be provided.
curl -X POST https://api.sapling.ai/api/v1/summarize \
-H "Content-Type: application/json" \
-d '{"key":"<api-key>", "texts": ["First document ...", "Second document ..."], "length": "short"}'
The batch response is {"results": [...]} with one entry per input, in input order; each entry has
exactly the single-response shape above:
{
"results": [
{
"summary": "...",
"key_points": ["...", "..."],
"length": "short",
"result": "..."
},
{
"summary": "...",
"key_points": ["..."],
"length": "short",
"result": "..."
}
]
}
Items are billed individually (a batch of N costs the same as N single requests), and each item is
cached the same way as a single request — batches and single calls share the cache. An item that is
empty after HTML stripping returns a 400 naming its index. If any item fails to summarize, the
whole request returns a 502 and nothing is billed; the items that did succeed are already cached,
so a retry only re-runs the failures.
File Uploads
Reports, papers, contracts and slide decks usually arrive as files. Instead of extracting their text
yourself, you can upload the document to the file endpoint. It reads the document's text and
summarizes it exactly like text.
POST to https://api.sapling.ai/api/v1/file-summarize as multipart/form-data.
-
file(required): the document. The format is chosen by file extension:.pdf,.docx,.pptx,.odt,.txt,.md,.htmlor.htm. Uploads are limited to 30MB; a larger file returns413. -
jsonParams(optional): a JSON object with the options below, sent as a file part or as a plain form field:length: optional, the same values as on/api/v1/summarize(defaults tomedium).key: optional when you send the key as a bearer token in theAuthorizationheader.return_usage: optional boolean;trueadds the character count submitted for metering to the response. It is counted before repeat-request deduplication, so it can exceed what you are billed (see Per-Request Usage).
Any other option returns a
400, so a misspelled"lenght"is never silently read as the default.
curl -X POST https://api.sapling.ai/api/v1/file-summarize \
-H "Authorization: Bearer <api-key>" \
-F "file=@report.pdf" \
-F 'jsonParams={"length": "short"}'
import json
import requests
from pprint import pprint
with open("report.pdf", "rb") as f:
response = requests.post(
"https://api.sapling.ai/api/v1/file-summarize",
headers={"Authorization": "Bearer <api-key>"},
files={"file": f},
data={"jsonParams": json.dumps({"length": "short"})},
)
if 200 <= response.status_code < 300:
pprint(response.json())
else:
print('Error: ', response.status_code, response.text)
The response has the single-request shape (summary, key_points, length, result) plus a
document object:
{
"summary": "Revenue rose 12% on subscription growth, while support costs fell ...",
"key_points": ["...", "..."],
"length": "short",
"result": "Revenue rose 12% on subscription growth, while support costs fell ...",
"document": {
"file_type": "pdf",
"characters": 48210,
"characters_used": 19996,
"truncated": true
}
}
file_type: the extension the document was read as.characters: the length of the text extracted from the file.characters_used: how much of that text was summarized. This is also what is billed.truncated:truewhen the text was longer than 20,000 characters (the same cap astext). Instead of returning a400, only the first 20,000 characters are read, cut back to a word boundary, so the summary covers only that part of the document. To summarize a later section, extract its text yourself and send it astext.
Billing and caching are the same as for text: the same text sent either way shares one cache entry.
An .html or .htm file is converted to text when it is read; text read from any file is
then used as-is rather than markup-stripped again, so a PDF whose text literally contains a <b
keeps it. Problems with the file itself return {"error": "<reason>"}. A 400 here means one
of these:
- the
filepart is missing - the extension is unsupported
- the document is empty, encrypted, corrupt or has no extractable text
Problems with jsonParams or length return {"msg": "..."}. A summarization failure returns a
502 and is not billed. Upload requests are limited to 60 per minute per account; the limit is shared
with the other upload endpoints.
Request Parameters
POST to https://api.sapling.ai/api/v1/summarize
key: String
32-character API key. Can also be supplied via the Authorization header as a bearer token; if both are provided, the key parameter takes precedence.
text: String
Input document to summarize, up to 20,000 characters. May be plain text or HTML (a webpage or email
body): markup is stripped while paragraph and heading boundaries are preserved. Provide exactly one
of text and texts.
texts: List[String]
Batch form (see Batch Requests): 1–10 documents to summarize in one request, each
treated exactly like text above, with a combined length of up to 20,000 characters. The response
becomes {"results": [...]}, one entry per item in input order.
length: String, optional, defaults to medium
Target summary length: short (a sentence or two), medium, or long (a fuller digest of the
source). The same option applies to every item of a batch.
Response Parameters
summary: String
The prose summary.
key_points: List[String]
The source's salient points as short standalone statements, most important first.
length: String
The length option the summary was generated with.
result: String
Mirrors summary. This is the endpoint's original response key, kept for backward compatibility —
prefer summary in new integrations.
Tips
- Results for identical text and options are cached briefly on Sapling's side, so re-requesting the same document is fast and does not produce a different summary.
- A summarization failure returns a
502and is neither cached nor billed — retry the request. - Rate-limited requests return a
429with aRetry-Afterheader giving the honest backoff in seconds.