Saltar al contenido principal

SEO Signals API

La SEO Signals API es el endpoint canónico que los storefronts headless usan para ir a buscar las señales SEO/AEO/GEO enriquecidas de Clione para una entidad concreta. También es lo que alimenta el SDK @clione/seo por debajo.

Úsala cuando:

  • Estás construyendo un storefront headless / a medida y quieres renderizar las señales de Clione en tu propia plantilla.
  • No quieres instalar un widget de embed o un theme app block.
  • Necesitas control fino sobre qué señales lees y dónde las renderizas.

Para tiendas no-headless (BigCommerce Stencil o temas Liquid de Shopify), prefiere el Schema Injector (BC) o el theme app block (Shopify) — gestionan la misma entrega automáticamente.


Endpoint

GET /api/v1/public/seo-signals/:platform/:entityType/:entityId

Parámetros de path:

ParamValores
platformbigcommerce | shopify
entityTypeproduct | category | collection | page
entityIdEl ID nativo de la plataforma para la entidad (ID de producto de BC, GID o ID numérico de producto de Shopify)

Autenticación

Envía tu API key pública de Clione de una de tres maneras (por orden de preferencia):

Authorization: Bearer sk_live_...
x-api-key: sk_live_...
?apiKey=sk_live_...

La key debe tener scope products:read. Genera keys desde Store → Settings → API Keys.

Aplica la lista blanca de dominios: si tu key tiene allowed domains configurados, el header Origin (o Referer, fallback) de la petición debe coincidir. Pon el dominio permitido al dominio de tu storefront headless.


Forma de la respuesta

{
"entity": {
"id": "1234",
"platform": "shopify",
"entityType": "product",
"name": "Linen bed sheet set",
"url": "https://shop.example.com/products/linen-sheet-set"
},
"signals": {
"metaTitle": "Linen Bed Sheet Set — Cool, Breathable, Made in Portugal",
"metaDescription": "Pure European linen sheet set ideal for hot sleepers...",
"canonicalUrl": "https://shop.example.com/products/linen-sheet-set",
"keywords": ["linen sheets", "breathable bedding", "summer bedding", "sábanas de lino"],
"ogTags": {
"title": "Linen Bed Sheet Set",
"description": "Cool, breathable bedding...",
"image": "https://cdn.example.com/linen.jpg",
"type": "product"
},
"jsonLd": {
"@context": "https://schema.org",
"@type": "Product",
"name": "Linen Bed Sheet Set",
"description": "...",
"keywords": "linen sheets, breathable bedding...",
"offers": {
"@type": "Offer",
"price": "129.00",
"priceCurrency": "EUR"
}
}
},
"metadata": {
"enrichedAt": "2026-05-30T11:23:45.000Z",
"version": 4
}
}

Los campos vacíos se omiten (no se devuelven como null). Si la entidad no está enriquecida, signals es {} y metadata.enrichedAt es null.


Ejemplo — fetch

const apiKey = process.env.CLIONE_API_KEY
const platform = 'shopify'
const productId = '1234'

const res = await fetch(
`https://api.clione.ai/api/v1/public/seo-signals/${platform}/product/${productId}`,
{
headers: { Authorization: `Bearer ${apiKey}` },
},
)

if (!res.ok) throw new Error(`Clione SEO Signals: ${res.status}`)

const { signals, entity } = await res.json()

Ejemplo — curl

curl -s \
-H "Authorization: Bearer sk_live_..." \
"https://api.clione.ai/api/v1/public/seo-signals/shopify/product/1234" | jq .

Renderizar en Next.js (Hydrogen / Catalyst / Vue Storefront)

La mayoría de frameworks tienen una API de head / metadata. Mapea las señales sobre ella:

Next.js App Router

import { getSignals } from '@clione/seo'

export async function generateMetadata({ params }) {
const { signals, entity } = await getSignals('product', params.id, {
apiKey: process.env.CLIONE_API_KEY,
storeId: process.env.CLIONE_STORE_ID,
platform: 'shopify',
})

return {
title: signals.metaTitle,
description: signals.metaDescription,
alternates: { canonical: signals.canonicalUrl },
openGraph: signals.ogTags,
other: {
'script:ld+json': JSON.stringify(signals.jsonLd),
},
}
}

Nuxt / Vue Storefront

import { useClioneSignals } from '@clione/seo/nuxt'

const { signals } = await useClioneSignals('product', productId)
useHead({
title: signals.metaTitle,
meta: [
{ name: 'description', content: signals.metaDescription },
...Object.entries(signals.ogTags).map(([k, v]) => ({ property: `og:${k}`, content: v })),
],
link: [{ rel: 'canonical', href: signals.canonicalUrl }],
script: [{ type: 'application/ld+json', innerHTML: JSON.stringify(signals.jsonLd) }],
})

Mira @clione/seo para el SDK.


Notas por plataforma

La forma de la respuesta es idéntica entre BigCommerce y Shopify. El parámetro de path :platform es la única diferencia.

BigCommerce

  • entityType: product devuelve JSON-LD completo con aggregateRating si las reviews están activadas en BC.
  • entityType: category devuelve meta title + description + keywords. Sin JSON-LD aún.
  • entityType: page devuelve meta title + description + keywords. Sin JSON-LD aún.
  • entityId es el ID numérico de BC (p. ej. 1234), no el slug.

Shopify

  • entityType: product devuelve JSON-LD completo.
  • entityType: collection devuelve meta title + description. Sin JSON-LD aún.
  • entityType: page devuelve meta title + description. Sin JSON-LD aún.
  • entityId acepta tanto el ID numérico (1234) como el GID (gid://shopify/Product/1234).

Caché

Las respuestas incluyen Cache-Control: public, max-age=60. Cachea en tu edge (Cloudflare, Vercel) para reducir latencia. Clione también cachea las señales enriquecidas server-side e invalida al enriquecer, así que puedes cachear más tiempo si tu tráfico lo justifica.


Respuestas de error

StatusCausa
401API key ausente o inválida.
403API key válida pero el Origin no está en los allowed domains, o falta el scope products:read.
404Entidad no encontrada (ID equivocado, plataforma equivocada, o no sincronizada).
429Rate limit. Backoff y reintenta. Los límites son generosos (100 req/seg/key) pero deployments headless martilleando un producto caliente pueden alcanzarlos.
5xxError del servidor. Reintenta con backoff exponencial.

Solución de problemas

Devuelve 404 aunque veo el producto en mi dashboard — El producto está en la BBDD de Clione pero no para la plataforma que consultaste. Revisa que :platform coincida con la tienda desde la que se sincronizó el producto. Confirma también que la entidad ha sido sincronizada (no solo creada en el admin de la plataforma ayer).

Objeto signals vacío — El producto no se ha enriquecido. Enriquécelo primero desde el dashboard.

JSON-LD sin aggregateRating — Las reviews no están activadas en tu plataforma O ningún producto tiene ratings aún. Mira Configuración de Reviews.