+ Integration Guide
Twitter/X API with Go: Complete Guide
How to search X/Twitter and scrape tweets using Go and the FetchLayer API. Clean, idiomatic Go examples with proper error handling and struct decoding.
Written by Alex P.
- Go
- Golang
- twitter scraping
- X API
- Twitter API
- API integration
This guide shows how to use the FetchLayer Twitter/X API with Go. All examples use the standard library — no third-party HTTP clients needed.
Setup
- Get a free API key (no credit card)
- Go 1.21+ (for
slogand modern stdlib features)
API Client
package main
import (
"bytes"
"encoding/json"
"fmt"
"net/http"
"os"
)
const baseURL = "https://api.fetchlayer.dev/twitter"
var apiKey = os.Getenv("FETCHLAYER_API_KEY")
func twitter(endpoint string, body any, result any) error {
payload, err := json.Marshal(body)
if err != nil {
return fmt.Errorf("marshal: %w", err)
}
req, err := http.NewRequest("POST", baseURL+"/"+endpoint, bytes.NewReader(payload))
if err != nil {
return fmt.Errorf("request: %w", err)
}
req.Header.Set("Authorization", "Bearer "+apiKey)
req.Header.Set("Content-Type", "application/json")
resp, err := http.DefaultClient.Do(req)
if err != nil {
return fmt.Errorf("do: %w", err)
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
return fmt.Errorf("API returned %d", resp.StatusCode)
}
return json.NewDecoder(resp.Body).Decode(result)
}
Types
type TwitterAuthor struct {
Handle string `json:"handle"`
DisplayName string `json:"displayName"`
IsVerified bool `json:"isVerified"`
FollowersCount int `json:"followersCount,omitempty"`
}
type Tweet struct {
ID string `json:"id"`
Text string `json:"text"`
Author TwitterAuthor `json:"author"`
CreatedAt string `json:"createdAt"`
LikeCount int `json:"likeCount"`
RetweetCount int `json:"retweetCount"`
ReplyCount int `json:"replyCount"`
ViewCount int `json:"viewCount,omitempty"`
URL string `json:"url"`
}
type SearchResponse struct {
Results []Tweet `json:"results"`
Cursor string `json:"cursor,omitempty"`
}
type TweetDetailResponse struct {
ID string `json:"id"`
Text string `json:"text"`
Author TwitterAuthor `json:"author"`
CreatedAt string `json:"createdAt"`
LikeCount int `json:"likeCount"`
RetweetCount int `json:"retweetCount"`
ReplyCount int `json:"replyCount"`
QuoteCount int `json:"quoteCount"`
ViewCount int `json:"viewCount"`
URL string `json:"url"`
Lang string `json:"lang"`
}
type UserProfile struct {
Handle string `json:"handle"`
DisplayName string `json:"displayName"`
Description string `json:"description"`
IsVerified bool `json:"isVerified"`
FollowersCount int `json:"followersCount"`
FollowingCount int `json:"followingCount"`
TweetsCount int `json:"tweetsCount"`
JoinedAt string `json:"joinedAt"`
Location string `json:"location,omitempty"`
Website string `json:"website,omitempty"`
}
Search Twitter/X
func main() {
var data SearchResponse
err := twitter("search", map[string]any{
"query": "best Go web frameworks",
"product": "Top",
"count": 10,
}, &data)
if err != nil {
fmt.Fprintf(os.Stderr, "error: %v\n", err)
os.Exit(1)
}
for _, tweet := range data.Results {
fmt.Printf("[%d likes] @%s: %s\n", tweet.LikeCount, tweet.Author.Handle, truncate(tweet.Text, 100))
}
}
Run it:
FETCHLAYER_API_KEY=sk-your-key go run main.go
Get a Tweet by ID
var tweet TweetDetailResponse
err := twitter("tweet-detail", map[string]any{
"tweetId": "1942939879222220800",
}, &tweet)
if err != nil {
log.Fatal(err)
}
fmt.Printf("@%s: %s\n", tweet.Author.Handle, tweet.Text)
fmt.Printf("%d likes · %d retweets · %d replies\n", tweet.LikeCount, tweet.RetweetCount, tweet.ReplyCount)
Get a User Profile
var profile UserProfile
err := twitter("user-profile-details", map[string]any{
"handle": "openai",
}, &profile)
if err != nil {
log.Fatal(err)
}
fmt.Printf("%s (@%s)\n", profile.DisplayName, profile.Handle)
fmt.Printf("Followers: %d | Following: %d | Tweets: %d\n",
profile.FollowersCount, profile.FollowingCount, profile.TweetsCount)
Get a User’s Tweets
type UserTweetsResponse struct {
Tweets []Tweet `json:"tweets"`
Cursor string `json:"cursor,omitempty"`
}
var data UserTweetsResponse
err := twitter("user-tweets", map[string]any{
"handle": "rauchg",
"count": 20,
}, &data)
if err != nil {
log.Fatal(err)
}
for _, tweet := range data.Tweets {
fmt.Printf("[%d likes] %s\n", tweet.LikeCount, truncate(tweet.Text, 120))
}
Get Followers
type AccountEntry struct {
Handle string `json:"handle"`
DisplayName string `json:"displayName"`
IsVerified bool `json:"isVerified"`
FollowersCount int `json:"followersCount"`
}
type FollowersResponse struct {
Accounts []AccountEntry `json:"accounts"`
Cursor string `json:"cursor,omitempty"`
}
var followers FollowersResponse
err := twitter("followers", map[string]any{
"handle": "openai",
"count": 50,
}, &followers)
if err != nil {
log.Fatal(err)
}
for _, account := range followers.Accounts {
fmt.Printf("@%s — %d followers (verified: %v)\n",
account.Handle, account.FollowersCount, account.IsVerified)
}
Full Example: Twitter Audience Analyzer
// analyzer.go — run with: FETCHLAYER_API_KEY=sk-... go run analyzer.go <handle>
func main() {
if len(os.Args) < 2 {
fmt.Fprintf(os.Stderr, "Usage: analyzer <handle>\n")
os.Exit(1)
}
handle := os.Args[1]
var profile UserProfile
if err := twitter("user-profile-details", map[string]any{"handle": handle}, &profile); err != nil {
log.Fatal(err)
}
var data UserTweetsResponse
if err := twitter("user-tweets", map[string]any{"handle": handle, "count": 50}, &data); err != nil {
log.Fatal(err)
}
totalLikes := 0
for _, t := range data.Tweets {
totalLikes += t.LikeCount
}
avgLikes := float64(totalLikes) / float64(max(1, len(data.Tweets)))
fmt.Printf("%s (@%s)\n", profile.DisplayName, profile.Handle)
fmt.Printf("Followers: %d\n", profile.FollowersCount)
fmt.Printf("Avg engagement: %.0f likes per tweet\n", avgLikes)
if profile.FollowersCount > 0 {
fmt.Printf("Engagement rate: %.2f%%\n", (avgLikes/float64(profile.FollowersCount))*100)
}
}
func truncate(s string, maxLen int) string {
if len(s) <= maxLen {
return s
}
return s[:maxLen] + "..."
}
What’s Next
- Twitter API with Python — Python version
- Twitter API with Node.js — JavaScript/Node version
- Twitter API with TypeScript — typed version
- Twitter API with Bun — Bun runtime version
- How to Scrape Twitter/X in 2026 — all scraping methods
- FetchLayer API Reference