exstru
Відкрити в Telegram
← Огляд API

exstru API · v1

Документація API.

Усе, що потрібно для інтеграції: доступ і ключ, параметри замовлення, статуси, архів, помилки, ліміти й правила списання кредитів.

БАЗОВА АДРЕСАhttps://exstru.com/api/v1
ФОРМАТJSON · UTF-8
АВТОРИЗАЦІЯBearer sg_…
РЕЗУЛЬТАТZIP-архів сайту

Швидкий старт

Три кроки від ключа до готового архіву. Сайт збирається в середньому близько хвилини, тому замовлення повертає номер завдання, а не сайт: далі ви опитуєте статус і завантажуєте ZIP.

01Отримайте ключКупіть пакет «Team», «Holding» або «Kraken» — API ввімкнеться на 30 днів безкоштовно. Ключ випускається в боті, у розділі «API».
02Замовте сайтНадішліть нішу, мову й тариф. У відповіді — номер завдання й місце в черзі.
03Заберіть архівОпитуйте статус раз на 3–5 секунд. Щойно замовлення готове, завантажте 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» в боті — там само його перевипускають і відкликають. Кредити за сайти списуються зі спільного балансу команди.

30 днів безкоштовноЗ першою покупкою пакета «Team», «Holding» або «Kraken». Один раз на команду. Нагадаємо за 7 і 3 дні до закінчення та в останній день.
$99 / 30 днівПісля пробного періоду. Оплата зі стабільного балансу в доларах, а не з кредитів.
АвтопродовженняВмикається лише вами. Якщо на продовження не вистачило коштів, власник отримує сповіщення, а API працює ще 24 години.
Без підпискиВимикається лише API: кабінет команди, кредити й генерація в боті продовжують працювати. Ключ відповідає 403 subscription_inactive.

Як передати ключ

У будь-якому з двох заголовків — вони рівноцінні. Другий потрібен, якщо ваша бібліотека вже займає Authorization.

заголовки
Authorization: Bearer sg_ваш_ключ
X-Api-Key: sg_ваш_ключ
Ключ — це доступ до кредитів команди.Зберігайте його на сервері, а не в браузері чи мобільному застосунку: звідти його легко витягти. Якщо ключ витік, відкличте або перевипустіть його в боті — старий одразу перестане працювати.

Тарифи в запиті

Тариф передається в полі tier і визначає, скільки кредитів спишеться і що отримає сайт. Підписка на API тариф не обмежує: за одним ключем можна замовляти будь-який.

Параметрbasicpremiumelite
Списується кредитів61025
Мов на сайті1до 3до 10
Свій колір бренду—✓✓
Логотип—унікальнийунікальний
ЗображеннястокAI під нішуAI під нішу
Формиконтактна+ зворотний дзвінок+ квіз
Основних сторінок~5–7~7–10~10–15+
Статей у блозі3–55–1010–15

Повне порівняння можливостей — на сторінці «Тарифи».

POST/api/v1/generate

Замовити сайт

Ставить сайт у чергу й списує кредити за тарифом. Відповідь надходить одразу — з номером завдання й місцем у черзі.

Параметри тіла запиту

ПолеОпис
tierобов’язковоstring · basic | premium | eliteТариф сайту: спишеться 6, 10 або 25 кредитів.
siteTypeобов’язковоstring · local-business | blogСайт компанії або блог. У блозі кількість статей залежить від тарифу: 3–5, 5–10 або 10–15.
nicheобов’язковоstring · 2–100 символівНіша своїми словами, наприклад «стоматологія» або «ремонт пральних машин». Генеруємо лише білі ніші: на решту — відмова 422 niche_refused з варіантами поруч, кредити не списуються.
languageобов’язковоstring · код ISO 639-1Основна мова сайту: двобуквений код однієї з 14 підтримуваних — en, de, ru, es, fr, it, pt, nl, pl, cs, ro, sv, da, no.
extraLanguagesнеобов’язковоstring[]Додаткові мови, на сайті з’явиться перемикач. Premium — до 2, Elite — до 9: разом з основною до 3 і до 10. На Basic — лише основна. Повтори, ліміт і несумісні мови — у правилах нижче.
countryобов’язковоstring · код ISO 3166-1Країна бізнесу: валюта цін, формат телефону й адреси, регіон у розмітці та обов’язкові юридичні сторінки, наприклад імпринт для DE, AT і CH. Обов’язкове поле. Список — у правилах нижче.
archiveFormatнеобов’язковоstring · html | phpФормат архіву: html — статичний сайт для будь-якого хостингу, php — форми самі надсилають заявки на пошту. Без поля — html. Докладніше — у правилах нижче.
baseUrlнеобов’язковоstring · доменДомен майбутнього сайту: з ним в архіві будуть sitemap.xml, canonical і hreflang. Формат — у правилах нижче.
brandColorнеобов’язковоstring · #rrggbbКолір бренду — на Premium і Elite, палітра будується навколо нього. Формат — у правилах нижче.
keywordsнеобов’язковоstring[] · до 8 фразКлючові фрази, які ввійдуть у заголовки й тексти.
companyInfoнеобов’язковоobjectНазва, контакти й факти про компанію. Якщо не передати, генератор вигадає їх сам; що більше даних, то точніші тексти. Схема — у правилах нижче.

Правила полів

Помилки формату повертаються всі одразу: 400 invalid_request, перелік — у data.issues. Кредити при цьому не списуються. Невідомі поля ігноруються.

companyInfoobject

Якщо об’єкт передано, name, email і phone обов’язкові. Без об’єкта назву й контакти вигадає генератор. Усі поля — рядки.

name2–200 · обов’язковоНазва компанії, як на вивісці.
emailemail · обов’язковоАдреса для сторінки контактів і форм.
phone5–30 · обов’язковоТелефон у міжнародному форматі: +34 600 000 000.
addressдо 300Адреса офісу або точки.
descriptionдо 1000Чим займається компанія: 1–3 речення.
legalInfoдо 500Юридична назва й реквізити для юридичних сторінок.
foundedYearдо 20Рік заснування: «2014» або «з 2014».
teamSizeдо 20Розмір команди: «12» або «10–15».
founderNameдо 120Ім’я засновника для сторінки «Про компанію».
founderRoleдо 120Посада засновника.
serviceAreaдо 160Географія роботи: «Мадрид і передмістя».
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: їм потрібна повна адреса.
ПередалиВийде
Example.COM/https://example.com
http://www.example.comhttps://www.example.com
https://example.com/clinic/?utm=1https://example.com/clinic
xn--80aswg.xn--p1aihttps://xn--80aswg.xn--p1ai
example.com:8080400 invalid_request
мій сайт.укр400 invalid_request
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, замовлення не створюється. Приберіть цю мову й повторіть.
приклад · premium
"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 | php
  • html (за замовчуванням) — статичний сайт: будь-який хостинг, 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"
  }
}
відповідь · 200
{
  "success": true,
  "jobId": "V1StGXR8Z5jd",
  "queue": {
    "position": 3,
    "etaSeconds": 90
  },
  "warnings": []
}

Поля відповіді

jobIdНомер завдання: потрібен для статусу, скасування й завантаження.
queueМісце в черзі (position, 1 — наступний) і приблизне очікування до старту в секундах (etaSeconds). null — якщо збирання почалося одразу.
warningsЩо із запиту не застосувалося — замовлення при цьому виконується. Масив об’єктів { code, field, message }: language_limit — мови понад тариф, brand_color_not_in_tier — колір бренду на Basic.
GET/api/v1/status/{jobId}

Дізнатися статус

Показує, на якому етапі замовлення. Опитуйте раз на 3–5 секунд, доки статус не стане кінцевим: completed, failed або cancelled.

statusОдин із п’яти статусів — див. нижче.
queuePositionМісце в черзі, поки замовлення чекає. Інакше null.
etaSecondsПриблизне очікування до старту, поки замовлення чекає.
progressГотовність від 0 до 100.
stepПоточний етап збирання текстом.
errorПричина, якщо збирання не вдалося.
readytrue — архів можна завантажувати.
відповідь · 200
{
  "jobId": "V1StGXR8Z5jd",
  "status": "processing",
  "queuePosition": null,
  "etaSeconds": null,
  "progress": 55,
  "step": "Тексти готові, підбираємо фото…",
  "error": null,
  "ready": false
}

Статуси

pendingЧекає в черзі. Можна скасувати.
processingЗбирається.
completedГотово — завантажуйте архів.
failedЗбирання не вдалося. Кредити повернулися автоматично.
cancelledСкасовано в черзі. Кредити повернулися.
POST/api/v1/cancel/{jobId}

Скасувати замовлення

Працює, поки замовлення чекає в черзі (pending). Кредити одразу повертаються на баланс. Якщо збирання вже почалося, скасувати його не можна — відповідь 409 not_waiting.

відповідь · 200
{ "jobId": "V1StGXR8Z5jd", "status": "cancelled", "refunded": true }
GET/api/v1/download/{jobId}

Завантажити архів

Віддає application/zip потоком, коли статус — completed. Архів зберігається 14 днів, завантажувати його можна скільки завгодно разів. Пізніше відповідь — 410 gone.

HTML · CSS · зображенняГотовий статичний сайт для будь-якого хостингу — без CMS і збирання.
robots.txt · сторінка 404Технічний мінімум — на всіх тарифах.
sitemap.xml · canonicalЯкщо в замовленні вказано домен у baseUrl.
Юридичні сторінкиМовами сайту — на всіх тарифах.

Помилки

Машинний код помилки — у data.code. Спирайтеся на нього: текст повідомлення може змінюватися.

приклад · 422
{
  "statusCode": 422,
  "message": "Цю нішу ми не генеруємо: …",
  "data": {
    "code": "niche_refused",
    "category": "gambling",
    "reason": "азартні ігри",
    "alternatives": [
      { "label": "клуб настільних ігор", "canonical": null }
    ]
  }
}
HTTPdata.codeЩо означає і що робити
400invalid_requestЗапит не пройшов перевірку. Усі проблеми одразу — у data.issues.
401no_keyКлюч не передано. Додайте заголовок Authorization або X-Api-Key.
401unknown_keyКлюч неправильний. Звірте його з ключем у боті.
402insufficient_creditsНе вистачає кредитів на балансі команди. Поповніть баланс або ввімкніть автопоповнення.
403key_blockedКлюч відкликано. Випустіть новий у боті.
403subscription_inactiveПідписка на API неактивна. Власник продовжує її в боті — $99 за 30 днів.
404not_foundЗавдання немає або воно належить іншій команді.
409not_waitingСкасувати можна лише замовлення в черзі — це вже збирається або готове.
409not_readyЗамовлення ще не готове. Дочекайтеся статусу completed.
410goneАрхів більше не зберігається: минуло 14 днів.
422niche_refusedЦю нішу не генеруємо. Причина — у data.category і data.reason, до 3 білих ніш поруч — у data.alternatives. Кредити не списуються.
422niche_language_refusedНішу робимо, але не цією мовою. Приберіть мову з language або extraLanguages. Кредити не списуються.
429queue_full_for_accountУ черзі вже 30 замовлень команди. Нове приймемо, коли частина збереться. Кредити не списуються.
429rate_limitedЗанадто часті запити. Зачекайте стільки секунд, скільки вказано в Retry-After.
503niche_unverifiedНе вдалося перевірити нішу. Повторіть запит — кредити не списуються.

Чуже завдання відповідає тим самим 404, що й неіснуюче, — тож номери завдань не можна перевірити перебором.

Ліміти й черга

5 на хвилинузамовлень на один ключ.
240 на хвилинуінших запитів: статус, скасування, завантаження.
30 у черзізамовлень однієї команди одночасно. Нові приймемо, коли частина збереться.
Чесна чергаЗамовлення однієї команди не затримують інших: у відповіді завжди видно місце й очікування.

У разі 429 надходить заголовок Retry-After із кількістю секунд. Дочекайтеся її: повтор раніше строку не обходить ліміт, а подовжує його. Ліміти рахуються за ключем, а не за IP-адресою.

Списання й повернення

Коли списуютьсяПід час постановки в чергу, до початку збирання: 6, 10 або 25 кредитів за тарифом. За самі виклики API платити не потрібно.
ЗбійЯкщо збирання не вдалося, кредити повертаються автоматично.
СкасуванняПоки замовлення в черзі, його можна скасувати — кредити повернуться одразу.
Без списанняВідмова за нішею, помилка в запиті або повна черга — кредити не списуються.
Без подвійних списаньСписання й повернення прив’язані до номера завдання: одне замовлення не спишеться й не повернеться двічі.
Бонусні кредитиЯкщо на балансі є бонусні кредити, вони витрачаються першими.
Куплені кредитиЗалишаються на балансі без обмеження в часі.
АвтопоповненняДля команд: коли кредитів менше за заданий поріг, обраний пакет купується зі стабільного балансу автоматично, і інтеграція не зупиняється. Вимкнено за замовчуванням.
Потрібна допомога з інтеграцією?Напишіть у підтримку [@username] — допоможемо з кодом і сценарієм.Отримати ключ у TelegramОгляд API