Локальный HTTP API
Santiago запускает локальный демон, который предоставляет HTTP API по адресу http://localhost:7891. Каждое действие в браузере, которое выполняет ваш код или AI-агент, проходит через этот демон, а он управляет запущенным браузером Camoufox через Playwright. На этой странице описаны базовые пути, конверт ответа, коды статусов и ошибок, а также то, как демон защищает эти эндпоинты от других вкладок на вашей машине.
Демон слушает только localhost — он никогда не доступен по сети. Если вы используете готовый агентский скилл, он уже общается по этому протоколу за вас; см. Установка агентского скилла. Полный каталог действий находится в справочнике API.
Базовые URL
Заголовок раздела «Базовые URL»Под 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
Заголовок раздела «Договоримся о переменной $PROFILE»В каждом примере ниже используется переменная оболочки для идентификатора профиля, чтобы можно было копировать команды без правки пути каждый раз. Экспортируйте её один раз с идентификатором запущенного профиля:
export PROFILE="3f9a1c20-7b6e-4f0a-9c2d-1e8b5a6d4c01"Все последующие сниппеты curl ссылаются на $PROFILE в URL.
Конверт ответа
Заголовок раздела «Конверт ответа»Каждый эндпоинт возвращает JSON в одной из двух форм. При успехе ok равно true, а полезная нагрузка лежит в data:
{ "ok": true, "data": { "url": "https://example.com/", "title": "Example Domain" } }При неудаче ok равно false, а error несёт машиночитаемый code и понятное человеку сообщение message:
{ "ok": false, "error": { "code": "PROFILE_NOT_RUNNING", "message": "Profile is not running" } }Некоторые действия, которые просто завершаются успехом без возврата данных, отвечают только { "ok": true } — например click, hover и scroll-to.
Первый запрос
Заголовок раздела «Первый запрос»Перейдите в запущенном профиле по URL. navigate возвращает итоговый url и title страницы:
curl -s -X POST "http://localhost:7891/api/automation/$PROFILE/navigate" \ -H "Content-Type: application/json" \ -d '{"url":"https://example.com"}'{ "ok": true, "data": { "url": "https://example.com/", "title": "Example Domain" } }Прочитать страницу так же просто. Действие snapshot возвращает дерево доступности, где каждый интерактивный элемент несёт [ref=…], который вы можете переиспользовать в последующих действиях:
curl -s -X POST "http://localhost:7891/api/automation/$PROFILE/snapshot" \ -H "Content-Type: application/json" \ -d '{}'{ "ok": true, "data": { "snapshot": "- heading \"Example\" [ref=e1]\n- textbox \"Email\" [ref=e2]\n..." } }Затем вы нацеливаетесь на элементы по этому ref или по CSS-selector — большинство эндпоинтов взаимодействия принимают любой из них:
curl -s -X POST "http://localhost:7891/api/automation/$PROFILE/click" \ -H "Content-Type: application/json" \ -d '{"ref":"e1"}'{ "ok": true }HTTP-коды статусов
Заголовок раздела «HTTP-коды статусов»Демон сопровождает каждый конверт ошибки соответствующим HTTP-статусом, так что для грубой обработки можно полагаться только на строку статуса.
| Статус | Значение | Когда вы его видите |
|---|---|---|
200 | Успех | Действие выполнено; читайте data. |
400 | Некорректный запрос | Обязательное поле отсутствует или недопустимо (например, пустой массив actions, индекс вкладки вне диапазона или попытка закрыть последнюю вкладку). |
401 | Не авторизован | Токены вашего аккаунта истекли или недействительны. Приложению нужно снова войти в систему. |
404 | Не найдено | Профиль не запущен (PROFILE_NOT_RUNNING) либо нет ожидающего диалога (NO_DIALOG). |
500 | Действие не удалось | Операция в браузере выбросила ошибку — элемент не найден, навигация по таймауту, ошибка в JavaScript и т. п. |
500 здесь обычно не означает падение: это значит, что запрошенная операция в браузере не смогла завершиться (например, локатор сработал по таймауту). error.code подскажет, какое действие не удалось, а error.message несёт исходное сообщение Playwright.
Коды ошибок
Заголовок раздела «Коды ошибок»Коды ошибок сгруппированы по области, из которой они приходят. Коды, оканчивающиеся на _FAILED, всегда несут исходную ошибку браузера в message.
Запрос и жизненный цикл
Заголовок раздела «Запрос и жизненный цикл»| Код | Статус | Значение |
|---|---|---|
PROFILE_NOT_RUNNING | 404 | Для :profileId нет запущенного браузера. Сначала запустите его. |
BAD_REQUEST | 400 | Обязательное поле отсутствовало или было недопустимо (например, пустой actions/fields, индекс вкладки вне диапазона). |
LAST_TAB | 400 | Вы попытались закрыть единственную открытую вкладку. Вместо этого остановите профиль. |
NO_DIALOG | 404 | Вы вызвали /dialog, но нет ожидающего alert/confirm/prompt. |
Сбои действий
Заголовок раздела «Сбои действий»| Код | Действие, которое его вызвало |
|---|---|
NAVIGATE_FAILED | navigate, back, forward, reload |
SNAPSHOT_FAILED | snapshot |
SCREENSHOT_FAILED | screenshot |
CLICK_FAILED | click |
HOVER_FAILED | hover |
DRAG_FAILED | drag |
SELECT_FAILED | select-option |
SELECT_COMBOBOX_FAILED | select-combobox |
TYPE_FAILED | type |
PRESS_SEQ_FAILED | press-sequentially |
KEY_PRESS_FAILED | press-key |
FILL_FORM_FAILED | fill-form |
FILL_PAGE_FAILED | fill-page |
SCROLL_FAILED | scroll-to |
MOUSE_FAILED | mouse/move, mouse/click, mouse/down, mouse/up, mouse/wheel |
TABS_FAILED | tabs (список) |
TAB_NEW_FAILED | tabs/new |
TAB_SELECT_FAILED | tabs/select |
TAB_CLOSE_FAILED | tabs/close |
EVALUATE_FAILED | evaluate |
WAIT_FAILED | wait |
BATCH_FAILED | batch |
DIALOG_FAILED | dialog |
Нацеливание на элементы
Заголовок раздела «Нацеливание на элементы»Эндпоинты взаимодействия (click, hover, type, scroll-to и подобные) требуют либо ref (из снимка), либо CSS-selector. Если вы не передадите ни того, ни другого, действие завершится ошибкой с сообщением:
Either "ref" or "selector" must be providedПример: обработка ошибки
Заголовок раздела «Пример: обработка ошибки»Когда элемента нет на странице, действие быстро завершается неудачей и возвращает соответствующий код _FAILED со статусом 500:
curl -s -X POST "http://localhost:7891/api/automation/$PROFILE/click" \ -H "Content-Type: application/json" \ -d '{"selector":"#does-not-exist"}'{ "ok": false, "error": { "code": "CLICK_FAILED", "message": "locator.click: Timeout 2000ms exceeded." } }Модель безопасности localhost
Заголовок раздела «Модель безопасности localhost»Поскольку демон слушает localhost, любая веб-страница, открытая в любом браузере на той же машине, в принципе могла бы попытаться отправить ему POST. Разрешающая CORS-политика не останавливает это: «простой» кросс-доменный POST полностью пропускает CORS-предзапрос (preflight), и даже когда предзапрос выполняется, origin с подстановочным символом всё равно его проходит. CORS управляет лишь тем, может ли страница прочитать ответ, — а не тем, дойдёт ли запрос до демона.
Santiago закрывает эту брешь двумя слоями защиты:
- Проверка origin при записи. Хук
onRequestотклоняет кросс-доменные запросыPOST,PATCHиDELETEна основе их заголовкаOrigin. Встроенный интерфейс Santiago отдаётся с того же origin, что и демон, поэтому его запросы проходят; запрос с другого сайта отклоняется. - Завершение работы, защищённое секретом. Эндпоинт завершения работы дополнительно требует внутренний секрет в заголовке. Он предназначен для вызова только процессом трея настольного приложения, но не автоматизацией.
Что это значит на практике:
curlи локальные скрипты работают. Клиенты командной строки и ваши собственные инструменты автоматизации не отправляют браузерный заголовокOrigin, поэтому проверка origin их не блокирует. Каждый пример сcurlна этой странице работает как есть с запущенным демоном.- Интерфейс с тем же origin работает. Встроенный интерфейс приложения разделяет origin демона и разрешён.
- Случайные веб-страницы заблокированы. Страница с какого-то стороннего сайта, которая пытается управлять вашими профилями, отклоняется проверкой
Origin.
Куда двигаться дальше
Заголовок раздела «Куда двигаться дальше»- Справочник API — полный каталог действий, полей и примеров полезной нагрузки.
- Запуск профилей — запустите профиль, чтобы его эндпоинты автоматизации стали доступны.
- Лучшие практики — темп, запасные варианты и пакетирование нескольких действий в одном вызове.
- Установка агентского скилла — позвольте AI-агенту управлять этим API за вас.