feat: public API, SEO and existing surfaces

This commit is contained in:
Florian Sylvain committed 2026-11-03 03:58:10 +01:00
1 parent 45fbbc33b1
commit c390fcfe8d
103 files changed
+4476 -231

No files matched your search

+6
View File
@@ -66,3 +66,9 @@ Sleep for `Retry-After` seconds, then retry once. Do not retry in a tight loop.
## Permissions follow the key's creator
A key acts as the user who made it. A key made by a user who is neither owner nor admin cannot do what only owners and admins can, and it answers `403 Only owners and admins can do this.` Check `GET /v1/auth/me` to read the role of the key.
## Languages
- Every article version has a `lang` and a `story_id`; the versions of one article share the `story_id`. List with `lang=fr` to filter a language, and the MCP `list_articles` tool takes `lang`.
- `GET /v1/public/site/{key}/lang/{lang}/article/{slug}` and `GET /v1/public/site/{key}/story/{story_id}` return only published versions, with `alternates`. Fallback is never silent: ask for it with `fallback=default`, and only the default language is tried.
- `GET /v1/article/{id}/seo` adds `lang`, `alternates`, `og.locale_alternates` and `fallbacks.site_text_skipped`. The canonical follows the site Public URL pattern unless the version overrides it.
+11
View File
@@ -79,3 +79,14 @@ curl "{{BASE_URL}}/v1/article/1?format=markdown"
```
Before step 4 this answers `404` with the text `Article not found`, because anonymous callers only see online articles.
## Read a language version (public)
Two public routes, no credential needed (a cookie or key is ignored and a draft is never returned):
```
GET /v1/public/site/journal/lang/fr/article/comment-nous-chiffrons-une-renovation
GET /v1/public/site/journal/story/5?lang=fr&fallback=default
```
The first matches site, language and slug exactly and never falls back (`404 article_not_found`). The second resolves a story: without `lang` it asks for the site default language, and `fallback=default` serves the default-language version when the requested one is not published (`fallback: true`, `requested_lang` keeps the asked language); otherwise `404 language_not_available`. Both answer the article object plus `alternates`, the other published versions of the story in enabled languages (`id`, `lang`, `story_id`, `slug`, `url`; `url` is `null` when the site has no Public URL pattern), default language first, then by tag. An invalid `lang` is `400 invalid_language`.