1. Perché servono Privacy Policy, Terms e Support
Partiamo da una verità scomoda: per il ChatGPT Store la presenza di una policy di privacy pubblica e di un contatto di supporto — non è «buona pratica», ma un requisito rigido. Nelle linee guida di OpenAI è esplicitamente scritto che ogni App deve avere una Privacy Policy pubblicata, in cui sia chiarito quali dati vengono raccolti e come vengono utilizzati, nonché un contatto per il supporto.
Ma la storia non è solo «per togliersi di dosso il moderatore». Questi documenti risolvono diverse esigenze contemporaneamente.
In primo luogo, sono il livello base di fiducia per l’utente. Vede che dietro l’app ci sono persone reali o un’azienda, ci sono regole del gioco e un luogo dove andare in caso di problemi. In un mondo in cui «l’ennesimo servizio di IA» compare ogni giorno, questo è già un vantaggio competitivo.
In secondo luogo, sono la formalizzazione di ciò che avete già implementato nell’architettura. Tutto ciò che avete definito nei moduli su sicurezza, logging, retention, eliminazione dei dati e pagamenti deve essere riflesso anche a parole. Se promettete «non conserviamo la conversazione» ma loggate per sempre tutto il tool‑input, non è solo poco elegante — è un motivo per serie contestazioni.
In terzo luogo, sono un ulteriore livello di contratto tra voi e OpenAI. Lo Store di fatto dice: «Siamo pronti a mostrare la tua App a milioni di persone, ma tu devi descrivere onestamente cosa fai con loro e essere reperibile quando qualcosa non va».
In sintesi: le pagine legali non sono «perché ce lo impongono gli avvocati». Sono un modo per allineare le aspettative: cosa fa l’App, quali dati tocca, quale responsabilità siete pronti ad assumervi e come l’utente può contattarvi.
2. Dove vivono questi URL legali in una ChatGPT App
Tecnicamente, per una ChatGPT App le pagine legali sono normali URL pubblici che indicate nei metadati dell’app e nel listing dello Store. Nelle guide vengono di solito chiamati qualcosa come privacy_policy_url, terms_of_service_url e contatto di supporto.
Questi URL devono rispettare alcune condizioni semplici ma importanti:
- Vivono su un dominio stabile del vostro prodotto o della vostra azienda. Niente link temporanei tipo ngrok, altrimenti dopo una settimana lo Store porta l’utente nel nulla.
- Sono accessibili senza autenticazione. L’utente (e il reviewer) devono poterli aprire nel browser senza login o rituali complessi.
- Sono aggiornati e corrispondono alla realtà. Se cambiate l’architettura di trattamento dei dati, col tempo dovrete aggiornare anche il testo.
Nel nostro progetto didattico GiftGenius abbiamo già un frontend in Next.js, che deployiamo, ad esempio, su Vercel. Quindi il posto logico per le pagine legali sono route del tipo:
- /legal/privacy
- /legal/terms
- /support
Di fatto sono solo tre pagine in più nell’applicazione, ma sono proprio quelle a cui farete riferimento nel form di invio della App per la review.
3. Privacy Policy: come descrivere onestamente cosa fate con i dati
Il ruolo della Privacy Policy
La Privacy Policy (informativa sulla privacy, di seguito — Policy) risponde alla domanda principale: «Cosa fa questa App con i miei (dell’utente) dati?» Deve descrivere quali categorie di dati trattate, da dove arrivano, perché vi servono, dove e per quanto sono conservati, a chi sono comunicati e come l’utente può chiederne la cancellazione.
La particolarità delle ChatGPT Apps è che per l’utente è importante capire cosa esattamente ricevete dalla chat. OpenAI sottolinea: la vostra App non deve cercare di ricostruire l’intero dialogo, ma lavorare solo con i frammenti che il modello o l’utente hanno esplicitamente inviato agli strumenti. Questo va indicato nella Policy.
Non iniziare dal testo, ma dall’architettura
Prima di scrivere anche solo una parola legale, è utile guardare la vostra App con gli occhi di un SRE/architetto: quali dati passano realmente attraverso il sistema.
Per il nostro esempio — GiftGenius — potrebbe apparire all’incirca così:
| Categoria di dati | Origine | Dove viene conservato | Periodo / comportamento |
|---|---|---|---|
| Testo della richiesta (snippet dalla chat) | Chiamata dello strumento da ChatGPT | Log delle richieste nel backend | N giorni oppure eliminiamo subito |
| Regali selezionati dall’utente | Azioni nel widget | Database di GiftGenius | Conserviamo fino alla cancellazione dell’account |
| Email dell’utente (se c’è OAuth) | Provider di autenticazione | Database utenti | Finché l’account è attivo |
| Metriche tecniche (IP, timestamp, errori) | Richieste HTTP | Log / sistema di monitoraggio | N giorni secondo la policy dei log |
Una tabella del genere può essere aggiunta direttamente nella documentazione del progetto (ad esempio in /docs): sarà utile per lo sviluppo, per il modulo Security e per la stessa Policy.
Poi si «traduce» questa struttura in linguaggio umano.
Struttura della Privacy Policy per GiftGenius
In un progetto didattico non serve scrivere un poema di 20 pagine: basta una struttura compatta ma sincera. Di solito si evidenziano alcune sezioni:
- Introduzione: chi siete e cos’è l’App.
- Quali dati raccogliete.
- Come li utilizzate.
- A chi li comunicate.
- Dove e per quanto li conservate.
- Diritti dell’utente (inclusa la richiesta di cancellazione).
- Contatti per questioni di privacy.
È importante capire che anche per un progetto didattico non è solo «un riempitivo». Nel modulo sulla sicurezza avete già ragionato su periodo di conservazione dei log, policy di eliminazione, backup — ora questo va formulato con cura.
Implementazione più semplice della pagina in Next.js
Creiamo la pagina /legal/privacy nella nostra applicazione. Nell’App Router è letteralmente un file:
// app/legal/privacy/page.tsx
export default function PrivacyPage() {
return (
<main className="mx-auto max-w-3xl p-8 prose">
<h1>Privacy Policy – GiftGenius</h1>
<p>Last updated: {new Date().toLocaleDateString()}</p>
{/* seguono le sezioni della policy */}
</main>
);
}
Questo esempio è volutamente semplice: l’obiettivo — fissare un URL statico. In un progetto reale il testo della policy quasi sempre è mantenuto separatamente (ad esempio in un file .md) e caricato, per non spargere tonnellate di testo nel JSX.
Per esempio, si può creare un loader tipico:
// app/legal/privacy/page.tsx
import policyHtml from "./policy.html"; // HTML precompilato
export default function PrivacyPage() {
return (
<main
className="mx-auto max-w-3xl p-8 prose"
dangerouslySetInnerHTML={{ __html: policyHtml }}
/>
);
}
Qui sono appropriati i commenti in stile «non fatelo senza capire perché»: dangerouslySetInnerHTML è sicuro solo se controllate la fonte dell’HTML (ad esempio lo generate voi stessi dal markdown in CI).
Collegamento con i processi reali
La cosa più importante: non si può scrivere nella Policy ciò che non esiste nel codice. Se dichiarate che:
- non conservate il testo delle richieste oltre 7 giorni;
- su richiesta dell’utente eliminate completamente il suo profilo;
- non usate questi dati per addestrare i vostri modelli,
allora dovete avere:
- impostazioni di retention nei log;
- un endpoint o un processo amministrativo per la cancellazione dell’utente;
- assenza di codice che riversa i log in un archivio esterno «per Data Science».
E viceversa: se avete attivato metriche di utilizzo, esperimenti A/B o analytics per paese, dovete dichiararlo onestamente nella Policy. E dare all’utente almeno diritti di base: sapere cosa è conservato e richiederne la cancellazione.
Chiarita la parte dei dati e della Privacy Policy. Resta da fissare non solo il trattamento dei dati, ma anche le «regole del gioco» — questo è compito dei Terms.
4. Terms of Use / Service: regole del gioco e disclaimer sull’IA
Perché servono i Terms, se esiste già la Policy
La Privacy Policy risponde alla domanda «cosa fate con i dati». I Terms of Use/Service (di seguito — Terms) — alla domanda «a quali condizioni si può utilizzare l’App». È un accordo legale tra voi e l’utente.
Vi si descrive:
- cos’è GiftGenius e quali funzionalità offre;
- quali azioni dell’utente sono ammesse e quali no;
- dove passano i «confini della magia» dell’IA (disclaimer sull’IA);
- quali sono i vostri limiti di responsabilità;
- come si risolvono le controversie e quale giurisdizione si applica.
Per un’app basata su IA sono particolarmente importanti due punti: il disclaimer di accuratezza e la limitazione di responsabilità.
Specificità dell’IA: «il modello può sbagliare»
La nostra GiftGenius fornisce raccomandazioni sui regali. È simpatico e relativamente sicuro, ma anche qui ci si può far male: l’utente ha chiesto «un regalo per una persona allergica alla frutta a guscio», il modello ha generato qualcosa di sbagliato, la persona ne risente e tutti sono scontenti.
È chiaro che i Terms non sono una corazza contro tutti i rischi, ma stabiliscono chiaramente:
- che i risultati sono generati dall’IA e possono essere imprecisi, obsoleti o semplicemente strani;
- che l’utente deve verificare autonomamente le informazioni importanti, specialmente quelle legate a salute, finanza e altre aree sensibili;
- che non fornite alcuna garanzia di «perfezione» delle raccomandazioni e non siete responsabili per un uso improprio del risultato.
Le formulazioni andranno poi affinate con un legale, ma per lo sviluppatore è importante capire il concetto.
Aspetti di commerce
Se la vostra App esegue qualsiasi operazione di pagamento (il modulo su ACP e commerce lo tratterete più a fondo, ma è previsto nel corso), nei Terms bisogna descrivere con cura:
- attraverso chi passano i pagamenti (Stripe, ACP, altro sistema);
- quali dati di pagamento vedete effettivamente;
- quali sono le condizioni di rimborso e annullamento dell’ordine;
- cosa è esattamente considerato una transazione riuscita.
La raccomandazione della piattaforma, in generale, è indicare chiaramente che i dati della carta sono trattati dal provider di pagamento e non dal vostro server, e che voi conservate solo il minimo necessario (ad esempio, l’ID della transazione).
Implementazione di /legal/terms in Next.js
Tecnicamente è tutto molto simile alla Privacy Policy. Creiamo la pagina:
// app/legal/terms/page.tsx
export default function TermsPage() {
return (
<main className="mx-auto max-w-3xl p-8 prose">
<h1>Terms of Use – GiftGenius</h1>
<p>Last updated: {new Date().toLocaleDateString()}</p>
{/* sezioni: descrizione del servizio, limitazioni, disclaimer IA, responsabilità */}
</main>
);
}
E, come per la Policy, è meglio tenere il testo in un file separato o in una CMS, e avere il minimo di markup nel codice.
Si può estrarre un wrapper comune per le pagine legali:
// app/legal/LegalLayout.tsx
export function LegalLayout(props: { title: string; children: React.ReactNode }) {
return (
<main className="mx-auto max-w-3xl p-8 prose">
<h1>{props.title}</h1>
<p>Last updated: {new Date().toLocaleDateString()}</p>
{props.children}
</main>
);
}
E poi usarla sia per la Policy che per i Terms. Non è «bellezza del codice», ma per non dimenticare di inserire la data di aggiornamento e mantenere uno stile uniforme.
5. Support / Contact: dove l’utente va con un problema
Minimo e «buona pratica»
Nelle linee guida di OpenAI è indicato che l’App deve avere un modo chiaro per contattare lo sviluppatore per il supporto. Può essere una semplice email, ma deve esistere, ricevere i messaggi e, almeno ogni tanto, ottenere risposta.
Variante minima per un progetto didattico:
- una pagina dedicata /support con una breve descrizione e mailto:support@yourdomain.com.
Variante più matura:
- form di contatto;
- link alla documentazione o a un Help Center;
- eventualmente — link a Slack/Discord, se costruite una community attorno al prodotto.
Pagina /support in Next.js
Partiamo dalla versione più semplice:
// app/support/page.tsx
export default function SupportPage() {
return (
<main className="mx-auto max-w-xl p-8 prose">
<h1>GiftGenius Support</h1>
<p>
If you have issues or questions, email us at{" "}
<a href="mailto:support@giftgenius.app">support@giftgenius.app</a>.
</p>
</main>
);
}
Una versione un po’ più avanzata — aggiungere un semplice form:
// app/support/page.tsx
"use client";
export default function SupportPage() {
const handleSubmit = (e: React.FormEvent) => {
e.preventDefault();
// qui ci sarà la chiamata API che invierà l’email/ticket
};
return (
<main className="mx-auto max-w-xl p-8 prose">
<h1>GiftGenius Support</h1>
<form onSubmit={handleSubmit}>
<input name="email" placeholder="Your email" className="border p-2 w-full" />
<textarea name="message" placeholder="How can we help?" className="border p-2 w-full mt-2" />
<button type="submit" className="mt-4 px-4 py-2 border rounded">
Send
</button>
</form>
</main>
);
}
Anche se non implementate un vero backend per questo form nel progetto didattico, la sola presenza di un URL chiaro e di una struttura di pagina vi avvicina già ai requisiti dello Store.
Collegamento con l’incident management
La pagina di Support non è solo «dove scrivere se è tutto down», ma parte del vostro quadro operativo. Nei moduli successivi parlerete di incidenti e della vita operativa dell’App. Lì la pagina di Support diventerà la «porta d’ingresso» per gli utenti: da lì arrivano bug report, domande, richieste di cancellazione dei dati. Ora è importante almeno fissare che tale porta esiste e non porta a «404 Not Found».
6. Integrazione delle pagine legali nell’app e nel listing
Configurazione unificata degli URL all’interno del progetto
Per non spargere nel codice «stringhe magiche» con gli URL, è comodo introdurre una semplice configurazione:
// lib/appConfig.ts
export const legalLinks = {
privacy: "https://giftgenius.app/legal/privacy",
terms: "https://giftgenius.app/legal/terms",
support: "https://giftgenius.app/support",
} as const;
Gli stessi URL li userete:
- nelle impostazioni della ChatGPT App (metadati);
- nella landing del prodotto;
- nelle email, se implementate le notifiche.
All’interno del widget potete dare all’utente accesso rapido a queste pagine tramite openExternal.
// all'interno del widget React GiftGenius
import { legalLinks } from "../lib/appConfig";
function FooterLinks() {
const handleOpen = (url: string) => {
window.openai?.openExternal({ url }); // Apps SDK helper
};
return (
<footer className="mt-4 text-xs text-gray-500">
<button onClick={() => handleOpen(legalLinks.privacy)}>Privacy</button>
<span> · </span>
<button onClick={() => handleOpen(legalLinks.terms)}>Terms</button>
</footer>
);
}
Nel codice reale del widget è meglio usare l’hook useOpenExternal dell’Apps SDK; qui per brevità è mostrata una chiamata diretta tramite window.openai.
Così aumentate la trasparenza: l’utente può raggiungere con un clic dal widget i documenti legali, senza doverli cercare nello Store.
Flusso dell’utente e del reviewer
Guardiamo il flusso di interazione con un piccolo schema:
flowchart TD A[Pagina di listing nel ChatGPT Store] --> B[L’utente legge la descrizione dell’App] B --> C[Apre Privacy / Terms dal link] B --> D[Installa / inizia a usare l’App] D --> E[Avvia il widget GiftGenius] E --> F["Se necessario preme 'Support' o 'Privacy'"]
Il reviewer del ChatGPT Store segue all’incirca lo stesso percorso, solo con un po’ più di sospetto. Controlla:
- cosa è scritto nel listing;
- cosa promettono Policy e Terms;
- come si comporta l’App in uno scenario reale;
- se il comportamento coincide con quanto avete scritto.
Se tutto è onesto e prevedibile, la probabilità di superare la review aumenta sensibilmente.
7. Esercizio pratico per la vostra App
Per non restare nella teoria, è utile abbozzare subito le bozze dei documenti per la vostra applicazione.
L’approccio può essere questo.
Per prima cosa, a livello di architettura, descrivete:
- quali categorie di dati trattate (testo della richiesta, ordini, email, metriche);
- se conservate le richieste testuali e, se sì, per quanto tempo;
- quali servizi esterni sono collegati (hosting, database, sistema di pagamento, analytics).
Dopo di che:
- Definite la struttura della Privacy Policy con le sezioni «cosa raccogliamo», «perché», «a chi trasferiamo», «per quanto conserviamo», «come cancellare i dati».
- Definite la struttura dei Terms: descrizione del servizio, regole d’uso, limitazioni (contenuti vietati e abusi), disclaimer IA, limitazione di responsabilità, link alla Policy.
- Create una pagina /support con un testo breve ed email.
- Aggiungete al progetto lib/appConfig.ts con gli URL delle pagine legali e usateli nel widget e in qualsiasi link esterno.
Anche se i testi saranno per ora molto grezzi e «poi li farete rivedere a un legale», avrete già fatto un lavoro importante: collegare l’implementazione tecnica alla descrizione legale.
8. Errori tipici nella preparazione delle pagine legali
Errore n. 1: copiare una privacy policy a caso da Internet e non modificarla.
A volte viene voglia di prendere la prima policy trovata, sostituire il nome del prodotto e considerare il lavoro finito. Il problema è che quel testo quasi certamente non corrisponde alla vostra architettura. Potrebbero esserci sezioni su app mobile, notifiche push o servizi di analytics specifici che non avete, e al contrario — non dirà nulla su un server MCP, i log degli strumenti e il lavoro tramite ChatGPT. Il reviewer noterà le discrepanze e gli utenti sentiranno che il testo è «di qualcun altro».
Errore n. 2: promettere nella Policy ciò che non è implementato nel codice.
L’esempio classico è la frase «cancelliamo tutti i vostri dati su semplice richiesta», quando nel codice non c’è né un endpoint di cancellazione né un meccanismo per cercare i dati di un utente specifico. Lo stesso vale per i periodi di conservazione dei log e per frasi come «non conserviamo il testo dei vostri messaggi» se in realtà inserite il tool‑input nel sistema di log senza retention. Una tale incongruenza è pericolosa sia per la review sia per gli utenti reali.
Errore n. 3: ignorare la specificità dell’IA nei Terms.
Se nei Terms non c’è una parola sul fatto che le risposte sono generate dal modello e possono essere imprecise, l’utente può aspettarsi dalla vostra App un livello di «verità assoluta». Per servizi di raccomandazione (regali, viaggi, scelta di prodotti) è ancora tollerabile, ma per medicina, finanza o consulenze legali una lacuna simile può finire molto male. Meglio dichiarare in modo esplicito e sincero limitazioni e responsabilità.
Errore n. 4: pagina di Support senza contatto reale o con indirizzo morto.
Una pagina /support che porta a mailto:hello@example.com, dove nessuno guarda mai, esiste formalmente ma è inutile nella pratica. L’utente non riceve feedback, i bug report si perdono e la reputazione dell’App ne risente. Anche la piattaforma si aspetta che rispondiate a reclami e problemi. Anche se siete un team piccolo, è importante controllare la posta in arrivo almeno ogni pochi giorni e rispondere.
Errore n. 5: dimenticare data e versione dei documenti.
A volte nelle pagine legali non c’è alcuna indicazione di quando siano state aggiornate. Per il reviewer è un campanello d’allarme: non è chiaro se i documenti corrispondano allo stato attuale del prodotto. Un semplice blocco «Last updated: …» risolve il problema sia per voi sia per gli utenti e aiuta a tenere la storia delle modifiche, se nel tempo intervenite sull’architettura e, di conseguenza, sul testo di Policy/Terms.
GO TO FULL VERSION