Discovering the T2.social API

So I’ve joined T2 (now Pebble) to try it out and it was pretty quiet there at the beginning. It was a bit hard to see whom to follow and such. So I decided to look a bit behind the curtain and see if T2 Social has an API.

By the way, if you need an invite reach out to me either via comments here or on Twitter @IlyaReshet.

Is there a T2 official API?

While there is no, official and documented API (at least at the time of writing which is the beginning of June 2023) that I could find I had an idea to look at the Network tab in the Chrome Developer Console

Quest after the T2 API using Chrome and Postman

When you go to my T2 profile with Dev Console open you can see a lot of requests going on the network.

Network tab in Chrome Developer Tools

That’s all nice, but how does it lead me to any API?

I noticed that some of the calls are called “query”

And when you look into the payload section you can see that it running some kind of query (dah!) against the fetchUser operation.

Then in the response, you can see what this operation returned to the browser.

T2 API call reply
T2 API call reply

Now we are cooking with Gas! We have user details, like id, handle, bio, location, number of users following this user and how many other users this user is following, etc.

But what is this “horrible” query with all these new lines (\n) and how can I use it in Postman or somewhere else

unformatted T2 API call
unformatted T2 API call

Apparently, it’s a GraphQL syntax and after replacing all the \n with new lines and (in Postman) moving the variables part out it looks a lot more readable

T2 API query in Postman
T2 API query in Postman

Here is the query nicely formatted


query fetchUserProfile($handle: String!, $from: Int, $limit: Int) {
  user(handle: $handle) {
    id
    is_profile_completed
    settings
    ...userFullFragment
    invite {
      id
      hashtag
      invite_type
      user {
        handle
        __typename
      }
      __typename
    }
    tweets(from: $from, limit: $limit) {
      is_thread
      ...tweetFragment
    __typename
    }
    replies(from: $from, limit: $limit) {
      is_thread
      ...tweetFragment
      parent {
        user {
          handle
          __typename
        }
        __typename
      }
      reposting {
        ...tweetFragment
        __typename
      }
      replies {
        ...tweetFragment
        __typename
      }
      __typename
    }
    __typename
  }
}

fragment tweetFragment on Tweet {
  id
  reply_to_id
  is_reposted
  is_liked
  is_reported
  replies_count
  reposts_count
  favorites_count
  reports_count
  created_at
  is_edited
  deleted_at
   block_reason   
  __typename
}

fragment userFullFragment on User {
  id
  handle
  name
  bio
  location
  website
  is_followed
  follows_you
  is_verified
  is_twitter_legacy
  verified_note
  created_at
  followers_count
  followings_count
  twitter_handle
  block_reason
  __typename
}

After reading a bit about GraphQL I was able to decipher what all that means:

  • query fetchUserProfile($handle: String!, $from: Int, $limit: Int) – here we are running a query (the name fetchUserProfile is just used for convenience and can be replaced with foobar or omitted at all) and telling which arguments (variables on the Postman screenshot) we want to pass to the operation.
  • user(handle: $handle) – we want to return a user whos handle field is equal to the value passed via the $handle variable
  • then we declare all the fields or classes we want the API to return.
    • * some of these are “simple” fields like id
    • * while others are more complicated like ...userFullFragmentfragments
      • * and even totally separated classes (that would require separate traditional REST API calls) can be fetched in the same query in GraphQL, like the tweets portion in the example above.

The T2 Social API

It’s a bit hard to document the T2 API schema without access , but I’ll try to add information as I continue to discover it.

The endpoint for T2 Social API: https://t2.social/api/query

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.