Files
RenewCMS/docs/llm/gotchas.md
T

68 lines
3.2 KiB
Markdown

# Gotchas
> What trips up API clients: session-only routes, error texts, rate limits and draft visibility.
## Session-only routes
An API key cannot call these routes. They answer `403` with a plain-text body and no JSON:
```
HTTP/1.1 403 Forbidden
This action needs a real session.
```
- `/v1/api-key/*`, `/v1/system/*`, `POST /v1/auth/verify`, `DELETE /v1/auth/register`.
- Every activity route under `/v1/activity`.
- Writes on sites (`POST`, `PATCH`, `DELETE` under `/v1/site`, so a key cannot create a site) and on authors (`POST`, `PATCH`, `DELETE` under `/v1/author`).
- `PATCH /v1/settings`.
Variant routes under `/v1/media/{id}/variants` answer `401` to a key instead. The sign-in routes (login, logout, register, password reset) ignore a key and give no `403`.
When a task needs one of these routes, stop and tell the user to do it in the app. Do not try to log in with a password.
## Error texts are plain text
Errors are not JSON. The body is one sentence; branch on the status code, and show the sentence to the user.
| Status | Typical text |
| --- | --- |
| `400` | `The request cannot be processed due to a mismatch in the format of the body.` |
| `401` | `You must be logged in to access this resource.` |
| `403` | `This action needs a real session.`, `Only the owner can do this.`, `Only owners and admins can do this.`, `You must verify your account to access this resource.` |
| `404` | `Article not found`, `Image not found` |
| `429` | `Too many requests. Please try again later.` |
An invalid, unknown, expired or revoked key answers `401`, even on public routes. It is never treated as anonymous.
## Rate limit: 429
Each key may make 120 requests per minute. The `429` response carries a `Retry-After` header holding the seconds to wait:
```
HTTP/1.1 429 Too Many Requests
Retry-After: 46
Too many requests. Please try again later.
```
Sleep for `Retry-After` seconds, then retry once. Do not retry in a tight loop. Prefer one list call with `size=100` over many single reads.
## Draft versus online
- Anonymous callers and unverified users only see online articles. A draft answers `404` with `Article not found`, the same as an id that does not exist.
- A verified session or a key sees drafts as well. In lists, `counts.draft` is `0` for anonymous callers and `status=draft` answers an empty page.
- `POST /v1/article/` always creates a draft. Publishing is a separate call, `PATCH /v1/article/{id}/publish`.
- Sitemaps list online articles only.
## Writes
- A title cannot be changed after creation. Create a new article instead.
- `PATCH /v1/article/{id}` accepts `body`, `site_id`, `author_ids` and the SEO fields only. `{}` and `null` values answer `400`, except `cover_image_id` and `social_image_id`, where `null` removes the image.
- Request bodies are HTML even though responses default to markdown. Send `<p>` and `<h2>`, not markdown syntax, or it is stored literally.
- Ids in paths are unsigned integers. Anything else answers `400`.
## 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.