Docs / Quotes Data API / Endpoints / List quotations
List quotations
Returns the active quotation pool, newest first. A quotation has no publication date of its own -- a line from Meditations is not "posted" -- so the only honest ordering is when the platform received it.
Query parameters
| Parameter | Type | Description |
|---|---|---|
q |
string | Full-text match on the quotation and its author. |
author |
string | Author name. |
category |
string | The upstream's own label. |
active |
string | Which half of the pool. `true` (the default) is the curated quotations; `false` is the bulk archive imported from the upstream and never published there; `any` is both. The archive is large and unvetted -- some of it is a mis-parsed CSV whose author field holds part of the quotation -- which is why it is opt-in rather than the default. |
limit |
integer | Items per page, 1–100. Defaults to 25. |
cursor |
string | Opaque cursor from a previous response's meta.next. Do not construct one. |
order |
string | Sort field: `ingested_at`, each optionally prefixed with `-` to reverse. Default is `-ingested_at`. Rows with no value for the sort column always sort LAST in either direction, so paging never leads with undated rows. |
source |
string | Restrict to ONE scraper source, by its stem — `abb`, not `ABB` or `abb-bank.az`. Not a list: `?source=a,b` and a repeated `?source=` do not select two sources. On `/v1/jobs` an unknown stem is a `400` naming it, and `source_type` is the way to select several sources at once. `GET /v1/sources` lists every stem. |
Request
curl -G https://api.softon.dev/v1/quotes \
-H "Authorization: Bearer $SOFTON_KEY" \
-d q=courage -d active=any -d limit=50
req, _ := http.NewRequestWithContext(ctx, "GET", "https://api.softon.dev/v1/quotes", nil) req.Header.Set("Authorization", "Bearer "+os.Getenv("SOFTON_KEY")) q := req.URL.Query() q.Set("q", "courage") q.Set("active", "any") q.Set("limit", "50") req.URL.RawQuery = q.Encode() res, err := http.DefaultClient.Do(req) if err != nil { log.Fatal(err) } defer res.Body.Close() var page struct { Data []Quote `json:"data"` Meta struct{ Next *string `json:"next"` } `json:"meta"` } if err := json.NewDecoder(res.Body).Decode(&page); err != nil { log.Fatal(err) } // page.Meta.Next → send it back as ?cursor= for the following page
import json, os, urllib.parse, urllib.request url = "https://api.softon.dev/v1/quotes" + "?" + urllib.parse.urlencode({ "q": "courage", "active": "any", "limit": "50", }) req = urllib.request.Request(url, headers={ "Authorization": "Bearer " + os.environ["SOFTON_KEY"], }) page = json.load(urllib.request.urlopen(req)) # page["meta"]["next"] → send it back as ?cursor= for the following page
const url = new URL("https://api.softon.dev/v1/quotes"); url.searchParams.set("q", "courage"); url.searchParams.set("active", "any"); url.searchParams.set("limit", "50"); const res = await fetch(url, { headers: { Authorization: `Bearer ${process.env.SOFTON_KEY}` }, }); if (!res.ok) throw new Error(`${res.status} ${await res.text()}`); const { data, meta } = await res.json(); // meta.next → send it back as ?cursor= for the following page
Response
The envelope is identical on every softon.dev API: data, meta, error. Only the shape inside data changes per dataset — see the response envelope.
{
"data": [
{
"id": "birjob:1766",
"source": "birjob",
"text": "Don\u2019t let others tell you what you can\u2019t do.",
"author": "Roy T. Bennett",
"category": "Believe In Yourself",
"origin": "passiton",
"ingested_at": "2026-08-06T07:29:46.646799Z"
}
],
"meta": { "count": 1, "next": "eyJvIjoyfQ", "request_id": "req_9Fv3" },
"error": null
}
Fields of each item in data[]
| Field | Type | Description |
|---|---|---|
id |
string | Stable identifier, "<source>:<source id>". |
source |
string | Which scraper delivered this quotation. |
text |
string | The quotation. |
author |
string · nullable | Attributed author. null where the collection does not name one. |
category |
string · nullable | The upstream's own label. A folksonomy, not an enum -- tens of thousands of distinct values -- so treat it as a tag rather than a fixed set. |
origin |
string · nullable | Where the quotation was collected from, e.g. "passiton". Distinct from source, which is the scraper that delivered it. |
ingested_at |
timestamp | When this version was stored. |
Try it
Send the request to see a response.