SafeLaw API
Юридические ответы по законодательству Узбекистана в вашем приложении. В каждом ответе — не только текст, но и ссылки на нормы: статья, её текст и ссылка на lex.uz, сверенные с базой актов.
Быстрый старт
- Получите ключ в кабинете: Настройки → API.
- Пополните кошелёк — с него списываются запросы (все ключи тратят общий баланс).
- Отправьте запрос на
https://api.safelaw.ai/v1/chatс ключом в заголовке.
curl https://api.safelaw.ai/v1/chat \
-H "Authorization: Bearer sf_live_ВАШ_КЛЮЧ" \
-H "Content-Type: application/json" \
-d '{
"question": "Какой срок исковой давности по трудовым спорам?",
"model": "safelaw-standard"
}'Единственный адрес API — https://api.safelaw.ai/v1/…. Пути вида safelaw.ai/api/… — это внутренние роуты сайта под сессионную авторизацию, они вернут 401 на ключ sf_live_…. Машиночитаемая спецификация (OpenAPI 3.0): api.safelaw.ai/v1/openapi.json.
Ключи и аутентификация
Ключ передаётся в заголовке Authorization: Bearer sf_live_…. Создаётся в кабинете и показывается один раз — храните его надёжно.
sf_live_…— боевой: тратит средства с кошелька, 60 запросов в минуту.sf_test_…— отладочный: ничего не тратит, упрощённая модель, 10 запросов в минуту. Удобно собрать интеграцию бесплатно.
POST /v1/chat
Параметры тела (JSON):
| Поле | Обяз. | Описание |
|---|---|---|
| question | да | Вопрос, до 8000 символов |
| model | нет | safelaw-standard (по умолч.) или safelaw-pro (сложнее/дороже) |
| jurisdiction | нет | Пока только UZ |
| attachments | нет | Файлы для анализа: массив { filename, content }, где content — файл в base64. До 3 файлов: документы (pdf, docx, doc, txt) и до 1 изображения (jpg, png, webp). Документы извлекаются в текст, фото читает модель. |
Ответ (200):
{
"id": "req_c6d549149002a83b8d5118e5",
"object": "chat.completion",
"created": 1786555918,
"model": "safelaw-standard",
"answer": "В Узбекистане сроки обращения в суд по трудовым спорам установлены ст. 560 ТК РУз...",
"citations": [
{
"act": "Трудовой кодекс Республики Узбекистан",
"article": "560",
"text": "Для обращения в суд за рассмотрением индивидуального трудового спора...",
"url": "https://lex.uz/acts/6257291",
"verified": true
}
],
"usage": { "input_tokens": 36819, "output_tokens": 446, "total_tokens": 37265 }
}answer— текст ответа.citations[]— нормы:act,article,text,url(lex.uz),verified. verified: true — норма сверена с текстом акта в базе; false — показывайте с осторожностью.document— сгенерированный документ (иск, договор, заявление), если модель его составила:{ title, content }.null, когда документа нет — сохранитеcontentв файл на своей стороне.usage— токены запроса (input_tokens,output_tokens,total_tokens) иcost_uzs— точная стоимость запроса в сумах (ровно на неё уменьшился баланс).- Названия моделей наши (
safelaw-standard/pro), а не имя поставщика — контракт не сломается при смене движка.
Файлы: анализ документов и генерация
Приложите документы или фото в attachments — их разберут вместе с вопросом (документ извлекается в текст, фото читает модель). А если попросить составить документ (иск, договор, заявление) — готовый текст вернётся в поле document.
# Анализ документа (или фото): приложите файл в attachments (base64)
curl https://api.safelaw.ai/v1/chat \
-H "Authorization: Bearer sf_live_..." \
-H "Content-Type: application/json" \
-d '{
"question": "Проанализируй этот договор: какие риски?",
"attachments": [
{ "filename": "contract.pdf", "content": "<файл в base64>" }
]
}'
# Если попросить составить документ — готовый текст придёт в поле document:
# { "answer": "...", "document": { "title": "ИСКОВОЕ ЗАЯВЛЕНИЕ", "content": "..." } }GET /v1/usage
Остаток кошелька и лимиты. Тот же заголовок авторизации.
curl https://api.safelaw.ai/v1/usage -H "Authorization: Bearer sf_live_..."Оплата
Каждый запрос списывает деньги прямо с кошелька аккаунта — отдельно покупать токены на ключ не нужно, все ключи тратят общий баланс. Тариф по токенам: вход — $4 за 1M, выход — $20 за 1M (считаются токены запроса и ответа). Точная стоимость каждого запроса приходит в usage.cost_uzs (в сумах), остаток — в заголовке X-Wallet-Balance-Uzs. Когда средства заканчиваются — ответ 402 с details.reason = "no_funds". Пополнение — в кабинете.
Лимиты и заголовки
60 запросов в минуту на боевой ключ (10 на отладочный). В каждом ответе есть заголовки, чтобы заранее видеть приближение к пределу:
| Заголовок | Значение |
|---|---|
| X-Request-Id | Идентификатор запроса — присылайте в поддержку |
| X-Wallet-Balance-Uzs | Остаток на кошельке в сумах |
| X-Quota-Remaining-Tokens | Остаток в пересчёте на токены |
| X-RateLimit-Limit-Requests | Лимит запросов в минуту |
| X-RateLimit-Remaining-Requests | Сколько осталось в текущем окне |
| Retry-After | Через сколько секунд повторить (при 429) |
Повторы без двойного списания
При обрыве связи неизвестно, выполнился ли запрос. Передайте заголовок Idempotency-Key — повтор с тем же значением вернёт сохранённый ответ и не спишет деньги второй раз.
Ошибки
Формат один и тот же всегда: type — категория (ветвите логику по ней), code — точная причина, message/message_en — что делать, param — поле при ошибке ввода, request_id — для поддержки.
{
"error": {
"type": "insufficient_quota",
"code": "no_funds",
"message": "На кошельке нет средств. Пополните кошелёк.",
"message_en": "Wallet balance is empty. Top up the wallet in the dashboard.",
"request_id": "req_1eb7a09fc0db4787",
"doc_url": "https://safelaw.ai/developers"
}
}| HTTP | type | Что делать |
|---|---|---|
| 401 | invalid_api_key | Ключ не передан или неверного формата — проверьте заголовок |
| 401 | revoked_api_key | Ключ отозван — создайте новый в кабинете |
| 402 | insufficient_quota | Нет средств (code=no_funds) или месячный предел (monthly_cap_reached) |
| 429 | rate_limit_exceeded | Слишком часто — повторите через секунды из заголовка Retry-After |
| 400 | invalid_request | Ошибка в теле — поле в error.param |
| 400 | context_too_large | Вопрос длиннее 8000 символов — сократите |
| 422 | unsupported_jurisdiction | Поддерживается только UZ |
| 503 | service_unavailable | Сервис временно недоступен — повтор с задержкой |
| 504 | timeout | Не уложились по времени — повторите |
Ошибки поставщика модели наружу не протекают — вы получаете либо ответ, либо честную ошибку с понятным действием.
Примеры кода
Python
import requests
r = requests.post(
"https://api.safelaw.ai/v1/chat",
headers={"Authorization": "Bearer sf_live_..."},
json={"question": "Какой срок исковой давности по трудовым спорам?"},
timeout=120,
)
if r.status_code == 402:
d = r.json()["error"]["details"]
raise SystemExit("Нет средств" if d["reason"] == "no_funds" else "Месячный предел")
r.raise_for_status()
data = r.json()
print(data["answer"])
for c in data["citations"]:
print(f'{c["act"]} ст. {c["article"]} -> {c["url"]} (сверено: {c["verified"]})')
print("Токенов:", data["usage"]["total_tokens"])Node.js
const res = await fetch("https://api.safelaw.ai/v1/chat", {
method: "POST",
headers: {
"Authorization": "Bearer sf_live_...",
"Content-Type": "application/json",
},
body: JSON.stringify({ question: "Какой срок исковой давности по трудовым спорам?" }),
});
if (!res.ok) {
const { error } = await res.json();
throw new Error(`${error.type}/${error.code}: ${error.message}`);
}
const data = await res.json();
console.log(data.answer);
data.citations.forEach((c) => console.log(c.act, "ст.", c.article, c.url));Ключи создаются в кабинете, в разделе «API».
Получить ключТехнические вопросы по API: api@safelaw.ai. Подключение API для компании, договор и счёт: sales@safelaw.ai.