{"openapi":"3.0.3","info":{"title":"SafeLaw API","version":"1.0.0","description":"Юридические ответы по законодательству Узбекистана. Кроме текста возвращает машиночитаемые ссылки на нормы (citations), сверенные с базой актов. Тарификация — с кошелька аккаунта: каждый запрос списывает деньги по расходу токенов."},"servers":[{"url":"https://api.safelaw.ai/v1","description":"Продакшн"}],"security":[{"bearerAuth":[]}],"paths":{"/chat":{"post":{"summary":"Задать юридический вопрос (можно с файлами)","description":"Основной эндпоинт. К вопросу можно приложить файлы (attachments): документы pdf/docx/doc/txt и до 1 изображения, каждый в base64 — их проанализируют вместе с вопросом. Если модель составит документ (иск, договор, заявление) — он вернётся в поле document {title, content}. Модели safelaw-auto/luna/hybrid/sol оплачиваются по фактической стоимости запроса в сумах; safelaw-auto сам выбирает профиль по сложности вопроса, фактический профиль — в поле profile. Старые safelaw-standard/safelaw-pro — по цене за токены, указанной на safelaw.ai/developers. Точная стоимость запроса — в usage.cost_uzs.","operationId":"chat","security":[{"bearerAuth":[]}],"parameters":[{"name":"Idempotency-Key","in":"header","required":false,"schema":{"type":"string"},"description":"Необязательный ключ повтора. Повтор с тем же значением вернёт сохранённый ответ и не спишет деньги дважды."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChatRequest"},"example":{"question":"Можно ли уволить работника на испытательном сроке?","model":"safelaw-standard"}}}},"responses":{"200":{"description":"Ответ сформирован","headers":{"X-Request-Id":{"schema":{"type":"string"}},"X-Wallet-Balance-Uzs":{"schema":{"type":"integer"},"description":"Остаток на кошельке в сумах"},"X-Quota-Remaining-Tokens":{"schema":{"type":"integer"},"description":"Остаток в пересчёте на токены"},"X-RateLimit-Remaining-Requests":{"schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChatResponse"}}}},"400":{"description":"Некорректный запрос","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Ключ отсутствует/неверен/отозван","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"Нет средств на кошельке (details.reason=no_funds) или месячный предел","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Юрисдикция не поддерживается","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Превышен лимит частоты (см. Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"Сервис временно недоступен","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"504":{"description":"Таймаут","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/usage":{"get":{"summary":"Остаток кошелька и лимиты","operationId":"usage","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"ok","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Usage"}}}},"401":{"description":"Ключ неверен","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}},"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","description":"Ключ вида sf_live_… (боевой) или sf_test_… (отладочный, не тратит средства). Заголовок: Authorization: Bearer sf_live_…"}},"schemas":{"ChatRequest":{"type":"object","required":["question"],"properties":{"question":{"type":"string","maxLength":8000,"description":"Вопрос"},"model":{"type":"string","enum":["safelaw-standard","safelaw-pro","safelaw-auto","safelaw-luna","safelaw-hybrid","safelaw-sol"],"default":"safelaw-standard","description":"safelaw-auto — профиль выбирается по сложности вопроса; safelaw-luna/hybrid/sol — профиль задан явно (luna — быстрый и дешёвый, sol — самый сильный). Новые модели оплачиваются по фактической стоимости запроса."},"jurisdiction":{"type":"string","enum":["UZ"],"default":"UZ"},"attachments":{"type":"array","maxItems":3,"description":"Вложения для анализа: документы (pdf, docx, doc, txt) и до 1 изображения (jpg, png, webp). Каждое — { filename, content(base64) }. Документы извлекаются в текст, фото анализируется vision.","items":{"$ref":"#/components/schemas/Attachment"}}}},"ChatResponse":{"type":"object","properties":{"id":{"type":"string","example":"req_c6d549149002a83b8d5118e5"},"object":{"type":"string","example":"chat.completion"},"created":{"type":"integer","example":1786555918},"model":{"type":"string","example":"safelaw-auto","description":"Запрошенная модель."},"profile":{"type":"string","enum":["luna","hybrid","sol"],"description":"Только для safelaw-auto/luna/hybrid/sol: профиль, которым фактически сформирован ответ (по нему и списание)."},"answer":{"type":"string","description":"Текст ответа (без внутренних маркеров). Может быть пустым, если модель просит уточнить — тогда смотрите follow_up_questions."},"citations":{"type":"array","items":{"$ref":"#/components/schemas/Citation"}},"document":{"allOf":[{"$ref":"#/components/schemas/GeneratedDocument"}],"nullable":true,"description":"Сгенерированный документ (иск, договор, заявление и т.п.), если модель его составила. null, когда документа нет."},"follow_up_questions":{"type":"array","items":{"type":"string"},"description":"Уточняющие вопросы, если модель просит детали. Обычно пустой массив."},"usage":{"$ref":"#/components/schemas/Usage_tokens"}}},"Citation":{"type":"object","properties":{"act":{"type":"string","example":"Трудовой кодекс Республики Узбекистан"},"article":{"type":"string","example":"560"},"text":{"type":"string","nullable":true},"url":{"type":"string","nullable":true,"example":"https://lex.uz/acts/6257291"},"verified":{"type":"boolean","description":"true — норма сверена с текстом акта в базе"}}},"Attachment":{"type":"object","required":["filename","content"],"properties":{"filename":{"type":"string","example":"contract.pdf","description":"Имя файла с расширением — по нему определяется тип (pdf/docx/doc/txt или изображение)."},"content":{"type":"string","description":"Содержимое файла, закодированное в base64."}}},"GeneratedDocument":{"type":"object","properties":{"title":{"type":"string","example":"ИСКОВОЕ ЗАЯВЛЕНИЕ","description":"Угаданное название документа — удобно для имени файла."},"content":{"type":"string","description":"Текст готового документа — сохраните его в .txt/.docx на своей стороне."}}},"Usage_tokens":{"type":"object","properties":{"input_tokens":{"type":"integer","description":"Входные токены запроса (все внутренние вызовы суммарно)."},"output_tokens":{"type":"integer","description":"Выходные токены ответа."},"total_tokens":{"type":"integer","description":"Сумма вход+выход. По ним и считается стоимость."},"cost_uzs":{"type":"integer","description":"Стоимость этого запроса в сумах: для safelaw-auto/luna/hybrid/sol — фактическая стоимость запроса, для старых моделей — по цене за токены со страницы safelaw.ai/developers. Ровно на эту сумму уменьшился баланс кошелька (личного или организации)."}}},"Usage":{"type":"object","properties":{"object":{"type":"string","example":"usage"},"key":{"type":"object","properties":{"prefix":{"type":"string"},"name":{"type":"string"},"mode":{"type":"string"}}},"wallet":{"type":"object","properties":{"balance_uzs":{"type":"integer"}}},"quota":{"type":"object","properties":{"remaining_tokens":{"type":"integer"},"used_this_period":{"type":"integer"},"monthly_cap":{"type":"integer","nullable":true},"resets_at":{"type":"string","format":"date-time"}}},"rate_limit":{"type":"object","properties":{"requests_per_minute":{"type":"integer"},"remaining":{"type":"integer"}}}}},"Error":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string","enum":["invalid_api_key","revoked_api_key","permission_denied","insufficient_quota","rate_limit_exceeded","invalid_request","context_too_large","unsupported_jurisdiction","service_unavailable","timeout","internal_error"],"description":"Категория ошибки — ветвите логику по ней"},"code":{"type":"string","description":"Точная причина, напр. no_funds, missing_question, monthly_cap_reached"},"message":{"type":"string","description":"Сообщение на русском"},"message_en":{"type":"string","description":"Сообщение на английском"},"param":{"type":"string","description":"Поле запроса при ошибке ввода"},"request_id":{"type":"string"},"doc_url":{"type":"string"},"details":{"type":"object","additionalProperties":true}},"required":["type","code","message","request_id"]}}}}}}