Перейти к содержимому
LegalStack
Введение

Быстрый старт

Создайте OAuth-приложение, получите DPoP-токен и сделайте первый запрос.

Регистрация

Зайдите на app.legalstack.ru/register и создайте команду. Вы станете её владельцем: OAuth-приложения создают только владелец и администраторы команды.

OAuth-приложение

В разделе «Настройки → API» откройте вкладку «OAuth-приложения», нажмите «Новое OAuth-приложение», отметьте grant-тип client_credentials и сохраните client_id и client_secret.

Секрет показывается один раз

Сохраните client_secret сразу: после закрытия окна его можно только перевыпустить.

Ключ DPoP

Каждый токен платформы привязан к ключу клиента: вместе с токеном в каждом запросе передаётся подписанное этим ключом доказательство, см. гайд Аутентификация. Поэтому первым делом создайте пару ключей и функцию, которая подписывает доказательство для конкретного запроса.

import { createHash, randomUUID } from 'node:crypto';
import { exportJWK, generateKeyPair, SignJWT } from 'jose';

const { privateKey, publicKey } = await generateKeyPair('ES256');
const jwk = await exportJWK(publicKey);

const hash = (value) => createHash('sha256').update(value).digest('base64url');

export const proof = (method, url, { nonce, accessToken } = {}) =>
  new SignJWT({
    htm: method,
    htu: url,
    jti: randomUUID(),
    ...(nonce ? { nonce } : {}),
    ...(accessToken ? { ath: hash(accessToken) } : {}),
  })
    .setProtectedHeader({ typ: 'dpop+jwt', alg: 'ES256', jwk })
    .setIssuedAt()
    .sign(privateKey);

Получение токена

Первый запрос к точке выдачи токенов получает 400 с error: use_dpop_nonce и заголовком DPoP-Nonce. Повторите запрос, включив это значение в доказательство, и сохраняйте nonce из каждого следующего ответа.

const TOKEN_URL = 'https://api.legalstack.ru/oauth/token';
let nonce;

async function requestToken() {
  const body = new URLSearchParams({
    grant_type: 'client_credentials',
    client_id: 'YOUR_CLIENT_ID',
    client_secret: 'YOUR_CLIENT_SECRET',
    scope: 'registry:read tasks:read',
    resource: 'https://api.legalstack.ru',
  });
  const response = await fetch(TOKEN_URL, {
    method: 'POST',
    headers: { 'Content-Type': 'application/x-www-form-urlencoded', DPoP: await proof('POST', TOKEN_URL, { nonce }) },
    body,
  });
  nonce = response.headers.get('DPoP-Nonce') ?? nonce;
  const json = await response.json();
  if (response.status === 400 && json.error === 'use_dpop_nonce') return requestToken();
  return json.access_token;
}

const accessToken = await requestToken();
Ответ
{
  "access_token": "eyJhbGciOiJFZERTQSIsImtpZCI6...",
  "token_type": "DPoP",
  "expires_in": 900,
  "scope": "registry:read tasks:read"
}

expires_in — время жизни в секундах. Запрашивайте только те scope, которые нужны интеграции: полный список — в каталоге scope, правила выдачи и обновления — в гайде Аутентификация.

Первый запрос

Токен передаётся со схемой DPoP, а доказательство для запроса включает ath — хеш токена — и nonce из последнего ответа. На 401 с кодом USE_DPOP_NONCE повторите запрос с новым nonce из заголовка.

async function api(method, path) {
  const url = `https://api.legalstack.ru${path}`;
  const response = await fetch(url, {
    method,
    headers: { Authorization: `DPoP ${accessToken}`, DPoP: await proof(method, url, { nonce, accessToken }) },
  });
  nonce = response.headers.get('DPoP-Nonce') ?? nonce;
  if (response.status === 401 && (await response.clone().json()).code === 'USE_DPOP_NONCE') return api(method, path);
  return response.json();
}

const tasks = await api('GET', '/api/v1/tasks');

Ответ — JSON-массив задач вашей команды. Ошибки приходят в формате Problem Details, см. гайд Ошибки.

Требования к клиенту

Только TLS 1.3

api.legalstack.ru и остальные домены платформы принимают только TLS 1.3. Штатные curl и PowerShell в Windows 10 не подключаются: используйте curl с OpenSSL, Windows 11, любой современный HTTP-клиент или язык с поддержкой TLS 1.3.

Одного curl для работы с API недостаточно: каждому запросу нужно подписанное доказательство DPoP, поэтому используйте язык с библиотекой JOSE, как в примерах выше.

Дальше: Аутентификация, справочник API и обработка ошибок.

На этой странице