Швидкий старт
Три кроки від ключа до готового архіву. Сайт збирається в середньому близько хвилини, тому замовлення повертає номер завдання, а не сайт: далі ви опитуєте статус і завантажуєте ZIP.
# 1. Замовити сайт
curl -X POST https://exstru.com/api/v1/generate \
-H 'Authorization: Bearer sg_ваш_ключ' \
-H 'Content-Type: application/json' \
-d '{ "tier": "premium", "siteType": "local-business",
"niche": "стоматологія", "language": "es", "country": "ES" }'
# → { "jobId": "V1StGXR8Z5jd", "queue": { "position": 3, … } }
# 2. Перевіряти статус раз на 3–5 секунд
curl https://exstru.com/api/v1/status/V1StGXR8Z5jd \
-H 'Authorization: Bearer sg_ваш_ключ'
# 3. Завантажити архів, коли status = completed
curl -o site.zip https://exstru.com/api/v1/download/V1StGXR8Z5jd \
-H 'Authorization: Bearer sg_ваш_ключ'Доступ і ключ
API підключається до команди. Ключ вигляду sg_… випускає власник у розділі «API» в боті — там само його перевипускають і відкликають. Кредити за сайти списуються зі спільного балансу команди.
Як передати ключ
У будь-якому з двох заголовків — вони рівноцінні. Другий потрібен, якщо ваша бібліотека вже займає Authorization.
Authorization: Bearer sg_ваш_ключ X-Api-Key: sg_ваш_ключ
Тарифи в запиті
Тариф передається в полі tier і визначає, скільки кредитів спишеться і що отримає сайт. Підписка на API тариф не обмежує: за одним ключем можна замовляти будь-який.
basicpremiumeliteПовне порівняння можливостей — на сторінці «Тарифи».
Замовити сайт
Ставить сайт у чергу й списує кредити за тарифом. Відповідь надходить одразу — з номером завдання й місцем у черзі.
Параметри тіла запиту
Правила полів
Помилки формату повертаються всі одразу: 400 invalid_request, перелік — у data.issues. Кредити при цьому не списуються. Невідомі поля ігноруються.
companyInfoobjectЯкщо об’єкт передано, name, email і phone обов’язкові. Без об’єкта назву й контакти вигадає генератор. Усі поля — рядки.
brandColorstring- Формат —
#rrggbbабо короткий#rgb, регістр не важливий, пробіли по краях обрізаються.#1E6FD9і#1e6fd9— один колір,#16dчитається як#1166dd. - Порожній рядок або відсутність поля — палітра підбирається під нішу.
- Інші записи —
rgb(), назви кольорів, код без#— помилка400 invalid_request. - Колір не копіюється один в один: у кожного сайту свій близький відтінок, щоб сайти однієї команди не повторювали один одного.
- На Basic поле приймається, але не застосовується — попередження
brand_color_not_in_tier.
baseUrlstring · до 253 символів- Домен латиницею: літери, цифри й дефіс, хоча б одна крапка. Кириличні домени — у punycode:
xn--… - Схема необов’язкова:
http://іhttps://приймаються, у посиланнях сайту завжди будеhttps. wwwзберігається — який хост канонічний, вирішуєте ви. Шлях допускається для сайту в підпапці.- Кінцевий слеш, параметри
?…і якір#…відкидаються. - Не можна: пробіли, порт, IP-адреса, логін в адресі (
user@) — помилка400 invalid_request. - Без домену сайт збирається без
sitemap.xml,canonical,og:urlіhreflang: їм потрібна повна адреса.
extraLanguagesstring[]- Коди — як у
language: двобуквені ISO 639-1 у нижньому регістрі зі списку підтримуваних. Регіональні варіанти (en-GB,pt-BR) не приймаються. - Основна мова лежить у корені сайту й позначена як
x-default. Додаткові — у підпапках/en/,/de/у порядку масиву. - Повтори й основна мова всередині
extraLanguagesпропускаються й до ліміту не зараховуються. - Ліміт тарифу — Premium 2, Elite 9 додаткових, Basic 0. Зайві мови відкидаються з кінця масиву, ціна замовлення не змінюється — попередження
language_limit. - Непідтримуваний код у
languageабоextraLanguages— помилка400 invalid_request. - Якщо нішу не можна робити однією з мов (наприклад, VPN російською) —
422 niche_language_refused, замовлення не створюється. Приберіть цю мову й повторіть.
"tier": "premium",
"language": "es",
"extraLanguages": ["es", "en", "en", "de", "fr"]
→ мови сайту: es (корінь), /en/, /de/
→ "warnings": [{
"code": "language_limit",
"field": "extraLanguages",
"message": "Premium: до 3 мов, fr не додано"
}]countrystring · 2 літери- Код ISO 3166-1, регістр не важливий:
mxіMX— одна країна. - Підтримуються:
US GB CA AU IE NZ DE AT CH ES MX CO CL FR BE RU KZ IT PT BR NL PL CZ RO SE DK NO. - Мову сайту країна не змінює — її задає
language. Англійський сайт для німецької компанії —"language": "en", "country": "DE": ціни в євро, телефон+49, імпринт англійською. - Без поля або з кодом не зі списку — помилка
400 invalid_requestз полемcountry, кредити не списуються.
"language": "es", "country": "MX" → ціни в песо → телефон +52 55 1234 5678 → <html lang="es-MX">
archiveFormatstring · html | phphtml(за замовчуванням) — статичний сайт: будь-який хостинг, Netlify, GitHub Pages.php— сторінки ті самі, поруч обробник заявок: форми надсилають їх наcompanyInfo.email. Потрібен хостинг із PHP 7.0 або новішим, де працює надсилання пошти (mail()).- Без
companyInfo.emailсайт отримує демо-контакти, і пошти для заявок немає: форми не приймають їх, доки ви не впишете адресу на початку PHP-файлу. - Ціна від формату не залежить. Інше значення — помилка
400 invalid_request.
Приклад
POST /api/v1/generate
Authorization: Bearer sg_ваш_ключ
Content-Type: application/json
{
"tier": "premium",
"siteType": "local-business",
"niche": "стоматологія",
"language": "es",
"country": "ES",
"extraLanguages": ["en", "de"],
"baseUrl": "sonrisa-clinica.es",
"brandColor": "#1e6fd9",
"keywords": ["implantes", "ortodoncia"],
"companyInfo": {
"name": "Sonrisa",
"email": "hola@sonrisa.es",
"phone": "+34 600 000 000"
}
}{
"success": true,
"jobId": "V1StGXR8Z5jd",
"queue": {
"position": 3,
"etaSeconds": 90
},
"warnings": []
}Поля відповіді
Дізнатися статус
Показує, на якому етапі замовлення. Опитуйте раз на 3–5 секунд, доки статус не стане кінцевим: completed, failed або cancelled.
{
"jobId": "V1StGXR8Z5jd",
"status": "processing",
"queuePosition": null,
"etaSeconds": null,
"progress": 55,
"step": "Тексти готові, підбираємо фото…",
"error": null,
"ready": false
}Статуси
Скасувати замовлення
Працює, поки замовлення чекає в черзі (pending). Кредити одразу повертаються на баланс. Якщо збирання вже почалося, скасувати його не можна — відповідь 409 not_waiting.
{ "jobId": "V1StGXR8Z5jd", "status": "cancelled", "refunded": true }Завантажити архів
Віддає application/zip потоком, коли статус — completed. Архів зберігається 14 днів, завантажувати його можна скільки завгодно разів. Пізніше відповідь — 410 gone.
Помилки
Машинний код помилки — у data.code. Спирайтеся на нього: текст повідомлення може змінюватися.
{
"statusCode": 422,
"message": "Цю нішу ми не генеруємо: …",
"data": {
"code": "niche_refused",
"category": "gambling",
"reason": "азартні ігри",
"alternatives": [
{ "label": "клуб настільних ігор", "canonical": null }
]
}
}Чуже завдання відповідає тим самим 404, що й неіснуюче, — тож номери завдань не можна перевірити перебором.
Ліміти й черга
У разі 429 надходить заголовок Retry-After із кількістю секунд. Дочекайтеся її: повтор раніше строку не обходить ліміт, а подовжує його. Ліміти рахуються за ключем, а не за IP-адресою.