The Social Rights Advocacy Centre maintains a searchable research collection on social and economic rights, Charter litigation, housing, poverty, equality and international human rights law. The same search that powers this site is available as an open API, so that researchers, reference tools and AI research agents can find and cite the original documents directly.
What is indexed
- Every HTML page on socialrights.ca (and the companion socialrightscura.ca archive).
- Every PDF the site publishes — factums, decisions, UN submissions, reports — indexed page by page, so a result points at the specific page that matches.
- OCR is applied to scanned PDFs where possible, so image-only documents are searchable too.
- The index is rebuilt nightly whenever the site changes. Every response carries a
buildblock that says when it was built and how much it covers.
Endpoint
The API is served for SRAC from jacksaiapps.com. This is the official Social Rights Advocacy Centre search endpoint; there is no separate socialrights.ca host for it.
No authentication, no API key. Plain HTTPS GET; responses are JSON (application/json, UTF-8) and allow cross-origin requests from any page.
Example
curl "https://jacksaiapps.com/srac/public-api/site-search?q=housing&limit=2"
{
"query": "housing",
"results": [
{
"kind": "pdf",
"title": "Volume 11 of Heegsma AR",
"url": "https://www.socialrights.ca/Heegsma/Volume 11 of Heegsma AR.pdf#page=234",
"rel_path": "Heegsma/Volume 11 of Heegsma AR.pdf",
"page": 234,
"snippet": "…the right to adequate <mark>housing</mark> under…",
"snippet_text": "…the right to adequate housing under…",
"score": -12.4
}
],
"scope": { "source_pages": [] },
"build": {
"built_at": "2026-08-11T07:09:26+00:00",
"html_count": 141,
"pdf_count": 1684,
"row_count": 92027,
"citation_count": 1434,
"orphan_count": 755,
"warning_count": 4
}
}
Query parameters
| Parameter | Meaning |
|---|---|
q required | The search query. Terms are stemmed, matched as prefixes and combined with AND, so housing remedy finds documents containing both. An empty query returns no results. |
limit | Maximum number of results. Default 20, maximum 200 (larger values are clamped). |
source_page | Restrict results to one HTML page and the PDFs it links to. Accepts a site-relative path (Brown-v-Alberta.html, /resources/UN/CRC2022.html) or a full socialrights.ca URL. |
source_pages | Repeatable form of source_page (&source_pages=a.html&source_pages=b.html); comma- or newline-separated values are also accepted. Results are limited to those pages and the PDFs they link to. |
Response fields
Results are one per document: all pages of a PDF collapse into its single best-matching page. They are ranked by relevance, with HTML pages ordered above PDFs at equal relevance.
| Field | Meaning |
|---|---|
query | The normalised query that was actually run. |
results | Array of result objects (below). |
scope.source_pages | The normalised source pages the search was restricted to; empty for a full-site search. |
build.built_at | UTC timestamp of the index build that answered the request. |
build.html_count | Number of HTML pages in the index. |
build.pdf_count | Number of PDF documents in the index. |
build.row_count | Total searchable rows (one per HTML page, one per PDF page). |
build.citation_count | Number of page→PDF citation links recorded (what powers source_page). |
build.orphan_count | PDFs indexed that no HTML page links to. |
build.warning_count | Non-fatal warnings raised during the build. |
Each result
| Field | Meaning |
|---|---|
kind | page for an HTML page, pdf for a PDF document. |
title | Document title (the page's <title>, or the PDF's title/filename). |
url | Public URL of the document — cite this. For PDFs it includes a #page=N fragment that opens the matching page. |
rel_path | Path of the document relative to the site root. |
page | 1-based PDF page number of the best-matching page; 0 for HTML pages. |
snippet | The matching passage with query terms wrapped in <mark> tags (HTML-escaped otherwise) — for display in web pages. |
snippet_text | The same passage as plain text, with no markup — for AI and API consumers. |
score | BM25 relevance score. Negative; more negative is a better match. Comparable only within one response. |
Listing the collection
A second endpoint returns a paginated manifest of every indexed document — metadata only, no text — so a client can learn the scope of the collection without harvesting it.
| Parameter | Meaning |
|---|---|
limit | Page size. Default 100, maximum 200. |
offset | Zero-based offset; pass the previous response's next_offset. |
kind | page or pdf to list only one kind. |
source_page | Only that HTML page and the PDFs it links to (same forms as the search endpoint). |
The response has documents, total, offset, limit, next_offset (null on the last page), filters and the same build block. Ordering is by kind (pages first) then path, and is stable for a given index build. Each document has:
| Field | Meaning |
|---|---|
kind, title, url, rel_path | As for search results (the URL carries no page fragment). |
page_count | Number of pages in the PDF where known; null for HTML pages. |
indexed_pages | Rows in the index for this document — PDF pages that yielded text. |
source_pages | For PDFs, the rel_paths of the HTML pages that link to it. These values can be passed straight back to source_page. |
The date a document was indexed is the manifest's build.built_at; the index does not track per-document modification dates.
Rate limits and errors
The API is public and free to use for research, but it runs on modest hardware, so there are limits — set high enough that any reasonable research use will never meet them:
- 300 requests per minute and 3,000 per hour per client IP address;
- 1,200 requests per minute across all clients combined.
Every response includes X-RateLimit-Limit, X-RateLimit-Remaining and X-RateLimit-Reset headers. Over the limit you receive HTTP 429 with a JSON body ({"error": "rate_limit_exceeded", …}) and a Retry-After header — wait that many seconds and retry. Bulk copying of the whole corpus is not what the API is for; if you need the collection for a legitimate project, please get in touch.
While the index is being rebuilt or is otherwise unavailable, the API returns HTTP 503 with an error field and empty results. This is brief and transient; retry shortly.
Machine-readable descriptions
- OpenAPI 3.1: socialrights.ca/openapi.json (also served live at jacksaiapps.com/srac/public-api/openapi.json).
- llms.txt: socialrights.ca/llms.txt — a short plain-text pointer for AI systems.
- Sitemap: socialrights.ca/sitemap.xml.
Terms of use and citation
This API is provided to facilitate research, retrieval, citation, and analysis of materials in the Social Rights Advocacy Centre collection. Please use reasonable request rates and cite original documents using the URLs provided in search results.
Search results are pointers, not the record: always cite and link the original document at its url. Snippets are short excerpts intended to help you find the right document, not a substitute for reading it. The API is read-only and stores no personal data beyond ordinary access logs.
Try it
Press Run to see a live response.