> ## 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-Risiko-API: Geo-, VPN- und Rechenzentrums-Signale

> Bewerten Sie IP-Adressen mit Didit: Geolokalisierung, ISP, VPN/Tor, Rechenzentrum, Bedrohungen und Abweichungen beim angegebenen Land.

Verwenden Sie `POST /v3/ip/risk/`, wenn Ihr Backend bereits eine IP-Adresse hat und eine serverseitige Risikoentscheidung benötigt.

Die Antwort enthält Geolokalisierung, Netzwerkeigentum, VPN- und Tor-Kennzeichen, Rechenzentrumskennzeichen, Bedrohungsdaten sowie `country_mismatch`, wenn Sie ein angegebenes Land übermitteln.

## Antwort interpretieren

* `status` ist `In Review`, wenn das ermittelte Land nicht mit `claimed_country` übereinstimmt oder wenn die Adresse mit VPN-, Tor- oder Rechenzentrumsinfrastruktur in Verbindung steht. Andernfalls ist er `Approved`.
* `ip.ip_country_code` enthält den ermittelten Ländercode. Vergleichen Sie Länder über `ip.country_mismatch`, statt rohe Länderzeichenfolgen selbst zu vergleichen.
* `ip.latitude` und `ip.longitude` geben eine ungefähre Netzwerk-Geolokalisierung an und keine genaue Standortangabe des Geräts.
* `ip.is_vpn_or_tor`, `ip.is_data_center`, `ip.proxy_type` und `ip.threat` liefern Nachweise für Netzwerkrisiken.
* `ip.asn_number`, `ip.asn_organization`, `ip.connection_type` und `ip.carrier` beschreiben das Netzwerk, zu dem die Adresse gehört.
* `request_id` ist die API-Sitzungs-ID. Speichern Sie sie zusammen mit `vendor_data`, wenn Sie das Ergebnis später mit Webhooks oder Aktivitäten in der Konsole abgleichen müssen.

> [!NOTE]
>
> Die IP-Anreicherung erfolgt nach dem Best-Effort-Prinzip. Wenn keine Anreicherungsquelle brauchbare Daten liefert, gibt der Endpoint eine genehmigte Antwort mit `ip.ip_address: null`, `ip.country_mismatch: null` und einem leeren `ip.threat`-Objekt zurück. Einzelne Anreicherungsfelder können ebenfalls `null` sein, wenn sie nicht verfügbar sind.

## Geräteintelligenz

Die IP Risk API ist ein rein serverseitiger Endpoint. Geräte-Fingerprinting gehört nicht dazu, weil ein Backend Browser- oder Gerätesignale allein nicht beobachten kann. Für gehostete Abläufe und SDK-Sitzungen stellt Didit die bereits erfassten Gerätefelder in der Sitzungsantwort bereit, darunter `device_fingerprint`, Geräte- und Browserdetails, `user_agent`, Rohdaten des Geräts sowie sitzungsübergreifende Treffer.

## Verhalten in der Sandbox

Sandbox-Schlüssel validieren die Anfrage und liefern deterministische, genehmigte Daten zurück. Sie kontaktieren keine externen Intelligence-Dienste, verbrauchen keine Credits, erstellen keine Sitzung und tragen nicht zu Networks bei.

## Abrechnung

Ein Aufruf der IP Risk API kostet \$0.02 zum Listenpreis. Eine Anfrage in der Produktionsumgebung ist abrechenbar, sobald die Abfrage startet.


## OpenAPI

````yaml de/openapi-25.json POST /v3/ip/risk/
openapi: 3.0.0
info:
  version: 3.0.0
  title: Didit Verification API
  description: API für Ausweisverifizierung. Authentifizierung über den x-api-key-Header.
servers:
  - url: https://verification.didit.me
security: []
tags: []
paths:
  /v3/ip/risk/:
    post:
      tags:
        - Standalone APIs
      summary: Risiko-Score für eine IP-Adresse ermitteln
      description: >-
        Gibt Geolokalisierung, Netzwerk-Eigentümerstruktur, VPN/Tor- und
        Rechenzentrums-Flags, Bedrohungsdaten sowie `country_mismatch` für eine
        angegebene IP-Adresse zurück. Der Endpoint erstellt eine API-Sitzung und
        gibt deren ID als `request_id` zurück.


        **Entscheidung.** `status` ist `In Review`, wenn das ermittelte Land im
        Konflikt mit `claimed_country` steht oder wenn die Adresse mit VPN-,
        Tor- oder Rechenzentrumsinfrastruktur verknüpft ist. Andernfalls lautet
        er `Approved`.


        **Best Effort.** Die IP-Anreicherung erfolgt nach dem
        Best-Effort-Prinzip. Wenn keine Anreicherungsquelle nutzbare Daten
        liefert, gibt der Endpoint eine genehmigte Antwort mit `ip.ip_address:
        null`, `ip.country_mismatch: null` und einem leeren `ip.threat`-Objekt
        zurück.


        **Abrechnung.** Live-Aufrufe nutzen die Preise der IP Risk API. Die
        Anfrage ist abrechenbar, sobald die Abfrage startet.


        **Sandbox.** Sandbox-Schlüssel validieren die Anfrage und geben
        deterministische, genehmigte Daten zurück, ohne Credits zu verbrauchen,
        eine Sitzung zu erstellen oder zu Networks beizutragen.


        **Authentifizierung.** Senden Sie den API-Schlüssel Ihrer Anwendung in
        `x-api-key`. Fehlende oder ungültige Anmeldedaten geben `403` zurück –
        diese API gibt niemals `401` zurück.


        **Rate-Limit.** Geteiltes Schreib-Budget von 300 Anfragen pro Minute pro
        API-Schlüssel über POST/PATCH/DELETE-Endpoints hinweg
        (Transaktionserstellungen und Ereignis-Ingestion haben ein separates
        Budget von 600).
      operationId: post_v3ip_risk
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/IPRiskRequest'
            examples:
              Minimal:
                summary: Eine Adresse mit Standardwerten bewerten
                value:
                  ip_address: 8.8.8.8
              With claimed country:
                summary: Score mit angegebenem Land zur Abweichungserkennung
                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: >-
            Die Risikobewertung wurde abgeschlossen. Prüfen Sie `status` für die
            Entscheidung; HTTP ist bei abgeschlossenen Abfragen immer `200`.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/IPRiskResponse'
              examples:
                Clean residential IP:
                  summary: Wohnadresse, angegebenes Land stimmt überein
                  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: >-
                    Rechenzentrumsadresse steht im Widerspruch zum angegebenen
                    Land
                  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: Zu bewertende IPv4- oder IPv6-Adresse.
          example: 8.8.8.8
        claimed_country:
          type: string
          maxLength: 3
          description: >-
            Optionales ISO 3166-1 alpha-2 oder alpha-3 Land, das vom Benutzer
            oder der Sitzung angegeben wurde. Wird zur Berechnung von
            `country_mismatch` verwendet.
          example: ESP
        user_agent:
          type: string
          maxLength: 512
          description: >-
            Vom Backend erkannter User-Agent. Wird als Anfragekontext
            gespeichert; bietet kein Geräte-Fingerprinting.
        vendor_data:
          type: string
          description: >-
            Ihre stabile Referenz für diese Anfrage. Wird in der API-Sitzung
            gespeichert und in der Antwort zurückgegeben.
        metadata:
          type: object
          nullable: true
          additionalProperties: true
          description: >-
            Ihre nicht sensiblen JSON-Metadaten. Werden in der API-Sitzung
            gespeichert und in der Antwort zurückgegeben.
    IPRiskResponse:
      type: object
      required:
        - request_id
        - status
        - created_at
      properties:
        request_id:
          type: string
          format: uuid
          description: >-
            ID der API-Sitzung, die für diese Anfrage erstellt wurde. Speichern
            Sie sie zusammen mit `vendor_data`, wenn Sie das Ergebnis mit
            späteren Webhooks oder Konsolenaktivitäten korrelieren müssen.
        status:
          type: string
          enum:
            - Approved
            - In Review
          description: >-
            Entscheidung für diese API-Sitzung: `In Review` bei Netzwerk- oder
            Länderabweichungsrisiko, andernfalls `Approved`.
        vendor_data:
          type: string
          nullable: true
          description: >-
            Rückgabe der von Ihnen gesendeten `vendor_data`, `null`, wenn Sie
            keine gesendet haben.
        metadata:
          type: object
          nullable: true
          additionalProperties: true
          description: >-
            Rückgabe der von Ihnen gesendeten `metadata`, `null`, wenn Sie keine
            gesendet haben.
        created_at:
          type: string
          format: date-time
          description: Zeitstempel dieser Antwort.
        ip:
          type: object
          description: >-
            IP-Risikoergebnis. Einzelne Anreicherungsfelder können `null` sein,
            wenn die Abfrage keine verwertbaren Daten zurückgegeben hat.
          required:
            - status
            - threat
          properties:
            status:
              type: string
              enum:
                - Approved
                - In Review
              description: >-
                `In Review`, wenn das ermittelte Land im Konflikt mit
                `claimed_country` steht oder wenn die Adresse mit VPN-, Tor-
                oder Rechenzentrumsinfrastruktur verknüpft ist. Andernfalls
                `Approved`.
            ip_address:
              type: string
              nullable: true
              description: >-
                Die bewertete Adresse. `null`, wenn keine Anreicherungsquelle
                verwertbare Daten zurückgegeben hat.
            ip_country:
              type: string
              nullable: true
              description: Ermittelter Ländername.
            ip_country_code:
              type: string
              nullable: true
              description: >-
                Ermittelter Ländercode. Vergleichen Sie Länder über
                `country_mismatch`, anstatt rohe Länder-Strings selbst zu
                vergleichen.
            ip_state:
              type: string
              nullable: true
              description: Ermitteltes Bundesland oder Region.
            ip_city:
              type: string
              nullable: true
              description: Ermittelte Stadt.
            latitude:
              type: number
              nullable: true
              description: >-
                Ungefähre Netzwerk-Geolokalisierung, kein genauer
                Gerätestandort.
            longitude:
              type: number
              nullable: true
              description: >-
                Ungefähre Netzwerk-Geolokalisierung, kein genauer
                Gerätestandort.
            isp:
              type: string
              nullable: true
              description: Internetanbieter, der die Adresse versorgt.
            organization:
              type: string
              nullable: true
              description: Organisation, der der Adressblock gehört.
            is_vpn_or_tor:
              type: boolean
              nullable: true
              description: >-
                `true`, wenn die Adresse mit einer VPN- oder Tor-Infrastruktur
                verknüpft ist.
            is_data_center:
              type: boolean
              nullable: true
              description: >-
                `true`, wenn die Adresse zu einem Hosting- oder
                Rechenzentrumsnetzwerk gehört.
            time_zone:
              type: string
              nullable: true
              description: Zeitzone des aufgelösten Standorts.
            time_zone_offset:
              type: string
              nullable: true
              description: UTC-Offset des aufgelösten Standorts.
            asn_number:
              type: number
              nullable: true
              description: Nummer des autonomen Systems.
            asn_organization:
              type: string
              nullable: true
              description: Organisation, die das autonome System betreibt.
            connection_type:
              type: string
              nullable: true
              description: Verbindungsklassifizierung (z. B. `cellular`, `hosting`).
            carrier:
              type: string
              nullable: true
              description: >-
                Mobilfunkanbieter, wenn sich die Adresse in einem Mobilfunknetz
                befindet.
            proxy_type:
              type: string
              nullable: true
              description: >-
                Proxy-Klassifizierung, wenn sich die Adresse hinter einem Proxy
                befindet.
            claimed_country:
              type: string
              nullable: true
              description: Rückgabe des von Ihnen gesendeten `claimed_country`.
            country_mismatch:
              type: boolean
              nullable: true
              description: >-
                `true`, wenn das ermittelte Land von `claimed_country` abweicht.
                `null`, wenn keine Anreicherungsdaten oder kein angegebenes Land
                verfügbar sind.
            threat:
              type: object
              additionalProperties: true
              description: >-
                Netzwerkbedrohungshinweise in Freiform aus der
                Anreicherungsquelle (z. B. `is_proxy`, `is_tor`). Leeres Objekt,
                wenn keine Anreicherungsdaten verfügbar sind. Als diagnostisches
                Detail und nicht als stabiler Kontrakt zu behandeln.
  responses:
    IPRiskValidationError:
      description: Validierung der Anfrage fehlgeschlagen.
      content:
        application/json:
          examples:
            Missing IP address:
              summary: Fehlende IP-Adresse
              value:
                ip_address:
                  - This field is required.
            Invalid IP address:
              summary: Ungültige IP-Adresse
              value:
                ip_address:
                  - Enter a valid IPv4 or IPv6 address.
            Country hint too long:
              summary: Länderhinweis zu lang
              value:
                claimed_country:
                  - Ensure this field has no more than 3 characters.
    RiskPermissionDenied:
      description: >-
        Der API-Schlüssel fehlt oder ist ungültig, oder die Organisation kann
        die Live-Abfrage nicht abdecken. Diese API gibt niemals `401` zurück.
      content:
        application/json:
          examples:
            Missing or invalid API key:
              summary: >-
                Kein `x-api-key`-Header, oder der Schlüssel ist ungültig oder
                widerrufen
              value:
                detail: You do not have permission to perform this action.
            Not enough credits:
              summary: >-
                Das Guthaben der Organisation reicht für den Preis der Abfrage
                nicht aus
              value:
                error: You don't have enough credits to perform this request.
    RateLimitedWrite:
      description: >-
        Das geteilte Schreiblimit von 300 Anfragen pro Minute pro API-Schlüssel
        wurde überschritten. Beachten Sie `Retry-After`, bevor Sie es erneut
        versuchen.
      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: >-
        Der API-Schlüssel Ihrer Anwendung, aus Entwickler -> API-Schlüssel in
        der Business Console. Der Primärschlüssel hat Vollzugriff. Ein benannter
        Schlüssel kann im Geltungsbereich eingeschränkt werden: keine, Lese-
        oder Schreibberechtigung pro Ressource, beschränkt auf bestimmte
        Workflows oder genehmigte Sitzungen, auf eine Liste von IP-Adressen und
        auf ein Ablaufdatum. 401 bedeutet, dass der Schlüssel falsch, widerrufen
        oder abgelaufen ist; 403 bedeutet, dass kein Schlüssel gesendet wurde,
        der Schlüssel keinen Zugriff auf diese Ressource oder Aktion hat oder
        die Anfrage von einer Adresse außerhalb seiner IP-Liste stammte; 404 bei
        einer Sitzungsroute bedeutet, dass die Sitzung außerhalb der Workflows
        oder Status des Schlüssels liegt. Ein Schlüssel ohne Medienzugriff
        erhält Bild-, Video- und PDF-URLs als null, und ein Schlüssel ohne
        Schreibberechtigung für Sitzungen erhält Sitzungslinks und Token als
        null. Siehe https://docs.didit.me/console/api-keys.

````

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