# go-mastodon: a Mastodon API client for Go with the streaming endpoints

> go-mastodon is a Go client for the Mastodon API, written by Yasuhiro Matsumoto, whose repository pairs one file per API area with a test file beside it and an examples directory holding a working program for each of the three authentication styles. It has almost no dependencies, and it covers the account, status, list, filter, notification, report and streaming endpoints.

**mattn/go-mastodon** — mastodon client for golang

- Repository: https://github.com/mattn/go-mastodon
- Stars: 648 · Forks: 90
- Language: Go
- License: MIT
- Published: 2026-10-21 · Updated: 2026-10-21 · Language: en
- Canonical page: https://hysenlabs.com/projects/mattn-go-mastodon

## One file per API area, one test file beside it

go-mastodon is a Mastodon client for Go, and the repository layout is the clearest description of its shape.

The top level holds a file per area of the API, and in almost every case the test file sits next to the source file with the same base name. There is accounts.go with accounts_test.go, admin.go with admin_test.go, apps.go with apps_test.go, filters.go with filters_test.go, instance.go with instance_test.go, lists.go with lists_test.go, notification.go with notification_test.go, polls.go with polls_test.go, report.go with report_test.go, status.go with status_test.go, streaming.go with streaming_test.go, streaming_ws.go with streaming_ws_test.go, and tags.go with tags_test.go.

The shared parts are mastodon.go for the client type and the request plumbing, helper.go for the small utilities, compat.go for compatibility handling, unixtime.go for time handling, and doc.go. The main package entry is mastodon.go, and there is a cmd/ directory for the command line entry point, plus a testdata/ directory holding the fixtures the tests run against.

That naming discipline is a good sign in a client library. When the API adds an endpoint, it lands in the file for that area, and when a method changes, the test for it changes with it. It also means the readme's endpoint checklist maps onto the code, which is more useful than a hand written list in a document.

The client is written by Yasuhiro Matsumoto, known as mattn, who is also the author of the widely used go-sqlite3 library. The MIT licence is the simplest one to work with, and the repository carries the Go Reference, Go Report Card, Codecov and build status badges at the top of the readme.

## Three ways to authenticate, three working examples

The usage section opens by saying there are three ways to authenticate users, and each one has a runnable program in the examples directory.

User credentials are described as the simplest method, allowing you to use an application registered in your account to interact with the Mastodon API on your behalf. The setup is to create an application on Mastodon by navigating to Preferences, then Development, then New Application, and to select the necessary scopes. The working example is examples/user-credentials/main.go.

Public applications use application tokens and have limited access to the API, allowing access only to public data. The documentation points to the Mastodon client token documentation, and the example is examples/public-application/main.go.

The third option is an application with client credentials, OAuth, which allows you to create an application that can interact with the API on behalf of a user. It registers the application and requests user authorization to obtain an access token. The example is examples/user-oauth-authorization/main.go.

Having a working program for each mode is worth more than a paragraph describing them, because the three differ in more than the token type. The user credentials path is a single token you paste, the public application path never touches a user account, and the OAuth path involves a redirect, a consent screen and a callback, which is the part where most people get stuck. A copy of the right example removes the guesswork.

The difference matters for what you are building. A bot that posts on its own account wants user credentials, a tool that only reads public timelines wants the public application path and never needs a token belonging to a person, and a service where a user signs in to your application wants the OAuth path.

## The endpoint checklist is the API surface in one screen

The readme includes a long status list of implemented endpoints, and it is the most informative part of the document for anyone deciding whether the client covers what they need.

The list is organised by API area and runs from accounts through to tags. For accounts there is fetching an account, verifying credentials, updating credentials, listing followers and following, listing statuses, following and unfollowing, blocking and unblocking, muting and unmuting, listing lists, fetching relationships, searching accounts, and verifying an application. The apps, blocks, bookmarks, conversations, favourites, filters and follow requests areas are each present, with the filters area showing the full set of list, create, update and delete operations.

Status operations are extensive: fetching a status, its context, its card, its edit history, who reblogged it and its source, favourited by, and who favourited, creating, updating and deleting, reblogging and unreblogging, favouriting and unfavouriting, bookmarking and unbookmarking.

The timelines area covers home, public, a tag timeline and a list timeline, and there is a search endpoint at the v2 path alongside the v1 endpoints, which is a detail worth noticing because a client that only implemented v1 search would silently miss the newer shape.

The streaming endpoints are listed at the end of the timelines group, including the user stream, the public stream, the hashtag stream, the local hashtag stream, the list stream and the direct stream. In the repository, the streaming area is covered by two files, streaming.go and streaming_ws.go, with a test file for each, and the websocket dependency in the module manifest is the gorilla websocket package, which is where the streaming implementation gets its transport. The link header dependency is used to read the pagination link header that Mastodon returns.

## A small dependency list and a retracted early tag

The dependency situation is unusually clean for a client of this size, and the manifest shows why.

The go.mod file requires exactly two direct dependencies: the gorilla websocket library at version 1.5.3, and the linkheader library from the linkheader project, which is used to parse the pagination headers. Everything else is the standard library. There is no HTTP client framework, no JSON layer beyond the standard one, and no OAuth library, so the authentication code in this repository is the authentication code you get.

The module declares go 1.25, and there is a go.work file with a matching go.work.sum at the root, which means the repository is set up as a Go workspace rather than a single module. There is a go.test.sh script alongside, and a .vscode directory for editor settings.

The one line in the manifest worth a second look is the retract directive:

```
retract [v0.0.7+incompatible, v0.0.7+incompatible] // Accidental; no major changes or features.
```

That retracts a specific version range, and the comment says why: it was accidental, with no major changes or features. Retracting a version in Go means the module tool will warn or refuse to resolve it, which is the polite way of saying do not use this one. It is a small thing, and it is also a sign of care about the module proxy, which is where an accidental tag becomes a permanent problem.

The installation is a single command, go install github.com/mattn/go-mastodon@latest, and there are no GitHub releases to sort through. The activity is steady rather than busy: the repository is not archived, the default branch is master, and the last push was on 2026-07-10, a little over three months before the current date.

## Installing and reading the code as a reference

The installation is a single command, and it is worth noticing that the module is fetched by tag rather than by a release, because the repository publishes none:

```shell
go install github.com/mattn/go-mastodon@latest
```

Beyond the install, the repository is usable as a reference document, which is how most people first meet a client library like this. The endpoint checklist in the readme is a map of the API, and the file layout is a map of the code, so you can answer a question about a specific Mastodon feature by finding the file whose name matches it and seeing the method inside.

There is also a cmd/ directory for a command line entry point, and the examples directory is a small collection of complete programs rather than fragments. That combination is what makes the library approachable: a complete program for the authentication mode you need, a file per API area, and a test file next to each one showing how the method is called.

The implementation is a thin translation layer, and that has a consequence for anyone extending it. Because the library is mostly a mapping of HTTP calls to Go methods, adding an endpoint the upstream library does not cover means writing the request yourself rather than extending a generic framework. For a client that tracks the API closely and is actively maintained, that is rarely necessary. For one that has drifted, it is the price of the small dependency list.

## Conclusion

go-mastodon suits a Go developer writing a Mastodon bot, a feed reader or an archival tool who wants the whole API surface in one dependency-light package with runnable examples for each authentication style. It does not suit a project that needs a maintained, semantically versioned release train, because the repository has no GitHub releases and the only published tag is retracted, and it does not suit someone who needs the streaming API to be a single consistent shape, since the streaming endpoints appear alongside a separate websocket implementation. Before building on it, read the example for your authentication mode, and check the endpoint list in the readme against what your server version actually serves.

## FAQ

### How do I authenticate a Go application against Mastodon with go-mastodon?

There are three methods. User credentials use an application you register in your own account and the scopes you select, public applications use application tokens with access only to public data, and the OAuth option registers an application and requests user authorization for an access token. Each has a working example in the examples directory.

### Which Mastodon API endpoints does go-mastodon implement?

The readme lists them: accounts, apps, blocks, bookmarks, conversations, favourites, filters, follow requests, followed tags, follows, instance and its activity and peers, lists, media, mutes, notifications, push subscriptions, reports, search, statuses with their context, card, history, source, reblog and favourite subresources, timelines including home, public, tag and list, the streaming endpoints, endorsements, and tags.

### What are the dependencies of go-mastodon?

Only two: the gorilla websocket library for streaming, and the linkheader library for reading the pagination link header. Everything else comes from the standard library, and the module declares Go 1.25.

### How do I install go-mastodon?

With go install github.com/mattn/go-mastodon@latest. The repository has no GitHub releases, and one early tag, v0.0.7+incompatible, is retracted in the module manifest as accidental, with no major changes or features.

## Sources

- [Issues](https://github.com/mattn/go-mastodon/issues)
- [License: MIT](https://github.com/mattn/go-mastodon/blob/master/LICENSE)
- [mattn/go-mastodon on GitHub](https://github.com/mattn/go-mastodon)
- [README](https://github.com/mattn/go-mastodon/blob/master/README.md)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/mattn-go-mastodon
