Паспорт ИИ-агента Проверить паспорт

Разработчикам

Как встроить проверку паспорта в своего агента: открытый API проверки и реестра, JSON-схема, тестовые паспорта и готовые фрагменты кода.

ключ не нуженCORS открытOpenAPI
Голографическая карточка на клавиатуре ноутбука, на экране размытый код

API

ЗапросЧто делает
GET /api/v1/check?url=example.ruЗагрузить паспорт с сайта и проверить. Можно передать адрес паспорта с #фрагментом
POST /api/v1/checkТело — {"url": "…"}, {"passport": {…}} или сам паспорт. Без адреса проверяются схема и подпись, уровень не присваивается
GET /api/v1/passportsРеестр: ?q= поиск по номеру, владельцу, ИНН, агенту; ?status=; ?limit= до 200; ?offset=
GET /api/v1/passports/AP-2026-000001Одна запись реестра с историей статусов и итогом последней проверки
GET /.well-known/agent-passport.schema.jsonJSON-схема формата 0.1

Ответ проверки

  • ok — true, если паспорт соответствует формату;
  • verdict — valid, invalid, inactive или fetch_error;
  • level — K2 или K3, только при проверке по адресу;
  • passports[] — краткие сведения о каждом паспорте в файле;
  • checks[] — все проверки: status ok, err, warn или info, путь к полю и текст по-русски;
  • registry — номер и статус, если паспорт есть в реестре.
{
  "ok": true,
  "verdict": "valid",
  "verdict_text": "Паспорт соответствует формату 0.1",
  "level": "K2",
  "format": "0.1",
  "checked_at": "2026-10-20T09:00:00Z",
  "source": {
    "url": "https://example.ru/.well-known/agent-passport.json",
    "http_status": 200
  },
  "passports": [
    {
      "passport_id": "https://example.ru/.well-known/agent-passport.json#zakupki",
      "status": "active",
      "agent_name": "Агент закупок",
      "operator": "ООО «Пример»",
      "signed": false,
      "level": "K2"
    }
  ],
  "counts": {
    "ok": 8,
    "err": 0,
    "warn": 0,
    "info": 2
  },
  "checks": [
    {
      "status": "ok",
      "code": "domain",
      "path": "operator.site",
      "text": "Паспорт лежит на домене оператора: example.ru"
    }
  ]
}

Проверка в своём агенте

Перед сделкой с чужим агентом возьмите адрес его паспорта из заголовка Agent-Passport и проверьте. Свой агент предъявляет паспорт так же:

Agent-Passport: https://example.ru/.well-known/agent-passport.json#zakupki

Если не хотите зависеть от нашего сервиса, проверяйте сами: схема открыта, подпись — стандартный Ed25519 над канонической формой JSON (RFC 8785). Пример на Python справа делает всё без нашего API; на PHP — через API.

Тестовые паспорта для своих тестов — на странице примеров.

Python: проверка у себя, включая подпись
# pip install requests jsonschema cryptography
import base64, json, requests, jsonschema
from urllib.parse import urlparse
from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PublicKey

SCHEMA = "https://паспорт-агента.рф/.well-known/agent-passport.schema.json"
b64d = lambda s: base64.urlsafe_b64decode(s + "=" * (-len(s) % 4))
b64e = lambda b: base64.urlsafe_b64encode(b).rstrip(b"=").decode()

def jcs(v):  # RFC 8785 для строк, целых чисел, true/false
    if isinstance(v, dict):
        ks = sorted(v, key=lambda k: k.encode("utf-16-be"))
        return "{" + ",".join(json.dumps(k, ensure_ascii=False) + ":" + jcs(v[k]) for k in ks) + "}"
    if isinstance(v, list):
        return "[" + ",".join(jcs(x) for x in v) + "]"
    return json.dumps(v, ensure_ascii=False)

def check(site):
    url = f"https://{site}/.well-known/agent-passport.json"
    p = requests.get(url, timeout=8).json()
    jsonschema.validate(p, requests.get(SCHEMA).json())
    assert urlparse(p["operator"]["site"]).hostname == site
    assert p["status"] == "active"
    level = "K2"
    for s in p.get("signatures", []):
        kid = json.loads(b64d(s["protected"]))["kid"]
        key = next(k for k in p["keys"] if k["kid"] == kid)
        body = {k: v for k, v in p.items() if k != "signatures"}
        msg = (s["protected"] + "." + b64e(jcs(body).encode())).encode()
        Ed25519PublicKey.from_public_bytes(b64d(key["x"])).verify(b64d(s["signature"]), msg)
        level = "K3"
    return level
PHP: через API
$r = json_decode(file_get_contents(
    'https://xn----7sbbaom0ddhbmjqf.xn--p1ai/api/v1/check?url=' . urlencode('example.ru')
), true);
if ($r['ok']) {
    echo $r['level'], ' ', $r['passports'][0]['operator'];
} else {
    echo 'сделку не заключаем: ', $r['verdict_text'];
}

Вопросы

Сколько проверок можно делать?

До 10 в минуту с одного адреса. При превышении API отвечает 429 и заголовком Retry-After. Для массовых проверок используйте схему у себя и API — только для спорных случаев.

Можно ли вызывать API из браузера?

Да, ответы разрешены для любых сайтов (CORS). Ключ не нужен.

Что значит verdict?

valid — соответствует; invalid — есть ошибки; inactive — оформлен верно, но приостановлен, отозван или просрочен; fetch_error — не удалось загрузить.

0.1

Не государственный документ. Паспорт публикует сам оператор, реестр подтверждает только соответствие формату и подпись на дату проверки.

О проекте