REST API पाइपलाइन, स्क्रिप्ट और ऐसी किसी भी चीज़ के लिए है जो एजेंट नहीं है। यदि आप इसके बजाय कोई मॉडल जोड़ रहे हैं, तो MCP server का उपयोग करें — यह समान अनुमति मॉडल पर टूल के रूप में समान ऑपरेशन प्रदर्शित करता है।

Base URL

fastsite स्व-होस्टेड है, इसलिए base URL आपका अपना इंजन होस्ट है। सब कुछ एक ही ओरिजिन के अंतर्गत है: डैशबोर्ड, API, MCP एंडपॉइंट और इनबाउंड वेबहुक।

https://your-host/api/v1

प्रमाणीकरण

हर अनुरोध एक हेडर में API key ले जाता है। इस सतह पर कोई bearer token और कोई सेशन नहीं है — bearer auth MCP के लिए है।

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

एक key 44 अक्षरों की स्ट्रिंग है: शाब्दिक उपसर्ग fs_, 8 अक्षरों की पब्लिक ID, एक अंडरस्कोर और 32 अक्षरों का सीक्रेट। सीक्रेट को argon2id से हैश करके संग्रहीत किया जाता है और केवल एक बार दिखाया जाता है, जब key बनाई जाती है।

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

हर साइट की अनुमति देने के लिए --sites=* का उपयोग करें। Keys को डैशबोर्ड से भी प्रबंधित किया जा सकता है, और किसी भी समय रोटेट या रद्द किया जा सकता है — एक रद्द की गई key कैश विंडो के अंत में नहीं बल्कि तुरंत काम करना बंद कर देती है।

हर विफलता एक जैसी दिखती है

एक गुम हेडर, एक खराब key, एक अज्ञात key, एक गलत सीक्रेट, एक रद्द की गई key, और एक निष्क्रिय उपयोगकर्ता — सभी एक ही संदेश के साथ एक ही 401 लौटाते हैं। यह जानबूझकर है — इसका मतलब है कि किसी key के अस्तित्व की जाँच नहीं की जा सकती।

रिस्पॉन्स एनवेलप

हर JSON रिस्पॉन्स की एक ही संरचना होती है, ताकि एक क्लाइंट एक ही फ़ील्ड पर ब्रांच कर सके।

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

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

लिस्ट एंडपॉइंट data के साथ एक pagination ब्लॉक जोड़ते हैं, और data किसी ऑब्जेक्ट की बजाय एक साधारण ऐरे है:

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

दो एंडपॉइंट जानबूझकर एनवेलप को तोड़ते हैं, क्योंकि उन्हें रैप करना बेकार होगा: एक शेल फ़ाइल पढ़ने पर text/plain के रूप में रॉ बाइट्स मिलते हैं, और उसे हटाने पर बिना बॉडी के 204 मिलता है।

एक पोस्ट बनाएं, फिर प्रकाशित करें

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

कंटेंट लिखने से वह प्रकाशित नहीं होता। दोनों जानबूझकर अलग ऑपरेशन हैं — एक पाइपलाइन जितना चाहे बना सकती है, संशोधित कर सकती है और सुधार कर सकती है, बिना किसी चीज़ के विजिटर तक पहुँचे। जब कंटेंट तैयार हो, तो साइट प्रकाशित करें:

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

यह एक job ID के साथ 202 लौटाता है; बिल्ड कतार पर चलता है। परिणाम के लिए GET /api/v1/jobs/0f3c… पोल करें।

title ही क्रिएट पर एकमात्र आवश्यक फ़ील्ड है। type का डिफ़ॉल्ट post है, status का डिफ़ॉल्ट draft है, और जब आप slug नहीं भेजते तो slug शीर्षक से निर्धारित होता है। यदि वह slug पहले से लिया हुआ है, तो इंजन एक काउंटर जोड़कर वास्तव में उपयोग किया गया slug लौटाता है — मान लेने की बजाय हमेशा उसे वापस पढ़ें।

एंडपॉइंट

कंटेंट

MethodPathScope
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

हटाना एक सॉफ्ट डिलीट है — आइटम ट्रैश में जाता है और पुनर्स्थापित किया जा सकता है। purge अपरिवर्तनीय है।

मीडिया

MethodPathScope
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

अपलोड या तो file नाम के फ़ील्ड के साथ multipart फ़ॉर्म स्वीकार करता है, या fetch के लिए url के साथ JSON। दोनों नहीं — यदि कोई फ़ाइल मौजूद है तो URL को अनदेखा किया जाता है।

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 आवश्यक है जब तक आप स्पष्ट रूप से decorative=true नहीं पास करते। यह शैली की प्राथमिकता नहीं है — एक गुम alt बिल्ड ऑडिट में विफल होता है, इसलिए API इसे बाद में प्रकाशन में समस्या उत्पन्न करने देने की बजाय पहले ही अस्वीकार कर देता है। URL इम्पोर्ट SSRF-गार्डेड हैं: प्राइवेट एड्रेस रेंज अस्वीकार किए जाते हैं, रीडायरेक्ट पुनः-सत्यापित किए जाते हैं, और डाउनलोड बाइट-कैप्ड होता है।

लाइब्रेरी को ?kind=image,video,file से फ़िल्टर करें। इमेज और वीडियो वेरिएंट पाइपलाइन से गुज़रते हैं; बाकी सब कुछ डाउनलोड योग्य फ़ाइल के रूप में संग्रहीत होता है।

Shell

MethodPathScope
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

बॉडी फ़ाइल है, JSON नहीं। कोई रैपर ऑब्जेक्ट नहीं है और कोई फ़ील्ड नाम नहीं है — आप बाइट्स भेजते हैं और बाइट्स वापस पाते हैं।

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

पाथ में स्लैश हो सकते हैं। राइट्स shell डायरेक्टरी तक सीमित हैं, 5 MB पर कैप्ड हैं, और एक एक्सटेंशन अनुमति सूची तक सीमित हैं (twig, css, js, json, woff2, svg, और सामान्य इमेज प्रकार)। कंटेंट के विपरीत, एक shell राइट रीबिल्ड कतार में डालता है — डिज़ाइन बदल गया, इसलिए आउटपुट को भी बदलना होगा। संपादनों का एक बर्स्ट प्रति फ़ाइल एक बिल्ड की बजाय एक ही बिल्ड में समेकित होता है।

जोखिम भरे बदलाव से पहले स्नैपशॉट लें। पुनर्स्थापित करने पर पहले एक स्नैपशॉट लिया जाता है, इसलिए एक रिस्टोर स्वयं भी पूर्ववत किया जा सकता है।

कंपोनेंट, रीडायरेक्ट, स्क्रिप्ट

MethodPathScope
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

एक कंपोनेंट {type: "html"|"react", source_code, css?, variables_schema?} है। React अपलोड के समय कंपाइल होता है, इसलिए एक टूटा हुआ कंपोनेंट बाद में टूटे पेज की बजाय आपके अनुरोध पर 422 होता है।

भाषाएं, प्रकाशन, साइट

MethodPathScope
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

पहले authoring guide प्राप्त करें

GET /api/v1/authoring-guide body HTML, इमेज एम्बेडिंग और shell कॉन्ट्रैक्ट के लिए मशीन-पठनीय नियम लौटाता है। एक साइट पास करने पर उसके locale और एम्बेड सिंटैक्स भी शामिल मिलते हैं। यही वह अंतर है जो कंटेंट को बिल्ड करने योग्य और ऑडिट में अस्वीकृत होने योग्य बनाता है।

Scope

Keys और OAuth ग्रांट एक ही scope शब्दावली साझा करते हैं, इसलिए एक एंडपॉइंट और एक टूल एक्सेस को समान रूप से लागू करते हैं।

Scopeअनुमति देता है
sites:readसाइट और उनकी सेटिंग देखें
sites:writeसाइट सेटिंग, रीडायरेक्ट, स्क्रिप्ट, वेबहुक बदलें
content:readपोस्ट और पेज पढ़ें
content:writeपोस्ट और पेज बनाएं और संपादित करें
media:readमीडिया लाइब्रेरी देखें
media:writeइमेज, वीडियो और फ़ाइलें अपलोड करें
components:writeकंपोनेंट बनाएं और अपडेट करें
shell:readटेम्पलेट और थीम पढ़ें
shell:writeटेम्पलेट और थीम संपादित करें
translations:managelocale और अनुवाद प्रबंधित करें
publishबिल्ड और प्रकाशित करें
jobs:readबिल्ड और job स्टेटस पढ़ें
backup:read · backup:run · backup:restoreबैकअप ऑपरेशन
adminसब कुछ

केवल admin किसी और चीज़ का तात्पर्य रखता है। कोई read/write पदानुक्रम नहीं है — content:write content:read प्रदान नहीं करता, इसलिए यदि आपको दोनों की आवश्यकता है तो दोनों माँगें। Keys एक साइट सूची से भी पिन होती हैं, और उस सूची के बाहर किसी साइट के लिए अनुरोध हैंडलर तक पहुँचने से पहले ही अस्वीकार कर दिया जाता है।

Idempotency

किसी भी POST पर Idempotency-Key हेडर भेजें और इंजन उसके विरुद्ध परिणाम रिकॉर्ड करता है।

  • समान method, path और body के साथ वही key संग्रहीत रिस्पॉन्स दोहराती है, उस पर Idempotency-Replayed: true के साथ।
  • भिन्न body के साथ वही key 422 है — यही वह तरीका है जिससे आपको पता चलता है कि आपके retry लॉजिक ने payload बदल दिया।
  • एक retry जो पहले वाले के चलते रहने के दौरान आती है, उसे 409 और Retry-After मिलता है।
  • यदि हैंडलर थ्रो करता है, या रिस्पॉन्स 5xx या 429 है, तो key रिलीज़ हो जाती है ताकि एक वास्तविक retry सफल हो सके।

अन्य method हेडर को पूरी तरह अनदेखा करते हैं।

दर सीमाएं

दो फिक्स्ड-विंडो सीमाएं, दोनों प्रति मिनट: प्रति IP 60 अनुरोध और प्रति API key 120। किसी भी को पार करने पर Retry-After के साथ 429 मिलता है। प्रति-IP बकेट वह है जिससे आप आमतौर पर पहले मिलेंगे, क्योंकि एक ही क्लाइंट एक ही एड्रेस है।

JSON अनुरोध बॉडी 4 MiB पर कैप्ड हैं। अपलोड उस जाँच से मुक्त हैं और प्रति-प्रकार मीडिया सीमाओं द्वारा सीमित हैं।

स्टेटस कोड

कोडअर्थ
200 · 201 · 202 · 204सफलता। 202 का अर्थ है कतारबद्ध — job पोल करें।
401गुम, खराब, अज्ञात या रद्द की गई key।
403वैध key, लेकिन scope या साइट की अनुमति नहीं है।
404ऐसा कोई रूट, साइट या रिकॉर्ड नहीं।
409डुप्लिकेट, या एक idempotent अनुरोध अभी भी प्रगति में है।
413बॉडी सीमा से अधिक।
422सत्यापन विफल — error.message पढ़ें।
429दर सीमित।

निर्माण से पहले जानने योग्य विवरण

  • टाइमस्टैम्प सख्त हैं। scheduled_at और published_at YYYY-MM-DDTHH:MM:SSZ होने चाहिए — UTC, अपरकेस T, अंत में Z+02:00 जैसे ऑफसेट कन्वर्ट करने की बजाय अस्वीकार किए जाते हैं।
  • स्टेटस मान draft, scheduled, published और archived हैं। शेड्यूलिंग के लिए scheduled_at आवश्यक है, और समय आने पर शेड्यूलर इसे आपके लिए प्रकाशित करता है।
  • पेजिंग ?page= और ?per_page= है, डिफ़ॉल्ट 20 और अधिकतम 100।
  • Body HTML हर पाथ पर सैनिटाइज़ होता है। इनलाइन स्टाइल हटाए जाते हैं, स्क्रिप्ट और iframe हटाए जाते हैं, और परिणाम warnings ऐरे के साथ वापस आता है। कंटेंट समस्याएं आपके अनुरोध को कभी विफल नहीं करतीं — वे रिपोर्ट की जाती हैं, सामान्य की जाती हैं और प्रकाशित होती हैं।
  • कुछ चीजें REST पर नहीं हैं। बैकअप, टीम और API-key प्रबंधन CLI और डैशबोर्ड ऑपरेशन हैं; बैकअप और रिस्टोर MCP पर भी उपलब्ध हैं।

आगे: एजेंट-संचालित प्रकाशन के लिए MCP server, या किसी अपस्ट्रीम सिस्टम से कंटेंट पुश करने के लिए webhooks