REST API:et är till för pipelines, skript och allt som inte är en agent. Om du kopplar upp en modell istället använder du MCP-servern — den exponerar samma operationer som verktyg över samma behörighetsmodell.

Bas-URL

fastsite är självhostat, så bas-URL:en är din egen värdmaskin. Allt finns under ett ursprung: dashboarden, API:et, MCP-slutpunkten och inkommande webhooks.

https://your-host/api/v1

Autentisering

Varje förfrågan bär en API-nyckel i en header. Det finns ingen bearer-token och ingen session på den här ytan — bearer-autentisering hör till MCP.

X-API-Key: fs_<key_id>_<secret>

En nyckel är en 44 tecken lång sträng: det literala prefixet fs_, ett 8-teckens publikt id, ett understreck och en 32-teckens hemlighet. Hemligheten hashas med argon2id i vila och visas exakt en gång, när nyckeln skapas.

php bin/fastsite key:create you@example.com \
  --name="Deploy pipeline" \
  --scopes=content:write,media:write,publish \
  --sites=blog

Använd --sites=* för att tillåta alla webbplatser. Nycklar hanteras även från dashboarden och kan roteras eller återkallas när som helst — en återkallad nyckel slutar fungera omedelbart snarare än i slutet av ett cachefönster.

Varje fel ser likadant ut

En saknad header, en felformaterad nyckel, en okänd nyckel, fel hemlighet, en återkallad nyckel och en inaktiverad användare returnerar alla samma 401 med samma meddelande. Det är avsiktligt — det innebär att en nyckel inte kan sonderas för existens.

Svarsomslaget

Varje JSON-svar har samma form, så en klient kan förgrena sig på ett enda fält.

{ "success": true, "data": { … } }

{ "success": false, "error": { "message": "…" } }

Listslutpunkter lägger till ett pagination-block bredvid data, och data är en vanlig array snarare än ett objekt:

{
  "success": true,
  "data": [ … ],
  "pagination": { "total": 42, "page": 1, "per_page": 20, "total_pages": 3 }
}

Två slutpunkter bryter avsiktligt mot omslaget, eftersom att omsluta dem vore meningslöst: att läsa en shell-fil returnerar rå bytes som text/plain, och att radera en returnerar 204 utan kropp.

Skapa ett inlägg och publicera sedan

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"
  }'

Att skriva innehåll publicerar det inte. De två är separata operationer av en anledning — en pipeline kan skapa, revidera och korrigera så mycket den behöver utan att något av det når besökarna. När innehållet är klart publicerar du webbplatsen:

curl -X POST https://your-host/api/v1/sites/blog/publish \
  -H "X-API-Key: $FASTSITE_KEY"
# → { "success": true, "data": { "job": "0f3c…" } }

Det returnerar 202 med ett jobb-id; bygget körs i kön. Polla GET /api/v1/jobs/0f3c… för resultatet.

title är det enda obligatoriska fältet vid skapande. type är som standard post, status är som standard draft, och sluggen härleds från titeln om du inte skickar en. Om den sluggen redan är tagen lägger motorn till en räknare och returnerar den slug den faktiskt använde — läs alltid tillbaka den istället för att anta.

Slutpunkter

Innehåll

MetodSökvägScope
GET/sites/{site}/contentcontent:read
POST/sites/{site}/contentcontent: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/trashcontent:read
POST/sites/{site}/content/{id}/restorecontent:write
DELETE/sites/{site}/content/{id}/purgecontent:write
POST/sites/{site}/content/{id}/fact-checkcontent:read

Radering är en mjuk radering — objektet flyttas till papperskorgen och kan återställas. purge är den oåterkalleliga åtgärden.

Media

MetodSökvägScope
GET/sites/{site}/mediamedia:read
POST/sites/{site}/mediamedia:write
DELETE/sites/{site}/media/{id}media:write
POST/sites/{site}/media/{id}/restoremedia:write
DELETE/sites/{site}/media/{id}/purgemedia:write

Uppladdning accepterar antingen ett multipart-formulär med ett fält som heter file, eller JSON med en url att hämta från. Inte båda — om en fil finns ignoreras 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-text krävs för bilder om du inte uttryckligen skickar decorative=true. Det är inte en stilpreferens — en saknad alt misslyckas i bygggranskingen, så API:et avvisar den vid ingången istället för att låta den bryta en publicering senare. URL-importer är SSRF-skyddade: privata adressintervall avvisas, omdirigeringar omvalideras och nedladdningen är byte-begränsad.

Filtrera biblioteket med ?kind=image,video,file. Bilder och video körs genom variantpipelinen; allt annat lagras som en nedladdningsbar fil.

Shell

MetodSökvägScope
GET/sites/{site}/shell/filesshell: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/snapshotshell:write
POST/sites/{site}/shell/restore/{rev}shell:write

Kroppen är filen, inte JSON. Det finns inget omslagsobjekt och inget fältnamn — du skickar bytes och får bytes tillbaka.

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

Sökvägen kan innehålla snedstreck. Skrivningar är begränsade till shell-katalogen, begränsade till 5 MB och begränsade till en tillåtelselista för filändelser (twig, css, js, json, woff2, svg och de vanliga bildtyperna). Till skillnad från innehåll köar en shell-skrivning ett återbygge — designen ändrades, så resultatet måste uppdateras. En serie redigeringar slås ihop till ett enda bygge snarare än ett per fil.

Ta en ögonblicksbild innan en riskabel ändring. Återställning tar en ögonblicksbild först, så en återställning är själv ångransbar.

Komponenter, omdirigeringar, skript

MetodSökvägScope
PUT/sites/{site}/components/{handle}components:write
GET · POST/sites/{site}/redirectssites:read · sites:write
DELETE/sites/{site}/redirects/{id}sites:write
GET · POST/sites/{site}/scriptssites:read · sites:write
DELETE/sites/{site}/scripts/{id}sites:write

En komponent är {type: "html"|"react", source_code, css?, variables_schema?}. React kompileras vid uppladdning, så en trasig komponent ger 422 på din förfrågan snarare än en trasig sida senare.

Språk, publicering, webbplatser

MetodSökvägScope
POST/sites/{site}/languagestranslations:manage
DELETE/sites/{site}/languages/{locale}translations:manage
POST/sites/{site}/publishpublish
GET/jobs/{uuid}jobs:read
GET/sitessites:read
POST/sitesadmin
PATCH/sites/{site}sites:write
GET · POST/sites/{site}/webhookssites:read · sites:write
GET/sites/{site}/webhooks/{id}/deliveriessites:read
DELETE/sites/{site}/webhooks/{id}sites:write
GET/authoring-guidesites:read
GET/sites/{site}/authoring-guidesites:read

Hämta författarguiden först

GET /api/v1/authoring-guide returnerar maskinläsbara regler för brödtext-HTML, bildembeddning och shell-kontraktet. Ange en webbplats för att få dess lokaler och embed-syntax infällda. Det är skillnaden mellan innehåll som byggs och innehåll som granskningen avvisar.

Scopes

Nycklar och OAuth-beviljanden delar ett scope-vokabulär, så en slutpunkt och ett verktyg tillämpar åtkomst på identiskt sätt.

ScopeBeviljar
sites:readVisa webbplatser och deras inställningar
sites:writeÄndra webbplatsinställningar, omdirigeringar, skript, webhooks
content:readLäs inlägg och sidor
content:writeSkapa och redigera inlägg och sidor
media:readVisa mediebiblioteket
media:writeLadda upp bilder, video och filer
components:writeSkapa och uppdatera komponenter
shell:readLäs mallar och tema
shell:writeRedigera mallar och tema
translations:manageHantera lokaler och översättningar
publishBygg och publicera
jobs:readLäs bygge- och jobbstatus
backup:read · backup:run · backup:restoreSäkerhetskopieringsoperationer
adminAllt

Bara admin innebär något annat. Det finns ingen läs/skriv-hierarki — content:write ger inte content:read, så be om båda om du behöver båda. Nycklar är också kopplade till en webbplatslista, och en förfrågan om en webbplats utanför den avvisas innan den når en hanterare.

Idempotens

Skicka en Idempotency-Key-header på valfri POST och motorn registrerar utfallet mot den.

  • Samma nyckel med samma metod, sökväg och kropp spelar upp det lagrade svaret, med Idempotency-Replayed: true på det.
  • Samma nyckel med en annan kropp ger 422 — det är så du får reda på att din återförsökslogik ändrade nyttolasten.
  • Ett återförsök som anländer medan det första fortfarande körs får 409 och ett Retry-After.
  • Om hanteraren kastar ett undantag, eller svaret är 5xx eller 429, frigörs nyckeln så att ett äkta återförsök kan lyckas.

Andra metoder ignorerar headern helt.

Hastighetsbegränsningar

Två fasta fönsterbegränsningar, båda per minut: 60 förfrågningar per IP och 120 per API-nyckel. Att överskrida någon av dem returnerar 429 med ett Retry-After. Hinken per IP är den du oftast stöter på, eftersom en enda klient är en adress.

JSON-förfrågningskroppar är begränsade till 4 MiB. Uppladdningar är undantagna från den kontrollen och begränsas istället av mediagränserna per typ.

Statuskoder

KodBetydelse
200 · 201 · 202 · 204Lyckades. 202 innebär köad — polla jobbet.
401Saknad, felformaterad, okänd eller återkallad nyckel.
403Giltig nyckel, men scope eller webbplats är inte tillåten.
404Ingen sådan rutt, webbplats eller post.
409Duplikat, eller en idempotent förfrågan fortfarande under bearbetning.
413Kropp över gränsen.
422Validering misslyckades — läs error.message.
429Hastighetsbegränsad.

Detaljer värda att känna till innan du bygger mot det

  • Tidsstämplar är strikta. scheduled_at och published_at måste vara YYYY-MM-DDTHH:MM:SSZ — UTC, versalt T, avslutande Z. Förskjutningar som +02:00 avvisas snarare än konverteras.
  • Statusvärden är draft, scheduled, published och archived. Schemaläggning kräver scheduled_at, och schemaläggaren publicerar det åt dig när tiden kommer.
  • Sidindelning sker med ?page= och ?per_page=, med standardvärde 20 och max 100.
  • Brödtext-HTML saneras på alla vägar. Inline-stilar tas bort, skript och iframes raderas, och resultatet returneras med en warnings-array. Innehållsproblem misslyckas aldrig din förfrågan — de rapporteras, normaliseras och publiceras.
  • Vissa saker finns inte på REST. Säkerhetskopieringar, team och API-nyckelhantering är CLI- och dashboardoperationer; säkerhetskopieringar och återställningar är också tillgängliga via MCP.

Nästa: MCP-servern för agentstyrd publicering, eller webhooks för att skicka in innehåll från ett uppströms system.