Описание приватного API api.kwork.ru, реконструированного из приложения.
https://api.kwork.ru/
Хост зависит от языкового сервера: ru → api.kwork.ru, en → api.kwork.com.
По умолчанию работаем с api.kwork.ru.
- Метод: преимущественно POST, тело
application/x-www-form-urlencoded(несколько методов —@BodyJSON илиmultipartдля загрузки файлов). - Путь метода добавляется к базовому URL:
POST https://api.kwork.ru/signIn.
| Заголовок | Значение | Обязателен |
|---|---|---|
Authorization |
Basic bW9iaWxlX2FwaTpxRnZmUmw3dw== |
да, на каждом запросе |
Cookie |
slrememberme=<value> |
для авторизованных запросов |
User-Agent |
UA приложения (уточняется перехватом) | желательно |
Authorization — статичный идентификатор клиента: Basic base64("mobile_api:qFvfRl7w").
Это не пользователь — это «ключ приложения», одинаковый для всех.
Большинство методов принимают общий набор полей:
| Поле | Назначение |
|---|---|
token |
пользовательский токен сессии (после /signIn) |
uad |
идентификатор установки приложения (см. ниже) |
slrememberme |
значение сессии (дублируется в Cookie) |
device |
название устройства/клиента |
makeOnline |
флаг «отметить пользователя онлайн» (0/1), у части методов |
uad = SHA1_hex( "35"
+ Σ(len(BuildProp_i) % 10) // 14 свойств Build.*
+ ANDROID_ID
+ currentTimeMillis )
Создаётся один раз при первом запуске и кэшируется. В библиотеке генерируем один стабильный hex-идентификатор и храним его (конфиг/файл), переиспользуя между запусками.
POST /signInс полямиlogin,password,recaptcha_pass_token(опц.) + заголовокAuthorization.- Ответ —
SignInResponse:
- Дальше
tokenкладём в поле формы каждого запроса, плюсCookie: slrememberme=....
При срабатывании анти-бота вход может потребовать капчу:
signInWithCaptcha(полеg-recaptcha-response) или подтверждение телефоном (phone_last).
Признак: POST /signIn возвращает HTTP 200 с телом
{"success": false, "error": "Подтвердите, что вы не робот", "error_code": 118}error_code 118 = нужна капча. Параметры (захвачены со страницы /captcha_only):
| Параметр | Значение |
|---|---|
| Провайдер | Google reCAPTCHA v2 (https://www.google.com/recaptcha/api.js) |
| sitekey | 6LdX9CATAAAAAARb0rBU8FXXdUBajy3IlVjZ2qHS (одинаков для .ru/.com) |
| Страница виджета | https://kwork.ru/captcha_only (callback RecaptchaSuccess, токен в #response=) |
Поток решения:
signIn→error_code 118.- Получить
g-recaptcha-response(WebView на/captcha_only, свой виджет с sitekey, или решалка вроде 2captcha по sitekey+pageurl). Токен привязан к доменуkwork.ruи живёт ~2 минуты. POST /signInWithCaptchaс полямиlogin,password,g-recaptcha-response,recaptcha_pass_token,phone_last→ успех +recaptcha_pass_token(на верхнем уровне ответа, рядом сresponse).recaptcha_pass_tokenпередавать в последующиеsignIn(полеrecaptcha_pass_token), чтобы капчу больше не спрашивали.
В библиотеке это login() → LoginChallenge → kw.solve_captcha(challenge, token)
(см. 07-usage.md). Есть также картиночная ветка (captcha_img/
captcha_sid/captchaCode) и подтверждение телефоном — для аккаунтов, где включены.
Внимание:
server: QRATOR— анти-DDoS Qrator. Его WAF может отдать HTTP 403 без тела — это НЕ капча (решать нечего), а жёсткий лимит; библиотека поднимаетKworkRateLimitError. Капча (118) и WAF-блок (403) — разные механизмы.
Иерархия Gson-моделей:
BooleanResponse // база
├─ success: boolean
├─ error: String?
├─ errorCode: Integer?
├─ errors: List<String>?
└─ restriction: Restriction? // ограничения/баны
DataResponse<T> extends BooleanResponse
└─ response: T // alternate-имена: "data", "portfolio"
PagedResponse<T> extends DataResponse<...>
└─ paging: { page, total, limit, pages }
MessageResponse extends BooleanResponse
└─ message: String
Практические выводы для клиента:
- Успех —
success == true; данные — вresponse(илиdata/portfolio). - Ошибка —
success == false; текст вerror, код вerrorCode, иногда списокerrors. - Пагинация — в объекте
paging(page/pages/total/limit). - Ограничения аккаунта — объект
restriction.
| Признак | Трактовка | Исключение в библиотеке |
|---|---|---|
success=false + текст про token/auth |
протух/неверен токен | KworkAuthError |
success=false + restriction |
бан/ограничение | KworkAPIError (+ payload) |
| HTTP 429 | rate-limit / анти-бот | KworkRateLimitError |
| HTTP ≥ 400 | транспортная ошибка | KworkAPIError |
См. 03-endpoints.md — 192 эндпоинта в 14 сервисах:
Actor, User, Catalog, Search, Exchange, Order, Dialog, Inbox,
Track, Notification, KworkDetails, Kwork, Portfolio, File.
{ "success": true, "response": { // полезная нагрузка DataResponse "token": "<user-token>", "expired": 1718900000 // срок действия токена }, "phone_mask": "+7 *** *** ** 00", "recaptcha_pass_token": "...", "is_registration": false }