system✳Parliamo del tuo progetto ↗
Inizia un progetto ↗
Trasparenza / Gli strumenti

Gli endpoint
di questo sito.

Non è un'API pubblica con una sua versione: sono gli stessi endpoint che le pagine usano per sé, aperti anche a chi non è un browser. Un 503 non è un guasto: è un prerequisito di configurazione non attivo, e il corpo dice quale.

Dove sono descritti

Tre rappresentazioni, tutte prodotte dallo stesso elenco (src/data/api-catalog.ts). Un catalogo, una specifica e una pagina che si contraddicono è il modo più rapido di non essere creduti da nessuno dei tre.

  • Catalogo — /.well-known/api-catalog, in application/linkset+json: una voce per endpoint con la sua anchor e le relazioni di servizio. È il formato che RFC 9727 definisce, scritto sopra il formato linkset di RFC 9264, ed è il target dell'header Link: rel="api-catalog" che ogni pagina di questo sito invia.
  • Specifica — openapi.json ↗: OpenAPI 3.1 generata dall'elenco, con i vincoli che il server applica davvero e gli stati che ogni handler può restituire. È il target service-desc.
  • Stato — api/health ↗: cosa è attivo in questo momento e cosa no. È il target status.
  • Questa pagina — /api/ è il target service-doc: la descrizione per una persona.

Le note su prerequisiti e limiti non stanno nel catalogo: in un linkset gli attributi qualificano il target di un link, e i prerequisiti appartengono all'endpoint, che lì è l'anchor. Stanno nella specifica, operazione per operazione, e qui sotto.

Come si chiama uno di questi endpoint

Richiesta POST con Content-Type: application/json e corpo sotto 16 kB. L'Origin della richiesta deve essere questo sito: un browser su un altro dominio viene respinto con un 403 prima ancora di leggere il corpo. È la ragione per cui questi endpoint sono usati dalle pagine del sito e da un servizio che li chiama dal server, non da una pagina di un altro sito.

I controlli di struttura e di campo hanno un limite contato nel database: 5 richieste per client per ora, 150 complessive. L'invio di una richiesta: 8 per client ogni 10 minuti, 200 complessive. Oltre il limite la risposta è 429, non un silenzio.

Quando la verifica umana è attiva, il token del widget sta nel corpo (captchaToken) e il server lo verifica lui: un client che non lo manda riceve un 400 leggibile.

Gli endpoint

Invio di una richiesta (brief)

POST /api/leads — Registra una richiesta di progetto. È l’unico endpoint che scrive un dato personale.

Prerequisiti. LEAD_INTAKE_ENABLED=true; DATABASE_URL, oppure SUPABASE_URL con SUPABASE_SERVICE_ROLE_KEY; RATE_LIMIT_SECRET di almeno 32 caratteri; TURNSTILE_SECRET quando CAPTCHA_ENABLED=true. Senza, la risposta è 503 e dice cosa manca.

Limite. 8 richieste per client ogni 10 minuti, 200 complessive per ora.

Stati. 201: {saved:true, reference}: la referenza è la chiave idempotente della registrazione. · 400: Corpo non valido o verifica umana mancante. · 403: Origine della richiesta diversa da questo sito, o verifica umana non accettata. · 409: La stessa chiave idempotente con un corpo diverso. · 413: Corpo oltre 16 kB. · 415: Content-Type diverso da application/json. · 429: Limite di richieste raggiunto. · 503: Prerequisito non attivo: invio non abilitato, storage non configurato o verifica umana non configurata su questo server.

Cosa la risposta non misura.

  • La referenza prova la registrazione. Non prova una notifica inviata, né una risposta umana.
  • Una notificazione che non parte non annulla il 201: resta in attesa e viene ripresa da /api/retry-notifications.
  • Non esiste un GET che legga le richieste: la lettura dei record sta nell’applicazione dell’operatore, non in questo sito.

Controllo strutturale di una pagina pubblica

POST /api/audit — Scarica l’HTML di un URL pubblico, lo legge senza eseguire gli script e aggiunge i segnali di robots.txt e sitemap del dominio.

Prerequisiti. URL_AUDIT_ENABLED=true; DATABASE_URL, oppure SUPABASE_URL con SUPABASE_SERVICE_ROLE_KEY; RATE_LIMIT_SECRET di almeno 32 caratteri. Senza, la risposta è 503 e dice cosa manca.

Limite. 5 richieste per client per ora, 150 complessive per ora. Il limite è nel database: senza storage il controllo non parte.

Stati. 200: Segnali osservati, cosa non è misurato e cosa resterebbe da verificare. · 400: URL non valido, non pubblico o con indirizzo non consentito. · 403: Origine della richiesta diversa da questo sito. · 422: La pagina non è leggibile: non HTML, oltre 1 MB, troppi redirect. · 429: Limite di richieste raggiunto. · 502: Impossibile leggere la pagina. · 503: Controllo non attivo su questo server o limite di richieste senza storage. · 504: Il sito ha impiegato troppo tempo a rispondere o a risolversi.

Cosa la risposta non misura.

  • I campi notMeasured e coverage fanno parte della risposta: indicizzazione effettiva, ranking, citazioni AI e accessibilità manuale richiedono fonti dedicate.
  • Un noindex è un segnale tecnico, non lo stato nell’indice.
  • Nessun punteggio: un controllo strutturale non è un voto SEO o GEO.

Dati di campo Core Web Vitals (CrUX via PageSpeed Insights)

POST /api/audit-vitals — Chiede al dataset pubblico di Google i valori P75 osservati su un URL. Strategia mobile.

Prerequisiti. URL_AUDIT_ENABLED=true; DATABASE_URL, oppure SUPABASE_URL con SUPABASE_SERVICE_ROLE_KEY; RATE_LIMIT_SECRET di almeno 32 caratteri. Senza, la risposta è 503 e dice cosa manca.

Limite. 5 richieste per client per ora, 150 complessive per ora. Il limite è nel database: senza storage il controllo non parte.

Stati. 200: status: measured | no_field_data | unavailable, con la fonte e il perimetro. measured può convivere con no_field_data per un solo URL. · 400: URL non valido o non pubblico. · 403: Origine della richiesta diversa da questo sito. · 429: Limite di richieste raggiunto. · 503: Controllo non attivo su questo server.

Cosa la risposta non misura.

  • Nessun valore è stimato quando il servizio pubblico non ne ha uno: no_field_data non significa prestazioni buone.
  • Sono dati aggregati di visite reali (P75), non la misura del tuo dispositivo.
  • Il campo CrUX e la misura di laboratorio di /api/audit-browser non sono confrontabili.

Audit nel browser con axe

POST /api/audit-browser — Apre la pagina in un browser headless sul server, blocca le risorse esterne e misura LCP/CLS di laboratorio e violazioni axe.

Prerequisiti. URL_AUDIT_ENABLED=true; DATABASE_URL, oppure SUPABASE_URL con SUPABASE_SERVICE_ROLE_KEY; RATE_LIMIT_SECRET di almeno 32 caratteri; un browser che il server può eseguire (AUDIT_BROWSER_EXECUTABLE); TURNSTILE_SECRET quando CAPTCHA_ENABLED=true. Senza, la risposta è 503 e dice cosa manca.

Limite. 5 richieste per client per ora, 150 complessive per ora. Il limite è nel database: senza storage il controllo non parte.

Stati. 200: Misure di laboratorio, violazioni axe con quelle non valutabili, risorse bloccate, perimetro dichiarato. · 400: URL non valido o verifica umana mancante. · 403: Origine non autorizzata o verifica umana non accettata. · 429: Limite di richieste raggiunto. · 503: Controllo non attivo, nessun browser disponibile sul server (nomina AUDIT_BROWSER_EXECUTABLE), o due audit già in corso.

Cosa la risposta non misura.

  • Il browser è quello che il server può davvero eseguire: Chromium bundled su Linux, o un eseguibile nominato altrove. Un browser assente viene detto prima di consumare un limite.
  • Le misure di questo browser non sono confrontabili con un laboratorio né con i dati di campo.
  • Le risorse esterne della pagina sono bloccate: l’audit vede la pagina come la vede il server, non come la vede una rete reale.

Scansione delle richieste oltre la finestra di conservazione (operatore)

POST /api/prune-leads — Applica subito la finestra di conservazione dei record e risponde di quanti ne ha rimossi.

Prerequisiti. API_ADMIN_SECRET di almeno 32 caratteri; DATABASE_URL, oppure SUPABASE_URL con SUPABASE_SERVICE_ROLE_KEY. Senza, la risposta è 503 e dice cosa manca.

Accesso. Authorization: Bearer con il secret dell'operatore. Non è distribuito a chi usa il sito.

Stati. 200: {windowDays, removed} · 403: Secret dell’operatore mancante, corto o diverso. · 503: Storage non configurato.

Cosa la risposta non misura.

  • Lo stesso lavoro il servizio lo fa da sé una volta al giorno: questo endpoint serve a leggerne il numero senza aspettare.
  • La finestra è quella dichiarata nell’informativa; un valore di ambiente assurdo non diventa una cancellazione improvvisa.

Recupero delle notificazioni non partite (operatore)

POST /api/retry-notifications — Riprova l’invio delle notifiche di richieste salvate che non sono partite.

Prerequisiti. API_ADMIN_SECRET di almeno 32 caratteri; DATABASE_URL, oppure SUPABASE_URL con SUPABASE_SERVICE_ROLE_KEY; un canale di notificazione: RESEND_API_KEY con LEAD_NOTIFY_EMAIL e EMAIL_FROM, oppure CRM_WEBHOOK_URL con CRM_WEBHOOK_SECRET. Senza, la risposta è 503 e dice cosa manca.

Accesso. Authorization: Bearer con il secret dell'operatore. Non è distribuito a chi usa il sito.

Stati. 200: {processed} · 403: Secret dell’operatore mancante, corto o diverso. · 503: Storage non configurato.

Cosa la risposta non misura.

  • Riprende solo invii degli ultimi 23 ore: le chiavi di idempotenza di Resend scadono dopo 24 ore e una ripresa oltre sarebbe un secondo invio.
  • Elabora un record per chiamata, nell’ordine di creazione.
  • Nessun canale configurato risponde {processed:0}: non è un errore, è che non c’è un canale da riprovare.

Stato del servizio

GET /api/health — Risponde dello stato del servizio e dei prerequisiti che lo abilitano. Nessuna autenticazione, nessuna scrittura.

0

Stati. 200: Il servizio ha risposto, con l’elenco dei prerequisiti e il loro stato di configurazione.

Cosa la risposta non misura.

  • Risponde 200 anche quando un prerequisito è spento: è la scelta dichiarata, perché un catalogo che punta a questo endpoint deve poter leggere una descrizione, non solo un codice.
  • Lo stato dei prerequisiti è configurazione letta dal processo, non una prova di connessione al database o ai servizi esterni.
  • Non è un monitor esterno e non misura disponibilità nel tempo.

Versione

Il numero che si legge nella specifica (1.1.0) è la versione del sito, non un contratto di versione di API. Un endpoint può cambiare senza che quel numero lo dichiari: la specifica è generata dal codice, quindi descrive il servizio che c'è adesso, non una promessa su una release.

Intorno a questi endpoint

Come sono trattati i dati che attraversano l'invio di una richiesta è descritto nella privacy ↗; i limiti di uso degli strumenti nelle note d'uso ↗. La preferenza dichiarata ai crawler — citazione concessa, addestramento negato — è nel robots.txt dello stesso dominio.

Il titolare è SmarthubTecnologies · [email protected] ↗.