El JSON de publicaciones y perfiles de X, campo por campo: una referencia para agentes

El JSON de publicaciones y perfiles de X, campo por campo: una referencia para agentes
Unif Engineering team
Unif Engineering team

Actualizado

Cada campo que devuelven los endpoints gratis de X de UnifAPI para posts, perfiles, páginas, límites y errores, con tipos y casos límite.

En resumen: los endpoints de X en UnifAPI, gratis, sin iniciar sesión y con límite por visitante, devuelven tres registros (post, profile y el envoltorio page de las listas) más una forma de error y tres encabezados de límite de uso. Los nombres de campo van en camelCase, los ids son cadenas (superan 2^53), las fechas son ISO 8601 en UTC, los recuentos son enteros y todo lo que X no informa está ausente, no a cero. Esta página lista cada campo con su tipo y los casos que un programa tiene que manejar: un repost que trae la publicación original más repostedBy, una cita que se anida un nivel, una cuenta protegida que devuelve sus recuentos pero no sus publicaciones, y views, que X informa en la mayoría de las publicaciones pero no en todas.

Los modelos leen bien el JSON que ya han visto. La diferencia entre un agente que usa una fuente de datos correctamente y uno que adivina nombres de campo está en si la referencia estaba en su contexto o en sus datos de entrenamiento. Esta es esa referencia. Es el mismo modelo que renderizan las páginas de los visualizadores para personas, así que lo que ves en /tools/x-profile-viewer es exactamente lo que devuelve /tools/x/profile?handle=….

Convenciones

  • Los ids son cadenas. Los ids de X son de 64 bits; los números JSON pierden precisión por encima de 2^53. Todo id es una cadena, también en las URLs y los cursores.
  • Las fechas son ISO 8601, UTC. createdAt y joinedAt tienen la forma 2026-10-05T22:33:56.000Z.
  • Los recuentos son enteros. Nunca cadenas formateadas, nunca nulos. Un recuento que X no informó se omite, no se pone a 0.
  • Opcional significa ausente. Un campo marcado como opcional falta en el objeto cuando no hay valor. Comprueba con "views" in post.metrics, no con === 0.
  • Las URLs son URLs canónicas de x.com. post.url es https://x.com/<handle>/status/<id>; las URLs de medios apuntan al CDN de X y nunca se vuelven a alojar.

post

Lo devuelve /tools/x/post (como post), y es cada elemento de posts.items en profile, media y search, y de replies.items en replies.

CampoTipoSignificado
idstringID de la publicación
textstringTexto completo. Las publicaciones largas (notas) se devuelven enteras; el enlace corto de medios del final se elimina cuando hay medios adjuntos
createdAtstring (ISO 8601)Hora de publicación
languagestring, opcionalCódigo BCP-47 detectado por X (en, ja, …)
conversationIdstring, opcionalId de la publicación raíz del hilo al que pertenece esta
inReplyToPostIdstring, opcionalLa publicación a la que responde esta, cuando es una respuesta
possiblySensitivebooleanLa marca de la propia X
urlstringURL canónica de x.com
authorprofile o nullEl autor; null solo cuando X lo ha retenido
metricsobjectVer abajo
mediaarray de mediaVacío cuando no hay
repostedByobject o nullPresente cuando esta entrada es un repost: { id, handle, name } de la cuenta que lo reposteó. El resto del registro es la publicación original
quotedpost o nullLa publicación citada cuando esta es una cita, anidada un nivel (una cita dentro de una cita no se expande)

metrics

CampoTipoSignificado
likesinteger
repostsintegerReposts (retweets), sin contar las citas
repliesintegerEl recuento de respuestas de X; puede superar el número de respuestas públicas legibles
quotesintegerPublicaciones que citan
bookmarksinteger
viewsinteger, opcionalImpresiones. X las informa en la mayoría de las publicaciones; ausente cuando no lo hace

media

CampoTipoSignificado
kindphoto | video | animated_gif
urlstring, opcionalImagen a tamaño completo, o el fotograma de portada para video y GIF
previewUrlstring, opcionalHoy es igual que url; reservado para una versión más pequeña
width, heightinteger, opcionalDimensiones originales
durationMsinteger, opcionalDuración del video
videoUrlstring, opcionalEl MP4 de mayor bitrate que expone X, en el CDN de X

profile

Lo devuelven /tools/x/profile, /tools/x/media y /tools/x/followers (como profile), es post.author y es cada elemento de users.items en followers.

CampoTipoSignificado
idstringID de usuario
handlestringSin la @, con las mayúsculas y minúsculas de X (NASA)
namestringNombre visible
verifiedbooleanCualquier verificación (azul, gobierno, empresa)
verifiedTypestring, opcionalGovernment, Business, … cuando X indica uno
protectedbooleanLas publicaciones no son públicas. Los endpoints devuelven los recuentos pero no las publicaciones
biostringPuede estar vacía
locationstringTexto libre, puede estar vacío
websitestring, opcionalURL expandida, no el enlace corto t.co
joinedAtstring (ISO 8601)
avatarUrlstring, opcionalVersión de 400×400
bannerUrlstring, opcional
followersinteger
followinginteger
postsintegerRecuento de publicaciones de toda la vida de la cuenta
listedinteger, opcionalListas en las que aparece la cuenta, cuando se informa
pinnedPostIdstring, opcional
urlstringhttps://x.com/<handle>

/tools/x/profile añade engagementRate: la media de me gusta, respuestas, reposts y citas por publicación original de la página, dividida entre los seguidores, como porcentaje con cuatro cifras significativas. Los reposts quedan fuera de la media. Para una cuenta con 90 millones de seguidores es un número pequeño (0.0058), lo cual es correcto, no un error.

page

Toda lista va envuelta:

{ "items": [ … ], "hasMore": true, "nextCursor": "DAAHCgABHUAq3YL__-wLAAIAAAATMj…" }
CampoTipoSignificado
itemsarrayregistros post, o registros profile en followers, o registros community
hasMorebooleanTrue exactamente cuando nextCursor está presente
nextCursorstring o nullOpaco. Devuélvelo como cursor= para obtener la página siguiente

Tamaños de página: 10 publicaciones en profile, 12 en media, 20 en replies, search y communities, 50 en followers, 30 tendencias. Los cursores son opacos; algunos tienen la forma 20@, otros son las cadenas DAAH… de la propia X. Nunca los analices.

Tendencias y comunidades

/tools/x/trends devuelve { woeid, locationSlug, generatedAt, trends: [ { rank, name, postCount?, url } ] }. postCount solo está presente en las tendencias para las que X informa un volumen; hoy, en la mayoría de las ubicaciones, no es ninguna, así que trátalo como opcional. url es la búsqueda en vivo en x.com.

/tools/x/communities devuelve { query, communities: page }, donde cada elemento es { id, name, description, memberCount?, access?, joinPolicy?, createdAt?, url }.

Encabezados de límite de uso

En cada respuesta, con éxito o con error:

X-RateLimit-Limit: 20
X-RateLimit-Remaining: 17
X-RateLimit-Reset: 1791357984

Reset son los segundos Unix del momento en que termina la ventana actual de 10 minutos. Una búsqueda cuesta 2 unidades; todo lo demás, 1. Un 429 añade Retry-After en segundos.

Errores

Toda respuesta que no sea 2xx es:

{ "error": { "type": "not_found", "message": "X user not found: @nobody_here_123" } }
typeHTTPCuándo
validation_error400Entrada ausente o mal formada (Missing handle: pass ?handle=…)
not_found404No existe la cuenta o la publicación; las cuentas suspendidas lo indican en el mensaje
rate_limited429Límite gratuito alcanzado; el cuerpo añade retryAfterSeconds y upgrade
upstream_error502La capa de datos de X respondió con un error
upstream_unavailable503Tiempo de espera agotado o inalcanzable
not_configured503El despliegue no tiene credenciales aguas arriba

Ramifica según type; message es para personas y puede cambiar.

Modo Markdown

Añade format=md o envía Accept: text/markdown a cualquier endpoint y el mismo registro se renderiza como Markdown: un encabezado con el autor, el texto, una línea de métricas, enlaces a los medios, la URL y un pie que indica el cursor siguiente. Lleva todos los campos de arriba salvo los ids en bruto dentro del objeto del autor, y es la forma más barata de meter un perfil o un hilo en el contexto de un modelo.

Dónde están las muestras

La página Markdown de cada herramienta trae una respuesta real capturada de su endpoint, recortada a unos pocos elementos: /tools/x-profile-viewer/index.md, /tools/x-post-viewer/index.md, /tools/x-search/index.md, etc. /llms.txt lista los ocho con una URL de ejemplo cada uno. La API de X / Twitter con medición de uso usa los mismos nombres de campo detrás de una clave de workspace, así que el código escrito contra los endpoints gratuitos se traslada sin cambios.