Skip to main content

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 -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"}'

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, .html or .htm. Uploads are limited to 30MB; a larger file returns 413.

  • 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 to medium).
    • key: optional when you send the key as a bearer token in the Authorization header.
    • return_usage: optional boolean; true adds 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: true when the text was longer than 20,000 characters (the same cap as text). Instead of returning a 400, 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 as text.

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 file part 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 502 and is neither cached nor billed — retry the request.
  • Rate-limited requests return a 429 with a Retry-After header giving the honest backoff in seconds.