Skip to content
Go Twitter REST and Streaming API v1.1
Go Makefile
Branch: master
Clone or download

Latest commit

roobre and dghubble Update links to twitter docs (#147)
* Previous links redirected to a mostly useless introduction page
Latest commit 39e5462 Jul 19, 2019


Type Name Latest commit message Commit time
Failed to load latest commit information.
examples Improve AppAuth example in README, godoc, and examples Jul 11, 2019
twitter Update links to twitter docs (#147) Jul 19, 2019
.gitignore Improve test coverage and use the assert test package Nov 7, 2015
.travis.yml Add Go v1.12 and remove Go v1.9 Mar 5, 2019 Add a go.mod file Jul 11, 2019
LICENSE Add LICENSE, gocover README badge, additional tests Apr 25, 2015
Makefile Replace test script with a make target Nov 26, 2018 Improve AppAuth example in README, godoc, and examples Jul 11, 2019
go.mod Add a go.mod file Jul 11, 2019
go.sum Add a go.mod file Jul 11, 2019

go-twitter Build Status GoDoc

go-twitter is a Go client library for the Twitter API. Check the usage section or try the examples to see how to access the Twitter API.


  • Twitter REST API:
    • Accounts
    • DirectMessageEvents
    • Favorites
    • Friends
    • Friendships
    • Followers
    • Lists
    • PremiumSearch
    • RateLimits
    • Search
    • Statuses
    • Timelines
    • Users
  • Twitter Streaming API
    • Public Streams
    • User Streams
    • Site Streams
    • Firehose Streams


go get


Read GoDoc



The twitter package provides a Client for accessing the Twitter API. Here are some example requests.

config := oauth1.NewConfig("consumerKey", "consumerSecret")
token := oauth1.NewToken("accessToken", "accessSecret")
httpClient := config.Client(oauth1.NoContext, token)

// Twitter client
client := twitter.NewClient(httpClient)

// Home Timeline
tweets, resp, err := client.Timelines.HomeTimeline(&twitter.HomeTimelineParams{
    Count: 20,

// Send a Tweet
tweet, resp, err := client.Statuses.Update("just setting up my twttr", nil)

// Status Show
tweet, resp, err := client.Statuses.Show(585613041028431872, nil)

// Search Tweets
search, resp, err := client.Search.Tweets(&twitter.SearchTweetParams{
    Query: "gopher",

// User Show
user, resp, err := client.Users.Show(&twitter.UserShowParams{
    ScreenName: "dghubble",

// Followers
followers, resp, err := client.Followers.List(&twitter.FollowerListParams{})

Authentication is handled by the http.Client passed to NewClient to handle user auth (OAuth1) or application auth (OAuth2). See the Authentication section.

Required parameters are passed as positional arguments. Optional parameters are passed typed params structs (or nil).

Streaming API

The Twitter Public, User, Site, and Firehose Streaming APIs can be accessed through the Client StreamService which provides methods Filter, Sample, User, Site, and Firehose.

Create a Client with an authenticated http.Client. All stream endpoints require a user auth context so choose an OAuth1 http.Client.

client := twitter.NewClient(httpClient)

Next, request a managed Stream be started.


Filter Streams return Tweets that match one or more filtering predicates such as Track, Follow, and Locations.

params := &twitter.StreamFilterParams{
    Track: []string{"kitten"},
    StallWarnings: twitter.Bool(true),
stream, err := client.Streams.Filter(params)


User Streams provide messages specific to the authenticate User and possibly those they follow.

params := &twitter.StreamUserParams{
    With:          "followings",
    StallWarnings: twitter.Bool(true),
stream, err := client.Streams.User(params)

Note To see Direct Message events, your consumer application must ask Users for read/write/DM access to their account.


Sample Streams return a small sample of public Tweets.

params := &twitter.StreamSampleParams{
    StallWarnings: twitter.Bool(true),
stream, err := client.Streams.Sample(params)

Site, Firehose

Site and Firehose Streams require your application to have special permissions, but their API works the same way.

Receiving Messages

Each Stream maintains the connection to the Twitter Streaming API endpoint, receives messages, and sends them on the Stream.Messages channel.

Go channels support range iterations which allow you to read the messages which are of type interface{}.

for message := range stream.Messages {

If you run this in your main goroutine, it will receive messages forever unless the stream stops. To continue execution, receive messages using a separate goroutine.


Receiving messages of type interface{} isn't very nice, it means you'll have to type switch and probably filter out message types you don't care about.

For this, try a Demux, like SwitchDemux, which receives messages and type switches them to call functions with typed messages.

For example, say you're only interested in Tweets and Direct Messages.

demux := twitter.NewSwitchDemux()
demux.Tweet = func(tweet *twitter.Tweet) {
demux.DM = func(dm *twitter.DirectMessage) {

Pass the Demux each message or give it the entire Stream.Message channel.

for message := range stream.Messages {
// or pass the channel


The Stream will stop itself if the stream disconnects and retrying produces unrecoverable errors. When this occurs, Stream will close the stream.Messages channel, so execution will break out of any message for range loops.

When you are finished receiving from a Stream, call Stop() which closes the connection, channels, and stops the goroutine before returning. This ensures resources are properly cleaned up.


Bad: In this example, Stop() is unlikely to be reached. Control stays in the message loop unless the Stream becomes disconnected and cannot retry.

// program does not terminate :(
stream, _ := client.Streams.Sample(params)
for message := range stream.Messages {

Bad: Here, messages are received on a non-main goroutine, but then Stop() is called immediately. The Stream is stopped and the program exits.

// got no messages :(
stream, _ := client.Streams.Sample(params)
go demux.HandleChan(stream.Messages)

Good: For main package scripts, one option is to receive messages in a goroutine and wait for CTRL-C to be pressed, then explicitly stop the Stream.

stream, err := client.Streams.Sample(params)
go demux.HandleChan(stream.Messages)

ch := make(chan os.Signal)
signal.Notify(ch, syscall.SIGINT, syscall.SIGTERM)



The API client accepts an any http.Client capable of making user auth (OAuth1) or application auth (OAuth2) authorized requests. See the dghubble/oauth1 and golang/oauth2 packages which can provide such agnostic clients.

Passing an http.Client directly grants you control over the underlying transport, avoids dependencies on particular OAuth1 or OAuth2 packages, and keeps client APIs separate from authentication protocols.

See the google/go-github client which takes the same approach.

For example, make requests as a consumer application on behalf of a user who has granted access, with OAuth1.

// OAuth1
import (

config := oauth1.NewConfig("consumerKey", "consumerSecret")
token := oauth1.NewToken("accessToken", "accessSecret")
// http.Client will automatically authorize Requests
httpClient := config.Client(oauth1.NoContext, token)

// Twitter client
client := twitter.NewClient(httpClient)

If no user auth context is needed, make requests as your application with application auth.

// OAuth2
import (

// oauth2 configures a client that uses app credentials to keep a fresh token
config := &clientcredentials.Config{
    ClientID:     "consumerKey",
    ClientSecret: "consumerSecret",
    TokenURL:     "",
// http.Client will automatically authorize Requests
httpClient := config.Client(oauth2.NoContext)

// Twitter client
client := twitter.NewClient(httpClient)    

To implement Login with Twitter for web or mobile, see the gologin package and examples.


  • Support gzipped streams
  • Auto-stop streams in the event of long stalls


See the Contributing Guide.


MIT License

You can’t perform that action at this time.