> ## 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 de risco de IP: geolocalização, VPN e datacenter

> A Didit calcula a pontuação de risco de um endereço IP com geolocalização, ISP, VPN/Tor, datacenter, ameaças e divergência do país declarado.

Use `POST /v3/ip/risk/` quando seu backend já tiver um endereço IP e precisar de uma decisão de risco de servidor para servidor.

A resposta inclui geolocalização, propriedade da rede, indicadores de VPN/Tor e de data center, dados de ameaças e `country_mismatch` quando você envia um país declarado.

## Interpretar a resposta

* `status` é `In Review` quando o país identificado diverge de `claimed_country` ou quando o endereço está associado a infraestrutura de VPN, Tor ou data center. Caso contrário, é `Approved`.
* `ip.ip_country_code` contém o código do país identificado. Compare países por meio de `ip.country_mismatch` em vez de comparar você mesmo as strings brutas de país.
* `ip.latitude` e `ip.longitude` são uma geolocalização aproximada da rede, não uma localização precisa do dispositivo.
* `ip.is_vpn_or_tor`, `ip.is_data_center`, `ip.proxy_type` e `ip.threat` trazem evidências de risco de rede.
* `ip.asn_number`, `ip.asn_organization`, `ip.connection_type` e `ip.carrier` descrevem a rede à qual o endereço pertence.
* `request_id` é o ID da sessão da API. Armazene-o junto com `vendor_data` se precisar correlacionar o resultado com webhooks posteriores ou com a atividade no console.

> [!NOTE]
>
> O enriquecimento de IP é realizado em regime de melhor esforço. Se nenhuma fonte de enriquecimento retornar dados utilizáveis, o endpoint retorna uma resposta aprovada com `ip.ip_address: null`, `ip.country_mismatch: null` e um objeto `ip.threat` vazio. Campos de enriquecimento individuais também podem ser `null` quando não estiverem disponíveis.

## Inteligência de dispositivo

A API de risco de IP é um endpoint exclusivamente de servidor para servidor. A impressão digital do dispositivo não é um endpoint desse tipo, pois um backend não consegue observar sozinho os sinais do navegador ou do dispositivo. Para sessões do fluxo hospedado e do SDK, a Didit expõe na resposta da sessão os campos de dispositivo já coletados, incluindo `device_fingerprint`, detalhes do dispositivo e do navegador, `user_agent`, dados brutos do dispositivo e correspondências entre sessões.

## Comportamento no sandbox

As chaves de sandbox validam a requisição e retornam dados determinísticos aprovados. Elas não acessam serviços externos de inteligência, não consomem créditos, não criam uma sessão nem contribuem para as Networks.

## Faturamento

As chamadas à API de risco de IP custam \$0.02 ao preço de tabela. Uma requisição no ambiente de produção é cobrada assim que a consulta começa.


## OpenAPI

````yaml pt-br/openapi-25.json POST /v3/ip/risk/
openapi: 3.0.0
info:
  version: 3.0.0
  title: Didit Verification API
  description: API de verificação de identidade. Autentique-se com o cabeçalho x-api-key.
servers:
  - url: https://verification.didit.me
security: []
tags: []
paths:
  /v3/ip/risk/:
    post:
      tags:
        - Standalone APIs
      summary: Calcular a pontuação de risco de um endereço IP
      description: >-
        Retorna geolocalização, propriedade da rede, indicadores de VPN/Tor e de
        data center, dados de ameaças e `country_mismatch` para um endereço IP
        informado. O endpoint cria uma sessão de API e retorna o id dela como
        `request_id`.


        **Decisão.** O `status` é `In Review` quando o país identificado diverge
        de `claimed_country` ou quando o endereço está associado a
        infraestrutura de VPN, Tor ou data center. Caso contrário, é `Approved`.


        **Melhor esforço.** O enriquecimento de IP é feito por melhor esforço.
        Se nenhuma fonte de enriquecimento retornar dados utilizáveis, o
        endpoint retorna uma resposta aprovada com `ip.ip_address: null`,
        `ip.country_mismatch: null` e um objeto `ip.threat` vazio.


        **Faturamento.** As chamadas no ambiente de produção usam os preços da
        IP Risk API. A requisição é cobrada assim que a consulta começa.


        **Sandbox.** As chaves de sandbox validam a requisição e retornam dados
        aprovados determinísticos, sem consumir créditos, criar uma sessão ou
        contribuir para o Networks.


        **Autenticação.** Envie a chave de API da sua aplicação em `x-api-key`.
        Credenciais ausentes ou inválidas retornam `403`: esta API nunca retorna
        `401`.


        **Limite de requisições.** Cota de escrita compartilhada de 300
        requisições por minuto por chave de API, somando todos os endpoints
        POST/PATCH/DELETE.
      operationId: post_v3ip_risk
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/IPRiskRequest'
            examples:
              Minimal:
                summary: Pontuar um endereço com os valores padrão
                value:
                  ip_address: 8.8.8.8
              With claimed country:
                summary: Pontuar com um país declarado para detectar divergências
                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: >-
            A avaliação de risco foi concluída. Verifique `status` para ver a
            decisão; o HTTP é sempre `200` para consultas concluídas.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/IPRiskResponse'
              examples:
                Clean residential IP:
                  summary: Endereço residencial, país declarado corresponde
                  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: Endereço de data center em conflito com o país declarado
                  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: Endereço IPv4 ou IPv6 a ser pontuado.
          example: 8.8.8.8
        claimed_country:
          type: string
          maxLength: 3
          description: >-
            País opcional em ISO 3166-1 alfa-2 ou alfa-3 declarado pelo usuário
            ou pela sessão. Usado para calcular `country_mismatch`.
          example: ESP
        user_agent:
          type: string
          maxLength: 512
          description: >-
            User agent observado pelo seu backend. Armazenado como contexto da
            requisição; não fornece fingerprinting de dispositivo.
        vendor_data:
          type: string
          description: >-
            Sua referência estável para esta requisição. Armazenada na sessão da
            API e devolvida na resposta.
        metadata:
          type: object
          nullable: true
          additionalProperties: true
          description: >-
            Seus metadados JSON não sensíveis. Armazenados na sessão da API e
            retornados na resposta.
    IPRiskResponse:
      type: object
      required:
        - request_id
        - status
        - created_at
      properties:
        request_id:
          type: string
          format: uuid
          description: >-
            Id da sessão de API criada para esta requisição. Armazene-o com
            `vendor_data` se precisar correlacionar o resultado com webhooks
            posteriores ou com a atividade no console.
        status:
          type: string
          enum:
            - Approved
            - In Review
          description: >-
            Decisão desta sessão de API: `In Review` em caso de risco de rede ou
            de divergência de país; caso contrário, `Approved`.
        vendor_data:
          type: string
          nullable: true
          description: >-
            Eco do `vendor_data` que você enviou, `null` quando você não enviou
            nenhum.
        metadata:
          type: object
          nullable: true
          additionalProperties: true
          description: >-
            Eco do `metadata` que você enviou, `null` quando você não enviou
            nenhum.
        created_at:
          type: string
          format: date-time
          description: Data e hora desta resposta.
        ip:
          type: object
          description: >-
            Resultado de risco do IP. Campos de enriquecimento individuais podem
            ser `null` quando a consulta não retornou dados utilizáveis.
          required:
            - status
            - threat
          properties:
            status:
              type: string
              enum:
                - Approved
                - In Review
              description: >-
                `In Review` quando o país identificado diverge de
                `claimed_country`, ou quando o endereço está associado a VPN,
                Tor ou infraestrutura de data center. Caso contrário,
                `Approved`.
            ip_address:
              type: string
              nullable: true
              description: >-
                O endereço pontuado. `null` quando nenhuma fonte de
                enriquecimento retornou dados utilizáveis.
            ip_country:
              type: string
              nullable: true
              description: Nome do país resolvido.
            ip_country_code:
              type: string
              nullable: true
              description: >-
                Código do país resolvido. Compare países por meio de
                `country_mismatch` em vez de comparar você mesmo as strings
                brutas de país.
            ip_state:
              type: string
              nullable: true
              description: Estado ou região resolvidos.
            ip_city:
              type: string
              nullable: true
              description: Cidade resolvida.
            latitude:
              type: number
              nullable: true
              description: >-
                Geolocalização aproximada pela rede, não uma localização precisa
                do dispositivo.
            longitude:
              type: number
              nullable: true
              description: >-
                Geolocalização aproximada pela rede, não uma localização precisa
                do dispositivo.
            isp:
              type: string
              nullable: true
              description: Provedor de serviços de internet que atende o endereço.
            organization:
              type: string
              nullable: true
              description: Organização proprietária do bloco de endereços.
            is_vpn_or_tor:
              type: boolean
              nullable: true
              description: >-
                `true` quando o endereço está associado a infraestrutura de VPN
                ou Tor.
            is_data_center:
              type: boolean
              nullable: true
              description: >-
                `true` quando o endereço pertence a uma rede de hospedagem ou de
                data center.
            time_zone:
              type: string
              nullable: true
              description: Fuso horário da localização resolvida.
            time_zone_offset:
              type: string
              nullable: true
              description: Deslocamento UTC da localização resolvida.
            asn_number:
              type: number
              nullable: true
              description: Número de sistema autônomo.
            asn_organization:
              type: string
              nullable: true
              description: Organização que opera o sistema autônomo.
            connection_type:
              type: string
              nullable: true
              description: Classificação da conexão (por exemplo, `cellular`, `hosting`).
            carrier:
              type: string
              nullable: true
              description: Operadora móvel quando o endereço está em uma rede móvel.
            proxy_type:
              type: string
              nullable: true
              description: Classificação de proxy quando o endereço está atrás de um proxy.
            claimed_country:
              type: string
              nullable: true
              description: Eco do `claimed_country` que você enviou.
            country_mismatch:
              type: boolean
              nullable: true
              description: >-
                `true` quando o país identificado difere de `claimed_country`.
                `null` quando não há dados de enriquecimento ou nenhum país
                declarado disponível.
            threat:
              type: object
              additionalProperties: true
              description: >-
                Evidências livres de ameaças de rede vindas da fonte de
                enriquecimento (por exemplo, `is_proxy`, `is_tor`). Objeto vazio
                quando não há dados de enriquecimento disponíveis. Trate como
                detalhe de diagnóstico, não como um contrato estável.
  responses:
    IPRiskValidationError:
      description: A validação da requisição falhou.
      content:
        application/json:
          examples:
            Missing IP address:
              summary: Endereço IP ausente
              value:
                ip_address:
                  - This field is required.
            Invalid IP address:
              summary: Endereço IP inválido
              value:
                ip_address:
                  - Enter a valid IPv4 or IPv6 address.
            Country hint too long:
              summary: Indicação de país muito longa
              value:
                claimed_country:
                  - Ensure this field has no more than 3 characters.
    RiskPermissionDenied:
      description: >-
        A chave de API está ausente ou é inválida, ou a organização não consegue
        cobrir a consulta em tempo real. Esta API nunca retorna `401`.
      content:
        application/json:
          examples:
            Missing or invalid API key:
              summary: >-
                Nenhum cabeçalho `x-api-key`, ou a chave é inválida ou foi
                revogada
              value:
                detail: You do not have permission to perform this action.
            Not enough credits:
              summary: O saldo da organização não cobre o preço da consulta
              value:
                error: You don't have enough credits to perform this request.
    RateLimitedWrite:
      description: >-
        O limite compartilhado de escrita de 300 requisições por minuto por
        chave de API foi excedido. Respeite `Retry-After` antes de tentar
        novamente.
      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: >-
        Chave de API da sua aplicação, em Developers -> API keys no Business
        Console. A chave principal tem acesso total. Uma chave nomeada pode ter
        escopo restrito: nenhum acesso, leitura ou escrita por recurso, limitada
        a alguns fluxos ou a sessões aprovadas, a uma lista de endereços IP e a
        uma data de validade. 401 significa que a chave está errada, revogada ou
        expirada; 403 significa que nenhuma chave foi enviada, que a chave não
        tem acesso a este recurso ou ação, ou que a requisição veio de um
        endereço fora da sua lista de IPs; 404 em uma rota de sessão significa
        que a sessão está fora dos fluxos ou status da chave. Uma chave sem
        acesso a mídia recebe URLs de imagem, vídeo e PDF como null, e uma chave
        sem permissão de escrita em sessões recebe links e tokens de sessão como
        null. Consulte https://docs.didit.me/console/api-keys.

````

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