> ## 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: Geo, VPN e Datacenter

> Calcule o risco de um endereço IP com geolocalização, ISP, sinais de VPN/Tor, datacenter, ameaças e incoerência de país declarado. Com a Didit.

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

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

## Interpretar a resposta

* `status` é `In Review` quando o país resolvido entra em conflito com `claimed_country`, ou quando o endereço está associado a infraestrutura de VPN, Tor ou centro de dados. Caso contrário, é `Approved`.
* `ip.ip_country_code` contém o código do país resolvido. Compare os países através de `ip.country_mismatch` em vez de comparar diretamente as strings de país.
* `ip.latitude` e `ip.longitude` são uma geolocalização aproximada da rede, não a localização precisa de um dispositivo.
* `ip.is_vpn_or_tor`, `ip.is_data_center`, `ip.proxy_type` e `ip.threat` contêm dados de risco da rede.
* `ip.asn_number`, `ip.asn_organization`, `ip.connection_type` e `ip.carrier` descrevem a rede a que o endereço pertence.
* `request_id` é o ID da sessão da API. Guarde-o com `vendor_data` se precisar de correlacionar o resultado com webhooks posteriores ou com a atividade na consola.

> [!NOTE]
>
> O enriquecimento de IP é efetuado da melhor forma possível. Se nenhuma fonte de enriquecimento devolver dados utilizáveis, o endpoint devolve 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 dispositivos

A API de risco de IP é um endpoint puramente servidor a servidor. A criação de uma impressão digital do dispositivo não funciona dessa forma, porque um backend, por si só, não consegue observar sinais do navegador ou do dispositivo. Nas sessões do fluxo alojado e do SDK, a Didit expõe na resposta da sessão os campos do dispositivo já recolhidos, 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 o pedido e devolvem dados aprovados determinísticos. Não contactam serviços externos de inteligência, não consomem créditos, não criam uma sessão nem contribuem para as Networks.

## Faturação

As chamadas à API de risco de IP custam \$0.02 ao preço de tabela. Um pedido em produção é faturável assim que a pesquisa é iniciada.


## OpenAPI

````yaml pt/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: >-
        Devolve a geolocalização, propriedade da rede, sinalizadores de VPN/Tor
        e centros de dados, dados de ameaças e `country_mismatch` para um
        endereço IP fornecido. O endpoint cria uma sessão de API e devolve o seu
        id como `request_id`.


        **Decisão.** O `status` fica em `In Review` quando o país determinado
        entra em conflito com `claimed_country` ou quando o endereço está
        associado a infraestruturas de VPN, Tor ou centros de dados. Caso
        contrário, é `Approved`.


        **Melhor esforço.** O enriquecimento de IP é efetuado tanto quanto
        possível. Se nenhuma fonte de enriquecimento devolver dados úteis, o
        endpoint devolve uma resposta aprovada com `ip.ip_address: null`,
        `ip.country_mismatch: null` e um objeto `ip.threat` vazio.


        **Faturação.** As chamadas em produção utilizam os preços da IP Risk
        API. O pedido é faturável assim que a consulta tem início.


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


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


        **Limite de pedidos.** Orçamento de escrita partilhado de 300 pedidos
        por minuto por chave de API em todos os endpoints POST/PATCH/DELETE (a
        criação de transações e a ingestão de eventos têm um orçamento separado
        de 600).
      operationId: post_v3ip_risk
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/IPRiskRequest'
            examples:
              Minimal:
                summary: Calcular a pontuação de uma morada com valores predefinidos
                value:
                  ip_address: 8.8.8.8
              With claimed country:
                summary: Pontuação com um país declarado para deteção de discrepâ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. Inspecione `status` para
            verificar a decisão; o código HTTP é sempre `200` para pesquisas
            concluídas.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/IPRiskResponse'
              examples:
                Clean residential IP:
                  summary: Morada de residência, o 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 centro de dados em conflito com o país indicado
                  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 pontuar.
          example: 8.8.8.8
        claimed_country:
          type: string
          maxLength: 3
          description: >-
            País ISO 3166-1 alpha-2 ou alpha-3 opcional declarado pelo
            utilizador ou pela sessão. Utilizado para calcular
            `country_mismatch`.
          example: ESP
        user_agent:
          type: string
          maxLength: 512
          description: >-
            Agente do utilizador observado pelo seu back-end. Armazenado como
            contexto do pedido; não fornece a impressão digital do dispositivo.
        vendor_data:
          type: string
          description: >-
            A sua referência estável para este pedido. Armazenada na sessão da
            API e refletida na resposta.
        metadata:
          type: object
          nullable: true
          additionalProperties: true
          description: >-
            Os seus metadados JSON não sensíveis. Armazenados na sessão da API e
            devolvidos 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 este pedido. Guarde-o com
            `vendor_data` se precisar de correlacionar o resultado com webhooks
            posteriores ou atividade na consola.
        status:
          type: string
          enum:
            - Approved
            - In Review
          description: >-
            Decisão para esta sessão de API: `In Review` em caso de risco de
            rede ou discrepância de país, caso contrário `Approved`.
        vendor_data:
          type: string
          nullable: true
          description: Eco do `vendor_data` que enviou, `null` se não tiver enviado nenhum.
        metadata:
          type: object
          nullable: true
          additionalProperties: true
          description: >-
            Eco do objeto `metadata` que enviou, `null` se não tiver enviado
            nenhum.
        created_at:
          type: string
          format: date-time
          description: Carimbo de data/hora desta resposta.
        ip:
          type: object
          description: >-
            Resultado de risco de IP. Os campos individuais de enriquecimento
            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 resolvido entrar em conflito com
                `claimed_country`, ou quando o endereço estiver associado a
                infraestruturas de VPN, Tor ou centro de dados. Caso contrário,
                `Approved`.
            ip_address:
              type: string
              nullable: true
              description: >-
                O endereço avaliado. `null` quando nenhuma fonte de
                enriquecimento devolveu 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 através de
                `country_mismatch` em vez de comparar diretamente as strings
                brutas dos países.
            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 de rede aproximada, não uma localização precisa
                do dispositivo.
            longitude:
              type: number
              nullable: true
              description: >-
                Geolocalização de rede aproximada, não uma localização precisa
                do dispositivo.
            isp:
              type: string
              nullable: true
              description: >-
                Fornecedor de serviços de Internet que presta serviço ao
                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 alojamento ou
                centro de dados.
            time_zone:
              type: string
              nullable: true
              description: Fuso horário da localização resolvida.
            time_zone_offset:
              type: string
              nullable: true
              description: Desfasamento UTC da localização determinada.
            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 ligação (por exemplo, `cellular`, `hosting`).
            carrier:
              type: string
              nullable: true
              description: Operadora móvel quando o endereço se encontra numa 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 enviou.
            country_mismatch:
              type: boolean
              nullable: true
              description: >-
                `true` quando o país apurado difere de `claimed_country`. `null`
                quando não estão disponíveis dados de enriquecimento ou país
                declarado.
            threat:
              type: object
              additionalProperties: true
              description: >-
                Evidência de ameaças de rede em formato livre a partir da fonte
                de enriquecimento (por exemplo, `is_proxy`, `is_tor`). Objeto
                vazio quando não existem dados de enriquecimento disponíveis.
                Considere-o como um detalhe de diagnóstico, não como um contrato
                estável.
  responses:
    IPRiskValidationError:
      description: A validação do pedido falhou.
      content:
        application/json:
          examples:
            Missing IP address:
              summary: Endereço IP em falta
              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: Sugestão de país demasiado longa
              value:
                claimed_country:
                  - Ensure this field has no more than 3 characters.
    RiskPermissionDenied:
      description: >-
        A chave de API está em falta ou é inválida, ou a organização não pode
        cobrir a consulta em tempo real. Esta API nunca devolve `401`.
      content:
        application/json:
          examples:
            Missing or invalid API key:
              summary: Sem 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 de escrita partilhado de 300 pedidos por minuto por chave de
        API foi excedido. Respeite o `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: >-
        A chave de API da sua aplicação, a partir de Programadores -> Chaves de
        API na Business Console. A chave principal tem acesso total. Uma chave
        nomeada pode ter o âmbito definido: nenhum, 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á
        incorreta, 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 o
        pedido veio de um endereço fora da sua lista de IP; 404 numa rota de
        sessão significa que a sessão está fora dos fluxos ou estados da chave.
        Uma chave sem acesso a multimédia recebe URLs de imagens, vídeos e PDFs
        como nulos, e uma chave sem permissão de escrita em sessões recebe
        ligações de sessão e tokens como nulos. Consulte
        https://docs.didit.me/console/api-keys.

````

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