tellmelotellmelo.
Mentions légalesConfidentialitéConditions d’utilisationSignaler un droit d’auteurContactAPIApplications

API

Ceci est une traduction. La version allemande est celle qui fait foi. En cas de divergence, c’est le texte allemand qui s’applique. Tu peux changer de langue en bas de page.

Pour commencer

  • Vue d’ensemble
  • Démarrage rapide
  • Ta clé
  • Ce qu’une clé a le droit de faire
  • Ce qu’aucune clé ne peut

Principes

  • Requêtes et réponses
  • Pages
  • Seulement ce qui est nouveau
  • Limites
  • En-têtes
  • Quand quelque chose ne marche pas
  • Versions

Points d’accès

  • Points d’accès
  • L’entrée
    • GET /
  • Publications
    • GET /posts
    • GET /posts/{id}
    • POST /posts
    • DELETE /posts/{id}
  • Réponses
    • GET /posts/{id}/replies
    • POST /posts/{id}/replies
  • Sondages
    • POST /posts/{id}/vote
  • Profils
    • GET /profiles/{handle}
    • GET /profiles/{handle}/posts
  • Communautés
    • GET /communities
    • GET /communities/{id}
    • GET /communities/{id}/posts
  • Découvrir
    • GET /tags
    • GET /search
    • GET /emojis
  • Ton compte
    • GET /me
    • GET /feed
  • Notifications
    • GET /notifications
    • POST /notifications/read
  • Messages
    • GET /conversations
    • GET /conversations/{with}/messages
    • POST /conversations/{with}/messages
    • POST /conversations/{with}/read
  • Relations
    • POST /relations

Objets

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

Plus

  • La description lisible par une machine
  • Ce qu’est devenue v1
  • Ce que nous attendons
Sommaire

Pour commencer

  • Vue d’ensemble
  • Démarrage rapide
  • Ta clé
  • Ce qu’une clé a le droit de faire
  • Ce qu’aucune clé ne peut

Principes

  • Requêtes et réponses
  • Pages
  • Seulement ce qui est nouveau
  • Limites
  • En-têtes
  • Quand quelque chose ne marche pas
  • Versions

Points d’accès

  • Points d’accès
  • L’entrée
    • GET /
  • Publications
    • GET /posts
    • GET /posts/{id}
    • POST /posts
    • DELETE /posts/{id}
  • Réponses
    • GET /posts/{id}/replies
    • POST /posts/{id}/replies
  • Sondages
    • POST /posts/{id}/vote
  • Profils
    • GET /profiles/{handle}
    • GET /profiles/{handle}/posts
  • Communautés
    • GET /communities
    • GET /communities/{id}
    • GET /communities/{id}/posts
  • Découvrir
    • GET /tags
    • GET /search
    • GET /emojis
  • Ton compte
    • GET /me
    • GET /feed
  • Notifications
    • GET /notifications
    • POST /notifications/read
  • Messages
    • GET /conversations
    • GET /conversations/{with}/messages
    • POST /conversations/{with}/messages
    • POST /conversations/{with}/read
  • Relations
    • POST /relations

Objets

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

Plus

  • La description lisible par une machine
  • Ce qu’est devenue v1
  • Ce que nous attendons

Vue d’ensemble

v2 est l’API de tellmelo pour tes propres programmes. Chaque requête porte une clé, chaque réponse est du JSON, et chaque liste se feuillette de la même manière. Ce qui se passe derrière une clé traverse les mêmes règles qu’un clic dans l’application : limites de débit, suspensions, droits retirés et réglages de cette instance valent ici pareillement.

  • Chaque chemin commence par /api/v2 à l’adresse de cette instance, celle des exemples de cette page.
  • Requêtes et réponses sont en JSON, en UTF-8. Les noms de champs, les codes et les valeurs sont en anglais et le restent.
  • Une clé agit en tant que ton compte, jamais au-delà : ce que tu ne peux pas voir dans l’application, aucune clé ne peut le lire.
https://tellmelo.com/api/v2

Démarrage rapide

  1. Crée une clé sous « Réglages → App et données → API » et copie-la. Elle n’est montrée qu’une seule fois.
  2. Interroge la racine avec elle. La réponse dit quelle version tourne, ce que la clé peut faire et combien de requêtes il lui reste cette minute.
  3. Ensuite, chaque chemin fonctionne de la même façon : la clé dans l’en-tête, du JSON en retour, et pour les listes items et 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"
}

Pour continuer : /me pour ton propre profil, /posts pour ce qui est public, /feed pour ce que l’application te montre.

Ta clé

Il y a exactement une clé par compte, liée à ton identifiant. Elle commence par tm_key_, pour qu’un scanner la reconnaisse là où elle n’a pas sa place. Elle s’affiche une seule fois, au moment où elle est créée ; ensuite il ne reste ici que son empreinte, et personne ne peut te la relire, ni nous ni toi. Qui l’égare en crée une nouvelle ; l’ancienne cesse de valoir à cet instant.

Tu la crées sous « Réglages → App et données → API ». Elle voyage dans l’en-tête de la requête, comme Authorization: Bearer tm_key_… ou comme X-Tellmelo-Key. Pas dans la barre d’adresse, car ce qui s’y trouve finit dans les journaux d’accès, dans l’historique du navigateur et dans le referer de chaque lien.

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

Ou, si c’est plus commode, dans un en-tête à part :

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

Pas dans la barre d’adresse. Ce qui s’y trouve finit dans le journal d’accès de chaque serveur intermédiaire, dans l’historique du navigateur et dans le referer de chaque lien. Une clé n’y a pas sa place.

La même clé charge aussi les images. Chaque url d’une réponse pointe vers /api/media de cette instance ; envoie-y aussi la clé dans l’en-tête, et l’image revient, pour autant que ton compte ait le droit de la voir.

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

Ce qu’une clé a le droit de faire

Une clé porte deux droits, et chaque chemin des tableaux ci-dessous dit lequel il lui faut. Deux et pas cinq : un droit qu’on ne sait pas s’expliquer en une phrase est un droit qu’on coche sans lire. Et la ligne honnête passe entre regarder et changer.

  • read : regarder. Les publications publiques, les profils, les communautés et les tags, et ton propre compte tel que tu le vois : fil, notifications, conversations, messages.
  • write : changer. Tout ce qui se passe en ton nom : publier, répondre, voter, envoyer des messages, suivre, rejoindre, bloquer, marquer des notifications comme lues.

Ce qu’aucune clé ne peut

Aucune clé n’atteint les données de ton compte : ni mot de passe, ni adresse e-mail, ni type de compte, ni lieu, ni rôle, ni suppression. Ni les connexions, ni les appareils de notification, ni les clés elles-mêmes : une clé capable d’émettre des clés ne pourrait plus être coupée. Ni l’administration, ni la direction d’une communauté, car dissoudre une communauté ou la transmettre est une décision sur les publications d’autrui. Ce que le mot de passe garde, aucune clé ne le peut : un secret posé dans un script sur la machine d’un autre ne doit pas pouvoir ce que peut la connexion. Prendre un compte coûte toujours la connexion.

Requêtes et réponses

  • Du JSON partout. Chaque réponse est en application/json, en UTF-8, erreurs comprises. Seules les images arrivent en images.
  • Ce que tu envoies. Un POST porte ses champs sous forme d’objet JSON dans le corps. Les paramètres de l’adresse complètent ce que le corps ne nomme pas ; si les deux nomment le même champ, le corps l’emporte.
  • Les dates sont des nombres entiers de millisecondes depuis le 1er janvier 1970, UTC, comme la base de données les garde. Aucun fuseau horaire à mal lire.
  • Les identifiants sont des chaînes. Ne les découpe pas et ne te fie pas à leur forme ; compare-les uniquement en entier.
  • Chaque champ est toujours là. Ce qui n’existe pas vaut null, jamais absent ; un nombre est toujours un nombre, une liste toujours une liste, vide s’il le faut.
  • Les textes sont du texte brut, tels qu’écrits. Les #tags, les @noms et les liens restent tels quels, de même que les émojis propres à l’instance, sous la forme :name: ; leurs images sont listées sous /emojis.
  • Les images sont des adresses relatives à cette instance, /api/media?id=…. Charge-les avec la même clé dans l’en-tête ; sans elle, la réponse est 401.

Pages

Chaque liste prend limit et cursor et répond par items et next. Tu continues en renvoyant le next de la dernière réponse comme cursor ; quand next est vide, la fin est atteinte. Une page pleine peut tout de même être la dernière, et qui ne s’arrête qu’à une page vide demande une fois de trop. Le curseur est opaque : une place dans une liste, pas un instant. Ne le démonte pas et n’en fabrique pas toi-même ; ce qu’il contient peut changer sans qu’aucun chemin ne change.

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

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

Une page contient 20 entrées sans limit, 50 au plus. Quelques listes ne se feuillettent pas du tout : c’est indiqué à leur chemin, et leur next vaut toujours null.

Seulement ce qui est nouveau

Chaque réponse porte un ETag. Un programme qui redemande sans cesse devrait renvoyer le dernier comme If-None-Match : si rien n’a changé depuis, la réponse est 304 et ne porte pas de corps. C’est la différence entre une liste qui passe sur le fil chaque minute et une qui passe quand il y a quelque chose dedans, pour ta machine autant que pour celle-ci.

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

Deux exceptions, toutes deux voulues : /feed ne porte pas d’ETag, parce que son ordre bouge avec le temps et que chaque réponse est différente ; et une écriture ne répond jamais 304. Deux publications identiques sont deux publications.

Limites

Une clé peut faire 120 requêtes par minute, 600 avec l’abonnement « Organisation », à moins que l’administration ne lui ait fixé un autre nombre. La limite vaut par clé, pas par compte et pas par adresse. Au-delà, la réponse est 429 et rien ne s’est passé : la requête a été refusée, pas exécutée. Attends une minute et renvoie-la ; un programme qui bute régulièrement devrait ralentir plutôt que redemander aussitôt.

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

En plus de la limite de la clé, les écritures comptent dans les mêmes limites que dans l’application : combien de publications, de réponses ou de relations en quelques minutes. Elles aussi répondent 429 avec le code rate_limited.

En-têtes

Les noms sont ceux que toute bibliothèque cliente connaît déjà. Aucun n’est obligatoire, sauf la clé.

Ce que tu envoies

En-têteSignification
AuthorizationPorte la clé : Bearer tm_key_…. La voie habituelle.
X-Tellmelo-KeyLa clé, en alternative à Authorization, pour les outils qui utilisent cet en-tête pour autre chose.
Content-Typeapplication/json, pour une requête avec un corps.
If-None-MatchL’ETag de la dernière réponse. Si rien n’a changé depuis, la réponse est 304, sans corps.

Ce qui revient

En-têteSignification
ETagL’empreinte de cette réponse, marquée comme faible (W/). Renvoie-la comme If-None-Match.
X-RateLimit-LimitCombien de requêtes cette clé peut faire par minute.
X-RateLimit-RemainingCombien il en reste dans la minute en cours.
X-RateLimit-ResetQuand la minute suivante commence, en secondes depuis 1970, UTC.
X-Tellmelo-ScopeCe que cette clé peut faire : read ou read write.
Retry-AfterAvec un 429 : combien de secondes attendre avant de redemander.
WWW-AuthenticateAvec un 401 pour une clé absente : Bearer, la façon dont une clé est attendue.
Cache-Controlno-store : aucun proxy intermédiaire ne peut garder une réponse, car elle dépend de la clé qui demande. Ton propre programme peut quand même la vérifier avec l’ETag.

Quand quelque chose ne marche pas

Les erreurs arrivent en JSON avec deux champs : un code anglais fixe dans error, que ton programme peut comparer, et une phrase dans message pour la personne devant, avec le code d’état qui va avec. Le code ne change pas ; la phrase peut changer, et elle peut changer dans chaque langue : un programme qui compare la phrase casse un jour que personne n’a annoncé.

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

Certaines erreurs apportent un champ de plus : docs avec un 401 pour une clé absente, limit avec un 429.

StatutCodeSignification
400bad_requestLa requête est illisible, un champ obligatoire manque, ou une valeur ne fait pas partie de celles permises. Le message dit laquelle.
401key_missingPas de clé dans l’en-tête.
401key_invalidLa clé n’est pas valable : mal recopiée, remplacée par une nouvelle, ou son compte est suspendu. Lequel des trois, ce n’est volontairement pas dit.
401unauthorizedRefusé comme non connecté, pour une autre raison que la clé. Rare, et une raison de regarder le compte derrière la clé.
403scope_missingIl manque à la clé le droit dont ce chemin a besoin : le plus souvent write pour une clé qui peut seulement lire.
403account_data_lockedCela touche aux données de ton compte, qu’aucune clé n’atteint : mot de passe, adresse e-mail, suppression et ce genre de choses.
403forbiddenTon compte n’a pas le droit de faire cela : le même refus que dans l’application, par exemple un droit retiré ou un blocage.
404unknown_pathCe chemin n’existe pas, ou pas avec cette méthode.
404not_foundLe chemin existe, mais pas ce qu’il désigne, ou tu n’as pas le droit de le voir. Les deux ne sont pas distingués.
409conflictCela entre en conflit avec ce qui existe déjà, par exemple un nom déjà pris.
413too_largeTrop grand : un texte ou une requête au-delà de ce que cette instance accepte.
422unprocessableLisible, mais pas possible sous cette forme.
429rate_limitedTrop de requêtes. Rien n’a été fait ; attends et renvoie-la.
500internal_errorQuelque chose a échoué de notre côté, pas du tien. C’est consigné en entier sur le serveur.

Versions

La version est dans le chemin. Tant qu’il y est écrit v2, ces chemins et leurs champs restent tels quels ; ce qui s’ajoute vient à côté.

Les ajouts font monter le second chiffre : 2.1 a apporté /emojis et le marquage d’une conversation comme lue. 2.4 a retiré le champ contentWarning, car les avertissements de contenu n’existent plus. 2.5 a retiré le champ alt des images, car les descriptions d’images n’existent plus. 2.6 ajoute le type de notification team pour le nouveau travail de l’équipe. Chaque chemin indique depuis quelle version il existe, et la racine dit quelle version tourne.

Points d’accès

Tous les chemins d’un coup d’œil, puis chacun en détail : ce qu’il prend, un exemple de requête et ce qui revient.

CheminDroitÀ quoi
L’entrée
GET/api/v2readL’entrée : quelle version parle cette API et comment s’appelle cette instance.
Publications
GET/api/v2/postsreadLes publications publiques, les plus récentes d’abord.
GET/api/v2/posts/{id}readUne seule publication, par son id.
POST/api/v2/postswritePublier une publication.
DELETE/api/v2/posts/{id}writeRetirer une de tes publications.
Réponses
GET/api/v2/posts/{id}/repliesreadLes réponses à une publication, telles que tu les vois : ce qu’a écrit un compte bloqué reste dehors.
POST/api/v2/posts/{id}/replieswriteRépondre à une publication.
Sondages
POST/api/v2/posts/{id}/votewriteParticiper à un sondage.
Profils
GET/api/v2/profiles/{handle}readUn profil, par son identifiant court.
GET/api/v2/profiles/{handle}/postsreadLes publications publiques d’un profil, les plus récentes d’abord.
Communautés
GET/api/v2/communitiesreadLes communautés ouvertes de cette instance.
GET/api/v2/communities/{id}readUne seule communauté, par son id.
GET/api/v2/communities/{id}/postsreadLes publications publiques d’une communauté, les plus récentes d’abord.
Découvrir
GET/api/v2/tagsreadLes tags qui tournent en ce moment.
GET/api/v2/searchreadUne recherche sur les publications, les noms, les identifiants courts et les tags.
GET/api/v2/emojisreadLes émojis propres à l’instance, avec l’adresse de leurs images.
Ton compte
GET/api/v2/mereadTon propre profil, avec l’id que les autres chemins attendent.
GET/api/v2/feedreadTon propre fil, tel que l’application le compose.
Notifications
GET/api/v2/notificationsreadTes propres notifications, les plus récentes d’abord, feuilletables, pour qu’un programme rattrape ce qu’il a manqué.
POST/api/v2/notifications/readwriteMarquer tes notifications comme lues.
Messages
GET/api/v2/conversationsreadTa boîte : une ligne par conversation, la plus récente d’abord.
GET/api/v2/conversations/{with}/messagesreadLes messages d’une conversation, les plus récents d’abord.
POST/api/v2/conversations/{with}/messageswriteEnvoyer un message dans une conversation.
POST/api/v2/conversations/{with}/readwriteMarquer tous les messages d’une conversation comme lus.
Relations
POST/api/v2/relationswriteAimer, garder, partager, suivre, rejoindre, bloquer, masquer, selon kind.

L’entrée

La première requête de tout programme : la clé fonctionne-t-elle, et que peut-elle faire ?

GET/api/v2

L’entrée : quelle version parle cette API et comment s’appelle cette instance.

  • Droit read
  • avec ETag
  • depuis v2.0

Sans barre oblique à la fin : /api/v2/ redirige vers /api/v2 avec 308, et tous les programmes ne suivent pas.

Exemple de requête

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

Réponse

Répond avec un Service.

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

Statuts possibles : 200304401429

Publications

Lire les publications publiques, publier les tiennes et les retirer.

GET/api/v2/posts

Les publications publiques, les plus récentes d’abord.

  • Droit read
  • paginé
  • avec ETag
  • depuis v2.0

Sur les chemins publics, les réactions ne sont pas comptées : counts.likes et counts.reposts valent 0 et pinned vaut false (une coupe, pas une mesure).

Les publications d’une communauté ne s’atteignent pas ici, ni dans la liste ni par leur id. Elles se lisent sous /communities/{id}/posts.

Paramètres

NomTypeSignification
limitdans l’adresseintegerfacultatifCombien d’entrées tient une page : 20 par défaut, 50 au plus.
cursordans l’adressestringfacultatifOù cela reprend : le next de la réponse précédente. Sans lui, depuis le haut.

Exemple de requête

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

Réponse

Répond avec une page de Post, sous forme de `items` et `next`.

Exemple
{
  "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"
}

Statuts possibles : 200304401429

GET/api/v2/posts/{id}

Une seule publication, par son id.

  • Droit read
  • avec ETag
  • depuis v2.0

Sur les chemins publics, les réactions ne sont pas comptées : counts.likes et counts.reposts valent 0 et pinned vaut false (une coupe, pas une mesure).

Les publications d’une communauté ne s’atteignent pas ici, ni dans la liste ni par leur id. Elles se lisent sous /communities/{id}/posts.

Paramètres

NomTypeSignification
iddans le cheminstringobligatoireL’id d’une publication.

Exemple de requête

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

Réponse

Répond avec un Post.

Exemple
{
  "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
}

Statuts possibles : 200304400401404429

POST/api/v2/posts

Publier une publication.

  • Droit write
  • depuis v2.0

Une publication a besoin d’un texte ou d’un sondage. Sa longueur, le nombre de réponses d’un sondage et combien de publications en combien de temps sont fixés par cette instance ; au-delà, la réponse est 400 ou 429, avec un message qui dit lequel.

On ne peut pas encore joindre d’images via l’API, seulement dans l’application.

Paramètres

NomTypeSignification
textdans le corpsstringfacultatifLe texte lui-même : de la publication, de la réponse ou du message.
communitydans le corpsstringfacultatifL’id de la communauté où va la publication. Sans elle, en dehors de toute communauté.
quotesdans le corpsstringfacultatifL’id de la publication que celle-ci cite.
polldans le corpsstring[]facultatifLes options de réponse d’un sondage, comme une liste de textes. Combien sont permises, l’instance le fixe.

Exemple de requête

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"

Réponse

Répond avec un Created.

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

Statuts possibles : 200400401403429

DELETE/api/v2/posts/{id}

Retirer une de tes publications.

  • Droit write
  • depuis v2.0

Paramètres

NomTypeSignification
iddans le cheminstringobligatoireL’id d’une publication.

Exemple de requête

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

Réponse

Répond avec un Ok.

Exemple
{
  "ok": true
}

Statuts possibles : 200400401403404429

Réponses

La conversation sous une publication : lue comme une liste que parentId transforme en arbre, écrite en répondant à la publication ou à une réponse.

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

Les réponses à une publication, telles que tu les vois : ce qu’a écrit un compte bloqué reste dehors.

  • Droit read
  • paginé
  • avec ETag
  • depuis v2.0

La liste est plate et dans l’ordre d’écriture ; parentId en fait un arbre. Une page contient des fils entiers, une réponse n’arrive donc jamais sans celle à laquelle elle répond. Ce qu’a écrit un compte que tu as bloqué, ou qui t’a bloqué, est laissé de côté. Deux clés peuvent voir des listes différentes.

Paramètres

NomTypeSignification
iddans le cheminstringobligatoireL’id d’une publication.
limitdans l’adresseintegerfacultatifCombien d’entrées tient une page : 20 par défaut, 50 au plus.
cursordans l’adressestringfacultatifOù cela reprend : le next de la réponse précédente. Sans lui, depuis le haut.

Exemple de requête

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

Réponse

Répond avec une page de Reply, sous forme de `items` et `next`.

Exemple
{
  "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"
}

Statuts possibles : 200304400401404429

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

Répondre à une publication.

  • Droit write
  • depuis v2.0

Sous une publication en mode lent, chaque personne peut répondre une fois toutes les 10 minutes ; une réponse de plus reçoit 429 avec le délai dans le message. Le mode ne s’applique ni à l’auteur ni aux comptes qu’il suit.

Paramètres

NomTypeSignification
iddans le cheminstringobligatoireL’id d’une publication.
textdans le corpsstringobligatoireLe texte lui-même : de la publication, de la réponse ou du message.
parentIddans le corpsstringfacultatifL’id de la réponse à laquelle celle-ci répond. Sans elle, directement à la publication.

Exemple de requête

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"

Réponse

Répond avec un Created.

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

Statuts possibles : 200400401403404429

Sondages

Un sondage est une publication dont poll est renseigné. Voter a son propre chemin.

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

Participer à un sondage.

  • Droit write
  • depuis v2.0

Les voix par réponse valent null tant que le résultat est retenu : avant ton propre vote, pendant que le sondage court. total est toujours là.

Paramètres

NomTypeSignification
iddans le cheminstringobligatoireL’id d’une publication.
optiondans le corpsintegerobligatoireQuelle réponse, comptée à partir de 0. Une par appel : un sondage à plusieurs réponses se vote en appelant plusieurs fois.
retractdans le corpsbooleanfacultatifSi cette voix est retirée : true l’annule.

Exemple de requête

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"

Réponse

Répond avec un Ok.

Exemple
{
  "ok": true
}

Statuts possibles : 200400401403404429

Profils

Les profils publics par leur nom court, et ce qu’ils ont publié.

GET/api/v2/profiles/{handle}

Un profil, par son identifiant court.

  • Droit read
  • avec ETag
  • depuis v2.0

Paramètres

NomTypeSignification
handledans le cheminstringobligatoireL’identifiant court d’un profil.

Exemple de requête

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

Réponse

Répond avec un Profile.

Exemple
{
  "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
}

Statuts possibles : 200304400401404429

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

Les publications publiques d’un profil, les plus récentes d’abord.

  • Droit read
  • paginé
  • avec ETag
  • depuis v2.0

Sur les chemins publics, les réactions ne sont pas comptées : counts.likes et counts.reposts valent 0 et pinned vaut false (une coupe, pas une mesure).

Les publications d’une communauté ne s’atteignent pas ici, ni dans la liste ni par leur id. Elles se lisent sous /communities/{id}/posts.

Paramètres

NomTypeSignification
handledans le cheminstringobligatoireL’identifiant court d’un profil.
limitdans l’adresseintegerfacultatifCombien d’entrées tient une page : 20 par défaut, 50 au plus.
cursordans l’adressestringfacultatifOù cela reprend : le next de la réponse précédente. Sans lui, depuis le haut.

Exemple de requête

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

Réponse

Répond avec une page de Post, sous forme de `items` et `next`.

Exemple
{
  "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"
}

Statuts possibles : 200304400401404429

Communautés

Les communautés ouvertes de cette instance et leurs publications. Les internes et les cachées ne sont pas accessibles avec une clé.

GET/api/v2/communities

Les communautés ouvertes de cette instance.

  • Droit read
  • avec ETag
  • depuis v2.0

Triée par nombre de membres, pas par date, cette liste ne se feuillette donc pas, et next vaut toujours null.

Paramètres

NomTypeSignification
limitdans l’adresseintegerfacultatifCombien d’entrées tient une page : 20 par défaut, 50 au plus.

Exemple de requête

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

Réponse

Répond avec une page de Community, sous forme de `items` et `next`.

Exemple
{
  "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
}

Statuts possibles : 200304401429

GET/api/v2/communities/{id}

Une seule communauté, par son id.

  • Droit read
  • avec ETag
  • depuis v2.0

Paramètres

NomTypeSignification
iddans le cheminstringobligatoireL’id d’une communauté.

Exemple de requête

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

Réponse

Répond avec un Community.

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

Statuts possibles : 200304400401404429

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

Les publications publiques d’une communauté, les plus récentes d’abord.

  • Droit read
  • paginé
  • avec ETag
  • depuis v2.0

Sur les chemins publics, les réactions ne sont pas comptées : counts.likes et counts.reposts valent 0 et pinned vaut false (une coupe, pas une mesure).

Paramètres

NomTypeSignification
iddans le cheminstringobligatoireL’id d’une communauté.
limitdans l’adresseintegerfacultatifCombien d’entrées tient une page : 20 par défaut, 50 au plus.
cursordans l’adressestringfacultatifOù cela reprend : le next de la réponse précédente. Sans lui, depuis le haut.

Exemple de requête

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

Réponse

Répond avec une page de Post, sous forme de `items` et `next`.

Exemple
{
  "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"
}

Statuts possibles : 200304400401404429

Découvrir

Ce dont on parle en ce moment, une recherche dans les publications, les profils et les tags, et les émojis propres à l’instance.

GET/api/v2/tags

Les tags qui tournent en ce moment.

  • Droit read
  • avec ETag
  • depuis v2.0

Les tags du moment, les plus publiés d’abord. Pas de pagination : limit ne fait que raccourcir la liste.

Paramètres

NomTypeSignification
limitdans l’adresseintegerfacultatifCombien d’entrées tient une page : 20 par défaut, 50 au plus.

Exemple de requête

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

Réponse

Répond avec une page de Tag, sous forme de `items` et `next`.

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

Statuts possibles : 200304401429

GET/api/v2/search

Une recherche sur les publications, les noms, les identifiants courts et les tags.

  • Droit read
  • avec ETag
  • depuis v2.0

Ne cherche que dans ce qui est public : publications hors communautés, profils et tags. limit compte par type : 20 peut ramener jusqu’à 20 publications, 20 profils et 20 tags.

Paramètres

NomTypeSignification
qdans l’adressestringobligatoireLes mots cherchés.
typedans l’adressestringfacultatifQuel genre de résultat. Sans lui, tous les genres.allpostsprofilestags
limitdans l’adresseintegerfacultatifCombien d’entrées tient une page : 20 par défaut, 50 au plus.

Exemple de requête

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

Réponse

Répond avec un SearchResult.

Exemple
{
  "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
    }
  ]
}

Statuts possibles : 200304400401429

GET/api/v2/emojis

Les émojis propres à l’instance, avec l’adresse de leurs images.

  • Droit read
  • avec ETag
  • depuis v2.1

Dans les textes, un émoji de cette instance apparaît sous la forme :name:. Remplace-le par l’image de cette liste ; un nom qui n’y figure pas reste du texte : il a été supprimé ou n’a jamais existé.

Exemple de requête

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

Réponse

Répond avec une page de Emoji, sous forme de `items` et `next`.

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

Statuts possibles : 200304401429

Ton compte

Ton propre profil et ton fil, composés comme l’application le fait pour toi.

GET/api/v2/me

Ton propre profil, avec l’id que les autres chemins attendent.

  • Droit read
  • avec ETag
  • depuis v2.0

Exemple de requête

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

Réponse

Répond avec un Profile.

Exemple
{
  "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
}

Statuts possibles : 200304401429

GET/api/v2/feed

Ton propre fil, tel que l’application le compose.

  • Droit read
  • paginé
  • depuis v2.0

Pas d’ETag ici : l’ordre bouge avec le temps, chaque réponse est donc différente. Une liste commencée reste pourtant la même jusqu’au bout : next porte le moment où elle a commencé.

Paramètres

NomTypeSignification
tabdans l’adressestringfacultatifQuel fil : for-you, following, latest ou bookmarks. latest par défaut.for-youfollowinglatestbookmarks
tagdans l’adressestringfacultatifSeulement les publications portant ce tag. Sans lui, aucun filtre.
limitdans l’adresseintegerfacultatifCombien d’entrées tient une page : 20 par défaut, 50 au plus.
cursordans l’adressestringfacultatifOù cela reprend : le next de la réponse précédente. Sans lui, depuis le haut.

Exemple de requête

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

Réponse

Répond avec une page de Post, sous forme de `items` et `next`.

Exemple
{
  "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"
}

Statuts possibles : 200400401429

Notifications

Ce qui s’est passé autour de ton compte, lisible page par page, pour qu’un programme puisse rattraper ce qu’il a manqué.

GET/api/v2/notifications

Tes propres notifications, les plus récentes d’abord, feuilletables, pour qu’un programme rattrape ce qu’il a manqué.

  • Droit read
  • paginé
  • avec ETag
  • depuis v2.0

Lire ne marque rien comme lu ; c’est POST /notifications/read qui le fait. Plusieurs évènements du même type sur la même publication sont regroupés en une ligne, et more dit combien.

Paramètres

NomTypeSignification
limitdans l’adresseintegerfacultatifCombien d’entrées tient une page : 20 par défaut, 50 au plus.
cursordans l’adressestringfacultatifOù cela reprend : le next de la réponse précédente. Sans lui, depuis le haut.

Exemple de requête

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

Réponse

Répond avec une page de Notification, sous forme de `items` et `next`.

Exemple
{
  "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"
}

Statuts possibles : 200304401429

POST/api/v2/notifications/read

Marquer tes notifications comme lues.

  • Droit write
  • depuis v2.0

Exemple de requête

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

Réponse

Répond avec un Ok.

Exemple
{
  "ok": true
}

Statuts possibles : 200401403429

Messages

Ta boîte de réception et tes conversations. Une conversation n’a pas d’identifiant propre ; elle porte le nom de l’autre compte.

GET/api/v2/conversations

Ta boîte : une ligne par conversation, la plus récente d’abord.

  • Droit read
  • paginé
  • avec ETag
  • depuis v2.0

Paramètres

NomTypeSignification
limitdans l’adresseintegerfacultatifCombien d’entrées tient une page : 20 par défaut, 50 au plus.
cursordans l’adressestringfacultatifOù cela reprend : le next de la réponse précédente. Sans lui, depuis le haut.

Exemple de requête

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

Réponse

Répond avec une page de Conversation, sous forme de `items` et `next`.

Exemple
{
  "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"
}

Statuts possibles : 200304401429

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

Les messages d’une conversation, les plus récents d’abord.

  • Droit read
  • paginé
  • avec ETag
  • depuis v2.0

Lire ne marque rien comme lu : un programme qui récupère en arrière-plan n’a rien montré à personne. C’est POST /conversations/{with}/read qui le fait.

Paramètres

NomTypeSignification
withdans le cheminstringobligatoireL’id du compte avec qui tu parles. Une conversation n’a pas d’id à elle : c’est l’autre compte, la même valeur que la boîte appelle with.
limitdans l’adresseintegerfacultatifCombien d’entrées tient une page : 20 par défaut, 50 au plus.
cursordans l’adressestringfacultatifOù cela reprend : le next de la réponse précédente. Sans lui, depuis le haut.

Exemple de requête

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

Réponse

Répond avec une page de Message, sous forme de `items` et `next`.

Exemple
{
  "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"
}

Statuts possibles : 200304400401404429

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

Envoyer un message dans une conversation.

  • Droit write
  • depuis v2.0

Les mêmes règles que dans l’application s’appliquent : on ne peut pas écrire à qui t’a bloqué, et les réglages de l’autre personne comptent. La réponse dit alors pourquoi.

On ne peut pas encore joindre d’images via l’API, seulement dans l’application.

Paramètres

NomTypeSignification
withdans le cheminstringobligatoireL’id du compte avec qui tu parles. Une conversation n’a pas d’id à elle : c’est l’autre compte, la même valeur que la boîte appelle with.
textdans le corpsstringobligatoireLe texte lui-même : de la publication, de la réponse ou du message.
replyTodans le corpsstringfacultatifL’id d’un message précédent de cette conversation auquel celui-ci répond. Depuis 2.2.

Exemple de requête

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"

Réponse

Répond avec un Ok.

Exemple
{
  "ok": true
}

Statuts possibles : 200400401403404429

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

Marquer tous les messages d’une conversation comme lus.

  • Droit write
  • depuis v2.1

Paramètres

NomTypeSignification
withdans le cheminstringobligatoireL’id du compte avec qui tu parles. Une conversation n’a pas d’id à elle : c’est l’autre compte, la même valeur que la boîte appelle with.

Exemple de requête

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

Réponse

Répond avec un Ok.

Exemple
{
  "ok": true
}

Statuts possibles : 200400401403404429

Relations

Aimer, enregistrer, republier, suivre, rejoindre et bloquer : un seul chemin pour tout, établi et retiré avec active.

POST/api/v2/relations

Aimer, garder, partager, suivre, rejoindre, bloquer, masquer, selon kind.

  • Droit write
  • depuis v2.0

target est une publication pour like, save et repost, une communauté pour join, un compte pour follow, block et mute, toujours par son id. active: false retire la relation. Personne ne peut suivre par-dessus un blocage, dans aucun sens. Seule la personne qui masque voit le masquage.

Paramètres

NomTypeSignification
kinddans le corpsstringobligatoireQuelle relation : like, save, repost, follow, join, block ou mute (depuis 2.2).likesaverepostfollowjoinblockmute
targetdans le corpsstringobligatoireCe que la relation vise, par son id : une publication, un profil ou une communauté, selon kind.
activedans le corpsbooleanfacultatifSi la relation doit tenir : true la pose, false la retire.

Exemple de requête

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"

Réponse

Répond avec un Ok.

Exemple
{
  "ok": true
}

Statuts possibles : 200400401403429

Objets

Tout ce qu’une réponse peut contenir, champ par champ. Chaque champ est toujours présent ; les types sont des types JSON, et [] signifie une liste.

Service

La réponse de la racine : qui répond, et ce que cette clé peut faire.

ChampTypeSignification
namestringToujours tellmelo.
versionstringLa version de l’API, par exemple 2.1.
scopestringCe que cette clé peut faire : read ou read write.
rateLimitRateLimitLe quota de cette clé.
docsstringOù se trouve cette documentation, comme chemin sur cette instance.
specstringOù se trouve la description lisible par machine.
Exemple
{
  "name": "tellmelo",
  "version": "2.6",
  "scope": "read write",
  "rateLimit": {
    "limit": 120,
    "remaining": 117
  },
  "docs": "/legal/api",
  "spec": "/api/v2/openapi.json"
}

RateLimit

Le quota de cette clé dans la minute en cours.

ChampTypeSignification
limitintegerRequêtes par minute.
remainingintegerCombien il en reste dans cette minute.
Exemple
{
  "limit": 120,
  "remaining": 117
}

Post

Une publication : la même forme partout, qu’elle soit publique, de ton fil ou d’une recherche.

ChampTypeSignification
idstringL’identifiant de la publication.
textstringou nullLe texte tel qu’écrit (null pour une publication qui n’est qu’un sondage ou que des images).
kindstringCe qu’est la publication.
  • post — Une publication avec du texte, des images ou une citation.
  • poll — Une publication avec un sondage.
authorProfileBriefQui l’a écrite.
communityCommunityBriefou nullLa communauté où elle a été écrite (null hors de toute communauté).
mediaMedia[]Ses images, dans l’ordre ; vide s’il n’y en a pas.
pollPollou nullLe sondage (null s’il n’y en a pas).
quotesstringou nullL’identifiant de la publication que celle-ci cite.
continuesstringou nullL’identifiant de la publication que celle-ci prolonge, comme complément.
countsCountsRéponses, mentions J’aime et republications.
pinnedbooleanSi elle est épinglée en haut du profil de son auteur.
createdAtintegerQuand elle a été écrite.
Exemple
{
  "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

Une réponse sous une publication : une publication avec deux champs de plus.

Chaque champ de Post, et en plus :

ChampTypeSignification
postIdstringLa publication à laquelle toute la conversation est rattachée.
parentIdstringou nullLa réponse à laquelle celle-ci répond (null si elle répond directement à la publication).
Exemple
{
  "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

Combien de réponses, de mentions J’aime et de republications a une publication.

ChampTypeSignification
repliesintegerLes réponses, tous niveaux confondus.
likesintegerLes mentions J’aime.
repostsintegerLes republications.
Exemple
{
  "replies": 4,
  "likes": 31,
  "reposts": 2
}

Media

Une image d’une publication ou d’un message.

ChampTypeSignification
urlstringL’adresse de l’image, relative à cette instance. Charge-la avec la clé dans l’en-tête.
Exemple
{
  "url": "/api/media?id=b2d7e9f1-3c4a-4e8b-a1f0-6d5c4b3a2918"
}

Poll

Le sondage d’une publication.

ChampTypeSignification
optionsPollOption[]Les réponses, dans l’ordre. option d’un vote compte à partir de 0.
totalintegerCombien de voix il y a au total : toujours, même quand la répartition est retenue.
multiplebooleanSi l’on peut choisir plus d’une réponse.
endsAtintegerou nullQuand le sondage se termine (null s’il n’a pas de fin).
runningbooleanSi l’on peut encore voter.
resultsVisiblebooleanSi les voix par réponse sont montrées (voir votes).
myVotesinteger[]Les réponses que tu as choisies, comptées à partir de 0.
Exemple
{
  "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

Une réponse d’un sondage.

ChampTypeSignification
textstringLa réponse.
votesintegerou nullSes voix (null tant que le résultat est retenu).
Exemple
{
  "text": "Lavender",
  "votes": 12
}

ProfileBrief

Un profil tel qu’il apparaît dans d’autres objets : comme auteur, dans une recherche.

ChampTypeSignification
idstringL’identifiant du compte : ce qu’attendent /relations et /conversations/{with}.
handlestringLe nom court, sans @. Il fait partie de l’adresse du profil et ne peut pas contenir d’émojis.
namestringLe nom affiché. Il peut contenir des émojis, y compris :name:.
verifiedbooleanSi le compte est vérifié.
accountKindstringQuel genre de compte c’est.
  • person — Une personne.
  • business — Une entreprise.
  • association — Une association.
  • automated — Un compte automatisé, comme un bot.
Exemple
{
  "id": "a3e1f7c2-54b9-4d0e-8f16-7b2c9d4e1a05",
  "handle": "mara",
  "name": "Mara 🌻",
  "verified": true,
  "accountKind": "person"
}

Profile

Un profil seul, avec sa description et ses abonnés.

Chaque champ de ProfileBrief, et en plus :

ChampTypeSignification
aboutstringou nullLa description (null s’il n’y en a pas).
websitestringou nullLe site web du profil (null s’il n’y en a pas). Depuis 2.3.
websiteVerifiedbooleanSi le site renvoie vers ce profil avec rel=me, vérifié au cours de la dernière semaine. Depuis 2.3.
followersintegerCombien de comptes le suivent.
createdAtintegerQuand le compte a été créé.
Exemple
{
  "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 communauté dans laquelle une publication a été écrite.

ChampTypeSignification
idstringL’identifiant de la communauté.
namestringou nullSon nom.
Exemple
{
  "id": "c81d4e2a-0f3b-4a6c-9e57-1d2b3c4a5f60",
  "name": "Urban Gardening"
}

Community

Une communauté de cette instance.

ChampTypeSignification
idstringL’identifiant de la communauté.
namestringSon nom.
descriptionstringou nullLa description (null s’il n’y en a pas).
tagsstring[]Les sujets dont elle traite.
membersintegerCombien de membres elle compte.
joinPolicystringComment on y entre.
  • open — Tout le monde peut rejoindre.
  • application — Rejoindre demande une candidature que la communauté accepte.
  • invite — Seulement sur invitation.
visibilitystringQui peut la voir. Via une clé toujours open : les autres ne sont pas accessibles.
  • open — Visible par tout le monde.
Exemple
{
  "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

Un tag et combien de publications le portent.

ChampTypeSignification
tagstringLe tag, sans #.
postsintegerCombien de publications récentes le portent.
Exemple
{
  "tag": "garden",
  "posts": 58
}

SearchResult

Ce qu’une recherche trouve : trois listes, chacune peut-être vide, jamais absente.

ChampTypeSignification
postsPost[]Les publications trouvées, les plus récentes d’abord.
profilesProfileBrief[]Les profils trouvés, par nom court.
tagsTag[]Les tags trouvés, les plus utilisés d’abord.
Exemple
{
  "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 émoji de cette instance.

ChampTypeSignification
namestringLe nom, tel qu’il figure entre les deux-points.
urlstringL’adresse de l’image, relative à cette instance.
Exemple
{
  "name": "tellmelo",
  "url": "/api/media?id=e1f2a3b4-c5d6-4e7f-8a9b-0c1d2e3f4a5b"
}

Notification

Une notification. Une ligne peut regrouper plusieurs évènements du même type.

ChampTypeSignification
idstringL’identifiant de la notification.
kindstringCe qui s’est passé.
  • reply — Quelqu’un t’a répondu.
  • like — Quelqu’un aime ta publication.
  • repost — Quelqu’un a republié ta publication.
  • follow — Quelqu’un te suit.
  • mention — Quelqu’un t’a mentionné.
  • group_mention — Quelqu’un a mentionné un groupe que tu diriges ; text est son nom.
  • message — Quelqu’un t’a écrit un message.
  • scheduled — Une de tes publications programmées est parue.
  • reminder — Un rappel sur une publication enregistrée est arrivé.
  • report — Ce qu’est devenu un signalement que tu as envoyé.
  • moderation — Une décision sur ton compte : un avertissement, une restriction, un recours.
  • team — Nouveau travail pour l’équipe, uniquement pour propriétaires, admins et modérateurs : signalements, recours, liens soumis, demandes, demandes de vérification et résiliations.
textstringou nullSeulement pour les signalements et la modération : le texte qui l’accompagne. Sinon null : la phrase d’une notification, c’est ton programme qui la construit.
actorActorQui l’a fait.
postIdstringou nullLa publication concernée (null s’il n’y en a pas).
readbooleanSi elle a été marquée comme lue.
moreintegerPour combien d’autres évènements cette ligne compte, au-delà de celui qui est nommé.
createdAtintegerQuand c’est arrivé la première fois.
updatedAtintegerQuand elle a regroupé un évènement pour la dernière fois. La liste est triée ainsi.
Exemple
{
  "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 a déclenché une notification.

ChampTypeSignification
handlestringLe nom court.
namestringLe nom affiché.
Exemple
{
  "handle": "jon",
  "name": "Jon"
}

Conversation

Une ligne de ta boîte de réception.

ChampTypeSignification
withstringL’identifiant de l’autre compte : ce qu’attend /conversations/{with}/messages.
handlestringSon nom court.
namestringSon nom affiché.
excerptstringou nullLe début du dernier message (null s’il n’a pas de texte).
truncatedbooleanSi l’extrait a été raccourci.
fromMebooleanSi le dernier message est de toi.
lastMessageIdstringL’identifiant du dernier message.
unreadintegerCombien de ses messages tu n’as pas encore lus.
updatedAtintegerQuand le dernier message a été écrit.
Exemple
{
  "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 message dans une conversation.

ChampTypeSignification
idstringL’identifiant du message.
textstringou nullLe texte (null pour un message qui n’est fait que d’images).
fromstringL’identifiant du compte qui l’a écrit.
tostringL’identifiant du compte à qui il a été écrit.
readbooleanSi le destinataire l’a lu.
mediaMedia[]Ses images ; vide s’il n’y en a pas.
replyTostringou nullL’id du message auquel celui-ci répond (null s’il ne répond à aucun). Depuis 2.2.
createdAtintegerQuand il a été envoyé.
Exemple
{
  "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 réponse d’une écriture qui a créé quelque chose.

ChampTypeSignification
idstringL’identifiant de ce qui a été créé.
scheduledForintegerou nullQuand cela apparaît, si la publication a été programmée (sinon null).
deleteAtintegerou nullQuand cela se supprime tout seul, si c’était réglé (sinon null).
Exemple
{
  "id": "5f0c2a9e-8d41-4b7a-9c3e-2e61d0f4a7b1",
  "scheduledFor": null,
  "deleteAt": null
}

Ok

La réponse d’une écriture qui n’a rien à rendre.

ChampTypeSignification
okbooleanToujours true.
Exemple
{
  "ok": true
}

La description lisible par une machine

Le même tableau à partir duquel cette page est bâtie est servi sous /api/v2/openapi.json : chemins, paramètres, droits et les formes qui reviennent. Un générateur de clients peut le lire, et il ne peut pas s’écarter de l’API, car la page, le routeur et la description viennent d’une seule liste.

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

Ce qu’est devenue v1

v1 est supprimée. Les anciens chemins sous /api/v1/ répondent 410 et indiquent dans le corps où aller. Pas de redirection, car v2 répond sous une autre forme, et un programme qui la suivrait recevrait un 200 qu’il ne sait pas lire. Il n’y avait alors pas encore de comptes publics, donc personne avec un programme dessus ; la retirer plus tard aurait voulu dire ne jamais la retirer.

Ce que nous attendons

Les mêmes principes que partout ailleurs : pas de harcèlement, pas de spam, pas de contenus d’autrui sans en avoir le droit. Un programme n’excuse rien : tu réponds de ce que ta clé écrit.

Retour à tellmelo