Document what the API can do
The markdown had no writing section at all, so posts, blocks, drafts and deletes were only visible in the admin. Adds them with every field, plus date and number rules and the media delete in both places.
This commit is contained in:
+83
@@ -105,6 +105,80 @@ curl -s -X POST -H "Authorization: Bearer $TOKEN" \
|
||||
|
||||
Antwort: `{ "marked": 1 }`, also die Zahl der tatsächlich neu vermerkten Einträge. Unbekannte Kennungen und Einträge fremder Projekte werden still verworfen, die Antwort bleibt 200.
|
||||
|
||||
## Schreiben
|
||||
|
||||
Ein Zugang mit Schreibrecht legt immer Entwürfe an. Veröffentlicht wird von Hand in der Verwaltung.
|
||||
|
||||
### GET /api/v1/post-types
|
||||
|
||||
Die verwaltbaren Beitragsarten mit Schlüssel, Bezeichnung und Farbe. Vor dem Schreiben abfragen statt raten.
|
||||
|
||||
### POST /api/v1/posts
|
||||
|
||||
Legt einen Beitrag als Entwurf an.
|
||||
|
||||
| Feld | Pflicht | Bedeutung |
|
||||
|---|---|---|
|
||||
| `project` | ja | Slug des Projekts |
|
||||
| `title` | ja | höchstens 200 Zeichen |
|
||||
| `type` | ja | Schlüssel einer Beitragsart |
|
||||
| `teaser` | nein | höchstens 500 Zeichen |
|
||||
| `audience` | nein | `internal`, `customer` oder `public`, Standard `internal` |
|
||||
| `author_name` | nein | sonst der Name des Zugangs |
|
||||
| `slug` | nein | sonst aus dem Titel gebildet |
|
||||
| `cover_media_id` | nein | Kennung eines hochgeladenen Bildes |
|
||||
| `publish_at` | nein | gewünschtes Datum, siehe unten |
|
||||
| `blocks` | nein | Inhalt, höchstens 100 Blöcke |
|
||||
| `idempotency_key` | nein | derselbe Schlüssel liefert denselben Beitrag zurück |
|
||||
|
||||
```bash
|
||||
curl -s -X POST -H "Authorization: Bearer $TOKEN" \
|
||||
-H "content-type: application/json" \
|
||||
-d '{
|
||||
"project": "trakk",
|
||||
"title": "SLA-Uhr zählt Feiertage nicht mehr mit",
|
||||
"teaser": "Reaktionszeiten liefen über Wochenenden weiter.",
|
||||
"type": "fix",
|
||||
"audience": "customer",
|
||||
"cover_media_id": "<medien-id>",
|
||||
"publish_at": "2026-06-04T09:00:00Z",
|
||||
"idempotency_key": "sla-2026-07-31"
|
||||
}' \
|
||||
http://localhost:4700/api/v1/posts
|
||||
```
|
||||
|
||||
Antwort 201 mit dem angelegten Entwurf. `number` ist `null`, die Nummer kommt beim Veröffentlichen.
|
||||
|
||||
### PATCH /api/v1/posts/:id
|
||||
|
||||
Ändert Titel, Anreißer, Art, Zielgruppe, Slug, Aufmacherbild oder Datum. Nur solange nichts veröffentlicht ist, sonst 409. Zum Ändern wird die Kennung gebraucht, nicht der Slug.
|
||||
|
||||
```bash
|
||||
curl -s -X PATCH -H "Authorization: Bearer $TOKEN" \
|
||||
-H "content-type: application/json" \
|
||||
-d '{"teaser":"Neuer Anreißer.","publish_at":"2026-06-04T09:00:00Z"}' \
|
||||
http://localhost:4700/api/v1/posts/<id>
|
||||
```
|
||||
|
||||
### PUT /api/v1/posts/:id/blocks
|
||||
|
||||
Setzt die Blöcke vollständig, in der übergebenen Reihenfolge. Höchstens 100.
|
||||
|
||||
```bash
|
||||
curl -s -X PUT -H "Authorization: Bearer $TOKEN" \
|
||||
-H "content-type: application/json" \
|
||||
-d '{"blocks":[{"type":"text","data":{"text":"Erster Absatz."}}]}' \
|
||||
http://localhost:4700/api/v1/posts/<id>/blocks
|
||||
```
|
||||
|
||||
### GET /api/v1/posts/:id
|
||||
|
||||
Liest den Entwurf mit allen Blöcken zurück, zum Prüfen vor der Freigabe. Mit Schreibrecht findet dieser Aufruf den Entwurf auch über den Slug.
|
||||
|
||||
### DELETE /api/v1/posts/:id
|
||||
|
||||
Löscht einen Entwurf. Veröffentlichtes lässt sich nicht löschen.
|
||||
|
||||
## Bilder
|
||||
|
||||
### POST /api/v1/media
|
||||
@@ -136,6 +210,15 @@ curl -s -X DELETE -H "Authorization: Bearer $TOKEN" \
|
||||
|
||||
Liefert eine Variante aus. Die Pfade stehen am Medium unter `variants`, je Eintrag mit `width`, `format` und `path`.
|
||||
|
||||
## Werkzeuge
|
||||
|
||||
| Adresse | Inhalt |
|
||||
|---|---|
|
||||
| `GET /api/v1/openapi.json` | maschinenlesbare Beschreibung für Postman, Bruno, Insomnia oder einen KI-Assistenten |
|
||||
| `GET /api/v1/style-guide` | dieser Redaktionsleitfaden als Markdown |
|
||||
|
||||
Beide verlangen ein Token. In der Verwaltung unter API lädt ein angemeldeter Admin beide Dateien ohne Token herunter.
|
||||
|
||||
## Redaktionsleitfaden
|
||||
|
||||
Wer über die API schreibt, schreibt für Menschen. Diese Regeln gelten für jeden Eintrag.
|
||||
|
||||
@@ -185,7 +185,7 @@ export default async function AdminApiPage() {
|
||||
method="GET"
|
||||
path="/api/v1/posts/:slug"
|
||||
auth="read"
|
||||
summary="Ein einzelner Eintrag. Nicht sichtbar heißt 404, nicht 403, damit die Antwort seine Existenz nicht verrät."
|
||||
summary="Ein einzelner Eintrag über Slug oder Kennung. Mit Schreibrecht findet der Aufruf auch eigene Entwürfe. Nicht sichtbar heißt 404, nicht 403, damit die Antwort seine Existenz nicht verrät."
|
||||
example={'curl -s -H "Authorization: Bearer $TOKEN" \\\n http://localhost:4700/api/v1/posts/regel-engine'}
|
||||
/>
|
||||
|
||||
@@ -221,8 +221,8 @@ export default async function AdminApiPage() {
|
||||
method="POST"
|
||||
path="/api/v1/posts"
|
||||
auth="write"
|
||||
summary="Legt einen Beitrag an, immer als Entwurf. Mit idempotency_key erzeugt ein wiederholter Aufruf keinen zweiten Beitrag."
|
||||
example={'curl -s -X POST -H "Authorization: Bearer $TOKEN" \\\n -H "content-type: application/json" \\\n -d \'{\n "project": "trakk",\n "title": "SLA-Uhr zählt Feiertage nicht mehr mit",\n "teaser": "Reaktionszeiten liefen über Wochenenden weiter.",\n "type": "fix",\n "audience": "customer",\n "idempotency_key": "sla-2026-07-31"\n }\' \\\n http://localhost:4700/api/v1/posts'}
|
||||
summary="Legt einen Beitrag an, immer als Entwurf. Aufmacherbild und Datum gehen gleich mit. Mit idempotency_key erzeugt ein wiederholter Aufruf keinen zweiten Beitrag."
|
||||
example={'curl -s -X POST -H "Authorization: Bearer $TOKEN" \\\n -H "content-type: application/json" \\\n -d \'{\n "project": "trakk",\n "title": "SLA-Uhr zählt Feiertage nicht mehr mit",\n "teaser": "Reaktionszeiten liefen über Wochenenden weiter.",\n "type": "fix",\n "audience": "customer",\n "cover_media_id": "<medien-id>",\n "publish_at": "2026-06-04T09:00:00Z",\n "idempotency_key": "sla-2026-07-31"\n }\' \\\n http://localhost:4700/api/v1/posts'}
|
||||
/>
|
||||
|
||||
<ApiEndpoint
|
||||
@@ -237,7 +237,7 @@ export default async function AdminApiPage() {
|
||||
method="PATCH"
|
||||
path="/api/v1/posts/:id"
|
||||
auth="write"
|
||||
summary="Ändert Titel, Anreißer, Art, Zielgruppe, Slug oder Aufmacherbild. Nur solange nichts veröffentlicht ist, sonst 409."
|
||||
summary="Ändert Titel, Anreißer, Art, Zielgruppe, Slug, Aufmacherbild oder Datum. Nur solange nichts veröffentlicht ist, sonst 409."
|
||||
example={'curl -s -X PATCH -H "Authorization: Bearer $TOKEN" \\\n -H "content-type: application/json" \\\n -d \'{"teaser":"Neuer Anreißer."}\' \\\n http://localhost:4700/api/v1/posts/<id>'}
|
||||
/>
|
||||
|
||||
@@ -264,6 +264,32 @@ export default async function AdminApiPage() {
|
||||
summary="Lädt ein Bild hoch und erzeugt WebP-Varianten. Nur Bildformate, höchstens 15 MB."
|
||||
example={'curl -s -X POST -H "Authorization: Bearer $TOKEN" \\\n -F "file=@screenshot.png" \\\n -F "project=trakk" \\\n -F "alt=Spaltenmenü mit den neuen Einträgen" \\\n http://localhost:4700/api/v1/media'}
|
||||
/>
|
||||
|
||||
<ApiEndpoint
|
||||
method="DELETE"
|
||||
path="/api/v1/media/:id"
|
||||
auth="write"
|
||||
summary="Löscht ein Bild samt Fassungen. Hängt es noch an einem Beitrag, kommt 409."
|
||||
example={'curl -s -X DELETE -H "Authorization: Bearer $TOKEN" \\\n http://localhost:4700/api/v1/media/<id>'}
|
||||
/>
|
||||
</section>
|
||||
|
||||
<section className="flex flex-col gap-4">
|
||||
<SectionLabel>Datum und Nummer</SectionLabel>
|
||||
<div className="flex max-w-read flex-col gap-4 text-pretty text-ink-2">
|
||||
<p className="m-0">
|
||||
<code className="font-mono text-small text-ink">publish_at</code> nimmt eine ISO-Zeitangabe entgegen,
|
||||
beim Anlegen und beim Ändern. Der Zugang veröffentlicht damit nichts, er hinterlegt nur das Datum.
|
||||
Gibt ein Mensch den Beitrag frei, übernimmt Logbuch genau dieses Datum statt der aktuellen Uhrzeit.
|
||||
So lassen sich ältere Meldungen richtig einsortieren.
|
||||
</p>
|
||||
<p className="m-0">
|
||||
Die laufende Nummer wird erst beim Veröffentlichen vergeben. Ein Entwurf hat
|
||||
{' '}
|
||||
<code className="font-mono text-small text-ink">number: null</code>. Damit bleiben die Nummern im
|
||||
Archiv lückenlos, auch wenn Entwürfe wieder verworfen werden.
|
||||
</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section className="flex flex-col gap-4">
|
||||
|
||||
Reference in New Issue
Block a user