Referencia para desarrolladores

Detección de Typosquatting

API de DomScan: Detecta amenazas de typosquatting y dominios similares que podrían usarse para phishing o abuso de marca.

Detección de Typosquatting

Detecta amenazas de typosquatting y dominios similares que podrían usarse para phishing o abuso de marca.

GET /v1/typos

Parámetros de consulta

ParámetroTipoDescripción
domain obligatorio string Dominio a comprobar para variantes de typosquatting
limit opcional number Maximo de permutaciones a comprobar (por defecto: 50)
check_registered opcional boolean token
Valores permitidos 1true
Predeterminado false
Comprueba qué permutaciones ya están registradas, hasta 50 dominios. Desactivado de forma predeterminada porque añade búsquedas en fuentes externas.

Respuesta de ejemplo

{
                "domain": "google.com",
                "permutations_generated": 50,
                "registered_typos": [
                {
                "domain": "gooogle.com",
                "type": "repetition",
                "risk": "high",
                "registered": true
                },
                {
                "domain": "googIe.com",
                "type": "homoglyph",
                "risk": "critical",
                "registered": true
                }
                ],
                "threat_level": "critical",
                "risk_summary": {
                "critical": 2,
                "high": 5,
                "medium": 10,
                "low": 8
                }
                }

Campos de respuesta

Campo Tipo
domain string
name string
tld string
permutations_generated integer
permutations_checked integer
registered_typos[] object[]
registered_typos[] object
registered_typos[].classification object
registered_typos[].classification.status string
registered_typos[].classification.reason string
registered_typos[].classification.evidence object
registered_typos[].classification.evidence.source string
registered_typos[].classification.evidence.method string
registered_typos[].classification.evidence.observed_at string
registered_typos[].classification.evidence.detail string
registered_typos[].classification.checked_at string
registered_typos[].domain string
registered_typos[].name string
registered_typos[].tld string
registered_typos[].type string
registered_typos[].risk string
registered_typos[].description string
registered_typos[].registered boolean
registered_typos[].checked_at string
available_typos integer
unknown_typos integer
risk_summary object
risk_summary.critical integer
risk_summary.high integer
risk_summary.medium integer
risk_summary.low integer
threat_level string
family_summary object
family_summary.generated_by_type object
family_summary.generated_by_risk object
family_summary.registered_by_type object
family_summary.registered_by_risk object
family_summary.top_generated_family string | null
family_summary.top_registered_family string | null
family_summary.critical_or_high_generated_count integer
family_summary.critical_or_high_registered_count integer
family_summary.coverage_ratio number
family_summary.checked_count integer
family_summary.available_count integer
family_summary.unknown_count integer
family_summary.omitted_count integer
family_summary.include_tld_swap boolean
family_summary.requested_limit integer
checked_at string
check_duration_ms integer
meta object
meta.served_by string
meta.cached boolean
meta.query_time_ms integer
meta.registration_check_requested boolean
meta.registration_check_limit integer
GET /v1/typos/threats Créditos: 12

Parámetros de consulta

Parámetro Tipo obligatorio
domain string obligatorio
limit integer
Predeterminado 200
opcional
include_tld_swap boolean
Predeterminado true
opcional

Campos de respuesta

Campo Tipo
domain string
name string
tld string
scan_summary object
scan_summary.permutations_generated integer
scan_summary.permutations_checked integer
scan_summary.permutations_submitted integer
scan_summary.definitive_results integer
scan_summary.unknown_results integer
scan_summary.omitted_results integer
scan_summary.registered_count integer
scan_summary.active_threats integer
scan_summary.available_for_defensive integer
scan_summary.check_limit integer
scan_summary.coverage_truncated boolean
threat_level string
protection_score object
protection_score.score integer
protection_score.grade string
protection_score.interpretation object
protection_score.interpretation.score_meaning string
protection_score.interpretation.factors string
protection_score.interpretation.note string
protection_score.vulnerabilities[] object[]
protection_score.vulnerabilities[] object
protection_score.vulnerabilities[].category string
protection_score.vulnerabilities[].count integer
protection_score.vulnerabilities[].risk string
protection_score.vulnerabilities[].description string
protection_score.recommendations[] string[]
protection_score.factors object
protection_score.factors.length_factor integer
protection_score.factors.homoglyph_factor integer
protection_score.factors.keyboard_factor integer
protection_score.factors.tld_factor integer
threats[] object[]
threats[] object
threats[].classification object
threats[].classification.status string
threats[].classification.reason string
threats[].classification.evidence object
threats[].classification.evidence.source string
threats[].classification.evidence.method string
threats[].classification.evidence.observed_at string
threats[].classification.evidence.detail string
threats[].classification.checked_at string
threats[].domain string
threats[].name string
threats[].tld string
threats[].type string
threats[].risk string
threats[].description string
threats[].registered boolean
threats[].checked_at string
threats[].dns_active boolean
threats[].has_website boolean
threats[].has_mx boolean
threats[].infrastructure object
threats[].threat_indicators[] string[]
threats[].threat_score integer
defensive_opportunities[] object[]
defensive_opportunities[] object
defensive_opportunities[].domain string
defensive_opportunities[].name string
defensive_opportunities[].tld string
defensive_opportunities[].type string
defensive_opportunities[].risk string
defensive_opportunities[].description string
risk_breakdown object
recommendations[] string[]
checked_at string
scan_duration_ms integer
meta object
meta.served_by string

Solicitud de ejemplo

curl -H "X-API-Key: $DOMSCAN_API_KEY" "https://domscan.net/v1/typos/threats?domain=example.com&limit=25&include_tld_swap=true"
const response = await fetch("https://domscan.net/v1/typos/threats?domain=example.com&limit=25&include_tld_swap=true", {
  headers: { "X-API-Key": process.env.DOMSCAN_API_KEY },
});
const data = await response.json();
console.log(data);
import os
import requests

response = requests.get(
    "https://domscan.net/v1/typos/threats?domain=example.com&limit=25&include_tld_swap=true",
    headers={"X-API-Key": os.environ["DOMSCAN_API_KEY"]},
)
print(response.json())
package main

import (
	"fmt"
	"io"
	"net/http"
	"os"
)

func main() {
	req, err := http.NewRequest(http.MethodGet, "https://domscan.net/v1/typos/threats?domain=example.com&limit=25&include_tld_swap=true", nil)
	if err != nil {
		panic(err)
	}
	req.Header.Set("X-API-Key", os.Getenv("DOMSCAN_API_KEY"))

	resp, err := http.DefaultClient.Do(req)
	if err != nil {
		panic(err)
	}
	defer resp.Body.Close()

	data, err := io.ReadAll(resp.Body)
	if err != nil {
		panic(err)
	}
	fmt.Println(resp.Status, string(data))
}
require "json"
require "net/http"

uri = URI("https://domscan.net/v1/typos/threats?domain=example.com&limit=25&include_tld_swap=true")
request = Net::HTTP::Get.new(uri)
request["X-API-Key"] = ENV.fetch("DOMSCAN_API_KEY")

response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
  http.request(request)
end
puts JSON.pretty_generate(JSON.parse(response.body))

Respuesta de ejemplo

{
  "domain": "example.com",
  "name": "example",
  "tld": "com",
  "scan_summary": {
    "permutations_generated": 109,
    "permutations_checked": 75,
    "permutations_submitted": 75,
    "definitive_results": 71,
    "unknown_results": 4,
    "omitted_results": 0,
    "registered_count": 2,
    "active_threats": 2,
    "available_for_defensive": 69,
    "check_limit": 75,
    "coverage_truncated": true
  },
  "threat_level": "high",
  "protection_score": {
    "score": 2,
    "grade": "F",
    "interpretation": {
      "score_meaning": "Higher score = less vulnerable to typosquatting attacks",
      "factors": "Domain length, homoglyph-susceptible characters, keyboard adjacency, TLD popularity, registered typosquats",
      "note": "Short, well-known domains score lower because they have a larger inherent attack surface for typosquatting, not because they lack brand protection measures."
    },
    "vulnerabilities": [
      {
        "category": "homoglyph",
        "count": 4,
        "risk": "critical",
        "description": "Contains 4 characters with visual lookalikes (e, a, l)"
      },
      {
        "category": "keyboard",
        "count": 5,
        "risk": "high",
        "description": "5 characters have many keyboard neighbors"
      },
      {
        "category": "tld",
        "count": 1,
        "risk": "medium",
        "description": ".com is a high-value TLD commonly targeted by typosquatters"
      },
      {
        "category": "registered_high",
        "count": 1,
        "risk": "high",
        "description": "1 high-risk typosquat domains are registered"
      }
    ],
    "recommendations": [
      "Consider defensive registrations for common homoglyph variants",
      "Consider registering example on alternative TLDs like .net, .org"
    ],
    "factors": {
      "length_factor": 90,
      "homoglyph_factor": 68,
      "keyboard_factor": 75,
      "tld_factor": 80
    }
  },
  "threats": [
    {
      "domain": "xeample.com",
      "type": "transposition",
      "risk": "high",
      "description": "Swapped 'e' and 'x'",
      "dns_active": true,
      "has_website": true,
      "has_mx": false,
      "infrastructure": {
        "nameservers": []
      },
      "threat_indicators": [
        "Active DNS configuration",
        "Domain resolves to IP (potential website)"
      ],
      "threat_score": 75
    },
    {
      "domain": "example.net",
      "type": "tld-swap",
      "risk": "medium",
      "description": "TLD changed from .com to .net",
      "dns_active": true,
      "has_website": false,
      "has_mx": false,
      "infrastructure": {
        "nameservers": []
      },
      "threat_indicators": [
        "Active DNS configuration"
      ],
      "threat_score": 40
    }
  ],
  "defensive_opportunities": [
    {
      "domain": "3xample.com",
      "type": "homoglyph",
      "risk": "critical"
    },
    {
      "domain": "ex4mple.com",
      "type": "homoglyph",
      "risk": "critical"
    },
    {
      "domain": "eaxmple.com",
      "type": "transposition",
      "risk": "high"
    }
  ],
  "risk_breakdown": {
    "critical": [],
    "high": [
      {
        "domain": "xeample.com",
        "name": "xeample",
        "tld": "com",
        "type": "transposition",
        "risk": "high",
        "description": "Swapped 'e' and 'x'",
        "registered": true,
        "checked_at": "2026-10-09T10:15:29.000Z",
        "dns_active": true,
        "has_website": true,
        "has_mx": false,
        "infrastructure": {
          "nameservers": []
        },
        "threat_indicators": [
          "Active DNS configuration",
          "Domain resolves to IP (potential website)"
        ],
        "threat_score": 75
      }
    ],
    "medium": [
      {
        "domain": "example.net",
        "name": "example",
        "tld": "net",
        "type": "tld-swap",
        "risk": "medium",
        "description": "TLD changed from .com to .net",
        "registered": true,
        "checked_at": "2026-10-09T10:15:29.000Z",
        "dns_active": true,
        "has_website": false,
        "has_mx": false,
        "infrastructure": {
          "nameservers": []
        },
        "threat_indicators": [
          "Active DNS configuration"
        ],
        "threat_score": 40
      }
    ],
    "low": []
  },
  "recommendations": [
    "2 registered typosquat domains have active DNS/websites. Monitor for phishing or brand abuse.",
    "18 high-risk typosquat domains are available. Consider defensive registration to protect your brand.",
    "Your domain has significant typosquatting vulnerability. Set up continuous monitoring for new registrations."
  ],
  "checked_at": "2026-10-09T10:15:30.000Z",
  "scan_duration_ms": 4120,
  "meta": {
    "served_by": "pop=MAD country=ES"
  }
}

Códigos de estado HTTP

  • 200 OK
  • 400 Solicitud incorrecta
  • 401 No autorizado
  • 402 Pago requerido
  • 429 Demasiadas solicitudes
  • 500 Error del servidor
GET /v1/typos/report Créditos: 18

Parámetros de consulta

Parámetro Tipo obligatorio
domain string obligatorio

Campos de respuesta

Campo Tipo
domain string
generated_at string
executive_summary object
executive_summary.threat_level string
executive_summary.protection_grade string
executive_summary.active_threats integer
executive_summary.registered_typos integer
executive_summary.immediate_action_required boolean
threat_analysis object
threat_analysis.domain string
threat_analysis.name string
threat_analysis.tld string
threat_analysis.scan_summary object
threat_analysis.scan_summary.permutations_generated integer
threat_analysis.scan_summary.permutations_checked integer
threat_analysis.scan_summary.permutations_submitted integer
threat_analysis.scan_summary.definitive_results integer
threat_analysis.scan_summary.unknown_results integer
threat_analysis.scan_summary.omitted_results integer
threat_analysis.scan_summary.registered_count integer
threat_analysis.scan_summary.active_threats integer
threat_analysis.scan_summary.available_for_defensive integer
threat_analysis.scan_summary.check_limit integer
threat_analysis.scan_summary.coverage_truncated boolean
threat_analysis.threat_level string
threat_analysis.protection_score object
threat_analysis.protection_score.score integer
threat_analysis.protection_score.grade string
threat_analysis.protection_score.interpretation object
threat_analysis.protection_score.interpretation.score_meaning string
threat_analysis.protection_score.interpretation.factors string
threat_analysis.protection_score.interpretation.note string
threat_analysis.protection_score.vulnerabilities[] object[]
threat_analysis.protection_score.vulnerabilities[] object
threat_analysis.protection_score.vulnerabilities[].category string
threat_analysis.protection_score.vulnerabilities[].count integer
threat_analysis.protection_score.vulnerabilities[].risk string
threat_analysis.protection_score.vulnerabilities[].description string
threat_analysis.protection_score.recommendations[] string[]
threat_analysis.protection_score.factors object
threat_analysis.protection_score.factors.length_factor integer
threat_analysis.protection_score.factors.homoglyph_factor integer
threat_analysis.protection_score.factors.keyboard_factor integer
threat_analysis.protection_score.factors.tld_factor integer
threat_analysis.threats[] object[]
threat_analysis.threats[] object
threat_analysis.threats[].classification object
threat_analysis.threats[].classification.status string
threat_analysis.threats[].classification.reason string
threat_analysis.threats[].classification.evidence object
threat_analysis.threats[].classification.evidence.source string
threat_analysis.threats[].classification.evidence.method string
threat_analysis.threats[].classification.evidence.observed_at string
threat_analysis.threats[].classification.evidence.detail string
threat_analysis.threats[].classification.checked_at string
threat_analysis.threats[].domain string
threat_analysis.threats[].name string
threat_analysis.threats[].tld string
threat_analysis.threats[].type string
threat_analysis.threats[].risk string
threat_analysis.threats[].description string
threat_analysis.threats[].registered boolean
threat_analysis.threats[].checked_at string
threat_analysis.threats[].dns_active boolean
threat_analysis.threats[].has_website boolean
threat_analysis.threats[].has_mx boolean
threat_analysis.threats[].infrastructure object
threat_analysis.threats[].threat_indicators[] string[]
threat_analysis.threats[].threat_score integer
threat_analysis.defensive_opportunities[] object[]
threat_analysis.defensive_opportunities[] object
threat_analysis.defensive_opportunities[].domain string
threat_analysis.defensive_opportunities[].name string
threat_analysis.defensive_opportunities[].tld string
threat_analysis.defensive_opportunities[].type string
threat_analysis.defensive_opportunities[].risk string
threat_analysis.defensive_opportunities[].description string
threat_analysis.risk_breakdown object
threat_analysis.recommendations[] string[]
threat_analysis.checked_at string
threat_analysis.scan_duration_ms integer
threat_analysis.meta object
threat_analysis.meta.served_by string
defensive_registration_priority object
monitoring_recommendations[] string[]
estimated_risk_exposure string
meta object
meta.served_by string
meta.report_duration_ms integer

Solicitud de ejemplo

curl -H "X-API-Key: $DOMSCAN_API_KEY" "https://domscan.net/v1/typos/report?domain=example.com"
const response = await fetch("https://domscan.net/v1/typos/report?domain=example.com", {
  headers: { "X-API-Key": process.env.DOMSCAN_API_KEY },
});
const data = await response.json();
console.log(data);
import os
import requests

response = requests.get(
    "https://domscan.net/v1/typos/report?domain=example.com",
    headers={"X-API-Key": os.environ["DOMSCAN_API_KEY"]},
)
print(response.json())
package main

import (
	"fmt"
	"io"
	"net/http"
	"os"
)

func main() {
	req, err := http.NewRequest(http.MethodGet, "https://domscan.net/v1/typos/report?domain=example.com", nil)
	if err != nil {
		panic(err)
	}
	req.Header.Set("X-API-Key", os.Getenv("DOMSCAN_API_KEY"))

	resp, err := http.DefaultClient.Do(req)
	if err != nil {
		panic(err)
	}
	defer resp.Body.Close()

	data, err := io.ReadAll(resp.Body)
	if err != nil {
		panic(err)
	}
	fmt.Println(resp.Status, string(data))
}
require "json"
require "net/http"

uri = URI("https://domscan.net/v1/typos/report?domain=example.com")
request = Net::HTTP::Get.new(uri)
request["X-API-Key"] = ENV.fetch("DOMSCAN_API_KEY")

response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
  http.request(request)
end
puts JSON.pretty_generate(JSON.parse(response.body))

Respuesta de ejemplo

{
  "domain": "example.com",
  "generated_at": "2026-08-27T12:00:00Z",
  "executive_summary": {
    "threat_level": "example",
    "protection_grade": "example",
    "active_threats": 1,
    "registered_typos": 1,
    "immediate_action_required": false
  },
  "threat_analysis": {
    "domain": "example.com",
    "scan_summary": {
      "permutations_generated": 1,
      "permutations_checked": 1,
      "registered_count": 1,
      "active_threats": 1,
      "available_for_defensive": 1,
      "permutations_submitted": 1,
      "definitive_results": 1,
      "unknown_results": 1,
      "omitted_results": 1,
      "check_limit": 1,
      "coverage_truncated": false
    },
    "threat_level": "none",
    "threats": [
      {
        "domain": "example.com",
        "type": "domain",
        "risk": "critical",
        "dns_active": true,
        "has_website": false,
        "threat_indicators": [
          "example"
        ],
        "threat_score": 85,
        "classification": {
          "status": "present",
          "evidence": {
            "source": "rdap",
            "method": "rdap_lookup",
            "observed_at": "2026-08-27T12:00:00Z",
            "detail": "example"
          },
          "checked_at": "2026-08-27T12:00:00Z",
          "reason": "blocked"
        },
        "name": "example",
        "tld": "com",
        "description": "example",
        "registered": false,
        "checked_at": "2026-08-27T12:00:00Z",
        "has_mx": false,
        "infrastructure": {}
      }
    ],
    "checked_at": "2026-08-27T12:00:00Z",
    "name": "example",
    "tld": "com",
    "protection_score": {
      "score": 85,
      "grade": "A",
      "interpretation": {
        "score_meaning": "example",
        "factors": "example",
        "note": "example"
      },
      "vulnerabilities": [
        {
          "category": "example",
          "count": 1,
          "risk": "critical",
          "description": "example"
        }
      ],
      "recommendations": [
        "example"
      ],
      "factors": {
        "length_factor": 1,
        "homoglyph_factor": 1,
        "keyboard_factor": 1,
        "tld_factor": 1
      }
    },
    "defensive_opportunities": [
      {
        "domain": "example.com",
        "name": "example",
        "tld": "com",
        "type": "omission",
        "risk": "critical",
        "description": "example"
      }
    ],
    "risk_breakdown": {},
    "recommendations": [
      "example"
    ],
    "scan_duration_ms": 1,
    "meta": {
      "served_by": "example"
    }
  },
  "estimated_risk_exposure": "minimal",
  "defensive_registration_priority": {},
  "monitoring_recommendations": [
    "example"
  ],
  "meta": {
    "served_by": "example",
    "report_duration_ms": 1
  }
}

Códigos de estado HTTP

  • 200 OK
  • 400 Solicitud incorrecta
  • 401 No autorizado
  • 402 Pago requerido
  • 429 Demasiadas solicitudes
  • 500 Error del servidor
GET /v1/typos/quick Créditos: 6

Parámetros de consulta

Parámetro Tipo obligatorio
domain string obligatorio
limit integer
Predeterminado 100
opcional

Campos de respuesta

Campo Tipo
domain string
registered_typos[] object[]
registered_typos[] object
registered_typos[].domain string
registered_typos[].type string
registered_typos[].risk string
registered_typos[].description string
registered_typos[].classification object
registered_typos[].classification.status string
registered_typos[].classification.reason string
registered_typos[].classification.evidence object
registered_typos[].classification.evidence.source string
registered_typos[].classification.evidence.method string
registered_typos[].classification.evidence.observed_at string
registered_typos[].classification.evidence.detail string
registered_typos[].classification.checked_at string
count integer
threat_level string
coverage object
coverage.requested integer
coverage.definitive integer
coverage.unknown integer
coverage.omitted integer
checked_at string
scan_duration_ms integer
meta object
meta.served_by string

Solicitud de ejemplo

curl -H "X-API-Key: $DOMSCAN_API_KEY" "https://domscan.net/v1/typos/quick?domain=example.com&limit=25"
const response = await fetch("https://domscan.net/v1/typos/quick?domain=example.com&limit=25", {
  headers: { "X-API-Key": process.env.DOMSCAN_API_KEY },
});
const data = await response.json();
console.log(data);
import os
import requests

response = requests.get(
    "https://domscan.net/v1/typos/quick?domain=example.com&limit=25",
    headers={"X-API-Key": os.environ["DOMSCAN_API_KEY"]},
)
print(response.json())
package main

import (
	"fmt"
	"io"
	"net/http"
	"os"
)

func main() {
	req, err := http.NewRequest(http.MethodGet, "https://domscan.net/v1/typos/quick?domain=example.com&limit=25", nil)
	if err != nil {
		panic(err)
	}
	req.Header.Set("X-API-Key", os.Getenv("DOMSCAN_API_KEY"))

	resp, err := http.DefaultClient.Do(req)
	if err != nil {
		panic(err)
	}
	defer resp.Body.Close()

	data, err := io.ReadAll(resp.Body)
	if err != nil {
		panic(err)
	}
	fmt.Println(resp.Status, string(data))
}
require "json"
require "net/http"

uri = URI("https://domscan.net/v1/typos/quick?domain=example.com&limit=25")
request = Net::HTTP::Get.new(uri)
request["X-API-Key"] = ENV.fetch("DOMSCAN_API_KEY")

response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
  http.request(request)
end
puts JSON.pretty_generate(JSON.parse(response.body))

Respuesta de ejemplo

{
  "domain": "example.com",
  "registered_typos": [
    {
      "domain": "xeample.com",
      "type": "transposition",
      "risk": "high",
      "description": "Swapped 'e' and 'x'"
    },
    {
      "domain": "example.net",
      "type": "tld-swap",
      "risk": "medium",
      "description": "TLD changed from .com to .net"
    }
  ],
  "count": 2,
  "threat_level": "high",
  "coverage": {
    "requested": 98,
    "definitive": 92,
    "unknown": 6,
    "omitted": 0
  },
  "checked_at": "2026-10-09T10:15:30.000Z",
  "scan_duration_ms": 2840,
  "meta": {
    "served_by": "pop=MAD country=ES"
  }
}

Códigos de estado HTTP

  • 200 OK
  • 400 Solicitud incorrecta
  • 401 No autorizado
  • 402 Pago requerido
  • 429 Demasiadas solicitudes
  • 500 Error del servidor
GET /v1/idn Créditos: 1

Parámetros de consulta

Parámetro Tipo obligatorio
domain string obligatorio

Campos de respuesta

Campo Tipo
input string
outcome string
unicode string
ascii string
is_idn boolean
valid boolean
errors[] string[]
labels[] object[]
labels[] object
labels[].unicode string
labels[].ascii string
labels[].is_idn boolean
labels[].scripts[] string[]
labels[].mixed_script boolean
labels[].has_invisible boolean
labels[].confusable_characters[] object[]
labels[].confusable_characters[] object
labels[].confusable_characters[].char string
labels[].confusable_characters[].codepoint string
labels[].confusable_characters[].script string
labels[].confusable_characters[].looks_like string
skeleton string
risk object
risk.level string
risk.reasons[] string[]
tld object
tld.label string
tld.ascii string
tld.is_idn boolean
checked_at string
caveats[] string[]

Solicitud de ejemplo

curl -H "X-API-Key: $DOMSCAN_API_KEY" "https://domscan.net/v1/idn?domain=xn--80ak6aa92e.com"
const response = await fetch("https://domscan.net/v1/idn?domain=xn--80ak6aa92e.com", {
  headers: { "X-API-Key": process.env.DOMSCAN_API_KEY },
});
const data = await response.json();
console.log(data);
import os
import requests

response = requests.get(
    "https://domscan.net/v1/idn?domain=xn--80ak6aa92e.com",
    headers={"X-API-Key": os.environ["DOMSCAN_API_KEY"]},
)
print(response.json())
package main

import (
	"fmt"
	"io"
	"net/http"
	"os"
)

func main() {
	req, err := http.NewRequest(http.MethodGet, "https://domscan.net/v1/idn?domain=xn--80ak6aa92e.com", nil)
	if err != nil {
		panic(err)
	}
	req.Header.Set("X-API-Key", os.Getenv("DOMSCAN_API_KEY"))

	resp, err := http.DefaultClient.Do(req)
	if err != nil {
		panic(err)
	}
	defer resp.Body.Close()

	data, err := io.ReadAll(resp.Body)
	if err != nil {
		panic(err)
	}
	fmt.Println(resp.Status, string(data))
}
require "json"
require "net/http"

uri = URI("https://domscan.net/v1/idn?domain=xn--80ak6aa92e.com")
request = Net::HTTP::Get.new(uri)
request["X-API-Key"] = ENV.fetch("DOMSCAN_API_KEY")

response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
  http.request(request)
end
puts JSON.pretty_generate(JSON.parse(response.body))

Respuesta de ejemplo

{
  "input": "xn--80ak6aa92e.com",
  "outcome": "analyzed",
  "unicode": "аррӏе.com",
  "ascii": "xn--80ak6aa92e.com",
  "is_idn": true,
  "valid": true,
  "errors": [],
  "labels": [
    {
      "unicode": "аррӏе",
      "ascii": "xn--80ak6aa92e",
      "is_idn": true,
      "scripts": [
        "Cyrillic"
      ],
      "mixed_script": false,
      "has_invisible": false,
      "confusable_characters": [
        {
          "char": "а",
          "codepoint": "U+0430",
          "script": "Cyrillic",
          "looks_like": "a"
        },
        {
          "char": "р",
          "codepoint": "U+0440",
          "script": "Cyrillic",
          "looks_like": "p"
        },
        {
          "char": "р",
          "codepoint": "U+0440",
          "script": "Cyrillic",
          "looks_like": "p"
        },
        {
          "char": "ӏ",
          "codepoint": "U+04CF",
          "script": "Cyrillic",
          "looks_like": "l"
        },
        {
          "char": "е",
          "codepoint": "U+0435",
          "script": "Cyrillic",
          "looks_like": "e"
        }
      ]
    },
    {
      "unicode": "com",
      "ascii": "com",
      "is_idn": false,
      "scripts": [
        "Latin"
      ],
      "mixed_script": false,
      "has_invisible": false,
      "confusable_characters": []
    }
  ],
  "skeleton": "apple.com",
  "risk": {
    "level": "high",
    "reasons": [
      "whole_script_confusable",
      "idn_label"
    ]
  },
  "tld": {
    "label": "com",
    "ascii": "com",
    "is_idn": false
  },
  "checked_at": "2026-10-09T10:15:30.000Z",
  "caveats": [
    "partial_confusable_table"
  ]
}

Códigos de estado HTTP

  • 200 OK
  • 400 Solicitud incorrecta
  • 401 No autorizado
  • 402 Pago requerido
  • 429 Demasiadas solicitudes