1. ¿Por qué hacen falta Privacy Policy, Terms y Support?
Empecemos con una verdad incómoda: para la ChatGPT Store, tener una política de privacidad pública y un contacto de soporte no es «buena práctica», es un requisito estricto. Las guías de OpenAI dicen claramente que cada App debe tener publicada una Privacy Policy, donde se explique con claridad qué datos se recogen y cómo se usan, así como un contacto de soporte.
Pero la historia no va solo de «para que el revisor te deje en paz». Estos documentos resuelven varias tareas a la vez.
En primer lugar, aportan un nivel básico de confianza para el usuario. Ve que detrás de la aplicación hay personas o una empresa, que hay reglas del juego y un lugar al que acudir si surge un problema. En un mundo donde aparece «otro servicio de IA» cada día, esto ya es una ventaja competitiva.
En segundo lugar, son la formalización de lo que ya hiciste en la arquitectura. Todo lo que decidiste en los módulos de seguridad, logging, retención, eliminación de datos y pagos debe estar también reflejado por escrito. Si prometes «no almacenamos las conversaciones», pero registras todo el tool‑input para siempre, no solo queda feo: es motivo de reclamaciones serias.
En tercer lugar, es otro nivel de contrato entre tú y OpenAI. La Store, de facto, dice: «Estamos dispuestos a mostrar tu App a millones de personas, pero debes describir honestamente lo que haces con ellas y estar localizable cuando algo vaya mal».
En resumen: las páginas legales no van de «los abogados nos obligan». Sirven para alinear expectativas: qué hace la App, qué datos toca, qué responsabilidad estás dispuesto a asumir y cómo puede el usuario hablar contigo.
2. Dónde viven estas URL legales en una ChatGPT App
Técnicamente, para una ChatGPT App las páginas legales son URL públicas normales que indicas en los metadatos de la aplicación y en el listado de la Store. En las guías suelen llamarlas algo como privacy_policy_url, terms_of_service_url y el contacto de soporte.
Estas URL deben cumplir varias condiciones simples pero importantes:
- Residen en un dominio estable de tu producto o empresa. Nada de enlaces temporales de ngrok, o en una semana la Store llevará al usuario a ninguna parte.
- Son accesibles sin autenticación. El usuario (y el revisor) deben poder abrirlas en el navegador sin login ni rituales complejos.
- Están actualizadas y coinciden con la realidad. Si cambias la arquitectura de tratamiento de datos, con el tiempo tendrás que actualizar también el texto.
En nuestro proyecto didáctico GiftGenius ya tenemos un frontend en Next.js desplegado, por ejemplo, en Vercel. Por tanto, el lugar lógico para las páginas legales son rutas del tipo:
- /legal/privacy
- /legal/terms
- /support
En esencia, son simplemente tres páginas más en la aplicación, pero son precisamente las que enlazarás en el formulario de envío de la App para revisión.
3. Privacy Policy: cómo describir honestamente qué haces con los datos
El papel de la Privacy Policy
La Privacy Policy (política de privacidad, en adelante — Policy) responde a la pregunta principal: «¿Qué hace esta App con mis datos (del usuario)?» Debe describir qué categorías de datos procesas, de dónde provienen, para qué los necesitas, dónde y cuánto tiempo se almacenan, a quién se transfieren y cómo puede el usuario solicitar su eliminación.
La particularidad de las ChatGPT Apps es que al usuario le importa entender qué es exactamente lo que recibes del chat. OpenAI subraya por separado: tu App no debe intentar reconstruir todo el diálogo, sino trabajar solo con los fragmentos que el modelo o el usuario envían explícitamente a las herramientas. Esto también conviene indicarlo en la Policy.
No empezamos por el texto, sino por la arquitectura
Antes de escribir una sola palabra legal, es útil mirar tu App con ojos de SRE/arquitecto: qué datos pasan realmente por el sistema.
Para nuestro ejemplo — GiftGenius — podría verse aproximadamente así:
| Categoría de datos | Origen | Dónde se almacena | Plazo / comportamiento |
|---|---|---|---|
| Texto de la consulta (fragmento del chat) | Llamada de herramienta desde ChatGPT | Registros de solicitudes en el backend | N días o lo eliminamos de inmediato |
| Regalos seleccionados por el usuario | Acciones en el widget | Base de datos de GiftGenius | Se conserva hasta la eliminación de la cuenta |
| Email del usuario (si hay OAuth) | Proveedor de autenticación | Base de usuarios | Mientras la cuenta esté activa |
| Métricas técnicas (IP, timestamp, errores) | Solicitudes HTTP | Logs / sistema de monitorización | N días según la política de logs |
Puedes crear esta tabla directamente en la documentación del proyecto (por ejemplo, en /docs): servirá para desarrollo, para el módulo de seguridad y para la propia Policy.
Luego traducimos esta estructura a un lenguaje comprensible para humanos.
Estructura de la Privacy Policy para GiftGenius
En un proyecto didáctico no hace falta escribir una epopeya de 20 páginas; basta con una estructura compacta pero honesta. Normalmente se distinguen varias secciones:
- Introducción: quién eres y de qué va la App.
- Qué datos recoges.
- Cómo los usas.
- A quién los transfieres.
- Dónde y cuánto tiempo los almacenas.
- Derechos del usuario (incluida la solicitud de eliminación).
- Contacto para cuestiones de privacidad.
Es importante entender que incluso para un proyecto didáctico esto no es un simple «relleno». En el módulo de seguridad ya pensaste en el periodo de retención de logs, la política de eliminación y copias de seguridad; ahora debes plasmarlo con cuidado.
Implementación más simple de la página en Next.js
Hagamos la página /legal/privacy en nuestra aplicación. En App Router es literalmente un archivo:
// 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>
{/* a continuación van las secciones de la política */}
</main>
);
}
Este ejemplo es deliberadamente simple: el objetivo es fijar una URL estática. En un proyecto real, el texto de la política casi siempre se almacena aparte (por ejemplo, en un archivo .md) y se carga para no dispersar toneladas de texto por el JSX.
Por ejemplo, puedes crear un loader típico:
// app/legal/privacy/page.tsx
import policyHtml from "./policy.html"; // HTML generado previamente
export default function PrivacyPage() {
return (
<main
className="mx-auto max-w-3xl p-8 prose"
dangerouslySetInnerHTML={{ __html: policyHtml }}
/>
);
}
Aquí encaja el consejo «no lo repitas sin entenderlo»: dangerouslySetInnerHTML es seguro solo si controlas la fuente del HTML (por ejemplo, lo generas tú mismo desde markdown en el CI).
Vinculación con procesos reales
Lo más importante: no puedes escribir en la Policy algo que no exista en tu código. Si declaras que:
- no almacenas textos de consultas más de 7 días;
- eliminas por completo el perfil del usuario a petición;
- no usas esos datos para entrenar tus propios modelos,
entonces debes tener:
- configuraciones de retención en los logs;
- un endpoint o proceso de administración para eliminar usuarios;
- ausencia de código que vuelque logs a un almacenamiento externo «para Data Science».
Y al contrario: si activaste métricas de uso, experimentos A/B o analítica por países, debes decirlo con honestidad en la Policy. Y dar al usuario al menos derechos básicos: saber qué se almacena y solicitar su eliminación.
Con los datos y la Privacy Policy resuelto, queda fijar no solo el tratamiento de datos, sino también las «reglas del juego» — esa es la tarea de los Terms.
4. Terms of Use / Service: reglas del juego y descargos de IA
¿Para qué sirven los Terms si ya hay una Policy?
La Privacy Policy responde a «qué haces con los datos». Los Terms Of Use/Service (en adelante — Terms) responden a «en qué condiciones se puede usar la App». Es un contrato legal entre tú y el usuario.
En ellos se describe:
- qué es GiftGenius y qué funciones ofrece;
- qué acciones del usuario son aceptables y cuáles no;
- dónde están los «límites de la magia» de la IA (descargos de responsabilidad de IA);
- qué limitaciones de responsabilidad tienes;
- cómo se resuelven disputas y qué jurisdicción aplica.
Para una app de IA, dos puntos son especialmente importantes: el descargo sobre precisión y la limitación de responsabilidad.
Especificidad de IA: «el modelo puede equivocarse»
Nuestro GiftGenius da recomendaciones de regalos. Es algo amable y relativamente seguro, pero incluso aquí puede haber problemas: el usuario pidió «un regalo para alguien con alergia a los frutos secos», el modelo generó algo inapropiado, la persona salió perjudicada, todos infelices.
Está claro que los Terms no son un chaleco antibalas contra todos los riesgos, pero dejan claro:
- que los resultados los genera una IA y pueden ser inexactos, estar desactualizados o ser extraños;
- que el usuario debe verificar por su cuenta la información importante, especialmente la relacionada con salud, finanzas y otras áreas sensibles;
- que no ofreces garantías de «perfección» de las recomendaciones y no te haces responsable por el uso indebido del resultado.
Más adelante un abogado deberá pulir las formulaciones, pero a un desarrollador le interesa comprender la idea.
Matices de comercio
Si tu App realiza cualquier acción de pago (verás el módulo de ACP y comercio con más detalle más adelante, está contemplado en el curso), en los Terms debes describir con cuidado:
- a través de quién se procesan los pagos (Stripe, ACP u otro sistema);
- qué datos de pago ves realmente;
- qué condiciones de reembolso y cancelación existen;
- qué se considera exactamente una transacción exitosa.
La recomendación de la plataforma en general es indicar explícitamente que los datos de tarjeta los procesa el proveedor de pagos, no tu servidor, y que tú almacenas solo lo mínimo (por ejemplo, el ID de la transacción).
Implementación de /legal/terms en Next.js
Técnicamente es muy parecido a la Privacy Policy. Creamos la página:
// 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>
{/* secciones: descripción del servicio, limitaciones, descargo de IA, responsabilidad */}
</main>
);
}
Y, como en el caso de la Policy, mejor mantener el texto en un archivo aparte o en una CMS, y dejar el mínimo de marcado en el código.
Podemos extraer un envoltorio común para las páginas legales:
// 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>
);
}
Y luego usarlo tanto para la Policy como para los Terms. No se trata de «la belleza del código», sino de no olvidar poner la fecha de actualización y mantener un estilo unificado.
5. Support / Contact: a dónde va el usuario cuando tiene un problema
Mínimos y «buena práctica»
Las guías de OpenAI indican que la App debe tener una forma clara de contactar con el desarrollador para soporte. Puede ser un simple email, pero debe existir, recibir mensajes y, al menos de vez en cuando, responderse.
La opción mínima para un proyecto didáctico:
- página separada /support con una breve descripción y mailto:support@yourdomain.com.
Una opción más madura:
- formulario de contacto;
- enlace a documentación o Help Center;
- posiblemente un enlace a Slack/Discord si construyes una comunidad alrededor del producto.
Página /support en Next.js
Empecemos por una variante muy simple:
// 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>
);
}
Un poco más avanzado — añadir un formulario sencillo:
// app/support/page.tsx
"use client";
export default function SupportPage() {
const handleSubmit = (e: React.FormEvent) => {
e.preventDefault();
// aquí irá la llamada al API que envíe el correo/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>
);
}
Aunque no implementes un backend real para este formulario en el proyecto didáctico, el mero hecho de tener una URL clara y la estructura de la página ya te acerca a los requisitos de la Store.
Relación con la gestión de incidentes
La página de soporte no es solo «dónde escribir si todo se cayó», sino parte de tu operativa. En módulos posteriores hablarás sobre incidentes y la vida operativa de la App. Allí, la página de soporte será «la puerta de entrada» para los usuarios: por ella llegan informes de bugs, preguntas y solicitudes de eliminación de datos. Ahora es importante, al menos, fijar que esa puerta existe y no conduce a «404 Not Found».
6. Integración de las páginas legales en la aplicación y en el listado
Configuración unificada de URL dentro del proyecto
Para no esparcir «cadenas mágicas» con URL por el código, conviene crear una configuración simple:
// 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;
Estas mismas URL las usarás:
- en la configuración de la ChatGPT App (metadatos);
- en la landing del producto;
- en correos, si implementas notificaciones por email.
Dentro del widget puedes dar al usuario acceso rápido a estas páginas mediante openExternal.
// dentro del widget de 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>
);
}
En el código real del widget, es mejor usar el hook useOpenExternal del Apps SDK; aquí, por brevedad, se muestra la llamada directa a través de window.openai.
Así aumentas la transparencia: el usuario puede ir con un clic desde el widget a los documentos legales, sin buscarlos en la Store.
Flujo del usuario y del revisor
Veamos el flujo de interacción con un pequeño esquema:
flowchart TD A[Página de listado en ChatGPT Store] --> B[El usuario lee la descripción de la App] B --> C[Abre Privacy / Terms mediante el enlace] B --> D[Instala / empieza a usar la App] D --> E[Inicia el widget de GiftGenius] E --> F["Si es necesario pulsa 'Support' o 'Privacy'"]
El revisor de la ChatGPT Store sigue un camino parecido, solo que con más suspicacia. Observa:
- qué pone en el listado;
- qué prometen la Policy y los Terms;
- cómo se comporta la App en un escenario real;
- si el comportamiento coincide con lo que escribiste.
Si todo es honesto y predecible, la probabilidad de pasar la revisión aumenta drásticamente.
7. Ejercicio práctico para tu App
Para no quedarnos en la teoría, es útil esbozar ahora mismo borradores de documentos para tu aplicación.
El enfoque puede ser este.
Primero, a nivel de arquitectura, describe:
- qué categorías de datos procesas (texto de la consulta, pedidos, email, métricas);
- si almacenas las consultas de texto y, en tal caso, durante cuánto tiempo;
- qué servicios externos están conectados (hosting, base de datos, pasarela de pago, analítica).
Después de esto:
- Redacta la estructura de la Privacy Policy con secciones «qué recogemos», «para qué», «a quién transferimos», «cuánto tiempo almacenamos», «cómo eliminar los datos».
- Redacta la estructura de los Terms: descripción del servicio, reglas de uso, limitaciones (contenido prohibido y abusos), descargo de IA, limitación de responsabilidad, enlaces a la Policy.
- Crea la página /support con un texto corto y un email.
- Añade al proyecto lib/appConfig.ts con las URL de las páginas legales y úsalas en el widget y en cualquier enlace externo.
Aunque los textos sean aún muy preliminares y planees «enseñárselos luego a un abogado», ya habrás hecho un trabajo importante: vincular la implementación técnica con la descripción legal.
8. Errores típicos al preparar las páginas legales
Error n.º 1: copiar una política de privacidad aleatoria de internet y no cambiarla.
A veces apetece tomar la primera política de privacidad que encuentras, cambiar el nombre del producto y dar por zanjada la tarea. El problema es que ese texto casi seguro no coincide con tu arquitectura. Puede tener secciones sobre app móvil, notificaciones push o servicios de analítica concretos que tú no usas, y, al contrario, no decir nada sobre un servidor MCP, los logs de herramientas y el trabajo a través de ChatGPT. El revisor notará las discrepancias, y los usuarios percibirán que el texto «es de otra persona».
Error n.º 2: prometer en la Policy lo que no está implementado en el código.
Ejemplo clásico: la frase «eliminamos todos tus datos a la primera solicitud», cuando en el código no hay endpoint de borrado ni siquiera un mecanismo para localizar los datos de un usuario concreto. Lo mismo aplica a los plazos de retención de logs y a frases como «no almacenamos el texto de tus mensajes», si en realidad guardas el tool‑input en un sistema de logs sin retención. Tal incoherencia es peligrosa tanto para la revisión como para usuarios reales.
Error n.º 3: ignorar la especificidad de IA en los Terms.
Si en los Terms no se menciona que las respuestas las genera un modelo y pueden ser inexactas, el usuario puede esperar de tu App «verdades absolutas». Para servicios de recomendaciones (regalos, viajes, selección de productos) aún puede ser tolerable, pero para medicina, finanzas o consejos legales ese vacío puede acabar muy mal. Mejor expresar las limitaciones y la responsabilidad de forma explícita y honesta.
Error n.º 4: página de soporte sin contacto real o con una dirección muerta.
La página /support que apunta a mailto:hello@example.com, a la que nadie entra nunca, existe formalmente pero, en la práctica, no sirve. El usuario no recibe respuesta, se pierden informes de bugs y la reputación de la App cae. La plataforma también espera que respondas a quejas y problemas. Aunque seas un equipo pequeño, es importante revisar la bandeja de entrada al menos cada pocos días y reaccionar.
Error n.º 5: olvidar la fecha y versión de los documentos.
A veces en las páginas legales no se indica cuándo se actualizaron. Para el revisor es una señal de alarma: no está claro si los documentos corresponden al estado actual del producto. Un bloque simple «Last updated: …» resuelve el problema tanto para ti como para los usuarios y ayuda a llevar un historial de cambios si con el tiempo ajustas la arquitectura y, en consecuencia, el texto de la Policy/Terms.
GO TO FULL VERSION