> ## 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.

# IP 风险 API：地理位置、VPN 与数据中心信号

> 使用 Didit 对 IP 地址进行风险评分，涵盖地理位置、ISP、VPN/Tor、数据中心、威胁及声称国家/地区不一致等信号。

使用 `POST /v3/ip/risk/`，当您的后端已经拿到 IP 地址并需要进行服务器到服务器的风险判定时使用。

响应包括地理位置、网络归属、VPN/Tor 与数据中心标记、威胁数据，以及在您提交声明国家时返回的 `country_mismatch`。

## 解读响应

* 当解析出的国家与 `claimed_country` 冲突，或该地址与 VPN、Tor 或数据中心基础设施相关联时，`status` 为 `In Review`。否则为 `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 会话 ID。如果您需要将结果与后续 Webhook 或控制台活动关联，请将其与 `vendor_data` 一起存储。

> [!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 zh/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: >-
        返回所提供 IP 地址的地理位置、网络所有权、VPN/Tor 和数据中心标记、威胁数据以及 `country_mismatch`。该
        endpoint 会创建一个 API 会话，并将其 ID 作为 `request_id` 返回。


        **决策。** 当解析出的国家/地区与 `claimed_country` 冲突，或者地址与 VPN、Tor
        或数据中心基础设施关联时，`status` 为 `In Review`。否则为 `Approved`。


        **尽力而为。** IP 数据增强是尽力而为的。如果没有数据增强来源返回可用数据，该 endpoint 会返回一个已通过的响应，其中
        `ip.ip_address: null`、`ip.country_mismatch: null`，以及一个空的 `ip.threat` 对象。


        **计费。** 生产环境调用按 IP Risk API 定价计费。一旦查询开始，该请求即计费。


        **沙盒。** 沙盒密钥会验证请求并返回确定性的已通过数据，不会消耗额度、创建会话或向 Networks 提供数据。


        **认证。** 在 `x-api-key` 中发送您的应用的 API 密钥。缺失或无效的凭据将返回 `403`，该 API 从不返回
        `401`。


        **速率限制。** 每个 API 密钥在所有 POST/PATCH/DELETE endpoint 之间共享每分钟 300
        次请求的写入配额（交易创建和事件摄入拥有单独的 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 会话 ID。如果您需要将结果与后续的 Webhook 或控制台活动关联，请将其与 `vendor_data`
            一同存储。
        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: >-
                当解析出的国家/地区与 `claimed_country` 冲突，或当地址与 VPN、Tor 或数据中心基础设施相关联时为
                `In Review`。否则为 `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: 当该地址与 VPN 或 Tor 基础设施关联时为 `true`。
            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: >-
                当解析出的国家/地区与 `claimed_country` 不一致时为
                `true`。当无可用补充数据或未提供声明的国家/地区时为 `null`。
            threat:
              type: object
              additionalProperties: true
              description: >-
                来自数据增强源的自由格式网络威胁证据（例如
                `is_proxy`、`is_tor`）。当没有可用的增强数据时为空对象。请将其视为诊断细节，而非稳定的接口约定。
  responses:
    IPRiskValidationError:
      description: 请求验证失败。
      content:
        application/json:
          examples:
            Missing IP address:
              summary: 缺少地址
              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: 已超出每个 API 密钥每分钟 300 次请求的共享写入限制。在重试之前请遵循 `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 密钥，可在 Business Console 的“开发者 -> API
        密钥”中获取。主密钥拥有完整访问权限。指定名称的密钥可设置作用域：针对每个资源设为无权限、只读或读写，限定于特定工作流或已通过的会话、限定于
        IP 地址列表，以及设置到期日期。401 表示密钥错误、已撤销或已过期；403 表示未发送密钥、密钥无权访问该资源或操作，或请求来自其 IP
        列表之外的地址；在会话路由上返回 404 表示该会话不在该密钥允许的工作流或状态范围内。没有媒体访问权限的密钥获取到的图片、视频和 PDF
        URL 将为 null；没有会话写入权限的密钥获取到的会话链接和 token 将为 null。请参阅
        https://docs.didit.me/console/api-keys。

````

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