Автоматизация
Локальный API, ключи и вызовы вашего сервера
- 50325
- Порт по умолчанию на 127.0.0.1
- 12
- Ходов в локальном интерфейсе
- 7
- Прав, которые несёт ключ сервера
- 13
- Событий, о которых придёт вызов
Интерфейс работает на вашем компьютере, а не на нашем сервере
Локальный API это небольшой HTTP-сервер внутри программы. Он слушает 127.0.0.1 и отвечает программам с этой же машины.
Он там, где и сама работа. Профили, куки, движок и мост для прокси лежат на вашем диске. Открыть окно браузера это местное действие, и наш сервер за вас его не сделает.
Отсюда же поведение без сети. Ваши сценарии продолжают звать программу по петле, а сама программа работает без связи с сервером сутки после проверки доступа.
Конверт ответа взят такой же, как у всего этого рода программ: code, data и msg. Сценарию, написанному под соседний инструмент, обычно нужен новый адрес и новый токен, а не переписывание.
Вести профили из своей программы
Смотреть список, создавать, запускать, останавливать и удалять, не трогая окно.
Подключить Puppeteer, Playwright или Selenium
Ход запуска отвечает точкой отладки именно этого профиля.
Запускать сохранённые сценарии снаружи
Ваше расписание или сборочный сервер берёт сценарий и названные профили.
Дать работать помощнику ИИ
Встроенный сервер MCP ходит теми же ходами, и ему нужен включённый интерфейс.
Один переключатель, один порт, один токен
Интерфейс выключен, пока вы его не включите. Включение открывает порт, поэтому по умолчанию его нет.
При первом запуске программа пишет local-api.json в свою папку данных. Там же заводится случайный токен: 24 байта, то есть 48 знаков, а файл кладётся с правами только для вас.
Порт по умолчанию 50325. Если его уже кто-то занял, сервер садится на любой свободный, и панель прямо говорит, какой он взял. Это важно: ваши сценарии и помощник ИИ смотрят на прежний адрес.
Токен передаётся тремя способами: параметром token в адресе, заголовком x-api-token или через Authorization: Bearer. Обновление токена останавливает все сценарии со старым сразу, поэтому программа сначала спрашивает подтверждение.
- 1
Откройте экран API в программе
На нём переключатель, адрес, токен и список ходов.
- 2
Включите локальный интерфейс
Состояние обязано читаться как «Запущен». Если обычный порт был занят, панель назовёт взятый.
- 3
Скопируйте адрес и токен
Панель даёт готовую строку curl с вашим токеном внутри.
- 4
Наведите на него свой сценарий
Токен нужен всем ходам, кроме /status. Неверный токен возвращается как 401.

Запрос обязан выглядеть программой, а не веб-страницей
Слушать петлю звучит как граница, но границей это не является. Страницы, которые вы открываете, работают на этом же компьютере и до 127.0.0.1 тоже дотягиваются.
Поэтому сервер сначала спрашивает, не страница ли это. Запрос с заголовком Origin отвергается. Отвергается и тот, у которого Sec-Fetch-Site не равен none, потому что none даёт только набранный руками адрес. У curl, у Python и у клиента MCP этих заголовков нет.
Заголовок Host сверяется с адресом, который мы на самом деле слушаем. Имя, которое со второго раза разрешается в 127.0.0.1, приходит сюда как evil.example, и такой запрос закрыт. Без этой сверки браузер считает ответ своим по происхождению и отдаёт странице тело.
Sec-Fetch-Mode нарочно не считается приметой. Собственный fetch в Node шлёт cors без Origin, и по такой примете отсеялись бы почти все написанные людьми сценарии.
За проверкой на страницу стоит даже /status
Двенадцать ходов и один конверт
Всё живёт на 127.0.0.1:50325, и у каждого ответа одни и те же три поля. code равен 0 при удаче, msg говорит success, а полезное лежит в data.
Отказ приходит с code -1 и причиной. Пропавший или неверный токен это HTTP 401 и code -401, запрос со следами страницы 403 и -403, несуществующий путь 404 и -404. Конверт и код HTTP всегда сходятся, поэтому ветвиться можно по любому из них.
Тело запроса читается как JSON и обрезается примерно на мегабайте. Всё, что больше, отбрасывается, и вызов обрабатывается так, будто тела не было.
- Вызов
- curl -H x-api-token:ВАШ_ТОКЕН http://127.0.0.1:50325/api/v1/browser/list
- Конверт
- { code: 0, msg: success, data: { list: [ ... ] } }
- Один профиль
- profileId, name, scenario, group, fingerprintTemplate, tags, lastUsedAt, running
- Его поле прокси
- protocol, host, port. Ни логина, ни пароля
- Неверный токен
- HTTP 401, { code: -401, msg: unauthorized }
- Зов со страницы
- HTTP 403, { code: -403, msg: forbidden }
Токен можно передать и параметром token в адресе, и заголовком Authorization: Bearer.
| Ход | Метод | Что делает |
|---|---|---|
| /status | GET | Говорит, что программа жива, и называет версию. Единственный ход без токена. |
| /api/v1/browser/list | GET | Ваши профили, у каждого его нынешнее состояние. |
| /api/v1/profile/list | GET | Тот же набор под именем, принятым у соседних инструментов. |
| /api/v1/browser/start | POST | Открывает профиль и отвечает его точкой отладки. |
| /api/v1/browser/stop | POST | Закрывает все окна профиля и говорит, сколько закрыл. |
| /api/v1/browser/active | GET | Номера профилей, открытых прямо сейчас. |
| /api/v1/profile/create | POST | Создаёт профиль через ту же проверку нормы, что и окно. |
| /api/v1/profile/delete | POST | Переносит профиль в корзину. |
| /api/v1/profile/code | GET | Нынешний одноразовый код профиля, у которого сохранён ключ 2FA. |
| /api/v1/proxy/list | GET | Сохранённая библиотека прокси: узлы и порты, но никогда пароли. |
| /api/v1/flow/list | GET | Сохранённые сценарии и число шагов в каждом. |
| /api/v1/flow/run | POST | Запускает сценарий на профилях, которые вы назвали. |
Запуск профиля и то, к чему вы подключаетесь
POST /api/v1/browser/start берёт profileId и в теле, и в строке запроса. Наши же примеры для Puppeteer и Playwright шлют его строкой, поэтому принимаются оба способа.
Разовый запуск без окна просится отдельно: headless в теле или headless=1 в строке. Строки 0, false и пустая читаются как «нет», а не как «непустая строка, значит да». Не прислали ничего, решает свойство самого профиля: ночной прогон и дневная работа руками это разные заходы одного профиля.
Что придёт в ответ, зависит от движка. У ARMANOS Browser точка отладки своя на каждый профиль и отделена от остальных. Программа читает порт из файла этого профиля, ожидая примерно четыре с половиной секунды, и отвечает полями debugPort и ws только для него.
У встроенного движка Electron отдельной точки на профиль нет. Его ответ называет порт уровня программы и прямо говорит, что он общий для всех профилей и на петле ничем не закрыт. Этот порт открывается только при выбранном встроенном движке: он не защищён ничем, и через него любая программа на машине управляет окном менеджера, а не только профилями.
Движок ARMANOS Browser
debugPort и ws только этого профиля. Ваша библиотека подключается прямо туда.
Встроенный движок
Общий порт уровня программы, названный в ответе вместе с оговоркой, что он общий.
Ни того, ни другого
Ответ говорит, что точки нет, и почему, вместо пустого поля.
Интерфейс проходит ту же проверку, что и кнопки
Интерфейс это не боковая дверь. Создание профиля идёт через ту же проверку доступа и нормы, что и кнопка в окне: 2 профиля на Free, от 10 до 100 на Professional, от 200 до 1000 на Business, 5000 и выше на Enterprise.
Запуск профиля сначала смотрит на доступ. Если копия заперта, вызов возвращает причину словами, а не пустой отказ.
У flow/run строгий счёт номеров. Незнакомые номера профилей называются в ответе полем data.unknown, чтобы вы поправили свой вызов. Ноль взятых в работу профилей это отказ, а не успех: раньше ход отвечал started: 0 при исправно идущем прогоне, и чужая программа открывала те же профили второй раз.
Два хода существуют потому, что без них сценарии встают. profile/code отдаёт нынешний одноразовый код профиля с сохранённым ключом 2FA, вместе с оставшимися секундами, издателем и учётной записью. proxy/list отдаёт ваши прокси с узлом и портом и никогда с паролем, чтобы утёкший токен не выдал разом все купленные прокси.
Удаление через интерфейс это корзина
Ключи сервера несут права и входят в платные тарифы
Токен выше управляет одной установкой на одном компьютере. Ключ сервера это другое: он говорит с нашим сервером откуда угодно и никогда не открывает окно браузера. Серверный ход с именем start отмечает профиль занятым и пишет журнал открытий, и это всё, что он делает.
Ключ выглядит как ak_ и 24 случайных байта. Вы видите его один раз, при создании. У нас остаются отпечаток sha256, первые десять знаков и данное вами имя: этого хватает, чтобы различать свои ключи, и не хватает, чтобы воспользоваться чужим. У каждого ключа есть права, а ход без объявленного права закрыт ключу вовсе, даже такому, которому выдали всё.
Ключи входят в платные тарифы. На Free их нет. Создание на Free отклоняется, а ключ, у которого кончился оплаченный срок, отвечает 402, а не 401 и не 403. Разница важна программе: по 401 она пойдёт заводить новый ключ, по 403 просить лишних прав, а 402 говорит правду.
Часть правил написана на день, когда ключ утечёт. Ключом нельзя завести ни ключ, ни подписку: это может только человек, вошедший паролем. Закрытый доступ владельца закрывает и его ключи на следующем же вызове. Отзыв оставляет строку на месте, чтобы журнал мог назвать ключ, которым сделано действие, и журнал пишет именно ключ, а не только человека. Держать можно 20 живых ключей, сервер по умолчанию пропускает 300 запросов в минуту и жёстче на ходах входа, а тариф под ключом перепроверяется не чаще раза в минуту.
| Право | Что открывает |
|---|---|
| profiles:read | Список профилей. |
| profiles:write | Создание, правку и удаление профиля. |
| browser:run | Отметку «профиль открыт» и «закрыт» на сервере, без права его переписывать. |
| proxies:read | Сохранённый список прокси, без паролей. |
| proxies:write | Создание, правку и удаление прокси, если роль участника это позволяет. |
| flows:read | Список сохранённых сценариев. |
| logs:read | Журнал действий, журнал открытий, адреса входов и правила подозрительной активности. |
Вызовы рассказывают вашему серверу, что произошло
Вызов это наш сервер, который стучится к вам, когда в вашем пространстве что-то случилось. Подписку заводит человек, вошедший паролем, но не ключ, и держать можно до десяти. События берутся из журнала, поэтому называют ровно то, что записано.
Каждый вызов подписан. Подпись это HMAC-SHA256 от времени и тела, она едет в заголовке X-Armanos-Signature рядом с X-Armanos-Event и X-Armanos-Timestamp. Оба набора разработчика её сверяют и оба отвергают подпись старше пяти минут, иначе перехваченный вызов годился бы вечно. Поля, чьи имена похожи на ключ входа, снимаются перед отправкой: code, token, secret, password, link, hash. Код приглашения и ссылка сброса пароля не уезжают на чужой сервер, даже если он ваш собственный.
О неудаче говорится честно. Три попытки по десять секунд, повтор только на 5xx и 429, с паузой между ними. Переадресация не исполняется: ответ «перейди на 127.0.0.1» иначе обошёл бы всю проверку адреса. Последний код ответа, причина словами и число неудач подряд записываются в саму подписку и видны в кабинете. После пятнадцати неудач подряд подписка выключается сама, с написанной причиной, а не молча.
Адрес проверяется перед каждой отправкой, и имя разрешается заново. Частные сети закрыты, включая служебный адрес облака, который отдаёт ключи от всей учётной записи. Пробная отправка из кабинета несёт test: true, чтобы ваша система не завела по ней несуществующий профиль.
- Метод
- POST, Content-Type application/json
- X-Armanos-Event
- profile.start
- X-Armanos-Timestamp
- Секунды Unix, они же часть подписи
- X-Armanos-Signature
- sha256=... HMAC от времени и тела
- Тело
- { id, event, createdAt, data }
- Доставка
- Хотя бы один раз. Храните id и отбрасывайте повторы
Переадресация не исполняется, а ответы 4xx, кроме 429, не повторяются.
Профили
profile.create, profile.update, profile.delete, profile.start, profile.stop
Прокси
proxy.create, proxy.update, proxy.delete
Ключи
apikey.create, apikey.revoke
Команда
team.invite, team.remove
Деньги
plan.change
Наборы разработчика нарочно остаются тонкой обёрткой
Наборов два: один для Node, второй одним файлом для Python, без единой сторонней зависимости. Оба версии 0.1.0 и оба намеренно тонкие. Набор, который умеет больше сервера, через месяц расходится с ним и начинает врать.
Оба берут ключ и адрес из среды, по умолчанию идут на наш адрес и сдаются через 30 секунд. Оба сверяют, что ключ выглядит как ak_ с латиницей и цифрами, ещё до отправки. Лишний пробел из буфера обмена прежде ломал сам заголовок запроса, и человек видел «сервер недоступен» при живом сервере.
Ошибки различаются кодом, а не текстом. Нехватка права, негодный или отозванный ключ и отсутствие связи это три разных кода, поэтому сценарий ветвится по коду, а не по сообщению, которое может быть переведено.
Что покрыто, следует из прав: профили смотреть, создавать, править, удалять, брать в работу и отпускать; прокси смотреть, заводить, править и удалять; список сценариев; четыре вида журналов. Запуск и остановка шлют имя машины, потому что замок профиля обязан различать две машины, а одно слово со всех машин ломало и замок, и учёт мест.
Половина, ради которой набор и нужен принимающему
Чего это не делает
- Локальный интерфейс дотягивается только до той копии ARMANOS, что стоит на этом компьютере. Хода из облака, открывающего у вас окно, нет, и ключ сервера ничего не запускает: он лишь отмечает профиль занятым и пишет журнал.
- Локальный токен один на весь интерфейс. У него нет ни прав по ходам, ни срока годности, и его обновление разом останавливает все ваши сценарии.
- У локального интерфейса нет своего предела запросов. Он доверяет машине, на которой работает, и потому всю нагрузку там несут проверка на страницу и проверка токена.
- Ключом сервера нельзя завести ни ключ, ни подписку, а любой ход без объявленного права закрыт ключу целиком. Корзина, показ отпечатка, смена и проверка прокси, правка сценариев доступны только входу паролем.
- Доставка вызова идёт «хотя бы один раз», и в теле едут лишь поля, оставшиеся после снятия ключей входа. Ваш приёмник обязан отбрасывать повторы по id и сам запрашивать предмет, когда события ему мало.
Как проверить
Каждое утверждение на этой странице взято из файла, который можно открыть, и почти каждое держит стенд, который исполняется.
- Локальный интерфейс отвергает запросы со следами страницы, и /status стоит за той же проверкой
- apps/desktop/src/lib/local-api.js · apps/desktop/test/local-api-gate.js
- Незащищённый порт отладки уровня программы открывается только для встроенного движка
- apps/desktop/src/main/main.js · apps/desktop/test/cdp-port-only-when-needed.js
- Токен случаен на каждой установке, а интерфейс изначально выключен
- apps/desktop/src/lib/api-config.js · apps/desktop/src/main/main.js
- Ключи сервера платные, и каждое право охраняет настоящий ход
- apps/server/src/api-keys/api-keys.service.ts · apps/server/test/ключи-платные.js · apps/server/test/права-ключей-живые.js
- Вызовы подписаны, их нельзя навести внутрь нашей сети, а неудачи записываются
- apps/server/src/webhooks/webhook-dispatch.service.ts · apps/server/test/webhooks.js · apps/web/test/webhooks-web.js
Читать дальше
MCP для помощников ИИ
Встроенный сервер, который даёт помощнику те же самые ходы.
Сборщик сценариев
Те сценарии, до которых снаружи достают flow/list и flow/run.
Расписание
Прогоны по времени внутри программы, когда своё расписание писать не хочется.
Тарифы и цены
На каких тарифах есть ключи API и сколько стоят место и лишний профиль.
Включите и позовите уже сегодня
Экран API есть в каждой сборке. Поставьте программу, включите интерфейс и наведите свой сценарий на 127.0.0.1.