Перейти до вмісту

Локальний HTTP API

Santiago запускає локальний демон, який надає HTTP API за адресою http://localhost:7891. Кожна дія в браузері, яку виконує ваш код або AI-агент, проходить через цей демон, що керує запущеним браузером Camoufox через Playwright. На цій сторінці описано базові шляхи, конверт відповіді, коди статусів і помилок, а також те, як демон захищає ці ендпоінти від інших вкладок на вашій машині.

Демон слухає лише на localhost — він ніколи не відкривається в мережу. Якщо ви використовуєте запакований agent skill, він уже спілкується цим протоколом за вас; див. Встановлення agent skill. Повний каталог дій по кожній окремій операції є в Довіднику API.

Під http://localhost:7891/api існують два базові шляхи:

ПризначенняБазовий шлях
Керування демоном (ліцензія, профілі, оновлення тощо)http://localhost:7891/api
Дії автоматизації браузераhttp://localhost:7891/api/automation/:profileId/<action>

Ендпоінти автоматизації завжди націлені на один запущений профіль, який визначається його :profileId у шляху. Сегмент <action> — це операція, наприклад navigate, click, snapshot або screenshot.

http://localhost:7891/api/automation/:profileId/<action>

Налаштуйте змінну $PROFILE

Section titled “Налаштуйте змінну $PROFILE”

Кожен приклад нижче використовує змінну оболонки для ідентифікатора профілю, щоб ви могли копіювати команди, не редагуючи шлях щоразу. Експортуйте її один раз з ідентифікатором запущеного профілю:

Set the profile id once
export PROFILE="3f9a1c20-7b6e-4f0a-9c2d-1e8b5a6d4c01"

Усі наступні фрагменти curl посилаються на $PROFILE в URL.

Кожен ендпоінт повертає JSON в одній із двох форм. У разі успіху ok дорівнює true, а корисне навантаження міститься в data:

Success
{ "ok": true, "data": { "url": "https://example.com/", "title": "Example Domain" } }

У разі помилки ok дорівнює false, а error несе машиночитний code плюс зрозумілий людині message:

Failure
{ "ok": false, "error": { "code": "PROFILE_NOT_RUNNING", "message": "Profile is not running" } }

Деякі дії, які просто завершуються успіхом без повернення даних, відповідають лише { "ok": true } — наприклад click, hover та scroll-to.

Перейдіть запущеним профілем на URL. navigate повертає підсумковий url та title сторінки:

Navigate the profile to a URL
curl -s -X POST "http://localhost:7891/api/automation/$PROFILE/navigate" \
-H "Content-Type: application/json" \
-d '{"url":"https://example.com"}'
Response
{ "ok": true, "data": { "url": "https://example.com/", "title": "Example Domain" } }

Зчитати сторінку так само просто. Дія snapshot повертає дерево доступності, де кожен інтерактивний елемент несе [ref=…], який можна повторно використати в наступних діях:

Capture the page structure
curl -s -X POST "http://localhost:7891/api/automation/$PROFILE/snapshot" \
-H "Content-Type: application/json" \
-d '{}'
Response
{ "ok": true, "data": { "snapshot": "- heading \"Example\" [ref=e1]\n- textbox \"Email\" [ref=e2]\n..." } }

Потім ви націлюєтесь на елементи за цим ref або за CSS-selector — більшість ендпоінтів взаємодії приймають будь-який із них:

Click an element by ref
curl -s -X POST "http://localhost:7891/api/automation/$PROFILE/click" \
-H "Content-Type: application/json" \
-d '{"ref":"e1"}'
Response
{ "ok": true }

Демон супроводжує кожен конверт помилки відповідним HTTP-статусом, тож для грубої обробки ви можете покладатися лише на рядок статусу.

СтатусЗначенняКоли ви його бачите
200УспіхДія виконалась; читайте data.
400Некоректний запитВідсутнє або недійсне обов’язкове поле (напр., порожній масив actions, індекс вкладки поза діапазоном або спроба закрити останню вкладку).
401Не авторизованоТокени вашого акаунту прострочені або недійсні. Застосунок потрібно знову авторизувати.
404Не знайденоПрофіль не запущений (PROFILE_NOT_RUNNING) або немає очікуваного діалогу (NO_DIALOG).
500Дія не виконаласьОперація браузера викинула виняток — елемент не знайдено, навігація завершилась таймаутом, помилка JavaScript тощо.

500 тут зазвичай не є збоєм: він означає, що запитана операція браузера не змогла завершитись (наприклад, локатор завершився таймаутом). error.code підкаже, яка дія не вдалася, а error.message несе базове повідомлення Playwright.

Коди помилок згруповані за областю, з якої вони походять. Коди, що закінчуються на _FAILED, завжди несуть базову помилку браузера в полі message.

КодСтатусЗначення
PROFILE_NOT_RUNNING404Для :profileId немає запущеного браузера. Спершу запустіть його.
BAD_REQUEST400Обов’язкове поле відсутнє або недійсне (напр., actions/fields порожні, індекс вкладки поза діапазоном).
LAST_TAB400Ви спробували закрити єдину відкриту вкладку. Замість цього зупиніть профіль.
NO_DIALOG404Ви викликали /dialog, але немає очікуваного alert/confirm/prompt.
КодДія, що його спричинила
NAVIGATE_FAILEDnavigate, back, forward, reload
SNAPSHOT_FAILEDsnapshot
SCREENSHOT_FAILEDscreenshot
CLICK_FAILEDclick
HOVER_FAILEDhover
DRAG_FAILEDdrag
SELECT_FAILEDselect-option
SELECT_COMBOBOX_FAILEDselect-combobox
TYPE_FAILEDtype
PRESS_SEQ_FAILEDpress-sequentially
KEY_PRESS_FAILEDpress-key
FILL_FORM_FAILEDfill-form
FILL_PAGE_FAILEDfill-page
SCROLL_FAILEDscroll-to
MOUSE_FAILEDmouse/move, mouse/click, mouse/down, mouse/up, mouse/wheel
TABS_FAILEDtabs (список)
TAB_NEW_FAILEDtabs/new
TAB_SELECT_FAILEDtabs/select
TAB_CLOSE_FAILEDtabs/close
EVALUATE_FAILEDevaluate
WAIT_FAILEDwait
BATCH_FAILEDbatch
DIALOG_FAILEDdialog

Націлювання на елементи

Section titled “Націлювання на елементи”

Ендпоінти взаємодії (click, hover, type, scroll-to та подібні) вимагають або ref (зі знімка), або CSS-selector. Якщо ви не надішлете жодного, дія завершиться помилкою з повідомленням:

Either "ref" or "selector" must be provided

Приклад: обробка помилки

Section titled “Приклад: обробка помилки”

Коли елемента немає на сторінці, дія швидко завершується невдачею та повертає відповідний код _FAILED зі статусом 500:

Click a selector that isn't there
curl -s -X POST "http://localhost:7891/api/automation/$PROFILE/click" \
-H "Content-Type: application/json" \
-d '{"selector":"#does-not-exist"}'
Response
{ "ok": false, "error": { "code": "CLICK_FAILED", "message": "locator.click: Timeout 2000ms exceeded." } }

Оскільки демон слухає на localhost, будь-яка вебсторінка, відкрита в будь-якому браузері на тій самій машині, в принципі може спробувати зробити POST до нього. Дозволяюча політика CORS не зупиняє цього: «простий» крос-доменний POST повністю пропускає preflight-перевірку CORS, а навіть коли preflight спрацьовує, wildcard-origin усе одно його проходить. CORS лише визначає, чи може сторінка читати відповідь, — а не чи дійде запит до демона.

Santiago закриває цю прогалину двома рівнями захисту:

  • Перевірка origin на записи. Хук onRequest відхиляє крос-доменні запити POST, PATCH та DELETE на основі їхнього заголовка Origin. Вбудований інтерфейс Santiago обслуговується з того ж origin, що й демон, тож його запити проходять; запит з іншого сайту відхиляється.
  • Вимкнення за секретом. Ендпоінт вимкнення додатково вимагає внутрішнього секрету в заголовку. Його має викликати лише процес трея десктопного застосунку, ніколи — автоматизація.

Що це означає на практиці:

  • curl та локальні скрипти працюють. Клієнти командного рядка та ваші власні інструменти автоматизації не надсилають браузерний заголовок Origin, тож перевірка origin їх не блокує. Кожен приклад curl на цій сторінці працює як є з запущеним демоном.
  • Інтерфейс із тим самим origin працює. Вбудований інтерфейс ділить origin із демоном і дозволений.
  • Випадкові вебсторінки заблоковані. Сторінка на якомусь іншому сайті, що намагається керувати вашими профілями, відхиляється перевіркою Origin.