Consumir esta doc
Esta página es para agentes de IA y para las herramientas que los alimentan. Si eres una persona, lo que sigue también sirve: es el resumen más denso del sitio.
Cargar la documentación completa
Sección titulada «Cargar la documentación completa»Tres archivos, según cuánto contexto tengas disponible:
| Archivo | Qué trae | Cuándo usarlo |
|---|---|---|
/docs/llms.txt | Índice con la descripción y los enlaces a cada página. | Para decidir qué leer. |
/docs/llms-small.txt | El sitio entero en markdown, sin los bloques accesorios. | Contexto acotado. |
/docs/llms-full.txt | El sitio entero en markdown, completo. | El default. Trae todo el contrato. |
También hay un volcado acotado a los shapes de sección:
/docs/_llms-txt/referencia-de-secciones.txt.
curl https://sectionfy.codefy-apps.com/docs/llms-full.txtAdemás, cualquier página del sitio se puede pedir como markdown crudo agregando
.md a su ruta:
curl https://sectionfy.codefy-apps.com/docs/referencia/estructura-respuesta.mdEl contrato máquina
Sección titulada «El contrato máquina»Para generar clientes tipados o alimentar herramientas que hablen OpenAPI:
https://sectionfy.codefy-apps.com/api/public/content/openapi.jsonCubre los endpoints del bundle de contenido. Esta documentación es un superconjunto: incluye además las reglas de comportamiento que un esquema no puede expresar.
Lo esencial en veinte líneas
Sección titulada «Lo esencial en veinte líneas»BASE: https://sectionfy.codefy-apps.comAUTH: token opaco `ndp_pub_…` como segmento de la URL. Sin headers. Solo GET.
RUTAS /api/public/content/{token}/{page} page ∈ {home-page, category-page, product-page} /api/public/content/{token}/{page}/{targetId} page ∈ {product, category} /api/public/content/{token}/products/all → { page, products: [...] } (ARRAY) /api/public/key-features-banner/{token} → { sections } (sin `page`) /api/public/promo-modal/{token} → { sections } (sin `page`; placement=home|category|product, target_id en category/product) /api/public/featured-benefits/{token} → { sections } (sin `page`; placement=home|category|product, target_id en category/product) /api/public/video-banner/{token} → { sections } (sin `page`; placement=home|category|product, target_id en category/product) /api/public/video-reviews/{token} → { sections } (sin `page`; placement=home|category|product, target_id en category/product)
RESPUESTA: { page, product_id?, category_id?, sections: { [clave]: Seccion } } `page` viene NORMALIZADO: home-page→home, category-page→category, product-page→product clave = `{kind}-{placement}-{targetId|general}-{blockId}` placement ∈ {home, category, product} — idéntico a `page`
SECCION: { tipo, titulo, items[], estado, orden, indice?, nombre_personalizado? } `tipo` = discriminador en MAYUSCULAS (FAQ, RICH_DESCRIPTION, …). Usarlo para despachar. `items` SIEMPRE es array, nunca null. Puede estar vacío.
REGLA DE RENDER (obligatoria) renderizar solo si estado.lifecycle === 'active' && estado.storefrontVisible === trueLas siete reglas que el JSON no te dice
Sección titulada «Las siete reglas que el JSON no te dice»Un esquema describe la forma de la respuesta. Estas son las reglas de comportamiento que hay que respetar igual, y que ninguna inspección del JSON revela:
-
El bundle es un almacén, no una lista de render. Incluye a propósito secciones ocultas y archivadas. Filtrar por
estadoes obligatorio; omitirlo publica contenido que el comerciante apagó. -
El vocabulario de
{page}cambia según haya{targetId}. Con target:product/category. Sin target:product-page/category-page/home-page. Mezclarlos da400, sin fallback. -
Un tipo puede aparecer varias veces en la misma página, con el mismo
kindy distintoblockId. Quedarse con la primera coincidencia descarta contenido en silencio. -
Emparejar por token exacto, nunca por prefijo.
startsWith('faq')también matcheafaq_with_image, que es otro tipo con otro shape. Prefiere el campotipo; si tienes que parsear la clave, corta por-{page}-. -
Un
targetIdsin contenido devuelve200consections: {}, no404. Un404significa que la tienda ya no está activa. Son situaciones distintas. -
Una llamada por página, no una por sección. La respuesta trae todos los tipos juntos. El límite es de 600 peticiones por minuto y por tienda.
-
El texto es contenido libre del comerciante.
titulo,pregunta,respuestaytextotienen que escaparse antes de interpolarse en HTML.
Los tipos de sección
Sección titulada «Los tipos de sección»El comerciante ve un nombre en español; la API devuelve un identificador. Es la misma sección con dos nombres, y quien te encargue trabajo usará el primero:
tipo en el JSON | Token de la clave | Nombre en el panel |
|---|---|---|
FAQ | faq | Preguntas Frecuentes |
FAQ_WITH_IMAGE | faq_with_image | Preguntas con imagen |
IMAGE_CAROUSEL | image_carousel | Carrusel de imágenes |
SPECS | specs | Carrusel de Especificaciones |
SPECS_FAQ | specs_faq | FAQS de Especificaciones |
RICH_DESCRIPTION | rich_description | Banner Características Técnicas |
GRID_PROMOCIONAL | grid_promocional | Grid Promocional |
CALL_TO_ACTION_BANNER | call_to_action_banner | Call to Action Banner |
KEY_FEATURES_BANNER | key_features_banner | Banner de Características Clave |
PROMO_MODAL | promo_modal | Banner Promocional |
FEATURED_BENEFITS | featured_benefits | Beneficios Destacados |
VIDEO_BANNER | video_banner | Video Banner |
VIDEO_REVIEWS | video_reviews | Carrusel de testimonios en video |
El contrato lo fija el tipo, no la etiqueta: los nombres del panel pueden cambiar
sin que cambie el identificador.
Excepciones por tipo
Sección titulada «Excepciones por tipo»Casos donde un tipo se sale del patrón general. Son la fuente habitual de código generado que falla en runtime:
| Tipo | Excepción |
|---|---|
grid_promocional | imagen es un string (URL suelta), no { url, alt }. Los campos de texto están ausentes, no en null. |
rich_description | items[].icono es un string, no un objeto. Las acciones se despachan por modo (image/link/pdf), que determina qué campo existe. |
image_carousel | items[].imagen no es nullable — es el único tipo con esa garantía. |
call_to_action_banner | El contenido está a nivel sección; items siempre viene vacío. boton es { etiqueta, url } — sin nueva_pestana. |
specs | titulo y descripcion son requeridos. |
key_features_banner | Endpoint propio, no llega en el bundle. titulo y descripcion de cada item sí pueden ser null. |
promo_modal | Sobre genérico, sin items: los campos van en campos. buttonUrl es siempre https:// o null; campos.imageUrl puede ser un video (imageMimeType: video/…). |
featured_benefits | Sobre genérico: los campos van en campos. campos.imageUrl puede ser un video (imageMimeType: video/…); el título editable es campos.heading. |
video_banner | Sobre genérico: los campos van en campos. campos.videoUrl es siempre un video (videoMimeType: video/…) o null; cada botón trae url https:// o null. |
video_reviews | Sobre genérico: los campos van en campos. campos.mediaUrl puede ser un video (mediaMimeType: video/…) o null si el archivo no está READY (omite el item); la descripción de la sección es campos.descripcion; productLinkUrl es siempre https:// o null. |
Cache-Control: public, max-age=0, s-maxage=60, stale-while-revalidate=60ETag: W/"…" → reenviar como If-None-Match; un 304 no trae cuerpoEl ETag es opaco: compararlo y reenviarlo, nunca parsearlo. Un cambio del
comerciante puede tardar hasta ~2 minutos en propagarse por la caché de borde.
Errores
Sección titulada «Errores»| Código | Causa | ¿Reintentar? |
|---|---|---|
400 | Token con formato inválido, o page fuera del vocabulario. | No |
401 | Token bien formado pero inexistente. | No |
403 | Origen no permitido. | No |
404 | La tienda ya no está activa. | No |
429 | Límite de peticiones superado. | Sí, con espera |
500 | Error del servidor. | Sí, con backoff |
Cuerpo de error: { statusCode, message, error? }. message es lo único que
distingue dos errores del mismo código.
