API plugin
Exposes a single endpoint, GET /api/content.json, that returns every indexable item across every content plugin (Academy, Blog, Docs, FAQ, Pages) as a flat JSON list, via ContentService::allContent() — the same aggregation the Sitemap plugin uses. This is the feed an external pipeline (e.g. a tokenizer that loads embeddings into Qdrant) is meant to consume, and it is the source of truth external tools index against — not a page-by-page crawl of the website.
{
"meta": {
"count": 424,
"url": "https://example.com/",
"generated": "2026-08-17 16:52:39"
},
"data": [
{
"id": "docs_doc_facturacion_anular-dte",
"checksum": "b256587c...",
"type": "docs",
"category": "doc",
"uri": "facturacion/anular-dte",
"link": "https://example.com/docs/facturacion/anular-dte.json",
"image": null,
"title": "Anular un DTE",
"description": "Pasos para anular un Documento Tributario Electrónico",
"authors": [{ "name": "Anonymous", "slug": "anonymous" }],
"tags": [{ "name": "facturacion", "slug": "facturacion", "count": 12 }],
"date": "2026-03-12",
"last_update": "2026-03-12",
"time": 2
}
]
}
Items with an empty body (data()), or that are not indexable (see generic frontmatter), are skipped.
Configuration (services.yaml)
None. Enabling the plugin (api: ~) is all that’s needed — it has no options of its own, it only reads whatever the Academy/Blog/Docs/FAQ/Pages plugins already loaded.
parameters:
derafu.content.config:
plugins:
api: ~
Filtering
The endpoint accepts the same filters as ContentRegistry::filter() as query parameters — for example /api/content.json?type=docs&tag=facturacion&limit=20&page=1. Useful keys: type, category, tag, author, search, year+month, indexable, searchable, limit, page.
Content frontmatter
Not applicable — this plugin has no content items of its own, it aggregates the ones from the plugins that do.