REST API'et er til pipelines, scripts og alt, der ikke er en agent. Hvis du i stedet kobler en model til, skal du bruge MCP-serveren — den eksponerer de samme operationer som værktøjer over den samme tilladelsesmodel.
Basis-URL
fastsite er selv-hostet, så basis-URL'en er din egen engine-host. Alt bor under ét origin: dashboardet, API'et, MCP-endpointet og indgående webhooks.
https://your-host/api/v1 Autentificering
Hver anmodning medbringer en API-nøgle i et header. Der er ingen bearer-token og ingen session på denne overflade — bearer-auth tilhører MCP.
X-API-Key: fs_<key_id>_<secret> En nøgle er en streng på 44 tegn: det bogstavelige præfiks fs_, et offentligt id på 8 tegn, en underscore og en hemmelighed på 32 tegn. Hemmeligheden er hashet med argon2id i hvile og vises præcis én gang, når nøglen oprettes.
php bin/fastsite key:create you@example.com \
--name="Deploy pipeline" \
--scopes=content:write,media:write,publish \
--sites=blog Brug --sites=* for at tillade alle sites. Nøgler administreres også fra dashboardet og kan roteres eller tilbagekaldes til enhver tid — en tilbagekaldt nøgle holder op med at virke øjeblikkeligt frem for ved slutningen af et cache-vindue.
Alle fejl ser ens ud
Et manglende header, en misdannet nøgle, en ukendt nøgle, en forkert hemmelighed, en tilbagekaldt nøgle og en deaktiveret bruger returnerer alle den samme 401 med den samme besked. Det er bevidst — det betyder, at en nøgle ikke kan sondes for eksistens.
Svar-envelopen
Hvert JSON-svar har den samme form, så en klient kan forgrene sig på ét felt.
{ "success": true, "data": { … } }
{ "success": false, "error": { "message": "…" } } Liste-endpoints tilføjer en pagination-blok ved siden af data, og data er et almindeligt array frem for et objekt:
{
"success": true,
"data": [ … ],
"pagination": { "total": 42, "page": 1, "per_page": 20, "total_pages": 3 }
} To endpoints bryder bevidst envelopen, fordi det ville være meningsløst at indpakke dem: læsning af en shell-fil returnerer de rå bytes som text/plain, og sletning af en returnerer 204 uden krop.
Opret et indlæg, og publicér det derefter
curl -X POST https://your-host/api/v1/sites/blog/content \
-H "X-API-Key: $FASTSITE_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: 2f1c9a7e-…" \
-d '{
"type": "post",
"title": "Hello, world",
"body_html": "<p>Shipped in a single call.</p>",
"status": "published"
}' At skrive indhold publicerer det ikke. De to er separate operationer med vilje — en pipeline kan oprette, revidere og rette så meget som nødvendigt uden at noget af det når besøgende. Når indholdet er klar, publiceres sitet:
curl -X POST https://your-host/api/v1/sites/blog/publish \
-H "X-API-Key: $FASTSITE_KEY"
# → { "success": true, "data": { "job": "0f3c…" } } Det returnerer 202 med et job-id; bygningen kører i køen. Forespørg GET /api/v1/jobs/0f3c… for resultatet.
title er det eneste påkrævede felt ved oprettelse. type er som standard post, status er som standard draft, og slugget afleses fra titlen, når du ikke sender et. Hvis det slug er taget, tilføjer enginen en tæller og returnerer det slug, den faktisk brugte — læs det altid tilbage frem for at antage.
Endpoints
Indhold
| Metode | Sti | Scope |
|---|---|---|
| GET | /sites/{site}/content | content:read |
| POST | /sites/{site}/content | content:write |
| GET | /sites/{site}/content/{id} | content:read |
| PATCH | /sites/{site}/content/{id} | content:write |
| DELETE | /sites/{site}/content/{id} | content:write |
| GET | /sites/{site}/content/trash | content:read |
| POST | /sites/{site}/content/{id}/restore | content:write |
| DELETE | /sites/{site}/content/{id}/purge | content:write |
| POST | /sites/{site}/content/{id}/fact-check | content:read |
Sletning er en blød sletning — elementet flyttes til papirkurven og kan gendannes. purge er den uigenkaldelige.
Medier
| Metode | Sti | Scope |
|---|---|---|
| GET | /sites/{site}/media | media:read |
| POST | /sites/{site}/media | media:write |
| DELETE | /sites/{site}/media/{id} | media:write |
| POST | /sites/{site}/media/{id}/restore | media:write |
| DELETE | /sites/{site}/media/{id}/purge | media:write |
Upload accepterer enten en multipart-formular med et felt ved navn file eller JSON med en url der hentes. Ikke begge — hvis en fil er til stede, ignoreres URL'en.
curl -X POST https://your-host/api/v1/sites/blog/media \
-H "X-API-Key: $FASTSITE_KEY" \
-F file=@hero.jpg \
-F alt="Sunrise over the harbour" Alt-tekst er påkrævet for billeder, medmindre du eksplicit sender decorative=true. Det er ikke en stilpræference — en manglende alt-tekst fejler byggerevisionen, så API'et afviser det ved døren frem for at lade det ødelægge en publicering senere. URL-imports er SSRF-beskyttet: private adresseintervaller afvises, omdirigeringer genvalideres og downloaden er byte-begrænset.
Filtrer biblioteket med ?kind=image,video,file. Billeder og video køres gennem variant-pipelinen; alt andet gemmes som en fil til download.
Shell
| Metode | Sti | Scope |
|---|---|---|
| GET | /sites/{site}/shell/files | shell:read |
| GET | /sites/{site}/shell/file/{path} | shell:read |
| PUT | /sites/{site}/shell/file/{path} | shell:write |
| DELETE | /sites/{site}/shell/file/{path} | shell:write |
| POST | /sites/{site}/shell/snapshot | shell:write |
| POST | /sites/{site}/shell/restore/{rev} | shell:write |
Kroppen er filen, ikke JSON. Der er intet wrapper-objekt og intet feltnavn — du sender bytes og får bytes tilbage.
curl -X PUT https://your-host/api/v1/sites/blog/shell/file/templates/base.html.twig \
-H "X-API-Key: $FASTSITE_KEY" \
--data-binary @base.html.twig Stien må indeholde skråstreger. Skrivninger er begrænset til shell-mappen, begrænset til 5 MB og begrænset til en tilladt liste over filendelser (twig, css, js, json, woff2, svg og de sædvanlige billedtyper). I modsætning til indhold sætter en shell-skrivning en genopbygning i gang — designet ændrede sig, så outputtet skal følge med. En strøm af redigeringer sammenflettes til én bygning frem for én per fil.
Tag et snapshot inden en risikabel ændring. Gendannelse tager et snapshot først, så en gendannelse i sig selv kan fortrydes.
Komponenter, omdirigeringer, scripts
| Metode | Sti | Scope |
|---|---|---|
| PUT | /sites/{site}/components/{handle} | components:write |
| GET · POST | /sites/{site}/redirects | sites:read · sites:write |
| DELETE | /sites/{site}/redirects/{id} | sites:write |
| GET · POST | /sites/{site}/scripts | sites:read · sites:write |
| DELETE | /sites/{site}/scripts/{id} | sites:write |
En komponent er {type: "html"|"react", source_code, css?, variables_schema?}. React kompileres ved upload, så en ødelagt komponent giver en 422 på din anmodning frem for en ødelagt side senere.
Sprog, publicering, sites
| Metode | Sti | Scope |
|---|---|---|
| POST | /sites/{site}/languages | translations:manage |
| DELETE | /sites/{site}/languages/{locale} | translations:manage |
| POST | /sites/{site}/publish | publish |
| GET | /jobs/{uuid} | jobs:read |
| GET | /sites | sites:read |
| POST | /sites | admin |
| PATCH | /sites/{site} | sites:write |
| GET · POST | /sites/{site}/webhooks | sites:read · sites:write |
| GET | /sites/{site}/webhooks/{id}/deliveries | sites:read |
| DELETE | /sites/{site}/webhooks/{id} | sites:write |
| GET | /authoring-guide | sites:read |
| GET | /sites/{site}/authoring-guide | sites:read |
Hent forfattervejledningen først
GET /api/v1/authoring-guide returnerer de maskinlæsbare regler for brødtekst-HTML, billedindlejring og shell-kontrakten. Send et site for at få dets lokaliteter og indlejringssyntaks foldet ind. Det er forskellen på indhold der bygger, og indhold som revisionen afviser.
Scopes
Nøgler og OAuth-tilladelser deler ét scope-ordforråd, så et endpoint og et værktøj håndhæver adgang identisk.
| Scope | Giver adgang til |
|---|---|
sites:read | Se sites og deres indstillinger |
sites:write | Ændre site-indstillinger, omdirigeringer, scripts, webhooks |
content:read | Læse indlæg og sider |
content:write | Oprette og redigere indlæg og sider |
media:read | Se mediebiblioteket |
media:write | Uploade billeder, video og filer |
components:write | Oprette og opdatere komponenter |
shell:read | Læse skabeloner og tema |
shell:write | Redigere skabeloner og tema |
translations:manage | Administrere lokaliteter og oversættelser |
publish | Bygge og publicere |
jobs:read | Læse bygge- og jobstatus |
backup:read · backup:run · backup:restore | Sikkerhedskopieringsoperationer |
admin | Alt |
Kun admin indebærer noget andet. Der er ingen læse/skrive-hierarki — content:write giver ikke content:read, så bed om begge hvis du har brug for begge. Nøgler er også fastgjort til en site-liste, og en anmodning for et site uden for den afvises, inden den når en handler.
Idempotens
Send et Idempotency-Key-header på enhver POST, og enginen registrerer resultatet mod det.
- Den samme nøgle med samme metode, sti og krop afspiller det gemte svar med
Idempotency-Replayed: truepå det. - Den samme nøgle med en anden krop er en
422— det er sådan du finder ud af, at din genprøvningslogik ændrede indholdet. - En genprøvning der ankommer, mens den første stadig kører, får
409og enRetry-After. - Hvis handleren kaster, eller svaret er en
5xxeller en429, frigives nøglen, så en ægte genprøvning kan lykkes.
Andre metoder ignorerer headeren fuldstændigt.
Hastighedsbegrænsninger
To faste vindueslimitter, begge per minut: 60 anmodninger per IP og 120 per API-nøgle. Overskridelse af en af dem returnerer 429 med en Retry-After. Per-IP-spanden er den du oftest vil møde, da en enkelt klient er én adresse.
JSON-anmodningskroppe er begrænset til 4 MiB. Uploads er undtaget fra denne kontrol og begrænset af de per-type mediegrænser i stedet.
Statuskoder
| Kode | Betydning |
|---|---|
| 200 · 201 · 202 · 204 | Succes. 202 betyder sat i kø — forespørg jobbet. |
| 401 | Manglende, misdannet, ukendt eller tilbagekaldt nøgle. |
| 403 | Gyldig nøgle, men scope eller site er ikke tilladt. |
| 404 | Ingen sådan rute, site eller post. |
| 409 | Duplikat, eller en idempotent anmodning stadig i gang. |
| 413 | Krop over grænsen. |
| 422 | Validering mislykkedes — læs error.message. |
| 429 | Hastighedsbegrænset. |
Detaljer der er værd at kende, inden du bygger mod det
- Tidsstempler er strenge.
scheduled_atogpublished_atskal væreYYYY-MM-DDTHH:MM:SSZ— UTC, stortT, afsluttendeZ. Forskydninger som+02:00afvises frem for at blive konverteret. - Statusværdier er
draft,scheduled,publishedogarchived. Planlægning kræverscheduled_at, og planlæggeren publicerer det for dig, når tiden kommer. - Sideinddeling sker med
?page=og?per_page=, standard er 20 og max er 100. - Brødtekst-HTML saneres på alle veje. Inline-styles fjernes, scripts og iframes fjernes, og resultatet returneres med et
warnings-array. Indholdsproblemer fejler aldrig din anmodning — de rapporteres, normaliseres og publiceres. - Nogle ting er ikke på REST. Sikkerhedskopier, teams og API-nøgleadministration er CLI- og dashboardoperationer; sikkerhedskopier og gendannelser er også tilgængelige via MCP.
Næste: MCP-serveren til agent-drevet publicering, eller webhooks til at skubbe indhold ind fra et upstream-system.