> ## Documentation Index
> Fetch the complete documentation index at: https://docs.didit.me/llms.txt
> Use this file to discover all available pages before exploring further.

# API проверки IP-рисков: геолокация, VPN и дата-центры

> Оцените риск IP-адреса с помощью Didit: геолокация, провайдер, VPN/Tor, дата-центр, угрозы и несовпадение заявленной страны.

Используйте `POST /v3/ip/risk/`, когда ваш бэкенд уже располагает IP-адресом и ему нужно получить решение о риске для взаимодействия между серверами.

Ответ включает геолокацию, данные о владельце сети, флаги VPN/Tor и центров обработки данных, данные об угрозах, а также `country_mismatch`, если вы передаёте заявленную страну.

## Интерпретация ответа

* `status` принимает значение `In Review`, если страна, определённая по адресу, не совпадает с `claimed_country`, или если адрес связан с инфраструктурой VPN, Tor или центра обработки данных. В остальных случаях значение `Approved`.
* `ip.ip_country_code` содержит код страны, определённый по адресу. Для сравнения стран используйте `ip.country_mismatch`, а не сравнивайте строки с названиями стран самостоятельно.
* `ip.latitude` и `ip.longitude` содержат приблизительную геолокацию сети, а не точное местоположение устройства.
* `ip.is_vpn_or_tor`, `ip.is_data_center`, `ip.proxy_type` и `ip.threat` содержат признаки сетевого риска.
* `ip.asn_number`, `ip.asn_organization`, `ip.connection_type` и `ip.carrier` описывают сеть, к которой принадлежит адрес.
* `request_id` является идентификатором API-сессии. Сохраняйте его вместе с `vendor_data`, если нужно связать результат с последующими webhook-событиями или активностью в консоли.

> [!NOTE]
>
> Обогащение данных по IP выполняется по возможности. Если ни один источник обогащения не возвращает пригодных данных, endpoint возвращает одобренный ответ с `ip.ip_address: null`, `ip.country_mismatch: null` и пустым объектом `ip.threat`. Отдельные поля обогащения также могут быть `null`, если данные недоступны.

## Анализ устройства

IP Risk API является исключительно серверным endpoint для взаимодействия между серверами. Фингерпринтинг устройства он не выполняет, поскольку бэкенд сам по себе не может наблюдать сигналы браузера или устройства. Для сессий в размещённом сценарии и в SDK Didit предоставляет уже собранные данные об устройстве в ответе сессии, включая `device_fingerprint`, сведения об устройстве и браузере, `user_agent`, необработанные данные об устройстве и совпадения между сессиями.

## Поведение в песочнице

Ключи песочницы проверяют запрос и возвращают детерминированные одобренные данные. Они не обращаются к внешним сервисам анализа данных, не списывают кредиты, не создают сессию и не вносят вклад в Networks.

## Биллинг

Вызов IP Risk API стоит \$0.02 по прайс-листу. Запрос в боевом режиме тарифицируется с момента начала поиска.


## OpenAPI

````yaml ru/openapi-25.json POST /v3/ip/risk/
openapi: 3.0.0
info:
  version: 3.0.0
  title: Didit Verification API
  description: >-
    API верификации личности. Аутентификация выполняется с помощью заголовка
    x-api-key.
servers:
  - url: https://verification.didit.me
security: []
tags: []
paths:
  /v3/ip/risk/:
    post:
      tags:
        - Standalone APIs
      summary: Рассчитать оценку риска для IP-адреса
      description: >-
        Возвращает данные геолокации, сведения о владельце сети, флаги
        использования VPN/Tor и дата-центров, данные об угрозах, а также
        `country_mismatch` для указанного IP-адреса. Endpoint создаёт API-сессию
        и возвращает её идентификатор как `request_id`.


        **Решение.** Поле `status` принимает значение `In Review`, если
        определённая страна не совпадает с `claimed_country` или если адрес
        связан с инфраструктурой VPN, Tor или дата-центров. В остальных случаях
        возвращается `Approved`.


        **По возможности.** Обогащение данных по IP выполняется по возможности.
        Если ни один источник обогащения не вернул пригодных данных, endpoint
        возвращает одобренный ответ с `ip.ip_address: null`,
        `ip.country_mismatch: null` и пустым объектом `ip.threat`.


        **Биллинг.** Запросы в продакшн-среде тарифицируются по ценам IP Risk
        API. Запрос подлежит оплате с момента начала поиска.


        **Песочница.** Ключи песочницы валидируют запрос и возвращают
        детерминированные одобренные данные без списания кредитов, создания
        сессии или передачи данных в Networks.


        **Аутентификация.** Передавайте API-ключ вашего приложения в заголовке
        `x-api-key`. При отсутствии или недействительности учётных данных
        возвращается `403` - этот API никогда не возвращает `401`.


        **Лимит запросов.** Общий лимит на запись составляет 300 запросов в
        минуту на API-ключ для всех endpoint POST/PATCH/DELETE (для создания
        транзакций и приёма событий действует отдельный лимит в 600).
      operationId: post_v3ip_risk
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/IPRiskRequest'
            examples:
              Minimal:
                summary: Оценить адрес со значениями по умолчанию
                value:
                  ip_address: 8.8.8.8
              With claimed country:
                summary: Оценить с заявленной страной для обнаружения несоответствий
                value:
                  ip_address: 8.8.8.8
                  claimed_country: ESP
                  user_agent: >-
                    Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)
                    AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.4
                    Safari/605.1.15
                  vendor_data: lead-123
      responses:
        '200':
          description: >-
            Оценка риска завершена. Проверьте `status` для получения решения;
            для завершённых запросов HTTP-код всегда `200`.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/IPRiskResponse'
              examples:
                Clean residential IP:
                  summary: Адрес проживания, заявленная страна совпадает
                  value:
                    request_id: 9a96ed2a-721e-4b86-8cbf-d61eda529279
                    status: Approved
                    ip:
                      status: Approved
                      ip_address: 192.0.2.10
                      ip_country: Spain
                      ip_country_code: ES
                      ip_state: Madrid
                      ip_city: Madrid
                      latitude: 40.4168
                      longitude: -3.7038
                      isp: Example Telecom
                      organization: Example Telecom SA
                      is_vpn_or_tor: false
                      is_data_center: false
                      time_zone: Europe/Madrid
                      time_zone_offset: '+0200'
                      asn_number: 3352
                      asn_organization: EXAMPLE-TELECOM
                      connection_type: broadband
                      carrier: Example Telecom
                      proxy_type: null
                      claimed_country: ESP
                      country_mismatch: false
                      threat: {}
                    vendor_data: lead-123
                    metadata: null
                    created_at: '2026-09-01T10:30:00.123456+00:00'
                Datacenter mismatch:
                  summary: Адрес дата-центра конфликтует с заявленной страной
                  value:
                    request_id: 5b1d4e9a-3c7b-4f8e-9a2d-1b0c9d8e7f6a
                    status: In Review
                    ip:
                      status: In Review
                      ip_address: 8.8.8.8
                      ip_country: United States
                      ip_country_code: US
                      ip_state: California
                      ip_city: Mountain View
                      latitude: 37.386
                      longitude: -122.0838
                      isp: Google
                      organization: Google LLC
                      is_vpn_or_tor: true
                      is_data_center: true
                      time_zone: America/Los_Angeles
                      time_zone_offset: '-0700'
                      asn_number: 15169
                      asn_organization: GOOGLE, US
                      connection_type: hosting
                      carrier: null
                      proxy_type: VPN
                      claimed_country: ESP
                      country_mismatch: true
                      threat:
                        is_proxy: true
                        is_data_center: true
                        is_tor: false
                    vendor_data: lead-126
                    metadata: null
                    created_at: '2026-09-01T10:30:00.123456+00:00'
        '400':
          $ref: '#/components/responses/IPRiskValidationError'
        '403':
          $ref: '#/components/responses/RiskPermissionDenied'
        '429':
          $ref: '#/components/responses/RateLimitedWrite'
      security:
        - ApiKeyAuth: []
      x-codeSamples:
        - lang: curl
          label: curl
          source: |-
            curl -X POST https://verification.didit.me/v3/ip/risk/ \
              -H 'x-api-key: YOUR_API_KEY' \
              -H 'Content-Type: application/json' \
              -d '{
                "ip_address": "8.8.8.8",
                "claimed_country": "ESP",
                "user_agent": "Mozilla/5.0",
                "vendor_data": "lead-123"
              }'
        - lang: python
          label: Python
          source: |-
            from didit import Didit

            # Reads DIDIT_API_KEY.
            client = Didit()

            result = client.ip.assess_risk(
                ip_address="8.8.8.8",
            )
            print(result)
        - lang: javascript
          label: Node.js
          source: |-
            import Didit from "@didit-protocol/sdk-node";

            // Reads DIDIT_API_KEY.
            const didit = new Didit();

            const result = await didit.ip.assessRisk({
              ip_address: "8.8.8.8",
            });
            console.log(result);
        - lang: go
          label: Go
          source: "ctx := context.Background()\n// Reads DIDIT_API_KEY.\nclient := didit.NewClient()\n\nresult, err := client.IP.AssessRisk(ctx, didit.IPRiskRequest{\n\tIPAddress: \"8.8.8.8\",\n})\nif err != nil {\n\tlog.Fatal(err)\n}\nfmt.Printf(\"%+v\\n\", result)"
        - lang: java
          label: Java
          source: |-
            import me.didit.Didit;
            import me.didit.types.IPRiskRequest;

            // Reads DIDIT_API_KEY.
            Didit client = new Didit();

            var result = client.ip().assessRisk(IPRiskRequest.builder()
                    .ipAddress("8.8.8.8")
                    .build());
            System.out.println(result);
        - lang: php
          label: PHP
          source: |-
            <?php

            require 'vendor/autoload.php';

            use Didit\DiditClient;

            // Reads DIDIT_API_KEY.
            $didit = new DiditClient();

            $result = $didit->ip->assessRisk([
                'ip_address' => '8.8.8.8',
            ]);
            print_r($result->toArray());
        - lang: ruby
          label: Ruby
          source: |-
            require "didit"

            # Reads DIDIT_API_KEY.
            didit = Didit::Client.new

            result = didit.ip.assess_risk(ip_address: "8.8.8.8")
            puts result.to_h
        - lang: csharp
          label: .NET
          source: |-
            using System;
            using System.Text.Json;
            using Didit;

            // Reads DIDIT_API_KEY.
            using var client = new DiditClient();

            var result = await client.Ip.AssessRiskAsync(new IPRiskRequest
            {
                IpAddress = "8.8.8.8",
            });
            Console.WriteLine(JsonSerializer.Serialize(result));
components:
  schemas:
    IPRiskRequest:
      type: object
      required:
        - ip_address
      properties:
        ip_address:
          type: string
          format: ip
          description: Адрес IPv4 или IPv6 для оценки.
          example: 8.8.8.8
        claimed_country:
          type: string
          maxLength: 3
          description: >-
            Необязательный код страны ISO 3166-1 alpha-2 или alpha-3, заявленный
            пользователем или сессией. Используется для вычисления
            `country_mismatch`.
          example: ESP
        user_agent:
          type: string
          maxLength: 512
          description: >-
            User-Agent, зафиксированный вашим бэкендом. Сохраняется как контекст
            запроса; не обеспечивает фингерпринтинг устройства.
        vendor_data:
          type: string
          description: >-
            Ваш постоянный идентификатор для этого запроса. Сохраняется в
            API-сессии и возвращается в ответе.
        metadata:
          type: object
          nullable: true
          additionalProperties: true
          description: >-
            Ваши неконфиденциальные метаданные JSON. Сохраняются в сессии API и
            возвращаются в ответе.
    IPRiskResponse:
      type: object
      required:
        - request_id
        - status
        - created_at
      properties:
        request_id:
          type: string
          format: uuid
          description: >-
            Идентификатор API-сессии, созданной для этого запроса. Сохраняйте
            его вместе с `vendor_data`, если нужно сопоставлять результат с
            последующими событиями webhook или действиями в консоли.
        status:
          type: string
          enum:
            - Approved
            - In Review
          description: >-
            Решение для этой API-сессии: `In Review` при риске сети или
            несовпадении стран, иначе `Approved`.
        vendor_data:
          type: string
          nullable: true
          description: >-
            Эхо-значение переданного вами `vendor_data`, либо `null`, если вы
            его не передавали.
        metadata:
          type: object
          nullable: true
          additionalProperties: true
          description: >-
            Эхо-значение переданного вами `metadata`, либо `null`, если вы его
            не передавали.
        created_at:
          type: string
          format: date-time
          description: Временная метка этого ответа.
        ip:
          type: object
          description: >-
            Результат оценки риска IP-адреса. Отдельные поля обогащения данных
            могут иметь значение `null`, если при поиске не было получено
            пригодных данных.
          required:
            - status
            - threat
          properties:
            status:
              type: string
              enum:
                - Approved
                - In Review
              description: >-
                `In Review`, если определённая страна конфликтует с
                `claimed_country`, или если адрес связан с VPN, Tor или
                инфраструктурой центров обработки данных. В противном случае
                `Approved`.
            ip_address:
              type: string
              nullable: true
              description: >-
                Оценённый адрес. `null`, если ни один источник обогащения данных
                не вернул пригодных данных.
            ip_country:
              type: string
              nullable: true
              description: Определенное название страны.
            ip_country_code:
              type: string
              nullable: true
              description: >-
                Определенный код страны. Сравнивайте страны с помощью
                `country_mismatch` вместо самостоятельного сравнения исходных
                строк стран.
            ip_state:
              type: string
              nullable: true
              description: Определенный штат или регион.
            ip_city:
              type: string
              nullable: true
              description: Определенный город.
            latitude:
              type: number
              nullable: true
              description: >-
                Приблизительная геолокация по сети, а не точное местоположение
                устройства.
            longitude:
              type: number
              nullable: true
              description: >-
                Приблизительная геолокация по сети, а не точное местоположение
                устройства.
            isp:
              type: string
              nullable: true
              description: Интернет-провайдер, предоставляющий услуги по этому адресу.
            organization:
              type: string
              nullable: true
              description: Организация, владеющая блоком адресов.
            is_vpn_or_tor:
              type: boolean
              nullable: true
              description: '`true`, когда адрес связан с инфраструктурой VPN или Tor.'
            is_data_center:
              type: boolean
              nullable: true
              description: '`true`, когда адрес принадлежит сети хостинга или дата-центра.'
            time_zone:
              type: string
              nullable: true
              description: Часовой пояс определённого местоположения.
            time_zone_offset:
              type: string
              nullable: true
              description: Смещение по UTC для определённого местоположения.
            asn_number:
              type: number
              nullable: true
              description: Номер автономной системы (ASN).
            asn_organization:
              type: string
              nullable: true
              description: Организация, управляющая автономной системой.
            connection_type:
              type: string
              nullable: true
              description: Классификация соединения (например, `cellular`, `hosting`).
            carrier:
              type: string
              nullable: true
              description: Оператор мобильной связи, если адрес находится в мобильной сети.
            proxy_type:
              type: string
              nullable: true
              description: Классификация прокси, если адрес находится за прокси.
            claimed_country:
              type: string
              nullable: true
              description: Эхо-значение переданного вами `claimed_country`.
            country_mismatch:
              type: boolean
              nullable: true
              description: >-
                `true`, если определённая страна отличается от
                `claimed_country`. `null`, если нет данных обогащения или
                заявленная страна недоступна.
            threat:
              type: object
              additionalProperties: true
              description: >-
                Данные о сетевых угрозах в свободной форме от источника
                обогащения (например, `is_proxy`, `is_tor`). Пустой объект, если
                данные обогащения отсутствуют. Рассматривайте как
                диагностические подробности, а не как стабильный контракт.
  responses:
    IPRiskValidationError:
      description: Ошибка валидации запроса.
      content:
        application/json:
          examples:
            Missing IP address:
              summary: Отсутствует IP-адрес
              value:
                ip_address:
                  - This field is required.
            Invalid IP address:
              summary: Недопустимый IP-адрес
              value:
                ip_address:
                  - Enter a valid IPv4 or IPv6 address.
            Country hint too long:
              summary: Подсказка страны слишком длинная
              value:
                claimed_country:
                  - Ensure this field has no more than 3 characters.
    RiskPermissionDenied:
      description: >-
        API-ключ отсутствует или недействителен, либо организация не может
        покрыть проверку в реальном времени. Этот API никогда не возвращает
        `401`.
      content:
        application/json:
          examples:
            Missing or invalid API key:
              summary: >-
                Отсутствует заголовок `x-api-key`, либо ключ недействителен или
                отозван
              value:
                detail: You do not have permission to perform this action.
            Not enough credits:
              summary: Баланс организации недостаточен для оплаты цены поиска
              value:
                error: You don't have enough credits to perform this request.
    RateLimitedWrite:
      description: >-
        Превышен общий лимит на запись в 300 запросов в минуту на один API-ключ.
        Подождите время, указанное в `Retry-After`, перед повторной попыткой.
      content:
        application/json:
          schema:
            type: object
            required:
              - detail
            properties:
              detail:
                type: string
          example:
            detail: >-
              Write request rate limit exceeded. You can make up to 300 requests
              per minute.
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      in: header
      name: x-api-key
      description: >-
        API-ключ вашего приложения из раздела «Разработчикам» -> «API-ключи» в
        Business Console. Основной ключ имеет полный доступ. Именованный ключ
        может иметь ограниченную область действия: без доступа, чтение или
        запись для каждого ресурса, ограничение определенными сценариями или
        одобренными сессиями, списком IP-адресов и сроком действия. 401
        означает, что ключ неверен, отозван или его срок действия истек; 403
        означает, что ключ не был передан, у ключа нет доступа к этому ресурсу
        или действию, либо запрос поступил с адреса вне его списка IP-адресов;
        404 на маршруте сессии означает, что сессия не входит в сценарии или
        статусы ключа. Ключ без доступа к медиа получает URL изображений, видео
        и PDF как null, а ключ без прав на запись сессий получает ссылки на
        сессии и токены как null. См. https://docs.didit.me/console/api-keys.

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.