Référence développeur
Détection de Typosquattage
API DomScan : Détectez les menaces de typosquattage et les domaines similaires qui pourraient être utilisés pour l'hameçonnage ou l'abus de marque.
Détection de Typosquattage
Détectez les menaces de typosquattage et les domaines similaires qui pourraient être utilisés pour l'hameçonnage ou l'abus de marque.
GET
/v1/typos
Paramètres de requête
| Paramètre | Type | Description |
|---|---|---|
| domain requis | string | Domaine à vérifier pour les variantes de typosquattage |
| limit optionnel | number | Max de permutations à vérifier (par défaut : 50) |
| check_registered optionnel |
boolean token
Valeurs autorisées
1true
Défaut
false
|
Vérifie quelles permutations sont déjà enregistrées, jusqu'à 50 domaines. Désactivé par défaut car il ajoute des recherches externes. |
Exemple de réponse
{
"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
}
}
Champs de réponse
| Champ | Type |
|---|---|
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édits: 12
Paramètres de requête
| Paramètre | Type | requis |
|---|---|---|
| domain | string | requis |
| limit |
integer
Défaut
200
|
optionnel |
| include_tld_swap |
boolean
Défaut
true
|
optionnel |
Champs de réponse
| Champ | Type |
|---|---|
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 |
Exemple de requête
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))Exemple de réponse
{
"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"
}
}
Codes de statut HTTP
200OK400Requête incorrecte401Non autorisé402Paiement requis429Trop de requêtes500Erreur serveur
GET
/v1/typos/report
Crédits: 18
Paramètres de requête
| Paramètre | Type | requis |
|---|---|---|
| domain | string | requis |
Champs de réponse
| Champ | Type |
|---|---|
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 |
Exemple de requête
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))Exemple de réponse
{
"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
}
}
Codes de statut HTTP
200OK400Requête incorrecte401Non autorisé402Paiement requis429Trop de requêtes500Erreur serveur
GET
/v1/typos/quick
Crédits: 6
Paramètres de requête
| Paramètre | Type | requis |
|---|---|---|
| domain | string | requis |
| limit |
integer
Défaut
100
|
optionnel |
Champs de réponse
| Champ | Type |
|---|---|
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 |
Exemple de requête
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))Exemple de réponse
{
"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"
}
}
Codes de statut HTTP
200OK400Requête incorrecte401Non autorisé402Paiement requis429Trop de requêtes500Erreur serveur
GET
/v1/idn
Crédits: 1
Paramètres de requête
| Paramètre | Type | requis |
|---|---|---|
| domain | string | requis |
Champs de réponse
| Champ | Type |
|---|---|
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[] |
Exemple de requête
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))Exemple de réponse
{
"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"
]
}
Codes de statut HTTP
200OK400Requête incorrecte401Non autorisé402Paiement requis429Trop de requêtes