tellmelotellmelo.
Aviso legalPrivacidadCondiciones de usoDenunciar derechos de autorContactoAPIAplicaciones

API

Esto es una traducción. La versión alemana es la vinculante: si este texto difiere de ella, se aplica el alemán. Puedes cambiar de idioma al pie de la página.

Primeros pasos

  • Visión general
  • Inicio rápido
  • Tu clave
  • Lo que puede una clave
  • Lo que ninguna clave puede

Fundamentos

  • Peticiones y respuestas
  • Páginas
  • Solo lo nuevo
  • Límites
  • Cabeceras
  • Cuando algo no funciona
  • Versiones

Rutas

  • Rutas
  • La entrada
    • GET /
  • Publicaciones
    • GET /posts
    • GET /posts/{id}
    • POST /posts
    • DELETE /posts/{id}
  • Respuestas
    • GET /posts/{id}/replies
    • POST /posts/{id}/replies
  • Encuestas
    • POST /posts/{id}/vote
  • Perfiles
    • GET /profiles/{handle}
    • GET /profiles/{handle}/posts
  • Comunidades
    • GET /communities
    • GET /communities/{id}
    • GET /communities/{id}/posts
  • Descubrir
    • GET /tags
    • GET /search
    • GET /emojis
  • Tu cuenta
    • GET /me
    • GET /feed
  • Notificaciones
    • GET /notifications
    • POST /notifications/read
  • Mensajes
    • GET /conversations
    • GET /conversations/{with}/messages
    • POST /conversations/{with}/messages
    • POST /conversations/{with}/read
  • Relaciones
    • POST /relations

Objetos

  • Objetos
  • Service
  • RateLimit
  • Post
  • Reply
  • Counts
  • Media
  • Poll
  • PollOption
  • ProfileBrief
  • Profile
  • CommunityBrief
  • Community
  • Tag
  • SearchResult
  • Emoji
  • Notification
  • Actor
  • Conversation
  • Message
  • Created
  • Ok

Más

  • La descripción legible por una máquina
  • Qué ha sido de v1
  • Lo que esperamos
Contenido

Primeros pasos

  • Visión general
  • Inicio rápido
  • Tu clave
  • Lo que puede una clave
  • Lo que ninguna clave puede

Fundamentos

  • Peticiones y respuestas
  • Páginas
  • Solo lo nuevo
  • Límites
  • Cabeceras
  • Cuando algo no funciona
  • Versiones

Rutas

  • Rutas
  • La entrada
    • GET /
  • Publicaciones
    • GET /posts
    • GET /posts/{id}
    • POST /posts
    • DELETE /posts/{id}
  • Respuestas
    • GET /posts/{id}/replies
    • POST /posts/{id}/replies
  • Encuestas
    • POST /posts/{id}/vote
  • Perfiles
    • GET /profiles/{handle}
    • GET /profiles/{handle}/posts
  • Comunidades
    • GET /communities
    • GET /communities/{id}
    • GET /communities/{id}/posts
  • Descubrir
    • GET /tags
    • GET /search
    • GET /emojis
  • Tu cuenta
    • GET /me
    • GET /feed
  • Notificaciones
    • GET /notifications
    • POST /notifications/read
  • Mensajes
    • GET /conversations
    • GET /conversations/{with}/messages
    • POST /conversations/{with}/messages
    • POST /conversations/{with}/read
  • Relaciones
    • POST /relations

Objetos

  • Objetos
  • Service
  • RateLimit
  • Post
  • Reply
  • Counts
  • Media
  • Poll
  • PollOption
  • ProfileBrief
  • Profile
  • CommunityBrief
  • Community
  • Tag
  • SearchResult
  • Emoji
  • Notification
  • Actor
  • Conversation
  • Message
  • Created
  • Ok

Más

  • La descripción legible por una máquina
  • Qué ha sido de v1
  • Lo que esperamos

Visión general

v2 es la API de tellmelo para tus propios programas. Cada petición lleva una clave, cada respuesta es JSON y cada lista se pagina de la misma manera. Lo que ocurre detrás de una clave pasa por las mismas reglas que un clic en la aplicación: límites de ritmo, suspensiones, derechos retirados y los ajustes de esta instancia valen aquí igual.

  • Cada ruta empieza por /api/v2 en la dirección de esta instancia, la que aparece en los ejemplos de esta página.
  • Las peticiones y las respuestas son JSON en UTF-8. Los nombres de campo, los códigos y los valores están en inglés y seguirán así.
  • Una clave actúa como tu cuenta y nunca más allá: lo que no puedes ver en la aplicación, tampoco lo puede leer ninguna clave.
https://tellmelo.com/api/v2

Inicio rápido

  1. Crea una clave en «Ajustes → App y datos → API» y cópiala. Solo se muestra una vez.
  2. Consulta con ella la raíz. La respuesta dice qué versión está funcionando, qué puede hacer la clave y cuántas peticiones le quedan en este minuto.
  3. A partir de ahí todas las rutas funcionan igual: la clave en la cabecera, JSON de vuelta y, en las listas, items y next.
curl -H "Authorization: Bearer tm_key_…" https://tellmelo.com/api/v2
{
  "name": "tellmelo",
  "version": "2.6",
  "scope": "read write",
  "rateLimit": {
    "limit": 120,
    "remaining": 117
  },
  "docs": "/legal/api",
  "spec": "/api/v2/openapi.json"
}

Para seguir: /me para tu propio perfil, /posts para lo público, /feed para lo que te muestra la aplicación.

Tu clave

Hay exactamente una clave por cuenta, ligada a tu identificador de usuario. Empieza por tm_key_, para que un escáner la reconozca donde no pinta nada. Se muestra una sola vez, en el momento en que se crea; después aquí solo queda su huella, y nadie te la puede volver a leer, ni nosotros ni tú. Quien la pierde crea una nueva; la vieja deja de valer en ese momento.

La creas en «Ajustes → App y datos → API». Viaja en la cabecera de la petición, como Authorization: Bearer tm_key_… o como X-Tellmelo-Key. No en la barra de direcciones, porque lo que está ahí acaba en los registros de acceso, en el historial del navegador y en el referer de cada enlace.

curl -H "Authorization: Bearer tm_key_…" \
  https://tellmelo.com/api/v2/posts

O, si te resulta más cómodo, en una cabecera propia:

curl -H "X-Tellmelo-Key: tm_key_…" https://tellmelo.com/api/v2

No en la barra de direcciones. Lo que está ahí acaba en el registro de cada servidor intermedio, en el historial del navegador y en el referer de cada enlace. Una clave no pinta nada ahí.

La misma clave también carga imágenes. Cada url de una respuesta apunta a /api/media de esta instancia; envía allí también la clave en la cabecera y la imagen vuelve, en la medida en que tu cuenta pueda verla.

curl -H "Authorization: Bearer tm_key_…" \
  -o picture.webp "https://tellmelo.com/api/media?id=…"

Lo que puede una clave

Una clave lleva dos derechos, y cada ruta de las tablas de abajo dice cuál de ellos necesita. Dos y no cinco: un derecho que no sabes explicarte en una frase es un derecho que marcas sin leer. Y la línea honesta pasa entre mirar y cambiar.

  • read: mirar. Las publicaciones públicas, los perfiles, las comunidades y las etiquetas, y tu propia cuenta tal como la ves: feed, notificaciones, conversaciones, mensajes.
  • write: cambiar. Todo lo que ocurre en tu nombre: publicar, responder, votar, enviar mensajes, seguir, unirse, bloquear, marcar notificaciones como leídas.

Lo que ninguna clave puede

Ninguna clave llega a los datos de tu cuenta: ni contraseña, ni dirección de correo, ni tipo de cuenta, ni lugar, ni rol, ni eliminación. Tampoco las sesiones, ni los dispositivos de aviso, ni las claves mismas: una que pudiera emitir claves ya no se podría apagar. Tampoco la administración, ni la dirección de una comunidad, porque disolver una comunidad o entregarla es una decisión sobre publicaciones ajenas. Lo que guarda la contraseña, ninguna clave lo puede: un secreto que está en un script en la máquina de otro no debe poder lo que puede el inicio de sesión. Apoderarse de una cuenta sigue costando el inicio de sesión.

Peticiones y respuestas

  • JSON en todas partes. Cada respuesta es application/json en UTF-8, errores incluidos. Solo las imágenes llegan como imágenes.
  • Lo que envías. Un POST lleva sus campos como objeto JSON en el cuerpo. Los parámetros de la dirección completan lo que el cuerpo no nombra; si ambos nombran el mismo campo, gana el cuerpo.
  • Las fechas son números enteros de milisegundos desde el 1 de enero de 1970, UTC, tal como las guarda la base de datos. No hay zona horaria que leer mal.
  • Los identificadores son cadenas. No los desmontes ni confíes en su forma; compáralos solo enteros.
  • Cada campo está siempre. Lo que no existe es null, nunca falta; un recuento es siempre un número y una lista siempre una lista, vacía si hace falta.
  • Los textos son texto plano, tal como se escribieron. Las #etiquetas, los @nombres y los enlaces quedan como están, igual que los emojis propios de la instancia, como :name:; sus imágenes están en /emojis.
  • Las imágenes son direcciones relativas a esta instancia, /api/media?id=…. Cárgalas con la misma clave en la cabecera; sin ella la respuesta es 401.

Páginas

Cada lista toma limit y cursor y responde con items y next. Sigues enviando de vuelta el next de la última respuesta como cursor; cuando next está vacío, se ha llegado al final. Una página llena puede ser aun así la última, y quien solo para ante una página vacía pregunta una vez de más. El cursor es opaco: un lugar en una lista, no un instante. No lo desarmes ni te fabriques uno; lo que lleva dentro puede cambiar sin que cambie ninguna ruta.

{ "items": [ … ], "next": "MTc1ODYyNDAwMDAwMDo1ZjBjMmE5ZS04ZDQx" }

curl -H "Authorization: Bearer tm_key_…" \
  "https://tellmelo.com/api/v2/posts?limit=20&cursor=MTc1ODYyNDAwMDAwMDo1ZjBjMmE5ZS04ZDQx"

Una página tiene 20 entradas sin limit, 50 como mucho. Algunas listas no se paginan en absoluto: se indica en su ruta, y su next es siempre null.

Solo lo nuevo

Cada respuesta lleva un ETag. Un programa que pregunta una y otra vez debería devolver el último como If-None-Match: si desde entonces no ha cambiado nada, la respuesta es 304 y no lleva cuerpo. Esa es la diferencia entre una lista que cruza el cable cada minuto y una que lo cruza cuando hay algo dentro, para tu máquina tanto como para esta.

ETag: W/"3Qk1mJ7fQe2Yb0sVxT9aL4pNdRc"
If-None-Match: W/"3Qk1mJ7fQe2Yb0sVxT9aL4pNdRc"  →  304

Dos excepciones, ambas a propósito: /feed no lleva ETag, porque su orden se mueve con el tiempo y cada respuesta es distinta; y una escritura nunca responde 304. Dos publicaciones iguales son dos publicaciones.

Límites

Una clave puede hacer 120 peticiones por minuto, 600 con la suscripción «Organización», salvo que la administración le haya puesto otro número. El límite vale por clave, no por cuenta ni por dirección. Por encima, la respuesta es 429 y no ha pasado nada: la petición se rechazó, no se ejecutó. Espera un minuto y vuelve a enviarla; un programa que choca a menudo debería ir más despacio en vez de preguntar otra vez al momento.

X-RateLimit-Limit: 120
X-RateLimit-Remaining: 117
X-RateLimit-Reset: 1758624060

Además del límite de la clave, las escrituras cuentan para los mismos límites que en la aplicación: cuántas publicaciones, respuestas o relaciones en pocos minutos. También responden 429 con el código rate_limited.

Cabeceras

Los nombres son los que ya conoce cualquier biblioteca cliente. Ninguna es obligatoria salvo la clave.

Lo que envías

CabeceraSignificado
AuthorizationLleva la clave: Bearer tm_key_…. La forma habitual.
X-Tellmelo-KeyLa clave, como alternativa a Authorization, para herramientas que usan esa cabecera para otra cosa.
Content-Typeapplication/json, para una petición con cuerpo.
If-None-MatchEl ETag de la última respuesta. Si nada ha cambiado desde entonces, la respuesta es 304 sin cuerpo.

Lo que vuelve

CabeceraSignificado
ETagLa huella de esta respuesta, marcada como débil (W/). Devuélvela como If-None-Match.
X-RateLimit-LimitCuántas peticiones puede hacer esta clave por minuto.
X-RateLimit-RemainingCuántas quedan en el minuto actual.
X-RateLimit-ResetCuándo empieza el siguiente minuto, en segundos desde 1970, UTC.
X-Tellmelo-ScopeLo que puede hacer esta clave: read o read write.
Retry-AfterCon un 429: cuántos segundos esperar antes de volver a preguntar.
WWW-AuthenticateCon un 401 por falta de clave: Bearer, así se espera una clave.
Cache-Controlno-store: ningún proxy intermedio puede guardar una respuesta, porque depende de la clave que pregunta. Tu propio programa sí puede comprobarla con el ETag.

Cuando algo no funciona

Los errores llegan como JSON con dos campos: un código fijo en inglés en error que tu programa puede comparar, y una frase en message para la persona que está delante, con el código de estado que le corresponde. El código se mantiene; la frase puede cambiar, y puede cambiar en cualquier idioma: un programa que compara la frase se rompe un día que nadie ha anunciado.

{ "error": "rate_limited",
  "message": "Too many requests. Try again in a minute.",
  "limit": 120 }

Algunos errores traen un campo más: docs con un 401 por falta de clave, limit con un 429.

EstadoCódigoSignificado
400bad_requestLa petición no se puede leer, falta un campo obligatorio o un valor no está entre los permitidos. El message dice cuál.
401key_missingNo hay clave en la cabecera.
401key_invalidLa clave no es válida: mal copiada, sustituida por una nueva o su cuenta está suspendida. Cuál de estas, no se dice a propósito.
401unauthorizedRechazado como sin sesión, por un motivo distinto de la clave. Raro, y un motivo para mirar la cuenta que hay detrás de la clave.
403scope_missingA la clave le falta el derecho que necesita esta ruta: casi siempre write en una clave que solo puede leer.
403account_data_lockedEsto afecta a los datos de tu cuenta, a los que no llega ninguna clave: contraseña, correo electrónico, eliminación y cosas así.
403forbiddenTu cuenta no puede hacer esto: el mismo rechazo que en la aplicación, por ejemplo un derecho retirado o un bloqueo.
404unknown_pathEsta ruta no existe, o no con este método.
404not_foundLa ruta existe, pero no lo que nombra, o no puedes verlo. Ambas cosas no se distinguen.
409conflictChoca con algo que ya existe, por ejemplo un nombre ocupado.
413too_largeDemasiado grande: un texto o una petición por encima de lo que acepta esta instancia.
422unprocessableLegible, pero no posible de esta forma.
429rate_limitedDemasiadas peticiones. No se ha hecho nada; espera y envíala de nuevo.
500internal_errorAlgo ha fallado de nuestro lado, no del tuyo. Queda registrado completo en el servidor.

Versiones

La versión está en la ruta. Mientras ahí ponga v2, estas rutas y sus campos se quedan como están; lo que se añade viene al lado.

Las novedades suben el segundo número: 2.1 trajo /emojis y marcar una conversación como leída. 2.4 quitó el campo contentWarning, porque ya no hay avisos de contenido. 2.5 quitó el campo alt de las imágenes, porque ya no hay descripciones de imágenes. 2.6 añade el tipo de notificación team para el nuevo trabajo del equipo. Cada ruta dice desde qué versión existe, y la raíz dice qué versión está funcionando.

Rutas

Todas las rutas de un vistazo y luego cada una en detalle: qué recibe, una petición de ejemplo y qué devuelve.

RutaDerechoPara qué
La entrada
GET/api/v2readLa entrada: qué versión habla esta API y cómo se llama esta instancia.
Publicaciones
GET/api/v2/postsreadLas publicaciones públicas, las más nuevas primero.
GET/api/v2/posts/{id}readUna sola publicación, por su id.
POST/api/v2/postswritePublicar una publicación.
DELETE/api/v2/posts/{id}writeRetirar una publicación tuya.
Respuestas
GET/api/v2/posts/{id}/repliesreadLas respuestas a una publicación, tal como las ves tú: lo que escribió una cuenta bloqueada se queda fuera.
POST/api/v2/posts/{id}/replieswriteResponder a una publicación.
Encuestas
POST/api/v2/posts/{id}/votewriteParticipar en una encuesta.
Perfiles
GET/api/v2/profiles/{handle}readUn perfil, por su alias.
GET/api/v2/profiles/{handle}/postsreadLas publicaciones públicas de un perfil, las más nuevas primero.
Comunidades
GET/api/v2/communitiesreadLas comunidades abiertas de esta instancia.
GET/api/v2/communities/{id}readUna sola comunidad, por su id.
GET/api/v2/communities/{id}/postsreadLas publicaciones públicas de una comunidad, las más nuevas primero.
Descubrir
GET/api/v2/tagsreadLas etiquetas que están en marcha ahora mismo.
GET/api/v2/searchreadUna búsqueda por publicaciones, nombres, alias y etiquetas.
GET/api/v2/emojisreadLos emojis propios de la instancia, con la dirección de sus imágenes.
Tu cuenta
GET/api/v2/mereadTu propio perfil, con el id que esperan las demás rutas.
GET/api/v2/feedreadTu propio feed, tal como lo compone la aplicación.
Notificaciones
GET/api/v2/notificationsreadTus propias notificaciones, las más nuevas primero, paginables, para que un programa recupere lo que se ha perdido.
POST/api/v2/notifications/readwriteMarcar tus notificaciones como leídas.
Mensajes
GET/api/v2/conversationsreadTu buzón: una fila por conversación, la más reciente primero.
GET/api/v2/conversations/{with}/messagesreadLos mensajes de una conversación, los más nuevos primero.
POST/api/v2/conversations/{with}/messageswriteEnviar un mensaje en una conversación.
POST/api/v2/conversations/{with}/readwriteMarcar como leídos todos los mensajes de una conversación.
Relaciones
POST/api/v2/relationswriteDar me gusta, guardar, compartir, seguir, unirse, bloquear, silenciar, según kind.

La entrada

La primera petición de todo programa: ¿funciona la clave y qué puede hacer?

GET/api/v2

La entrada: qué versión habla esta API y cómo se llama esta instancia.

  • Derecho read
  • con ETag
  • desde v2.0

Sin barra al final: /api/v2/ redirige a /api/v2 con 308, y no todos los programas lo siguen.

Petición de ejemplo

curl \
  -H "Authorization: Bearer tm_key_…" \
  "https://tellmelo.com/api/v2"

Respuesta

Responde con un Service.

Ejemplo
{
  "name": "tellmelo",
  "version": "2.6",
  "scope": "read write",
  "rateLimit": {
    "limit": 120,
    "remaining": 117
  },
  "docs": "/legal/api",
  "spec": "/api/v2/openapi.json"
}

Estados posibles: 200304401429

Publicaciones

Leer publicaciones públicas, publicar las tuyas y volver a quitarlas.

GET/api/v2/posts

Las publicaciones públicas, las más nuevas primero.

  • Derecho read
  • paginable
  • con ETag
  • desde v2.0

En las rutas públicas no se cuentan las reacciones: counts.likes y counts.reposts son 0 y pinned es false (un recorte, no una medición).

Las publicaciones dentro de una comunidad no se alcanzan aquí, ni en la lista ni por su id. Se leen en /communities/{id}/posts.

Parámetros

NombreTipoSignificado
limiten la direcciónintegeropcionalCuántas entradas caben en una página: 20 por defecto, 50 como máximo.
cursoren la direcciónstringopcionalPor dónde sigue: el next de la respuesta anterior. Sin él, desde arriba.

Petición de ejemplo

curl \
  -H "Authorization: Bearer tm_key_…" \
  "https://tellmelo.com/api/v2/posts?limit=20"

Respuesta

Responde con una página de Post, como `items` y `next`.

Ejemplo
{
  "items": [
    {
      "id": "5f0c2a9e-8d41-4b7a-9c3e-2e61d0f4a7b1",
      "text": "The bees are back in the garden 🐝 #garden",
      "kind": "poll",
      "author": {
        "id": "a3e1f7c2-54b9-4d0e-8f16-7b2c9d4e1a05",
        "handle": "mara",
        "name": "Mara 🌻",
        "verified": true,
        "accountKind": "person"
      },
      "community": {
        "id": "c81d4e2a-0f3b-4a6c-9e57-1d2b3c4a5f60",
        "name": "Urban Gardening"
      },
      "media": [
        {
          "url": "/api/media?id=b2d7e9f1-3c4a-4e8b-a1f0-6d5c4b3a2918"
        }
      ],
      "poll": {
        "options": [
          {
            "text": "Lavender",
            "votes": 12
          },
          {
            "text": "Sunflowers",
            "votes": 7
          },
          {
            "text": "Clover",
            "votes": 3
          }
        ],
        "total": 22,
        "multiple": false,
        "endsAt": 1758710400000,
        "running": true,
        "resultsVisible": true,
        "myVotes": [
          0
        ]
      },
      "quotes": null,
      "continues": null,
      "counts": {
        "replies": 4,
        "likes": 31,
        "reposts": 2
      },
      "pinned": false,
      "createdAt": 1758624000000
    }
  ],
  "next": "MTc1ODYyNDAwMDAwMDo1ZjBjMmE5ZS04ZDQx"
}

Estados posibles: 200304401429

GET/api/v2/posts/{id}

Una sola publicación, por su id.

  • Derecho read
  • con ETag
  • desde v2.0

En las rutas públicas no se cuentan las reacciones: counts.likes y counts.reposts son 0 y pinned es false (un recorte, no una medición).

Las publicaciones dentro de una comunidad no se alcanzan aquí, ni en la lista ni por su id. Se leen en /communities/{id}/posts.

Parámetros

NombreTipoSignificado
iden la rutastringobligatorioEl id de una publicación.

Petición de ejemplo

curl \
  -H "Authorization: Bearer tm_key_…" \
  "https://tellmelo.com/api/v2/posts/5f0c2a9e-8d41-4b7a-9c3e-2e61d0f4a7b1"

Respuesta

Responde con un Post.

Ejemplo
{
  "id": "5f0c2a9e-8d41-4b7a-9c3e-2e61d0f4a7b1",
  "text": "The bees are back in the garden 🐝 #garden",
  "kind": "poll",
  "author": {
    "id": "a3e1f7c2-54b9-4d0e-8f16-7b2c9d4e1a05",
    "handle": "mara",
    "name": "Mara 🌻",
    "verified": true,
    "accountKind": "person"
  },
  "community": {
    "id": "c81d4e2a-0f3b-4a6c-9e57-1d2b3c4a5f60",
    "name": "Urban Gardening"
  },
  "media": [
    {
      "url": "/api/media?id=b2d7e9f1-3c4a-4e8b-a1f0-6d5c4b3a2918"
    }
  ],
  "poll": {
    "options": [
      {
        "text": "Lavender",
        "votes": 12
      },
      {
        "text": "Sunflowers",
        "votes": 7
      },
      {
        "text": "Clover",
        "votes": 3
      }
    ],
    "total": 22,
    "multiple": false,
    "endsAt": 1758710400000,
    "running": true,
    "resultsVisible": true,
    "myVotes": [
      0
    ]
  },
  "quotes": null,
  "continues": null,
  "counts": {
    "replies": 4,
    "likes": 31,
    "reposts": 2
  },
  "pinned": false,
  "createdAt": 1758624000000
}

Estados posibles: 200304400401404429

POST/api/v2/posts

Publicar una publicación.

  • Derecho write
  • desde v2.0

Una publicación necesita texto o una encuesta. Su longitud, el número de respuestas de una encuesta y cuántas publicaciones en cuánto tiempo los fija esta instancia; por encima, la respuesta es 400 o 429, con un message que dice cuál.

Todavía no se pueden adjuntar imágenes a través de la API, solo en la aplicación.

Parámetros

NombreTipoSignificado
texten el cuerpostringopcionalEl texto mismo: de la publicación, de la respuesta o del mensaje.
communityen el cuerpostringopcionalEl id de la comunidad a la que va la publicación. Sin él, fuera de toda comunidad.
quotesen el cuerpostringopcionalEl id de la publicación que esta cita.
pollen el cuerpostring[]opcionalLas opciones de respuesta de una encuesta, como una lista de textos. Cuántas se permiten lo fija la instancia.

Petición de ejemplo

curl -X POST \
  -H "Authorization: Bearer tm_key_…" \
  -H "Content-Type: application/json" \
  -d '{"text":"The bees are back in the garden 🐝 #garden"}' \
  "https://tellmelo.com/api/v2/posts"

Respuesta

Responde con un Created.

Ejemplo
{
  "id": "5f0c2a9e-8d41-4b7a-9c3e-2e61d0f4a7b1",
  "scheduledFor": null,
  "deleteAt": null
}

Estados posibles: 200400401403429

DELETE/api/v2/posts/{id}

Retirar una publicación tuya.

  • Derecho write
  • desde v2.0

Parámetros

NombreTipoSignificado
iden la rutastringobligatorioEl id de una publicación.

Petición de ejemplo

curl -X DELETE \
  -H "Authorization: Bearer tm_key_…" \
  "https://tellmelo.com/api/v2/posts/5f0c2a9e-8d41-4b7a-9c3e-2e61d0f4a7b1"

Respuesta

Responde con un Ok.

Ejemplo
{
  "ok": true
}

Estados posibles: 200400401403404429

Respuestas

La conversación bajo una publicación: leída como una lista que parentId convierte en árbol, escrita respondiendo a la publicación o a una respuesta.

GET/api/v2/posts/{id}/replies

Las respuestas a una publicación, tal como las ves tú: lo que escribió una cuenta bloqueada se queda fuera.

  • Derecho read
  • paginable
  • con ETag
  • desde v2.0

La lista es plana y en el orden de escritura; parentId la convierte en árbol. Una página contiene hilos enteros, así que una respuesta nunca llega sin aquella a la que responde. Lo que escribió una cuenta que bloqueaste, o que te bloqueó, queda fuera. Dos claves pueden ver listas distintas.

Parámetros

NombreTipoSignificado
iden la rutastringobligatorioEl id de una publicación.
limiten la direcciónintegeropcionalCuántas entradas caben en una página: 20 por defecto, 50 como máximo.
cursoren la direcciónstringopcionalPor dónde sigue: el next de la respuesta anterior. Sin él, desde arriba.

Petición de ejemplo

curl \
  -H "Authorization: Bearer tm_key_…" \
  "https://tellmelo.com/api/v2/posts/5f0c2a9e-8d41-4b7a-9c3e-2e61d0f4a7b1/replies?limit=20"

Respuesta

Responde con una página de Reply, como `items` y `next`.

Ejemplo
{
  "items": [
    {
      "id": "9e4b1c7d-2a3f-4d5e-8b6c-0f1e2d3c4b5a",
      "text": "Same here, the lavender is full of them.",
      "kind": "post",
      "author": {
        "id": "d4c3b2a1-6e5f-4a7b-9c8d-1e2f3a4b5c6d",
        "handle": "jon",
        "name": "Jon",
        "verified": false,
        "accountKind": "person"
      },
      "community": null,
      "media": [],
      "poll": null,
      "quotes": null,
      "continues": null,
      "counts": {
        "replies": 0,
        "likes": 3,
        "reposts": 0
      },
      "pinned": false,
      "createdAt": 1758624600000,
      "postId": "5f0c2a9e-8d41-4b7a-9c3e-2e61d0f4a7b1",
      "parentId": null
    }
  ],
  "next": "MTc1ODYyNDAwMDAwMDo1ZjBjMmE5ZS04ZDQx"
}

Estados posibles: 200304400401404429

POST/api/v2/posts/{id}/replies

Responder a una publicación.

  • Derecho write
  • desde v2.0

En una publicación en modo lento, cada persona puede responder una vez cada 10 minutos; otra respuesta recibe 429 con la espera en el mensaje. El modo no se aplica al autor ni a las cuentas que sigue.

Parámetros

NombreTipoSignificado
iden la rutastringobligatorioEl id de una publicación.
texten el cuerpostringobligatorioEl texto mismo: de la publicación, de la respuesta o del mensaje.
parentIden el cuerpostringopcionalEl id de la respuesta a la que esta responde. Sin él, directo a la publicación.

Petición de ejemplo

curl -X POST \
  -H "Authorization: Bearer tm_key_…" \
  -H "Content-Type: application/json" \
  -d '{"text":"Same here, the lavender is full of them."}' \
  "https://tellmelo.com/api/v2/posts/5f0c2a9e-8d41-4b7a-9c3e-2e61d0f4a7b1/replies"

Respuesta

Responde con un Created.

Ejemplo
{
  "id": "5f0c2a9e-8d41-4b7a-9c3e-2e61d0f4a7b1",
  "scheduledFor": null,
  "deleteAt": null
}

Estados posibles: 200400401403404429

Encuestas

Una encuesta es una publicación con poll rellenado. Votar tiene su propia ruta.

POST/api/v2/posts/{id}/vote

Participar en una encuesta.

  • Derecho write
  • desde v2.0

Los votos por respuesta son null mientras el resultado esté retenido: antes de tu propio voto, mientras la encuesta sigue abierta. total está siempre.

Parámetros

NombreTipoSignificado
iden la rutastringobligatorioEl id de una publicación.
optionen el cuerpointegerobligatorioQué respuesta, contando desde 0. Una por llamada: una encuesta con varias respuestas se vota llamando más de una vez.
retracten el cuerpobooleanopcionalSi este voto se retira: true lo deshace.

Petición de ejemplo

curl -X POST \
  -H "Authorization: Bearer tm_key_…" \
  -H "Content-Type: application/json" \
  -d '{"option":0}' \
  "https://tellmelo.com/api/v2/posts/5f0c2a9e-8d41-4b7a-9c3e-2e61d0f4a7b1/vote"

Respuesta

Responde con un Ok.

Ejemplo
{
  "ok": true
}

Estados posibles: 200400401403404429

Perfiles

Perfiles públicos por su nombre corto, y lo que han publicado.

GET/api/v2/profiles/{handle}

Un perfil, por su alias.

  • Derecho read
  • con ETag
  • desde v2.0

Parámetros

NombreTipoSignificado
handleen la rutastringobligatorioEl alias de un perfil.

Petición de ejemplo

curl \
  -H "Authorization: Bearer tm_key_…" \
  "https://tellmelo.com/api/v2/profiles/mara"

Respuesta

Responde con un Profile.

Ejemplo
{
  "id": "a3e1f7c2-54b9-4d0e-8f16-7b2c9d4e1a05",
  "handle": "mara",
  "name": "Mara 🌻",
  "verified": true,
  "accountKind": "person",
  "about": "Beekeeper, allotment, too many seeds. :tellmelo:",
  "website": "https://mara-imkerei.example/",
  "websiteVerified": true,
  "followers": 148,
  "createdAt": 1750848000000
}

Estados posibles: 200304400401404429

GET/api/v2/profiles/{handle}/posts

Las publicaciones públicas de un perfil, las más nuevas primero.

  • Derecho read
  • paginable
  • con ETag
  • desde v2.0

En las rutas públicas no se cuentan las reacciones: counts.likes y counts.reposts son 0 y pinned es false (un recorte, no una medición).

Las publicaciones dentro de una comunidad no se alcanzan aquí, ni en la lista ni por su id. Se leen en /communities/{id}/posts.

Parámetros

NombreTipoSignificado
handleen la rutastringobligatorioEl alias de un perfil.
limiten la direcciónintegeropcionalCuántas entradas caben en una página: 20 por defecto, 50 como máximo.
cursoren la direcciónstringopcionalPor dónde sigue: el next de la respuesta anterior. Sin él, desde arriba.

Petición de ejemplo

curl \
  -H "Authorization: Bearer tm_key_…" \
  "https://tellmelo.com/api/v2/profiles/mara/posts?limit=20"

Respuesta

Responde con una página de Post, como `items` y `next`.

Ejemplo
{
  "items": [
    {
      "id": "5f0c2a9e-8d41-4b7a-9c3e-2e61d0f4a7b1",
      "text": "The bees are back in the garden 🐝 #garden",
      "kind": "poll",
      "author": {
        "id": "a3e1f7c2-54b9-4d0e-8f16-7b2c9d4e1a05",
        "handle": "mara",
        "name": "Mara 🌻",
        "verified": true,
        "accountKind": "person"
      },
      "community": {
        "id": "c81d4e2a-0f3b-4a6c-9e57-1d2b3c4a5f60",
        "name": "Urban Gardening"
      },
      "media": [
        {
          "url": "/api/media?id=b2d7e9f1-3c4a-4e8b-a1f0-6d5c4b3a2918"
        }
      ],
      "poll": {
        "options": [
          {
            "text": "Lavender",
            "votes": 12
          },
          {
            "text": "Sunflowers",
            "votes": 7
          },
          {
            "text": "Clover",
            "votes": 3
          }
        ],
        "total": 22,
        "multiple": false,
        "endsAt": 1758710400000,
        "running": true,
        "resultsVisible": true,
        "myVotes": [
          0
        ]
      },
      "quotes": null,
      "continues": null,
      "counts": {
        "replies": 4,
        "likes": 31,
        "reposts": 2
      },
      "pinned": false,
      "createdAt": 1758624000000
    }
  ],
  "next": "MTc1ODYyNDAwMDAwMDo1ZjBjMmE5ZS04ZDQx"
}

Estados posibles: 200304400401404429

Comunidades

Las comunidades abiertas de esta instancia y sus publicaciones. Las internas y las ocultas no se alcanzan con una clave.

GET/api/v2/communities

Las comunidades abiertas de esta instancia.

  • Derecho read
  • con ETag
  • desde v2.0

Ordenada por número de miembros, no por fecha, por eso esta lista no se pagina y next es siempre null.

Parámetros

NombreTipoSignificado
limiten la direcciónintegeropcionalCuántas entradas caben en una página: 20 por defecto, 50 como máximo.

Petición de ejemplo

curl \
  -H "Authorization: Bearer tm_key_…" \
  "https://tellmelo.com/api/v2/communities?limit=20"

Respuesta

Responde con una página de Community, como `items` y `next`.

Ejemplo
{
  "items": [
    {
      "id": "c81d4e2a-0f3b-4a6c-9e57-1d2b3c4a5f60",
      "name": "Urban Gardening",
      "description": "Balconies, allotments, rooftops: whatever grows.",
      "tags": [
        "garden",
        "bees"
      ],
      "members": 312,
      "joinPolicy": "open",
      "visibility": "open"
    }
  ],
  "next": null
}

Estados posibles: 200304401429

GET/api/v2/communities/{id}

Una sola comunidad, por su id.

  • Derecho read
  • con ETag
  • desde v2.0

Parámetros

NombreTipoSignificado
iden la rutastringobligatorioEl id de una comunidad.

Petición de ejemplo

curl \
  -H "Authorization: Bearer tm_key_…" \
  "https://tellmelo.com/api/v2/communities/c81d4e2a-0f3b-4a6c-9e57-1d2b3c4a5f60"

Respuesta

Responde con un Community.

Ejemplo
{
  "id": "c81d4e2a-0f3b-4a6c-9e57-1d2b3c4a5f60",
  "name": "Urban Gardening",
  "description": "Balconies, allotments, rooftops: whatever grows.",
  "tags": [
    "garden",
    "bees"
  ],
  "members": 312,
  "joinPolicy": "open",
  "visibility": "open"
}

Estados posibles: 200304400401404429

GET/api/v2/communities/{id}/posts

Las publicaciones públicas de una comunidad, las más nuevas primero.

  • Derecho read
  • paginable
  • con ETag
  • desde v2.0

En las rutas públicas no se cuentan las reacciones: counts.likes y counts.reposts son 0 y pinned es false (un recorte, no una medición).

Parámetros

NombreTipoSignificado
iden la rutastringobligatorioEl id de una comunidad.
limiten la direcciónintegeropcionalCuántas entradas caben en una página: 20 por defecto, 50 como máximo.
cursoren la direcciónstringopcionalPor dónde sigue: el next de la respuesta anterior. Sin él, desde arriba.

Petición de ejemplo

curl \
  -H "Authorization: Bearer tm_key_…" \
  "https://tellmelo.com/api/v2/communities/c81d4e2a-0f3b-4a6c-9e57-1d2b3c4a5f60/posts?limit=20"

Respuesta

Responde con una página de Post, como `items` y `next`.

Ejemplo
{
  "items": [
    {
      "id": "5f0c2a9e-8d41-4b7a-9c3e-2e61d0f4a7b1",
      "text": "The bees are back in the garden 🐝 #garden",
      "kind": "poll",
      "author": {
        "id": "a3e1f7c2-54b9-4d0e-8f16-7b2c9d4e1a05",
        "handle": "mara",
        "name": "Mara 🌻",
        "verified": true,
        "accountKind": "person"
      },
      "community": {
        "id": "c81d4e2a-0f3b-4a6c-9e57-1d2b3c4a5f60",
        "name": "Urban Gardening"
      },
      "media": [
        {
          "url": "/api/media?id=b2d7e9f1-3c4a-4e8b-a1f0-6d5c4b3a2918"
        }
      ],
      "poll": {
        "options": [
          {
            "text": "Lavender",
            "votes": 12
          },
          {
            "text": "Sunflowers",
            "votes": 7
          },
          {
            "text": "Clover",
            "votes": 3
          }
        ],
        "total": 22,
        "multiple": false,
        "endsAt": 1758710400000,
        "running": true,
        "resultsVisible": true,
        "myVotes": [
          0
        ]
      },
      "quotes": null,
      "continues": null,
      "counts": {
        "replies": 4,
        "likes": 31,
        "reposts": 2
      },
      "pinned": false,
      "createdAt": 1758624000000
    }
  ],
  "next": "MTc1ODYyNDAwMDAwMDo1ZjBjMmE5ZS04ZDQx"
}

Estados posibles: 200304400401404429

Descubrir

De qué se está hablando, una búsqueda en publicaciones, perfiles y etiquetas, y los emojis propios de la instancia.

GET/api/v2/tags

Las etiquetas que están en marcha ahora mismo.

  • Derecho read
  • con ETag
  • desde v2.0

Las etiquetas del momento, las más publicadas primero. Sin paginación: limit solo acorta la lista.

Parámetros

NombreTipoSignificado
limiten la direcciónintegeropcionalCuántas entradas caben en una página: 20 por defecto, 50 como máximo.

Petición de ejemplo

curl \
  -H "Authorization: Bearer tm_key_…" \
  "https://tellmelo.com/api/v2/tags?limit=10"

Respuesta

Responde con una página de Tag, como `items` y `next`.

Ejemplo
{
  "items": [
    {
      "tag": "garden",
      "posts": 58
    }
  ],
  "next": null
}

Estados posibles: 200304401429

GET/api/v2/search

Una búsqueda por publicaciones, nombres, alias y etiquetas.

  • Derecho read
  • con ETag
  • desde v2.0

Busca solo en lo público: publicaciones fuera de comunidades, perfiles y etiquetas. limit cuenta por tipo: 20 puede traer hasta 20 publicaciones, 20 perfiles y 20 etiquetas.

Parámetros

NombreTipoSignificado
qen la direcciónstringobligatorioLas palabras que se buscan.
typeen la direcciónstringopcionalQué clase de resultado. Sin él, todas las clases.allpostsprofilestags
limiten la direcciónintegeropcionalCuántas entradas caben en una página: 20 por defecto, 50 como máximo.

Petición de ejemplo

curl \
  -H "Authorization: Bearer tm_key_…" \
  "https://tellmelo.com/api/v2/search?q=garden&type=posts"

Respuesta

Responde con un SearchResult.

Ejemplo
{
  "posts": [
    {
      "id": "5f0c2a9e-8d41-4b7a-9c3e-2e61d0f4a7b1",
      "text": "The bees are back in the garden 🐝 #garden",
      "kind": "poll",
      "author": {
        "id": "a3e1f7c2-54b9-4d0e-8f16-7b2c9d4e1a05",
        "handle": "mara",
        "name": "Mara 🌻",
        "verified": true,
        "accountKind": "person"
      },
      "community": {
        "id": "c81d4e2a-0f3b-4a6c-9e57-1d2b3c4a5f60",
        "name": "Urban Gardening"
      },
      "media": [
        {
          "url": "/api/media?id=b2d7e9f1-3c4a-4e8b-a1f0-6d5c4b3a2918"
        }
      ],
      "poll": {
        "options": [
          {
            "text": "Lavender",
            "votes": 12
          },
          {
            "text": "Sunflowers",
            "votes": 7
          },
          {
            "text": "Clover",
            "votes": 3
          }
        ],
        "total": 22,
        "multiple": false,
        "endsAt": 1758710400000,
        "running": true,
        "resultsVisible": true,
        "myVotes": [
          0
        ]
      },
      "quotes": null,
      "continues": null,
      "counts": {
        "replies": 4,
        "likes": 31,
        "reposts": 2
      },
      "pinned": false,
      "createdAt": 1758624000000
    }
  ],
  "profiles": [
    {
      "id": "a3e1f7c2-54b9-4d0e-8f16-7b2c9d4e1a05",
      "handle": "mara",
      "name": "Mara 🌻",
      "verified": true,
      "accountKind": "person"
    }
  ],
  "tags": [
    {
      "tag": "garden",
      "posts": 58
    }
  ]
}

Estados posibles: 200304400401429

GET/api/v2/emojis

Los emojis propios de la instancia, con la dirección de sus imágenes.

  • Derecho read
  • con ETag
  • desde v2.1

En los textos, un emoji de esta instancia aparece como :name:. Sustitúyelo por la imagen de esta lista; un nombre que no esté en ella sigue siendo texto: se borró o nunca existió.

Petición de ejemplo

curl \
  -H "Authorization: Bearer tm_key_…" \
  "https://tellmelo.com/api/v2/emojis"

Respuesta

Responde con una página de Emoji, como `items` y `next`.

Ejemplo
{
  "items": [
    {
      "name": "tellmelo",
      "url": "/api/media?id=e1f2a3b4-c5d6-4e7f-8a9b-0c1d2e3f4a5b"
    }
  ],
  "next": null
}

Estados posibles: 200304401429

Tu cuenta

Tu propio perfil y tu feed, compuestos como lo hace la aplicación para ti.

GET/api/v2/me

Tu propio perfil, con el id que esperan las demás rutas.

  • Derecho read
  • con ETag
  • desde v2.0

Petición de ejemplo

curl \
  -H "Authorization: Bearer tm_key_…" \
  "https://tellmelo.com/api/v2/me"

Respuesta

Responde con un Profile.

Ejemplo
{
  "id": "a3e1f7c2-54b9-4d0e-8f16-7b2c9d4e1a05",
  "handle": "mara",
  "name": "Mara 🌻",
  "verified": true,
  "accountKind": "person",
  "about": "Beekeeper, allotment, too many seeds. :tellmelo:",
  "website": "https://mara-imkerei.example/",
  "websiteVerified": true,
  "followers": 148,
  "createdAt": 1750848000000
}

Estados posibles: 200304401429

GET/api/v2/feed

Tu propio feed, tal como lo compone la aplicación.

  • Derecho read
  • paginable
  • desde v2.0

Aquí no hay ETag: el orden se mueve con el tiempo, así que cada respuesta es distinta. Aun así, una lista empezada sigue igual hasta el final: next lleva el momento en que empezó.

Parámetros

NombreTipoSignificado
taben la direcciónstringopcionalQué feed: for-you, following, latest o bookmarks. latest por defecto.for-youfollowinglatestbookmarks
tagen la direcciónstringopcionalSolo publicaciones con esta etiqueta. Sin ella, ningún filtro.
limiten la direcciónintegeropcionalCuántas entradas caben en una página: 20 por defecto, 50 como máximo.
cursoren la direcciónstringopcionalPor dónde sigue: el next de la respuesta anterior. Sin él, desde arriba.

Petición de ejemplo

curl \
  -H "Authorization: Bearer tm_key_…" \
  "https://tellmelo.com/api/v2/feed?tab=following&limit=20"

Respuesta

Responde con una página de Post, como `items` y `next`.

Ejemplo
{
  "items": [
    {
      "id": "5f0c2a9e-8d41-4b7a-9c3e-2e61d0f4a7b1",
      "text": "The bees are back in the garden 🐝 #garden",
      "kind": "poll",
      "author": {
        "id": "a3e1f7c2-54b9-4d0e-8f16-7b2c9d4e1a05",
        "handle": "mara",
        "name": "Mara 🌻",
        "verified": true,
        "accountKind": "person"
      },
      "community": {
        "id": "c81d4e2a-0f3b-4a6c-9e57-1d2b3c4a5f60",
        "name": "Urban Gardening"
      },
      "media": [
        {
          "url": "/api/media?id=b2d7e9f1-3c4a-4e8b-a1f0-6d5c4b3a2918"
        }
      ],
      "poll": {
        "options": [
          {
            "text": "Lavender",
            "votes": 12
          },
          {
            "text": "Sunflowers",
            "votes": 7
          },
          {
            "text": "Clover",
            "votes": 3
          }
        ],
        "total": 22,
        "multiple": false,
        "endsAt": 1758710400000,
        "running": true,
        "resultsVisible": true,
        "myVotes": [
          0
        ]
      },
      "quotes": null,
      "continues": null,
      "counts": {
        "replies": 4,
        "likes": 31,
        "reposts": 2
      },
      "pinned": false,
      "createdAt": 1758624000000
    }
  ],
  "next": "MTc1ODYyNDAwMDAwMDo1ZjBjMmE5ZS04ZDQx"
}

Estados posibles: 200400401429

Notificaciones

Lo que ha pasado en torno a tu cuenta, legible página a página, para que un programa pueda ponerse al día con lo que se perdió.

GET/api/v2/notifications

Tus propias notificaciones, las más nuevas primero, paginables, para que un programa recupere lo que se ha perdido.

  • Derecho read
  • paginable
  • con ETag
  • desde v2.0

Leer no marca nada como leído; lo hace POST /notifications/read. Varios eventos del mismo tipo sobre la misma publicación se agrupan en una fila, y more dice cuántos.

Parámetros

NombreTipoSignificado
limiten la direcciónintegeropcionalCuántas entradas caben en una página: 20 por defecto, 50 como máximo.
cursoren la direcciónstringopcionalPor dónde sigue: el next de la respuesta anterior. Sin él, desde arriba.

Petición de ejemplo

curl \
  -H "Authorization: Bearer tm_key_…" \
  "https://tellmelo.com/api/v2/notifications?limit=20"

Respuesta

Responde con una página de Notification, como `items` y `next`.

Ejemplo
{
  "items": [
    {
      "id": "3f2e1d0c-9b8a-4765-8432-10fedcba9876",
      "kind": "like",
      "text": null,
      "actor": {
        "handle": "jon",
        "name": "Jon"
      },
      "postId": "5f0c2a9e-8d41-4b7a-9c3e-2e61d0f4a7b1",
      "read": false,
      "more": 2,
      "createdAt": 1758624300000,
      "updatedAt": 1758624900000
    }
  ],
  "next": "MTc1ODYyNDAwMDAwMDo1ZjBjMmE5ZS04ZDQx"
}

Estados posibles: 200304401429

POST/api/v2/notifications/read

Marcar tus notificaciones como leídas.

  • Derecho write
  • desde v2.0

Petición de ejemplo

curl -X POST \
  -H "Authorization: Bearer tm_key_…" \
  "https://tellmelo.com/api/v2/notifications/read"

Respuesta

Responde con un Ok.

Ejemplo
{
  "ok": true
}

Estados posibles: 200401403429

Mensajes

Tu bandeja de entrada y tus conversaciones. Una conversación no tiene identificador propio; se llama como la otra cuenta.

GET/api/v2/conversations

Tu buzón: una fila por conversación, la más reciente primero.

  • Derecho read
  • paginable
  • con ETag
  • desde v2.0

Parámetros

NombreTipoSignificado
limiten la direcciónintegeropcionalCuántas entradas caben en una página: 20 por defecto, 50 como máximo.
cursoren la direcciónstringopcionalPor dónde sigue: el next de la respuesta anterior. Sin él, desde arriba.

Petición de ejemplo

curl \
  -H "Authorization: Bearer tm_key_…" \
  "https://tellmelo.com/api/v2/conversations?limit=20"

Respuesta

Responde con una página de Conversation, como `items` y `next`.

Ejemplo
{
  "items": [
    {
      "with": "d4c3b2a1-6e5f-4a7b-9c8d-1e2f3a4b5c6d",
      "handle": "jon",
      "name": "Jon",
      "excerpt": "See you on Saturday at the market!",
      "truncated": false,
      "fromMe": true,
      "lastMessageId": "7c6b5a49-3827-4165-9f0e-d1c2b3a49586",
      "unread": 0,
      "updatedAt": 1758624060000
    }
  ],
  "next": "MTc1ODYyNDAwMDAwMDo1ZjBjMmE5ZS04ZDQx"
}

Estados posibles: 200304401429

GET/api/v2/conversations/{with}/messages

Los mensajes de una conversación, los más nuevos primero.

  • Derecho read
  • paginable
  • con ETag
  • desde v2.0

Leer no marca nada como leído: un programa que consulta en segundo plano no le ha mostrado nada a nadie. Lo hace POST /conversations/{with}/read.

Parámetros

NombreTipoSignificado
withen la rutastringobligatorioEl id de la cuenta con la que hablas. Una conversación no tiene un id propio: es la otra cuenta, el mismo valor que el buzón llama with.
limiten la direcciónintegeropcionalCuántas entradas caben en una página: 20 por defecto, 50 como máximo.
cursoren la direcciónstringopcionalPor dónde sigue: el next de la respuesta anterior. Sin él, desde arriba.

Petición de ejemplo

curl \
  -H "Authorization: Bearer tm_key_…" \
  "https://tellmelo.com/api/v2/conversations/a3e1f7c2-54b9-4d0e-8f16-7b2c9d4e1a05/messages?limit=20"

Respuesta

Responde con una página de Message, como `items` y `next`.

Ejemplo
{
  "items": [
    {
      "id": "7c6b5a49-3827-4165-9f0e-d1c2b3a49586",
      "text": "See you on Saturday at the market!",
      "from": "a3e1f7c2-54b9-4d0e-8f16-7b2c9d4e1a05",
      "to": "d4c3b2a1-6e5f-4a7b-9c8d-1e2f3a4b5c6d",
      "read": true,
      "media": [],
      "replyTo": null,
      "createdAt": 1758624060000
    }
  ],
  "next": "MTc1ODYyNDAwMDAwMDo1ZjBjMmE5ZS04ZDQx"
}

Estados posibles: 200304400401404429

POST/api/v2/conversations/{with}/messages

Enviar un mensaje en una conversación.

  • Derecho write
  • desde v2.0

Se aplican las mismas reglas que en la aplicación: a quien te bloqueó no se le puede escribir, y cuentan los ajustes de la otra persona. La respuesta dice entonces por qué.

Todavía no se pueden adjuntar imágenes a través de la API, solo en la aplicación.

Parámetros

NombreTipoSignificado
withen la rutastringobligatorioEl id de la cuenta con la que hablas. Una conversación no tiene un id propio: es la otra cuenta, el mismo valor que el buzón llama with.
texten el cuerpostringobligatorioEl texto mismo: de la publicación, de la respuesta o del mensaje.
replyToen el cuerpostringopcionalEl id de un mensaje anterior de esta conversación al que responde este. Desde 2.2.

Petición de ejemplo

curl -X POST \
  -H "Authorization: Bearer tm_key_…" \
  -H "Content-Type: application/json" \
  -d '{"text":"See you on Saturday at the market!"}' \
  "https://tellmelo.com/api/v2/conversations/a3e1f7c2-54b9-4d0e-8f16-7b2c9d4e1a05/messages"

Respuesta

Responde con un Ok.

Ejemplo
{
  "ok": true
}

Estados posibles: 200400401403404429

POST/api/v2/conversations/{with}/read

Marcar como leídos todos los mensajes de una conversación.

  • Derecho write
  • desde v2.1

Parámetros

NombreTipoSignificado
withen la rutastringobligatorioEl id de la cuenta con la que hablas. Una conversación no tiene un id propio: es la otra cuenta, el mismo valor que el buzón llama with.

Petición de ejemplo

curl -X POST \
  -H "Authorization: Bearer tm_key_…" \
  "https://tellmelo.com/api/v2/conversations/a3e1f7c2-54b9-4d0e-8f16-7b2c9d4e1a05/read"

Respuesta

Responde con un Ok.

Ejemplo
{
  "ok": true
}

Estados posibles: 200400401403404429

Relaciones

Me gusta, guardar, compartir, seguir, unirse y bloquear: una sola ruta para todo, activada y retirada con active.

POST/api/v2/relations

Dar me gusta, guardar, compartir, seguir, unirse, bloquear, silenciar, según kind.

  • Derecho write
  • desde v2.0

target es una publicación para like, save y repost, una comunidad para join y una cuenta para follow, block y mute, siempre por su id. active: false retira la relación. Nadie puede seguir a través de un bloqueo, en ninguna dirección. Solo quien silencia ve el silencio.

Parámetros

NombreTipoSignificado
kinden el cuerpostringobligatorioQué relación: like, save, repost, follow, join, block o mute (desde 2.2).likesaverepostfollowjoinblockmute
targeten el cuerpostringobligatorioA qué apunta la relación, por su id: una publicación, un perfil o una comunidad, según kind.
activeen el cuerpobooleanopcionalSi la relación debe existir: true la pone, false la retira.

Petición de ejemplo

curl -X POST \
  -H "Authorization: Bearer tm_key_…" \
  -H "Content-Type: application/json" \
  -d '{"kind":"like","target":"5f0c2a9e-8d41-4b7a-9c3e-2e61d0f4a7b1","active":true}' \
  "https://tellmelo.com/api/v2/relations"

Respuesta

Responde con un Ok.

Ejemplo
{
  "ok": true
}

Estados posibles: 200400401403429

Objetos

Todo lo que puede contener una respuesta, campo por campo. Cada campo está siempre presente; los tipos son tipos JSON, y [] significa una lista.

Service

La respuesta de la raíz: quién responde y qué puede hacer esta clave.

CampoTipoSignificado
namestringSiempre tellmelo.
versionstringLa versión de la API, por ejemplo 2.1.
scopestringLo que puede hacer esta clave: read o read write.
rateLimitRateLimitEl cupo de esta clave.
docsstringDónde está esta documentación, como ruta en esta instancia.
specstringDónde está la descripción legible por máquina.
Ejemplo
{
  "name": "tellmelo",
  "version": "2.6",
  "scope": "read write",
  "rateLimit": {
    "limit": 120,
    "remaining": 117
  },
  "docs": "/legal/api",
  "spec": "/api/v2/openapi.json"
}

RateLimit

El cupo de esta clave en el minuto actual.

CampoTipoSignificado
limitintegerPeticiones por minuto.
remainingintegerCuántas quedan en este minuto.
Ejemplo
{
  "limit": 120,
  "remaining": 117
}

Post

Una publicación: la misma forma en todas partes, sea pública, de tu feed o de una búsqueda.

CampoTipoSignificado
idstringEl identificador de la publicación.
textstringo nullEl texto tal como se escribió (null para una publicación que solo es una encuesta o solo imágenes).
kindstringQué es la publicación.
  • post — Una publicación con texto, imágenes o una cita.
  • poll — Una publicación con una encuesta.
authorProfileBriefQuién la escribió.
communityCommunityBriefo nullLa comunidad en la que se escribió (null fuera de cualquier comunidad).
mediaMedia[]Sus imágenes, en orden; vacía si no hay ninguna.
pollPollo nullLa encuesta (null si no hay ninguna).
quotesstringo nullEl identificador de la publicación que esta cita.
continuesstringo nullEl identificador de la publicación que esta continúa, como añadido.
countsCountsRespuestas, me gusta y publicaciones compartidas.
pinnedbooleanSi está fijada arriba en el perfil de quien la escribió.
createdAtintegerCuándo se escribió.
Ejemplo
{
  "id": "5f0c2a9e-8d41-4b7a-9c3e-2e61d0f4a7b1",
  "text": "The bees are back in the garden 🐝 #garden",
  "kind": "poll",
  "author": {
    "id": "a3e1f7c2-54b9-4d0e-8f16-7b2c9d4e1a05",
    "handle": "mara",
    "name": "Mara 🌻",
    "verified": true,
    "accountKind": "person"
  },
  "community": {
    "id": "c81d4e2a-0f3b-4a6c-9e57-1d2b3c4a5f60",
    "name": "Urban Gardening"
  },
  "media": [
    {
      "url": "/api/media?id=b2d7e9f1-3c4a-4e8b-a1f0-6d5c4b3a2918"
    }
  ],
  "poll": {
    "options": [
      {
        "text": "Lavender",
        "votes": 12
      },
      {
        "text": "Sunflowers",
        "votes": 7
      },
      {
        "text": "Clover",
        "votes": 3
      }
    ],
    "total": 22,
    "multiple": false,
    "endsAt": 1758710400000,
    "running": true,
    "resultsVisible": true,
    "myVotes": [
      0
    ]
  },
  "quotes": null,
  "continues": null,
  "counts": {
    "replies": 4,
    "likes": 31,
    "reposts": 2
  },
  "pinned": false,
  "createdAt": 1758624000000
}

Reply

Una respuesta bajo una publicación: una publicación con dos campos más.

Todos los campos de Post y, además:

CampoTipoSignificado
postIdstringLa publicación de la que cuelga toda la conversación.
parentIdstringo nullLa respuesta a la que responde esta (null si responde directamente a la publicación).
Ejemplo
{
  "id": "9e4b1c7d-2a3f-4d5e-8b6c-0f1e2d3c4b5a",
  "text": "Same here, the lavender is full of them.",
  "kind": "post",
  "author": {
    "id": "d4c3b2a1-6e5f-4a7b-9c8d-1e2f3a4b5c6d",
    "handle": "jon",
    "name": "Jon",
    "verified": false,
    "accountKind": "person"
  },
  "community": null,
  "media": [],
  "poll": null,
  "quotes": null,
  "continues": null,
  "counts": {
    "replies": 0,
    "likes": 3,
    "reposts": 0
  },
  "pinned": false,
  "createdAt": 1758624600000,
  "postId": "5f0c2a9e-8d41-4b7a-9c3e-2e61d0f4a7b1",
  "parentId": null
}

Counts

Cuántas respuestas, me gusta y publicaciones compartidas tiene una publicación.

CampoTipoSignificado
repliesintegerRespuestas, todos los niveles juntos.
likesintegerMe gusta.
repostsintegerPublicaciones compartidas.
Ejemplo
{
  "replies": 4,
  "likes": 31,
  "reposts": 2
}

Media

Una imagen de una publicación o de un mensaje.

CampoTipoSignificado
urlstringLa dirección de la imagen, relativa a esta instancia. Cárgala con la clave en la cabecera.
Ejemplo
{
  "url": "/api/media?id=b2d7e9f1-3c4a-4e8b-a1f0-6d5c4b3a2918"
}

Poll

La encuesta de una publicación.

CampoTipoSignificado
optionsPollOption[]Las respuestas, en orden. option al votar cuenta desde 0.
totalintegerCuántos votos hay en total: siempre, aunque el reparto esté retenido.
multiplebooleanSi se puede elegir más de una respuesta.
endsAtintegero nullCuándo termina la encuesta (null si no tiene fin).
runningbooleanSi todavía se puede votar.
resultsVisiblebooleanSi se muestran los votos por respuesta (ver votes).
myVotesinteger[]Las respuestas que elegiste, contadas desde 0.
Ejemplo
{
  "options": [
    {
      "text": "Lavender",
      "votes": 12
    },
    {
      "text": "Sunflowers",
      "votes": 7
    },
    {
      "text": "Clover",
      "votes": 3
    }
  ],
  "total": 22,
  "multiple": false,
  "endsAt": 1758710400000,
  "running": true,
  "resultsVisible": true,
  "myVotes": [
    0
  ]
}

PollOption

Una respuesta de una encuesta.

CampoTipoSignificado
textstringLa respuesta.
votesintegero nullSus votos (null mientras el resultado esté retenido).
Ejemplo
{
  "text": "Lavender",
  "votes": 12
}

ProfileBrief

Un perfil tal como aparece dentro de otros objetos: como autor, en una búsqueda.

CampoTipoSignificado
idstringEl identificador de la cuenta: lo que esperan /relations y /conversations/{with}.
handlestringEl nombre corto, sin @. Forma parte de la dirección del perfil y no puede contener emojis.
namestringEl nombre visible. Puede contener emojis, también :name:.
verifiedbooleanSi la cuenta está verificada.
accountKindstringQué tipo de cuenta es.
  • person — Una persona.
  • business — Una empresa.
  • association — Una asociación.
  • automated — Una cuenta automatizada, como un bot.
Ejemplo
{
  "id": "a3e1f7c2-54b9-4d0e-8f16-7b2c9d4e1a05",
  "handle": "mara",
  "name": "Mara 🌻",
  "verified": true,
  "accountKind": "person"
}

Profile

Un perfil por sí solo, con su descripción y sus seguidores.

Todos los campos de ProfileBrief y, además:

CampoTipoSignificado
aboutstringo nullLa descripción (null si no hay ninguna).
websitestringo nullLa web del perfil (null si no hay). Desde 2.3.
websiteVerifiedbooleanSi la web enlaza de vuelta a este perfil con rel=me, comprobado en la última semana. Desde 2.3.
followersintegerCuántas cuentas la siguen.
createdAtintegerCuándo se creó la cuenta.
Ejemplo
{
  "id": "a3e1f7c2-54b9-4d0e-8f16-7b2c9d4e1a05",
  "handle": "mara",
  "name": "Mara 🌻",
  "verified": true,
  "accountKind": "person",
  "about": "Beekeeper, allotment, too many seeds. :tellmelo:",
  "website": "https://mara-imkerei.example/",
  "websiteVerified": true,
  "followers": 148,
  "createdAt": 1750848000000
}

CommunityBrief

La comunidad en la que se escribió una publicación.

CampoTipoSignificado
idstringEl identificador de la comunidad.
namestringo nullSu nombre.
Ejemplo
{
  "id": "c81d4e2a-0f3b-4a6c-9e57-1d2b3c4a5f60",
  "name": "Urban Gardening"
}

Community

Una comunidad de esta instancia.

CampoTipoSignificado
idstringEl identificador de la comunidad.
namestringSu nombre.
descriptionstringo nullLa descripción (null si no hay ninguna).
tagsstring[]Los temas de los que trata.
membersintegerCuántos miembros tiene.
joinPolicystringCómo se entra.
  • open — Cualquiera puede unirse.
  • application — Unirse requiere una solicitud que la comunidad acepta.
  • invite — Solo por invitación.
visibilitystringQuién puede verla. Con una clave siempre open: las demás no se alcanzan.
  • open — Visible para todo el mundo.
Ejemplo
{
  "id": "c81d4e2a-0f3b-4a6c-9e57-1d2b3c4a5f60",
  "name": "Urban Gardening",
  "description": "Balconies, allotments, rooftops: whatever grows.",
  "tags": [
    "garden",
    "bees"
  ],
  "members": 312,
  "joinPolicy": "open",
  "visibility": "open"
}

Tag

Una etiqueta y cuántas publicaciones la llevan.

CampoTipoSignificado
tagstringLa etiqueta, sin #.
postsintegerCuántas publicaciones recientes la llevan.
Ejemplo
{
  "tag": "garden",
  "posts": 58
}

SearchResult

Lo que encuentra una búsqueda: tres listas, cada una quizá vacía, nunca ausente.

CampoTipoSignificado
postsPost[]Publicaciones encontradas, las más nuevas primero.
profilesProfileBrief[]Perfiles encontrados, por nombre corto.
tagsTag[]Etiquetas encontradas, las más usadas primero.
Ejemplo
{
  "posts": [
    {
      "id": "5f0c2a9e-8d41-4b7a-9c3e-2e61d0f4a7b1",
      "text": "The bees are back in the garden 🐝 #garden",
      "kind": "poll",
      "author": {
        "id": "a3e1f7c2-54b9-4d0e-8f16-7b2c9d4e1a05",
        "handle": "mara",
        "name": "Mara 🌻",
        "verified": true,
        "accountKind": "person"
      },
      "community": {
        "id": "c81d4e2a-0f3b-4a6c-9e57-1d2b3c4a5f60",
        "name": "Urban Gardening"
      },
      "media": [
        {
          "url": "/api/media?id=b2d7e9f1-3c4a-4e8b-a1f0-6d5c4b3a2918"
        }
      ],
      "poll": {
        "options": [
          {
            "text": "Lavender",
            "votes": 12
          },
          {
            "text": "Sunflowers",
            "votes": 7
          },
          {
            "text": "Clover",
            "votes": 3
          }
        ],
        "total": 22,
        "multiple": false,
        "endsAt": 1758710400000,
        "running": true,
        "resultsVisible": true,
        "myVotes": [
          0
        ]
      },
      "quotes": null,
      "continues": null,
      "counts": {
        "replies": 4,
        "likes": 31,
        "reposts": 2
      },
      "pinned": false,
      "createdAt": 1758624000000
    }
  ],
  "profiles": [
    {
      "id": "a3e1f7c2-54b9-4d0e-8f16-7b2c9d4e1a05",
      "handle": "mara",
      "name": "Mara 🌻",
      "verified": true,
      "accountKind": "person"
    }
  ],
  "tags": [
    {
      "tag": "garden",
      "posts": 58
    }
  ]
}

Emoji

Un emoji de esta instancia.

CampoTipoSignificado
namestringEl nombre, tal como aparece entre los dos puntos.
urlstringLa dirección de la imagen, relativa a esta instancia.
Ejemplo
{
  "name": "tellmelo",
  "url": "/api/media?id=e1f2a3b4-c5d6-4e7f-8a9b-0c1d2e3f4a5b"
}

Notification

Una notificación. Una fila puede agrupar varios eventos del mismo tipo.

CampoTipoSignificado
idstringEl identificador de la notificación.
kindstringQué ha pasado.
  • reply — Alguien te ha respondido.
  • like — A alguien le gusta tu publicación.
  • repost — Alguien ha compartido tu publicación.
  • follow — Alguien te sigue.
  • mention — Alguien te ha mencionado.
  • group_mention — Alguien ha mencionado un grupo que diriges; text es su nombre.
  • message — Alguien te ha escrito un mensaje.
  • scheduled — Una publicación tuya programada ya ha salido.
  • reminder — Ha llegado un recordatorio de una publicación guardada.
  • report — Qué ha sido de una denuncia que enviaste.
  • moderation — Una decisión sobre tu cuenta: una advertencia, una restricción, un recurso.
  • team — Nuevo trabajo para el equipo, solo para propietarios, admins y moderadores: denuncias, recursos, enlaces enviados, consultas, solicitudes de verificación y cancelaciones.
textstringo nullSolo en denuncias y moderación: el texto que la acompaña. Si no, null: la frase de una notificación la construye tu programa.
actorActorQuién lo hizo.
postIdstringo nullLa publicación de la que trata (null si no trata de ninguna).
readbooleanSi se ha marcado como leída.
moreintegerPor cuántos eventos más vale esta fila, además del nombrado.
createdAtintegerCuándo ocurrió por primera vez.
updatedAtintegerCuándo agrupó otro evento por última vez. La lista se ordena por esto.
Ejemplo
{
  "id": "3f2e1d0c-9b8a-4765-8432-10fedcba9876",
  "kind": "like",
  "text": null,
  "actor": {
    "handle": "jon",
    "name": "Jon"
  },
  "postId": "5f0c2a9e-8d41-4b7a-9c3e-2e61d0f4a7b1",
  "read": false,
  "more": 2,
  "createdAt": 1758624300000,
  "updatedAt": 1758624900000
}

Actor

Quién provocó una notificación.

CampoTipoSignificado
handlestringEl nombre corto.
namestringEl nombre visible.
Ejemplo
{
  "handle": "jon",
  "name": "Jon"
}

Conversation

Una fila de tu bandeja de entrada.

CampoTipoSignificado
withstringEl identificador de la otra cuenta: lo que espera /conversations/{with}/messages.
handlestringSu nombre corto.
namestringSu nombre visible.
excerptstringo nullEl comienzo del último mensaje (null si no tiene texto).
truncatedbooleanSi el extracto se acortó.
fromMebooleanSi el último mensaje es tuyo.
lastMessageIdstringEl identificador del último mensaje.
unreadintegerCuántos de sus mensajes no has leído aún.
updatedAtintegerCuándo se escribió el último mensaje.
Ejemplo
{
  "with": "d4c3b2a1-6e5f-4a7b-9c8d-1e2f3a4b5c6d",
  "handle": "jon",
  "name": "Jon",
  "excerpt": "See you on Saturday at the market!",
  "truncated": false,
  "fromMe": true,
  "lastMessageId": "7c6b5a49-3827-4165-9f0e-d1c2b3a49586",
  "unread": 0,
  "updatedAt": 1758624060000
}

Message

Un mensaje en una conversación.

CampoTipoSignificado
idstringEl identificador del mensaje.
textstringo nullEl texto (null para un mensaje que solo son imágenes).
fromstringEl identificador de la cuenta que lo escribió.
tostringEl identificador de la cuenta a la que se escribió.
readbooleanSi quien lo recibió lo ha leído.
mediaMedia[]Sus imágenes; vacía si no hay ninguna.
replyTostringo nullEl id del mensaje al que responde este (null si no responde a ninguno). Desde 2.2.
createdAtintegerCuándo se envió.
Ejemplo
{
  "id": "7c6b5a49-3827-4165-9f0e-d1c2b3a49586",
  "text": "See you on Saturday at the market!",
  "from": "a3e1f7c2-54b9-4d0e-8f16-7b2c9d4e1a05",
  "to": "d4c3b2a1-6e5f-4a7b-9c8d-1e2f3a4b5c6d",
  "read": true,
  "media": [],
  "replyTo": null,
  "createdAt": 1758624060000
}

Created

La respuesta de una escritura que creó algo.

CampoTipoSignificado
idstringEl identificador de lo que se creó.
scheduledForintegero nullCuándo aparece, si se programó la publicación (si no, null).
deleteAtintegero nullCuándo se borra solo, si se configuró (si no, null).
Ejemplo
{
  "id": "5f0c2a9e-8d41-4b7a-9c3e-2e61d0f4a7b1",
  "scheduledFor": null,
  "deleteAt": null
}

Ok

La respuesta de una escritura que no tiene nada que devolver.

CampoTipoSignificado
okbooleanSiempre true.
Ejemplo
{
  "ok": true
}

La descripción legible por una máquina

La misma tabla con la que está construida esta página se sirve en /api/v2/openapi.json: rutas, parámetros, derechos y las formas que vuelven. Un generador de clientes puede leerla, y no puede alejarse de la API, porque la página, el enrutador y la descripción salen de una sola lista.

https://tellmelo.com/api/v2/openapi.json

Qué ha sido de v1

v1 está eliminada. Las rutas antiguas bajo /api/v1/ responden 410 y dicen en el cuerpo adónde ir. Sin redirección, porque v2 responde con otra forma, y un programa que la siguiera recibiría un 200 que no sabe leer. En ese momento aún no había cuentas públicas y por tanto nadie con un programa encima; quitarla más tarde habría significado no quitarla nunca.

Lo que esperamos

Los mismos principios que en todo lo demás: sin acoso, sin spam, sin contenidos ajenos sin derecho a ellos. Un programa no disculpa nada: de lo que escribe tu clave respondes tú.

Volver a tellmelo