This page is available in English. Switch to English

Lo stesso motore,
dentro la tua app.

Un endpoint per servizio, una chiamata, la risposta documentata campo per campo: verifica contatto, deduplica, email, telefono, sito, codice fiscale, autocomplete. Singolo o a lotti; per i file grossi il lavoro va in coda e lo ritiri quando è pronto.

Specifica OpenAPI: openapi.json, per generare il client o importarla nel tuo strumento.

Un endpoint per servizio, con lo stesso nome che il servizio ha qui dentro: /contact, /dedupe, /email, /phone, /website, /tax-code, /enrichment. Ognuno accetta un elemento nel corpo della richiesta oppure una lista in items, fino a 500 per chiamata (100 per i siti, che vanno contattati uno a uno). La deduplica fa eccezione e vuole sempre una lista: confronta le anagrafiche fra loro. A parte stanno /suggest, l'autocomplete per i form (lavora a sessione mentre l'utente digita, non a lotti), e /credit, che dice quante elaborazioni restano e in che stato è ogni contatore, senza consumarne.

Autenticazione

L'host dell'API è www.radaraddress.com. I nomi dei campi, degli endpoint e dei valori sono identificativi inglesi, uguali in ogni lingua; le etichette, i motivi e i messaggi seguono la lingua della richiesta ("language": "de" o ?language=de, oppure l'header Accept-Language, oppure la lingua dell'account). L'header Content-Language dice in che lingua è arrivata la risposta.

L'accesso alle API avviene tramite token Bearer. L'account è gratuito: crei il token dall'area personale e lo includi nell'header di ogni richiesta nel formato:

# Every request needs the Authorization header
Authorization: Bearer {your-token}

Alla creazione puoi dare al token una scadenza facoltativa: passata quella data le richieste ricevono HTTP 401 con codice token_expired; senza scadenza il token vale finché non lo revochi. Puoi revocarlo o rigenerarlo in qualsiasi momento dalla tua area personale, dove vedi anche ultimo uso e numero di richieste servite. Una richiesta senza token o con token non valido restituisce HTTP 401.

I nomi italiani, per chi li usa già

L'API ha una versione sola, in inglese. Chi integrava con i nomi italiani non deve cambiare niente: i campi italiani sono accettati in ogni richiesta, gli endpoint rispondono anche col nome italiano (/contatto, /deduplica, /codicefiscale, /arricchimento, /telefono, /sito, /suggerisci, /nazioni, /credito), e la risposta esce con le chiavi e i codici italiani a chi lo chiede con "language": "it" o chiama www.radaraddress.it senza indicare la lingua.

La tabella completa dei campi: inglese → italiano
ingleseitalianoingleseitaliano
accountaccount membersmembri
actionazione methodmetodo
activated_onattivato_il metricmetrico
activeattiva min_levellivello_minimo
active_packsattivi missingmancano
addressindirizzo modifiedmodificati
address_keyindirizzo_confronto monthmese
addressesindirizzi monthly_cap_eurtetto_mese_eur
afterdopo multiple_postcodesmulticap
ageeta municipalitycomune
agreementconsenso municipality_codecomune_codice
ambiguous_yearanno_ambiguo municipality_code_typecomune_codice_tipo
areaarea n_recordsn_anagrafiche
asyncasincrono name_idnome_id
auto_topupauto_ricarica name_originalnome_originale
availabledisponibile national_numbernazionale
beforeprima nearbyvicino
belfiore_codecodice_belfiore needednecessarie
birth_countrynazione_nascita needs_topupda_ricaricare
birth_datedata_nascita networkrete
birth_placecomune_nascita normalizednormalizzato
birth_place_nameluogo_nascita normalized_postalnormalizzato_postale
birth_provinceprovincia_nascita not_foundnon_trovati
born_abroadnato_estero notenota
boughtcomprati notesnote
buildingedificio numbernumero
cadastral_codecatastale numbersnumeri
canonical_addressindirizzo_canonico occurrencesoccorrenze
canonical_citylocalita_canonica operationselaborazioni
care_ofpresso operatoroperatore
certificate_okcertificato_ok originorigine
changedmodificato otheraltro
changesmodifiche outcomeesito
chargedconsumate outcome_labelesito_label
checkcontrolla outcomesesiti
check_digitcontrollo overall_cap_eurtetto_globale_eur
citylocalita packspacchetti
city_keylocalita_confronto parsedletto
city_passescicli_localita phasefase
city_typelocalita_tipo phonetelefono
classclasse phone2telefono2
codecodice phone3telefono3
colourcolore phonestelefoni
commentscommenti placeluogo
conditionscondizioni positionposizione
confidenceconfidenza postcodecap
confirmedconfermato postcode_checkcap_verifica
consolidateconsolida precisionprecisione
contactcontatto preserve_originalpreserva_originale
contact_personreferente presumedpresunto
corrected_fromcorretta_da processedlavorato
countercontatore processed_atdatalav
counterscontatori professionqualifica
countriesnazioni provenanceprovenienza
countrynazione provinceprovincia
country_codenazione_iso2 provincial_capitalcapoluogo
country_originalnazione_originale reachableraggiungibile
country_prefixprefisso_paese reasonmotivo
createdcreato record_outcomeesito_record
creditcredito recordsanagrafiche
dedupededuplica redirectsredirect
detaildettaglio referenceriferimento
differencesdifferenze reference_idriferimento_id
discardedscartati remainingrimaste
disposableusa_e_getta renews_onsi_rinnova_il
districtquartiere reset_onsi_azzerano_il
domain_checkeddominio_verificato rowsrighe
domain_existsdominio_esiste salutationsaluto
donefatte savesalva
duration_msdurata_ms segment_passescicli_arcostradale
e164formato_e164 sessionsessione
educationtitolo_studio shortbreve
entriesschede singlessingoli
errorerrore sizetaglia
existsesiste sourcefonte
expiryscadenza specificityspecificita
explanationsspiegazioni spent_month_eurspeso_mese_eur
extensionestensione spent_overall_month_eurspeso_globale_mese_eur
fieldcampo statestato
final_urlurl_finale statesstati
first_namenome streetstrada
foreignesteri street_idvia_id
foreign_addressestero street_nametoponimo
formal_salutationsaluto_formale street_passescicli_toponimo
formatformato street_proper_nameduf
foundtrovato street_typedug
freegratuite sub_addresssubindirizzo
free_forevergratis_per_sempre sub_address_confirmedsubindirizzo_confermato
full_namenominativo subject_typetipo_soggetto
gendersesso subscriptionabbonamento
gender_sourcefonte_sesso suffixesponente
genericgenerica suggestionsuggerimento
groupgruppo summaryriepilogo
groupsgruppi supportedsupportato
hamletfrazione syntaxsintassi
hintssuggerimenti tax_codecodice_fiscale
homocodeomocodo tax_code_outcomecodice_fiscale_esito
house_numbercivico territoryterritorio
house_number_labelcivico_label texttesto
house_number_verifiedcivico_verificato time_mstempo_ms
house_numberscivici titletitolo
informal_salutationsaluto_informale to_checkda_controllare
iso2codice_iso2 totaltotali
iso3codice_iso3 towncitta
istat_codeistat truncatedtroncato
itemselementi typetipo
joblavoro type_normalizedtipo_norm
languagelingua typestipi
languageslingue unresolvednon_risolti
last_namecognome url_normalizedurl_normalizzato
last_onultimo_il usedusate
last_usedultimo_uso validvalida
leftresiduo valuevalore
legacy_defaultdefault_storico warningavviso
levellivello warningsavvisi
lightleggere websitesito
longlungo website2sito2
long_namenome_esteso website3sito3
main_recordprincipale websitessiti
matchcorrisponde zonedzonato
matchesabbinamenti

Anche i valori delle opzioni hanno il nome italiano: format nazionale/internazionale, action genera/valida/estrai/confronta/seleziona, foreign dichiarati/rileva, min_level certo/probabile/ambiguo; con "language": "it" escono così anche level, confidence, state, i codici di outcome e le intestazioni dei file. In ingresso sono accettati anche sinonimi comuni (zip, surname, phone_number, date_of_birth…) e le stesse intestazioni nei file dei lavori in blocco.

Endpoint verifica contatto

POST /api/v1/contact

Sistema il contatto intero: indirizzo secondo lo standard postale della sua nazione — in Italia e nelle nazioni col registro in servizio via e civico sono verificati nel registro nazionale degli indirizzi, nelle altre l'indirizzo esce nella forma postale del paese —, nominativo e — se la richiesta lo porta — il codice fiscale, che viene ripulito, completato se manca il solo carattere di controllo e confrontato con cognome, nome, sesso e data di nascita. Un contatto per volta, oppure fino a 500 in items: lo schema è lo stesso di tutti gli altri endpoint.

La nazione si indica con country_code (ISO 3166-1: IT, DE, FR…) oppure con country, scritto come capita: «Germania», «Germany», «Deutschland», «Repubblica federale di Germania», «UK», «Olanda». Se manca si presume Italia. Nelle nazioni col registro in servizio — oggi Francia, Germania, Spagna, Paesi Bassi, Belgio, Finlandia, Cechia, Portogallo, Danimarca, Norvegia, Austria, Svizzera, Slovacchia, Croazia, Romania, Ungheria, Slovenia, Irlanda, Islanda, Lussemburgo, Liechtenstein, San Marino, Monaco, Andorra, Città del Vaticano, l'elenco aggiornato è in Nazioni — via e civico vengono verificati nel registro nazionale degli indirizzi come in Italia: codice postale confermato o completato, coordinate del civico in geo, quartiere o arrondissement in district dove la città ne ha (Hamburg-Altstadt, Paris 4e Arrondissement), codice del comune in territory.municipality_code. Con la lingua italiana l'esito porta FOREIGN seguito dalle modifiche, nelle altre lingue solo le modifiche; se la via c'è e il numero no, HOUSE_NUMBER_NOT_FOUND. Nelle altre nazioni lavoriamo sulla forma, e il messaggio lo dice: codice postale nel formato del paese, abbreviazioni della via sciolte, maiuscole e nome della città come li scrive la posta di quella nazione (Hauptstr. 5, Monaco di Baviera → Hauptstraße 5, MÜNCHEN), con la riga della nazione. In entrambi i casi torna address_key, la forma con cui la deduplica riconosce la stessa via scritta in due modi. Con "foreign": "detect" un record senza nazione che non risulta in Italia viene riconosciuto come estero quando il testo lo dice chiaramente; il default declared lascia estero solo chi lo dice. Il catalogo completo delle nazioni, con nome breve e ufficiale, inglese e nella lingua della nazione, è disponibile con GET /api/v1/countries e si può interrogare con ?q=Germania, ?q=Deutschland o ?q=DE.

curl -X POST https://www.radaraddress.com/api/v1/contact \
  -H 'Authorization: Bearer YOUR_TOKEN' \
  -H 'Content-Type: application/json' \
  -d '{"address":"via leopardi 4","postcode":"20100","city":"milano","province":"mi","id":"RIF-001"}'

Per il lotto, gli stessi campi dentro items; la risposta è { count, results: [ { id, result } ] } nello stesso ordine dell'invio.

curl -X POST https://www.radaraddress.com/api/v1/contact \
  -H 'Authorization: Bearer YOUR_TOKEN' \
  -H 'Content-Type: application/json' \
  -d '{"items":[{"id":"1","address":"via leopardi 4","city":"milano"},
                   {"id":"2","address":"via roma 1","postcode":"20121","tax_code":"RSSMRA85M01H501Q"}]}'

Lo stesso endpoint per un indirizzo di un'altra nazione: basta country_code. Qui Amburgo, verificata nel registro tedesco, col quartiere e le coordinate del civico.

curl -X POST https://www.radaraddress.com/api/v1/contact \
  -H 'Authorization: Bearer YOUR_TOKEN' \
  -H 'Content-Type: application/json' \
  -d '{"address":"Mönckebergstr. 7","postcode":"20095","city":"Hamburg","country_code":"DE"}'
→ { "outcome": "FOREIGN MODIFIED CITY_FORM STREET_FORM",
  "normalized": { "address": "Mönckebergstraße 7", "postcode": "20095", "city": "HAMBURG", "country": "Germany", "country_code": "DE" },
  "municipality": "Hamburg", "district": "Hamburg-Altstadt", "address_key": "MONCKEBERGSTRASSE",
  "geo": { "lat": 53.5512437, "lon": 10.0028651, "precision": "house_number", "source": "inspire" },
  "territory": { "country": "DE", "municipality_code": "AdminUnitName_49021011010101", "municipality_code_type": "inspire" } }

Opzioni valide per l'intera chiamata: postal_form (forza anche normalized nella forma postale), preserve_original (tiene il nome scritto dall'utente ed espone il canonico a parte), precision 1–5 (default 3; oltre 3 il match è approssimato e l'affidabilità non sarà high).

Insieme all'indirizzo torna city_type, che dice se il recapito è in un capoluogo di provincia o in un comune della provincia — la differenza che serve a chi taglia una campagna per città. provincial_capital è true, false oppure null quando non abbiamo elementi per dirlo — e in quel caso non tiriamo a indovinare.

→ { "city_type": { "provincial_capital": true, "label": "Provincial capital" } }

Accanto al CAP torna postcode_check: da dove viene (source) e con che precisione (precision: house_number il numero stesso, interpolated i numeri vicini della stessa via, street la maggioranza della via, locality, municipality), quanti civici lo dicono (house_numbers) e con che accordo (agreement, da 0 a 1). Quando manca un riscontro per quel numero l'esito porta POSTCODE_UNCONFIRMED e confirmed è false: il CAP resta quello indicato, se è fra quelli della città, e va controllato.

→ { "postcode_check": { "source": "osm", "precision": "house_number", "house_numbers": 3, "agreement": 1, "confirmed": true } }

Tornano anche le coordinate in geo (latitudine e longitudine WGS84) e gli identificativi territoriali in territory: in Italia codice ISTAT e codice catastale del comune, CAB e identificativo nazionale della via; nelle altre nazioni country e il codice del comune nel registro nazionale (municipality_code). Il campo precision dice a che livello siamo arrivati: house_number quando il numero è georeferenziato, interpolated quando il numero esatto manca e il punto è stimato, street quando abbiamo il punto della strada, municipality quando abbiamo solo il centro del comune. source dice da dove viene il punto: anncsu è il registro nazionale italiano, inspire il registro nazionale della nazione, osm OpenStreetMap: in quel caso i dati sono © OpenStreetMap contributors, licenza ODbL, e l'attribuzione va riportata se li pubblichi. Dove il registro di una nazione impone un'attribuzione, esce nel messaggio. Nel CSV dei lavori in blocco sono le colonne latitude, longitude, geo_precision, istat_code e cadastral_code.

→ { "geo": { "lat": 45.4762711, "lon": 9.207104, "precision": "house_number", "source": "anncsu" },
  "territory": { "istat_code": "015146", "cadastral_code": "F205", "cab": "01600", "street_id": "1026700" } }

Piano, scala e interno scritti nell'indirizzo tornano anche come dato a sé in sub_address: un elenco di coppie type e value, lette con le regole postali della nazione (in Germania dopo «//», in Francia su una riga a sé, in Portogallo «3º Esq»). I tipi sono unit (interno), staircase (scala), floor (piano), block (palazzina), building (edificio), building_number (palazzo) e block_number (isolato). La riga dell'indirizzo resta nella forma della nazione. Quello che non riconosciamo resta scritto com'era e non entra nell'elenco: non lo indoviniamo. Quando l'unità indicata risulta a quel civico, sub_address_confirmed è true; altrimenti è null, mai false: non trovarla non vuol dire che sia sbagliata.

→ { "sub_address": [ { "type": "floor", "value": "3" }, { "type": "unit", "value": "ESQ" } ], "sub_address_confirmed": true }

Endpoint deduplica

POST /api/v1/dedupe

Riconosce i record riferiti alla stessa persona allo stesso recapito anche quando sono scritti in modo diverso: diminutivi ed equivalenze dei nomi (Dany ≈ Daniela), cognome e nome invertiti, abbreviazioni ("V. Roma" ≈ "Via Roma"), refusi di battitura. Il confronto degli indirizzi passa dal motore di normalizzazione: due grafie diverse della stessa via collassano sulla forma canonica prima del confronto. Massimo 500 contatti per chiamata (anagrafiche + riferimento); per liste più grandi usa il lavoro in blocco dall'area personale.

Rubriche. Un contatto della rubrica (Contatti di Apple, Google, Outlook: il modello vCard) ha più indirizzi, più telefoni e più email, ognuno con un'etichetta. L'endpoint li accetta così, senza tetto: addresses è un elenco di oggetti con type e i campi di sempre; phones ed emails sono elenchi in cui ogni elemento è il dato solo ("340 7491386") oppure {"type": "work", "value": "02 66710423"}, anche misti; i campi piatti di sempre restano validi e valgono come primo indirizzo e primo recapito. Due contatti sono la stessa persona se una qualunque coppia dei loro indirizzi coincide (l'ufficio dell'uno con l'unico indirizzo dell'altro), oppure se hanno lo stesso nominativo e un telefono o un'email in comune, in qualunque posizione e con qualunque etichetta. Il tipo non pesa sull'abbinamento: torna com'è arrivato, più type_normalized nel vocabolario vCard (home, work, cell…), così l'app sa dove riscrivere. Un contatto è una elaborazione, quanti indirizzi e recapiti abbia.

curl -X POST https://www.radaraddress.com/api/v1/dedupe \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "records": [
      { "id": "C1", "last_name": "Rossi", "first_name": "Daniela",
        "address": "Via Leopardi 4", "postcode": "20123", "city": "Milano", "province": "MI" },
      { "id": "C2", "last_name": "Rossi", "first_name": "Daniela",
        "address": "V. Leopardi 4", "postcode": "20100", "city": "milano", "province": "MI" }
    ]
  }'

La risposta raggruppa i doppioni in groups: ogni gruppo elenca gli id dei suoi members, indica quale tenere (main_record) e propone il record consolidato: il nominativo migliore e l'unione di indirizzi e recapiti (addresses, phones, emails), ognuno col tipo, con provenance (da quali contatti viene) e deduplicato: la stessa via in due grafie è un indirizzo solo, lo stesso numero con due etichette un numero solo. I contatti senza corrispondenze sono in singles, come oggetti {id, outcome}: con outcome INTERNAL_DUPLICATE il contatto non ha doppioni con altri ma ne ha al suo interno (indirizzo scritto due volte, numero ripetuto), e porta il suo record fuso. Riconosce la stessa via scritta in modi diversi ("V. Leopardi 4" ≈ "Via Giacomo Leopardi 4"), il CAP rimesso a posto in automatico e cognome e nome invertiti.

Parametri della deduplica
ParametroTipoDescrizione
recordsarrayObbligatorio. Record con last_name, first_name, address, postcode, city, province e facoltativi id, gender, email, phone, country. Le schede estere (campo country, oppure provincia EE) si riconoscono anche scritte in modo diverso («Hauptstr. 5» e «Hauptstraße 5»); due nazioni diverse non sono mai la stessa scheda. Un telefono o un'email in comune accostano due schede anche con l'indirizzo diverso: al massimo probable se il recapito è personale, solo ambiguous se è di un posto condiviso (un fisso, un'email generica)
addresses, phones, emailsarrayFacoltativi, dentro ogni anagrafica: gli elenchi della rubrica, senza tetto (vedi sopra). phone ed email accettano le stesse tre forme: il dato solo, un elenco di dati, un elenco di {type, value}
tax_codestringFacoltativo, dentro ogni anagrafica. Se è valido e torna col nominativo della scheda, due schede con lo stesso codice sono la stessa persona anche a indirizzi diversi (certain, motivo «stesso codice fiscale»); con due codici validi e diversi non sono mai certain né probable. Un codice che non torna col nominativo non pesa
referencearrayFacoltativo: modalità due liste. Ogni anagrafica viene cercata nel riferimento; risposta con matches e not_found
min_levelstringcertain | probable (default) | ambiguous: quanto elastico è il match. certain = via e civico devono coincidere; ambiguous ignora il civico. Due schede senza indirizzo né località non sono mai certain
foreignstringdeclared (default: estera è solo la scheda che indica la nazione) | detect (anche dai segnali espliciti nel testo: nome della nazione, città estera nota, codice postale con una forma non italiana)
saveboolDefault true: il risultato resta rileggibile per 30 giorni con GET /api/v1/dedupe?job=<code>; il codice arriva nel campo job. Con POST {"job", "group", "processed": true} marchi un gruppo come revisionato

Endpoint codice fiscale

POST /api/v1/tax-code

Tre azioni sul codice fiscale delle persone fisiche: generate dai dati anagrafici, validate un codice esistente (formato, carattere di controllo e omocodia), extract le informazioni contenute — data di nascita, età, sesso, comune o stato estero di nascita. In più compare verifica che un CF corrisponda ai dati anagrafici dichiarati. Copre i codici catastali di tutti i comuni italiani e degli stati esteri. Cognome e nome vanno passati in caratteri latini: per chi ha un nome in un altro alfabeto, il codice si calcola sulla traslitterazione riportata sul documento, che non è unica (Dmitrij/Dmitry); un nome non latino torna cognome_non_latino o nome_non_latino, e nel compare una differenza sul nominativo di chi è nato all'estero porta una nota sulla possibile traslitterazione diversa.

Le prime 500 elaborazioni leggere al mese sono gratuite (codice fiscale compreso), e la franchigia è una sola in ogni modalità di utilizzo: quello che fai qui, sul sito e nei file in blocco conta sullo stesso plafond. Oltre, si paga il prezzo delle operazioni leggere (vedi prezzi).

curl -X POST https://www.radaraddress.com/api/v1/tax-code \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "action": "generate",
    "last_name": "Rossi", "first_name": "Mario", "gender": "M",
    "birth_date": "1980-01-01", "birth_place": "Roma"
  }'

→ { "ok": true, "tax_code": "RSSMRA80A01H501U", "place": "Roma", "province": "RM" }

Per i volumi: { "action": "validate", "items": [ … ] } processa fino a 500 elementi per chiamata, ognuno col proprio id di correlazione. L'estrazione segnala con ambiguous_year i casi in cui le due cifre dell'anno non distinguono il secolo (1926 vs 2026).

Ogni risposta porta outcome, reason, notes e comments nella lingua della richiesta: GENERATED per generate, vuoto per un codice valido in validate, MATCH o MISMATCH per compare (con differences: i campi che non tornano). Quando il codice non passa i controlli l'esito è uno dei codici TAX_CODE_* elencati sotto e error ne dà la forma corta (check_digit, length, format, homocode, month, date, place, empty); su generate dice quale dato manca o non si risolve (last_name, first_name, gender, birth_date, birth_place, ambiguous_place con options, last_name_non_latin). suggestion porta il codice corretto quando il controllo lo sa ricostruire.

Endpoint arricchimento

POST /api/v1/enrichment

Arricchisce un nominativo: sesso dedotto dal nome, tipo di soggetto (persona fisica o giuridica), titolo normalizzato (Dott.ssa, Avv., …) e forme di saluto pronte per la corrispondenza — "Egregio Sig. Rossi", "Gentile Dott.ssa Bianchi", "Spett.le" per le aziende, "Gentile Famiglia" per i nuclei, "Caro/Cara" per l'informale. Riconosce anche la forma coniugale nel cognome ("Rossi in Verdi" → donna, con il dettaglio dei due cognomi). Il campo gender accetta anche le forme scritte («maschio», «donna», «Sig.ra», «male»); X indica un ente e G una famiglia o una coppia. Se il titolo manca, lo ricaviamo da profession (la professione) o da education, quando ne danno uno.

curl -X POST https://www.radaraddress.com/api/v1/enrichment \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "last_name": "Rossi", "first_name": "Dott.ssa Maria" }'

→ { "ok": true, "gender": "F", "subject_type": "natural_person", "title": "Dott.ssa",
    "formal_salutation": "Gentile Dott.ssa Rossi", "informal_salutation": "Cara Maria", … }

A lotti: { "items": [ … ] }, fino a 500 per chiamata. L'esito è ENRICHED (sesso e saluti impostati), LEGAL_PERSON (azienda o ente: si tratta come ragione sociale) o PARTIAL (manca il nome, o il sesso non si deduce): reason dice perché, comments cosa aggiungere per completare.

Endpoint verifica email

POST /api/v1/email

Verifica un indirizzo email: sintassi, esistenza del dominio (record MX/A), refusi dei domini comuni con correzione proposta (gmial.com → gmail.com), domini usa-e-getta, indirizzi generici (info@, amministrazione@: non di una persona). Non facciamo la verifica SMTP della singola casella, pratica invasiva e inaffidabile. Batch items fino a 500; "dns": false salta il lookup del dominio.

Un refuso certo si corregge d'ufficio: quando l'indirizzo com'è scritto non è nemmeno un indirizzo (nome@dominio,it con la virgola) o quando la correzione atterra su un provider noto (gmai.com → gmail.com, anche a una lettera di distanza se il dominio scritto non riceve posta), email esce corretta, corrected_from porta com'era scritta e l'esito è MODIFIED EMAIL_DOMAIN. Un refuso possibile su un dominio qualunque (rossi.con) resta una proposta: EMAIL_TYPO con la correzione in suggestion, e i controlli (domain_exists, domain_checked) fatti su di lei; l'indirizzo com'è scritto non è verificato.

Endpoint verifica telefono

POST /api/v1/phone

Controlla un numero senza chiamare nessuno: forma, classe e tipo, lunghezza secondo il piano di numerazione, distretto del fisso e operatore a cui il blocco è stato assegnato in origine. La class è la lettura che serve a lavorare una lista: mobile (ci mandi un SMS), landline (lo chiami in orario d'ufficio), special (non è il recapito di una persona: emergenze, pubblica utilità, numeri verdi e a tariffa maggiorata), foreign per i numeri con prefisso internazionale. Quando riconosciamo anche il servizio preciso, type lo dice (numero verde, tariffa speciale, costo ripartito, pubblica utilità). Il prefisso italiano scritto senza il + (39347…, refuso classico degli export) lo togliamo quando le cifre non lasciano dubbi — 3934567890 resta il cellulare che è. Se nello stesso campo ci sono più numeri («347… - 338…») li separiamo: tornano come phone, phone2, phone3, e phone non è mai vuoto quando almeno un numero c'è. Con "format": "international" il numero italiano esce in forma +39…; il valore predefinito national lo lascia nudo e mette il prefisso solo agli esteri. Per gli esteri torna anche e164, la nazione del prefisso in country_code e lo zero di rete dopo il prefisso viene tolto («+44 (0)20…» e «+44 20…» danno lo stesso numero). Con country_code (o country) nella chiamata o nell'elemento, un numero scritto senza prefisso è letto come numero nazionale di quella nazione: «020 7946 0958» in una scheda del Regno Unito è Londra, non Milano. Senza nazione resta italiano. Lotto items fino a 500.

Il numero della nazione del record non è «estero»: dove conosciamo il piano di numerazione esce con la sua class (mobile, landline, special), con format national resta senza prefisso nella forma del suo paese (zero di rete compreso) e torna anche national_number accanto a e164. PHONE_FOREIGN e class foreign restano per i numeri di una nazione diversa da quella del record.

curl -X POST https://www.radaraddress.com/api/v1/phone \
  -H 'Authorization: Bearer YOUR_TOKEN' \
  -H 'Content-Type: application/json' \
  -d '{"phone":"3470328959 - 011 1253265"}'

Endpoint verifica sito web

POST /api/v1/website

Verifica che l'indirizzo sia scritto bene e che il sito risponda davvero: esistenza del dominio, richiesta HTTP con i reindirizzamenti seguiti, codice finale, validità del certificato. Nessun giudizio sul contenuto. Anche qui più indirizzi nello stesso campo tornano come website, website2, website3. Con "network": false controlliamo solo la forma, senza contattare il sito. Lotto items fino a 100: ogni verifica apre una connessione, quindi il lotto è più piccolo degli altri endpoint.

curl -X POST https://www.radaraddress.com/api/v1/website \
  -H 'Authorization: Bearer YOUR_TOKEN' \
  -H 'Content-Type: application/json' \
  -d '{"website":"www.example.com"}'

Endpoint autocomplete indirizzo

POST /api/v1/suggest

Se parti da zero: come aggiungere l'autocomplete degli indirizzi al tuo form, in tre pezzi.

Suggerimenti mentre l'utente digita un indirizzo nel tuo form: l'intero stradario nazionale, con nome completato («via verdi» → «Via Giuseppe Verdi»), comune e provincia; il CAP arriva alla selezione, nelle grandi città zonate quello giusto del civico. Funziona a sessione: il client genera un UUID per ogni indirizzo in compilazione, le query di suggerimento sono gratuite, e si paga una verifica contatto quando l'utente seleziona e i campi si riempiono (azione select, che restituisce il record già normalizzato dal motore). I campi già compilati nel form — anche in parte — viaggiano come contesto e stringono i suggerimenti.

curl -X POST https://www.radaraddress.com/api/v1/suggest \
  -H 'Authorization: Bearer YOUR_TOKEN' \
  -H 'Content-Type: application/json' \
  -d '{"session":"CLIENT-UUID","q":"via verdi","city":"monz"}'

# when the user picks one: closes the session and charges the selection
curl -X POST https://www.radaraddress.com/api/v1/suggest \
  -H 'Authorization: Bearer YOUR_TOKEN' \
  -H 'Content-Type: application/json' \
  -d '{"session":"CLIENT-UUID","action":"select","street_id":1063428,"house_number":"4"}'

Scelta la via, si completa il civico: passando street_id con il civico parziale si ottengono i civici esistenti di quella via, con exists vero/falso per validare quello digitato — e la selezione si può ripetere con il civico senza nuovo addebito: l'addebito è a sessione e per via, non a click; un'altra via nella stessa sessione è un altro addebito. I civici si completano solo nella sessione che ha selezionato quella via. Nelle città zonate è il civico che determina il CAP esatto.

Il token API non va mai nel browser: il widget pronto all'uso (ra-suggerisci.js) chiama un piccolo proxy sul tuo server, che aggiunge il token e inoltra. Ogni sessione ammette fino a 30 chiamate e vale 10 minuti; le sessioni senza selezione sono gratuite fino a 200 al giorno per token, più cinque per ogni selezione. Widget, proxy pronto e form d'esempio sono nel kit di Il tuo form.

Funziona in ogni nazione in servizio (oggi Francia, Germania, Spagna, Paesi Bassi, Belgio, Finlandia, Cechia, Portogallo, Danimarca, Norvegia, Austria, Svizzera, Slovacchia, Croazia, Romania, Ungheria, Slovenia, Irlanda, Islanda, Lussemburgo, Liechtenstein, San Marino, Monaco, Andorra, Città del Vaticano; l'elenco aggiornato è in Nazioni): con country_code o country i suggerimenti vengono dal registro di quel paese, e il testo si scrive come si scrive lì — via, numero, codice postale e città anche in un campo solo: «kalverstraat 92 amst», «92 rue de rivoli paris», in Olanda «1012PH 92». Ogni risposta porta parsed, cioè come il server ha letto via (street), numero (house_number) e codice postale (postcode): il tuo form sa dove sta il numero senza conoscere le regole del paese. I suggerimenti portano via, città, eventuale località e source (registry, oppure osm dove il registro nazionale non pubblica); il codice postale e i numeri civici non stanno mai nei suggerimenti: arrivano con la selezione, che passa dal motore e torna lo stesso record di /contact (postcode confermato dal registro, geo al civico). Con la selezione si può passare anche postcode, quello scritto nel form. attribution è la dicitura della fonte da mostrare accanto ai suggerimenti: la licenza del registro la richiede. Se la nazione manca si presume IT; per una nazione non in servizio la risposta resta HTTP 200 con supported:false e hints:[], senza creare la sessione né addebitare nulla. Una sessione è di una nazione: se cambia, il client genera un nuovo UUID (altrimenti 409 session_country).

curl -X POST https://www.radaraddress.com/api/v1/suggest \
  -H 'Authorization: Bearer YOUR_TOKEN' \
  -H 'Content-Type: application/json' \
  -d '{"session":"CLIENT-UUID","q":"kalverstraat 92 amst","country_code":"NL"}'

{"ok":true,"phase":"streets",
 "hints":[{"type":"street","id":642154,"name":"Kalverstraat","municipality":"Amsterdam","area":"","source":"registry"}],
 "parsed":{"street":"kalverstraat","house_number":"92","postcode":""},
 "attribution":"Bron: Kadaster — BAG"}

Volumi grossi: il lavoro asincrono

Le chiamate normali rispondono subito, e per questo hanno un tetto di elementi — una richiesta HTTP che dura minuti non serve a nessuno. I tetti seguono quanto costa l'operazione:

Tetti di elementi per chiamata
EndpointElementi per chiamataPerché
/phone5.000verifica immediata
/tax-code, /enrichment2.000verifica veloce
/contact, /email, /dedupe500verifica completa
/website100una connessione al sito per ogni indirizzo

Oltre quei numeri non serve spezzare la lista a mano: si aggiunge "async": true e la chiamata torna subito con un codice, mentre l'elaborazione va nella stessa coda del caricamento file. Fino a 100.000 elementi per chiamata, e in I miei lavori ne compare uno solo.

curl -X POST https://www.radaraddress.com/api/v1/contact \
  -H 'Authorization: Bearer YOUR_TOKEN' \
  -H 'Content-Type: application/json' \
  -d '{"async":true,"items":[ … 100,000 contacts … ]}'

{"ok":true,"job":"369e46e9e7bb…","state":"queued","rows":100000}

Poi si rilegge quando serve, e il risultato arriva in JSON o come CSV:

curl 'https://www.radaraddress.com/api/v1/contact?job=369e46e9e7bb…' \
  -H 'Authorization: Bearer YOUR_TOKEN'

{"ok":true,"state":"completed","rows":100000,"done":100000,
 "outcomes":{"ok":1240,"modified":95300,"to_check":2100,"unresolved":1360}}

curl 'https://www.radaraddress.com/api/v1/contact?job=369e46e9e7bb…&format=csv' \
  -H 'Authorization: Bearer YOUR_TOKEN' -o result.csv

Sotto le 5.000 righe il risultato torna anche in results dentro il JSON; sopra, si scarica in CSV. L'addebito avviene quando il lavoro viene accodato, e la parte non elaborata torna nel saldo se il lavoro si ferma. Il token dev'essere legato a un account: il lavoro finisce nella tua coda.

Codici di esito

Ogni risposta include il campo outcome: una lista di parole chiave, vuota quando non c'è niente da segnalare. Lo schema è sempre <conditions> [MODIFIED <types>] — le condizioni davanti, le modifiche in coda — e vale per tutti i servizi. Accanto trovi outcome_label (o kind) con ok, modified, warning, error, e reason con la spiegazione in una riga. I codici sono identificativi: si confrontano, non si traducono; con "language": "it" escono i codici italiani (LOCALITA_NON_TROVATA MODIFICATO CAP INDIRIZZO), gli stessi parola per parola.

Indirizzo (verifica contatto)

Codici di esito — indirizzo (verifica contatto)
CodiceSignificato
OKNessuna modifica necessaria, indirizzo già conforme (esito vuoto)
MODIFIEDIndirizzo normalizzato con successo, seguito dai campi cambiati: POSTCODE, PROVINCE, CITY/CITY_FORM, STREET/STREET_FORM, BUILDING (il suffisso _FORM = solo formato/accenti, il valore era già corretto). Lo schema del campo è <conditions> [MODIFIED <types>]: le eventuali condizioni vengono prima, MODIFIED e i suoi tipi in coda
PO_BOXRecapito a casella postale riconosciuto (non una via): forma CASELLA POSTALE n
LOCALITY_WITHOUT_STREETL'indirizzo è una frazione/località senza nome via; il recapito è comunque possibile
CITY_NOT_FOUNDComune non riconosciuto
CITY_AMBIGUOUSNome di comune presente in più province
STREET_NOT_FOUNDVia non censita per questa località
STREET_AMBIGUOUSNome di via presente in più zone del comune
STREET_TYPE_MISSINGTipo di via non riconoscibile (manca Via/Corso/Piazza…)
HOUSE_NUMBER_MISSINGNumero civico assente o non valido
HOUSE_NUMBER_INVALID_FORMATNumero civico in forma non riconosciuta
POSTCODE_UNCONFIRMEDLa via esiste ma per quel numero non c'è un riscontro sul CAP: resta quello indicato, se è fra quelli della città
POSTCODE_PRESUMEDLa via esiste e il CAP l'abbiamo messo noi senza il riscontro del civico: la via ne ha più d'uno e il numero non decide, oppure non era scritto e viene dai civici vicini
INCOMPLETE_DATAInformazioni insufficienti per la normalizzazione
FOREIGNIndirizzo non italiano, nella forma postale della sua nazione; dove il registro nazionale è in servizio via e civico sono verificati, e lo dice il messaggio (solo con la lingua italiana)
HOUSE_NUMBER_NOT_FOUNDEstero: la via esiste nel registro nazionale, il numero civico indicato no (solo dove il registro ha tutti i civici: da una fonte parziale o da OpenStreetMap il numero che manca non è un verdetto)
POSTCODE_INVALID_FORMATEstero: il codice postale non ha la forma in uso nel paese indicato
COUNTRY_UNRESOLVEDEstero: la nazione scritta nell'indirizzo non è nel catalogo ISO 3166-1

Codice fiscale

Codici di esito — codice fiscale
CodiceSignificato
TAX_CODE_INVALIDIl codice non supera i controlli; reason dice quale (carattere di controllo, lunghezza, mese, data, comune) e suggestion propone la forma corretta quando è ricostruibile
TAX_CODE_MISMATCHIl codice è valido ma non combacia con cognome, nome, sesso o data della richiesta
MODIFIED TAX_CODEMancava il carattere di controllo: ricalcolato dai primi 15
MODIFIED TAX_CODE_FORMSolo la forma è stata ripulita (maiuscole, spazi)
GENERATEDEndpoint /tax-code, azione generate: codice calcolato dai dati anagrafici
MATCH / MISMATCHEndpoint /tax-code, azione compare: il codice combacia o no con i dati; con differences i campi che non tornano

Sull'endpoint /tax-code gli stessi controlli hanno codici propri — TAX_CODE_CHECK_DIGIT_WRONG, TAX_CODE_CHECK_DIGIT_MISSING, TAX_CODE_LENGTH_WRONG, TAX_CODE_FORMAT_WRONG, TAX_CODE_MONTH_WRONG, TAX_CODE_DATE_INVALID, TAX_CODE_PLACE_UNKNOWN, TAX_CODE_EMPTY — perché lì il codice fiscale è l'oggetto della verifica, non un campo del record.

Arricchimento

Codici di esito — arricchimento
CodiceSignificato
ENRICHEDPersona fisica: sesso dedotto o confermato, titolo e forme di saluto impostati
LEGAL_PERSONAzienda o ente: intestazione trattata come ragione sociale (Spett.le)
PARTIALManca il nome, o il sesso non si deduce dal nome: saluto neutro

Email

Codici di esito — email
CodiceSignificato
EMAIL_INVALIDSintassi non valida
EMAIL_DOMAIN_NOT_FOUNDIl dominio non riceve email (nessun record MX/A)
EMAIL_TYPORefuso possibile nel dominio: la correzione è una proposta, in suggestion e nel campo normalizzato
MODIFIED EMAIL_DOMAINRefuso certo nel dominio, corretto: corrected_from porta com'era scritto
EMAIL_DISPOSABLEDominio di posta temporanea
EMAIL_ROLE_BASEDIndirizzo dell'organizzazione (info@, ordini@), non di una persona. È una segnalazione, non un errore
EMAIL_EMPTYNessun indirizzo nel campo
MODIFIED EMAIL_FORMSolo la forma è stata ripulita (spazi, maiuscole)

Telefono

Codici di esito — telefono
CodiceSignificato
PHONE_INVALIDNon è un numero riconoscibile
PHONE_LENGTH_ANOMALOUSCifre in numero incompatibile col piano di numerazione
PHONE_OUT_OF_PLANNon comincia per 0 (fisso) né per 3 (cellulare)
PHONE_FOREIGNNumero con prefisso internazionale non italiano (o numero nazionale di una scheda estera): ne controlliamo solo la forma, in E.164
PHONE_SPECIALNumero verde o a tariffa speciale: non è un recapito personale
PHONE_SERVICENumero di pubblica utilità (112, 118…)
PHONE_WITH_EXTENSIONIl campo conteneva anche un interno o una nota: verifichiamo il solo numero
PHONE_EMPTYNessun numero nel campo
MODIFIED PHONE_FORMSolo la forma è stata ripulita (spazi, punti, prefisso)

Sito web

Codici di esito — sito web
CodiceSignificato
WEBSITE_INVALIDNon è un indirizzo web scritto correttamente
WEBSITE_DOMAIN_NOT_FOUNDIl dominio non esiste (nessun record DNS)
WEBSITE_NOT_RESPONDINGIl dominio esiste ma nessun server risponde
WEBSITE_PAGE_NOT_FOUNDIl sito risponde ma la pagina non c'è (404/410)
WEBSITE_ACCESS_DENIEDIl sito nega l'accesso (401/403): spesso è una protezione anti-robot
WEBSITE_CERTIFICATE_INVALIDIl sito risponde ma il certificato non è verificabile
WEBSITE_RESPONSE_ANOMALOUSCodice di risposta inatteso
WEBSITE_EMPTYNessun indirizzo nel campo
MODIFIED WEBSITE_FORMIndirizzo completato (schema, www) senza cambiarne la sostanza

Quanto costa ogni chiamata

Ogni chiamata consuma elaborazioni del contatore del servizio: verifica contatto (/contact, /suggest alla selezione), deduplica (/dedupe) ed elaborazioni leggere (/email, /phone, /website, /enrichment, /tax-code oltre la franchigia). Le elaborazioni si comprano a pacchetti che restano, o con un abbonamento mensile; il prezzo per 1.000 scende con la taglia ed è nella pagina prezzi. Ogni mese sono gratuite 50 verifiche contatto, 100 anagrafiche in deduplica e 500 elaborazioni leggere.

Ogni risposta dice che cosa ha consumato e da dove: il campo credit del JSON (counter, charged, free, subscription e packs con le elaborazioni prelevate e il residuo, available, auto_topup con il numero di pacchetti comprati in automatico, note in italiano) e gli header X-RA-Charged, X-RA-Available e, quando interviene, X-RA-Auto-Topup. Se le elaborazioni disponibili non coprono la chiamata e l'auto-ricarica del contatore non è attiva (o non riesce), la risposta è 402 payment_required e non viene elaborato nulla.

Per sapere quante elaborazioni restano senza consumarne nessuna c'è GET /api/v1/credit. Per ciascuno dei tre contatori (contact, dedupe, light) restituisce available, le free rimaste nel mese e la data in cui si azzerano (il 1°), l'subscription (residuo, taglia, rinnovo), i packs attivi uno per uno con quanto resta (non scadono) e quanti ne hai comprati, l'auto_topup (attiva, taglia, tetto e speso del mese in euro), l'uso (used nel mese, totali, ultimo uso) e soprattutto lo state, perché uno zero da solo non dice se hai esaurito o se quel servizio non lo usi: never_used, free (mai comprato, lavori nelle gratuite del mese), free_used_up, active, awaiting_renewal, used_up (hai comprato in passato e non resta nulla: va ricaricato), con un warning in italiano. In cima needs_topup elenca i contatori su cui intervenire ed endpoint dice quale contatore consuma ogni endpoint. Vuole il token di un account.

curl https://www.radaraddress.com/api/v1/credit -H 'Authorization: Bearer YOUR_TOKEN'
→ { "ok": true, "counters": { "contact": { "available": 48250, "free": { "remaining": 50, "month": 50 },
      "subscription": { "left": 23200, "size": 25000, "renews_on": "2026-10-03" }, "packs": { "left": 25000, "active_packs": [ … ] },
      "state": "active", "warning": "" }, "dedupe": { "state": "never_used", "warning": "Counter never used: zero does not mean used up. …", … },
      "light": { … } }, "needs_topup": [], "endpoint": { "contact": "contact", "email": "light", … } }
Contatore consumato da ogni endpoint
EndpointContatoreElaborazioni
/contactVerifica contatto1 per record (indirizzo, nominativo e codice fiscale insieme)
/suggestVerifica contatto1 per indirizzo selezionato (digitare è gratis)
/dedupeDeduplica1 per anagrafica (include la normalizzazione)
/tax-codeElaborazioni leggere1 per codice, oltre la franchigia
/emailElaborazioni leggere1 per email
/phoneElaborazioni leggere1 per numero
/websiteElaborazioni leggere1 per sito
/enrichmentElaborazioni leggere1 per nominativo

Si paga per elemento verificato, non per chiamata: se in un campo ci sono due numeri di telefono o due email, li verifichiamo tutti (fino a tre per riga) e ciascuno paga il suo prezzo. Una chiamata a lotto costa quanto le operazioni che contiene. Se il credito è esaurito e non hai l'auto-ricarica attiva, l'API risponde HTTP 402 (credito insufficiente); superato il rate limit risponde HTTP 429 con retry_after. Ricarichi il credito dall'area personale, o attivi un abbonamento per pagare meno l'operazione.

Rate limit

60 richieste al minuto sulle chiamate singole, 10 al minuto su quelle a lotto, 300 al minuto sull'autocomplete.

Prestazioni misurate sull'API di produzione con venti chiamate in parallelo: circa 200 verifiche al secondo, mediana sotto i 60 millisecondi.

Conteggio unico

L'API, il sito e i lavori in blocco scaricano sugli stessi contatori: un pacchetto vale ovunque.

Versionamento

Gli endpoint sono versionati (/api/v1/): quando ne esce una versione nuova, quella vecchia resta in piedi e viene annunciata per tempo la data in cui si spegne.

Pronto a integrare?

Registra l'account, genera il tuo token, ricarica il credito che ti serve e fai la prima chiamata in meno di un minuto.

Crea il tuo token

Vedi i prezzi