X scraper API. Live data from any public X link.
Get public posts, profiles and communities by link, handle or search, with posts in the same fields as on 20 other platforms. We handle the proxies, blocks and platform changes.
GET socialtap.dev/v1/x/post
Live data from 33 platforms.
What X data can you get?
Public X (formerly Twitter) profiles with exact follower counts, and posts with their full text, media and exact views, likes and reposts. Communities come with their rules, admin and exact member count. Find accounts, posts, Communities and hashtags by keyword in a search engine's web results.
Search
-
Web result
X (Twitter) Community Search API
Communities by topic, niche or name
From 1 credit / pageGET /v1/x/search_communities -
Web result
X (Twitter) Hashtag Search API
Hashtags related to a keyword or topic
1 credit / pageGET /v1/x/search_hashtags -
Web result
X (Twitter) Post Search API
Posts by keyword, hashtag or @mention
From 1 credit / pageGET /v1/x/search_posts -
Web result
X (Twitter) User Search API
Accounts by name, keyword, niche or place
From 1 credit / pageGET /v1/x/search_profiles
Call the X API from your code.
Copy the request for your language, or hand it to your agent.
const params = new URLSearchParams({
url: "https://x.com/NASA/status/2117633046002225363",
});
const res = await fetch(`https://socialtap.dev/v1/x/post?${params}`, {
headers: { "x-api-key": process.env.SOCIALTAP_API_KEY ?? "" },
});
const body = await res.json();
if (!res.ok) throw new Error(`${body.error.code}: ${body.error.message}`);
const { data, meta } = body;
console.log(data, meta.credits_charged);import os
import requests
res = requests.get(
"https://socialtap.dev/v1/x/post",
params={"url": "https://x.com/NASA/status/2117633046002225363"},
headers={"x-api-key": os.environ["SOCIALTAP_API_KEY"]},
)
body = res.json()
if not res.ok:
raise RuntimeError(f"{body['error']['code']}: {body['error']['message']}")
data, meta = body["data"], body["meta"]
print(data, meta["credits_charged"])require "json"
require "net/http"
uri = URI("https://socialtap.dev/v1/x/post")
uri.query = URI.encode_www_form('url' => 'https://x.com/NASA/status/2117633046002225363')
req = Net::HTTP::Get.new(uri)
req["x-api-key"] = ENV.fetch("SOCIALTAP_API_KEY")
res = Net::HTTP.start(uri.host, uri.port, use_ssl: uri.scheme == "https") { |http| http.request(req) }
body = JSON.parse(res.body)
raise "#{body["error"]["code"]}: #{body["error"]["message"]}" unless res.is_a?(Net::HTTPSuccess)
pp body["data"]
puts body["meta"]["credits_charged"]<?php
$query = http_build_query([
'url' => 'https://x.com/NASA/status/2117633046002225363',
]);
$ch = curl_init('https://socialtap.dev/v1/x/post?' . $query);
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ['x-api-key: ' . getenv('SOCIALTAP_API_KEY')],
]);
$body = json_decode(curl_exec($ch), true);
if (curl_getinfo($ch, CURLINFO_RESPONSE_CODE) >= 400) {
throw new RuntimeException($body['error']['code'] . ': ' . $body['error']['message']);
}
print_r($body['data']);
echo $body['meta']['credits_charged'], PHP_EOL;package main
import (
"encoding/json"
"fmt"
"log"
"net/http"
"net/url"
"os"
)
func main() {
q := url.Values{}
q.Set("url", "https://x.com/NASA/status/2117633046002225363")
req, err := http.NewRequest("GET", "https://socialtap.dev/v1/x/post?"+q.Encode(), nil)
if err != nil {
log.Fatal(err)
}
req.Header.Set("x-api-key", os.Getenv("SOCIALTAP_API_KEY"))
res, err := http.DefaultClient.Do(req)
if err != nil {
log.Fatal(err)
}
defer res.Body.Close()
var body struct {
Data json.RawMessage `json:"data"`
Meta map[string]any `json:"meta"`
Error *struct {
Code string `json:"code"`
Message string `json:"message"`
} `json:"error"`
}
if err := json.NewDecoder(res.Body).Decode(&body); err != nil {
log.Fatal(err)
}
if body.Error != nil {
log.Fatalf("%s: %s", body.Error.Code, body.Error.Message)
}
fmt.Println(string(body.Data), body.Meta["credits_charged"])
}curl -G 'https://socialtap.dev/v1/x/post' \
--data-urlencode 'url=https://x.com/NASA/status/2117633046002225363' \
-H "x-api-key: $SOCIALTAP_API_KEY"GET https://socialtap.dev/v1/x/postDocs const params = new URLSearchParams({
handle: "NASA",
});
const res = await fetch(`https://socialtap.dev/v1/x/profile?${params}`, {
headers: { "x-api-key": process.env.SOCIALTAP_API_KEY ?? "" },
});
const body = await res.json();
if (!res.ok) throw new Error(`${body.error.code}: ${body.error.message}`);
const { data, meta } = body;
console.log(data, meta.credits_charged);import os
import requests
res = requests.get(
"https://socialtap.dev/v1/x/profile",
params={"handle": "NASA"},
headers={"x-api-key": os.environ["SOCIALTAP_API_KEY"]},
)
body = res.json()
if not res.ok:
raise RuntimeError(f"{body['error']['code']}: {body['error']['message']}")
data, meta = body["data"], body["meta"]
print(data, meta["credits_charged"])require "json"
require "net/http"
uri = URI("https://socialtap.dev/v1/x/profile")
uri.query = URI.encode_www_form('handle' => 'NASA')
req = Net::HTTP::Get.new(uri)
req["x-api-key"] = ENV.fetch("SOCIALTAP_API_KEY")
res = Net::HTTP.start(uri.host, uri.port, use_ssl: uri.scheme == "https") { |http| http.request(req) }
body = JSON.parse(res.body)
raise "#{body["error"]["code"]}: #{body["error"]["message"]}" unless res.is_a?(Net::HTTPSuccess)
pp body["data"]
puts body["meta"]["credits_charged"]<?php
$query = http_build_query([
'handle' => 'NASA',
]);
$ch = curl_init('https://socialtap.dev/v1/x/profile?' . $query);
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ['x-api-key: ' . getenv('SOCIALTAP_API_KEY')],
]);
$body = json_decode(curl_exec($ch), true);
if (curl_getinfo($ch, CURLINFO_RESPONSE_CODE) >= 400) {
throw new RuntimeException($body['error']['code'] . ': ' . $body['error']['message']);
}
print_r($body['data']);
echo $body['meta']['credits_charged'], PHP_EOL;package main
import (
"encoding/json"
"fmt"
"log"
"net/http"
"net/url"
"os"
)
func main() {
q := url.Values{}
q.Set("handle", "NASA")
req, err := http.NewRequest("GET", "https://socialtap.dev/v1/x/profile?"+q.Encode(), nil)
if err != nil {
log.Fatal(err)
}
req.Header.Set("x-api-key", os.Getenv("SOCIALTAP_API_KEY"))
res, err := http.DefaultClient.Do(req)
if err != nil {
log.Fatal(err)
}
defer res.Body.Close()
var body struct {
Data json.RawMessage `json:"data"`
Meta map[string]any `json:"meta"`
Error *struct {
Code string `json:"code"`
Message string `json:"message"`
} `json:"error"`
}
if err := json.NewDecoder(res.Body).Decode(&body); err != nil {
log.Fatal(err)
}
if body.Error != nil {
log.Fatalf("%s: %s", body.Error.Code, body.Error.Message)
}
fmt.Println(string(body.Data), body.Meta["credits_charged"])
}curl 'https://socialtap.dev/v1/x/profile?handle=NASA' \
-H "x-api-key: $SOCIALTAP_API_KEY"GET https://socialtap.dev/v1/x/profileDocs const params = new URLSearchParams({
query: "build in public",
});
const res = await fetch(`https://socialtap.dev/v1/x/search_communities?${params}`, {
headers: { "x-api-key": process.env.SOCIALTAP_API_KEY ?? "" },
});
const body = await res.json();
if (!res.ok) throw new Error(`${body.error.code}: ${body.error.message}`);
const { data, page, meta } = body;
console.log(data, meta.credits_charged);import os
import requests
res = requests.get(
"https://socialtap.dev/v1/x/search_communities",
params={"query": "build in public"},
headers={"x-api-key": os.environ["SOCIALTAP_API_KEY"]},
)
body = res.json()
if not res.ok:
raise RuntimeError(f"{body['error']['code']}: {body['error']['message']}")
data, page, meta = body["data"], body["page"], body["meta"]
print(data, meta["credits_charged"])require "json"
require "net/http"
uri = URI("https://socialtap.dev/v1/x/search_communities")
uri.query = URI.encode_www_form('query' => 'build in public')
req = Net::HTTP::Get.new(uri)
req["x-api-key"] = ENV.fetch("SOCIALTAP_API_KEY")
res = Net::HTTP.start(uri.host, uri.port, use_ssl: uri.scheme == "https") { |http| http.request(req) }
body = JSON.parse(res.body)
raise "#{body["error"]["code"]}: #{body["error"]["message"]}" unless res.is_a?(Net::HTTPSuccess)
pp body["data"]
puts body["meta"]["credits_charged"]<?php
$query = http_build_query([
'query' => 'build in public',
]);
$ch = curl_init('https://socialtap.dev/v1/x/search_communities?' . $query);
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ['x-api-key: ' . getenv('SOCIALTAP_API_KEY')],
]);
$body = json_decode(curl_exec($ch), true);
if (curl_getinfo($ch, CURLINFO_RESPONSE_CODE) >= 400) {
throw new RuntimeException($body['error']['code'] . ': ' . $body['error']['message']);
}
print_r($body['data']);
echo $body['meta']['credits_charged'], PHP_EOL;package main
import (
"encoding/json"
"fmt"
"log"
"net/http"
"net/url"
"os"
)
func main() {
q := url.Values{}
q.Set("query", "build in public")
req, err := http.NewRequest("GET", "https://socialtap.dev/v1/x/search_communities?"+q.Encode(), nil)
if err != nil {
log.Fatal(err)
}
req.Header.Set("x-api-key", os.Getenv("SOCIALTAP_API_KEY"))
res, err := http.DefaultClient.Do(req)
if err != nil {
log.Fatal(err)
}
defer res.Body.Close()
var body struct {
Data json.RawMessage `json:"data"`
Page json.RawMessage `json:"page"`
Meta map[string]any `json:"meta"`
Error *struct {
Code string `json:"code"`
Message string `json:"message"`
} `json:"error"`
}
if err := json.NewDecoder(res.Body).Decode(&body); err != nil {
log.Fatal(err)
}
if body.Error != nil {
log.Fatalf("%s: %s", body.Error.Code, body.Error.Message)
}
fmt.Println(string(body.Data), body.Meta["credits_charged"])
}curl -G 'https://socialtap.dev/v1/x/search_communities' \
--data-urlencode 'query=build in public' \
-H "x-api-key: $SOCIALTAP_API_KEY"GET https://socialtap.dev/v1/x/search_communitiesDocs const params = new URLSearchParams({
url: "https://x.com/i/communities/1493446837214187523",
});
const res = await fetch(`https://socialtap.dev/v1/x/community?${params}`, {
headers: { "x-api-key": process.env.SOCIALTAP_API_KEY ?? "" },
});
const body = await res.json();
if (!res.ok) throw new Error(`${body.error.code}: ${body.error.message}`);
const { data, meta } = body;
console.log(data, meta.credits_charged);import os
import requests
res = requests.get(
"https://socialtap.dev/v1/x/community",
params={"url": "https://x.com/i/communities/1493446837214187523"},
headers={"x-api-key": os.environ["SOCIALTAP_API_KEY"]},
)
body = res.json()
if not res.ok:
raise RuntimeError(f"{body['error']['code']}: {body['error']['message']}")
data, meta = body["data"], body["meta"]
print(data, meta["credits_charged"])require "json"
require "net/http"
uri = URI("https://socialtap.dev/v1/x/community")
uri.query = URI.encode_www_form('url' => 'https://x.com/i/communities/1493446837214187523')
req = Net::HTTP::Get.new(uri)
req["x-api-key"] = ENV.fetch("SOCIALTAP_API_KEY")
res = Net::HTTP.start(uri.host, uri.port, use_ssl: uri.scheme == "https") { |http| http.request(req) }
body = JSON.parse(res.body)
raise "#{body["error"]["code"]}: #{body["error"]["message"]}" unless res.is_a?(Net::HTTPSuccess)
pp body["data"]
puts body["meta"]["credits_charged"]<?php
$query = http_build_query([
'url' => 'https://x.com/i/communities/1493446837214187523',
]);
$ch = curl_init('https://socialtap.dev/v1/x/community?' . $query);
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ['x-api-key: ' . getenv('SOCIALTAP_API_KEY')],
]);
$body = json_decode(curl_exec($ch), true);
if (curl_getinfo($ch, CURLINFO_RESPONSE_CODE) >= 400) {
throw new RuntimeException($body['error']['code'] . ': ' . $body['error']['message']);
}
print_r($body['data']);
echo $body['meta']['credits_charged'], PHP_EOL;package main
import (
"encoding/json"
"fmt"
"log"
"net/http"
"net/url"
"os"
)
func main() {
q := url.Values{}
q.Set("url", "https://x.com/i/communities/1493446837214187523")
req, err := http.NewRequest("GET", "https://socialtap.dev/v1/x/community?"+q.Encode(), nil)
if err != nil {
log.Fatal(err)
}
req.Header.Set("x-api-key", os.Getenv("SOCIALTAP_API_KEY"))
res, err := http.DefaultClient.Do(req)
if err != nil {
log.Fatal(err)
}
defer res.Body.Close()
var body struct {
Data json.RawMessage `json:"data"`
Meta map[string]any `json:"meta"`
Error *struct {
Code string `json:"code"`
Message string `json:"message"`
} `json:"error"`
}
if err := json.NewDecoder(res.Body).Decode(&body); err != nil {
log.Fatal(err)
}
if body.Error != nil {
log.Fatalf("%s: %s", body.Error.Code, body.Error.Message)
}
fmt.Println(string(body.Data), body.Meta["credits_charged"])
}curl -G 'https://socialtap.dev/v1/x/community' \
--data-urlencode 'url=https://x.com/i/communities/1493446837214187523' \
-H "x-api-key: $SOCIALTAP_API_KEY"GET https://socialtap.dev/v1/x/communityDocs const params = new URLSearchParams({
query: "cooking",
});
const res = await fetch(`https://socialtap.dev/v1/x/search_hashtags?${params}`, {
headers: { "x-api-key": process.env.SOCIALTAP_API_KEY ?? "" },
});
const body = await res.json();
if (!res.ok) throw new Error(`${body.error.code}: ${body.error.message}`);
const { data, page, meta } = body;
console.log(data, meta.credits_charged);import os
import requests
res = requests.get(
"https://socialtap.dev/v1/x/search_hashtags",
params={"query": "cooking"},
headers={"x-api-key": os.environ["SOCIALTAP_API_KEY"]},
)
body = res.json()
if not res.ok:
raise RuntimeError(f"{body['error']['code']}: {body['error']['message']}")
data, page, meta = body["data"], body["page"], body["meta"]
print(data, meta["credits_charged"])require "json"
require "net/http"
uri = URI("https://socialtap.dev/v1/x/search_hashtags")
uri.query = URI.encode_www_form('query' => 'cooking')
req = Net::HTTP::Get.new(uri)
req["x-api-key"] = ENV.fetch("SOCIALTAP_API_KEY")
res = Net::HTTP.start(uri.host, uri.port, use_ssl: uri.scheme == "https") { |http| http.request(req) }
body = JSON.parse(res.body)
raise "#{body["error"]["code"]}: #{body["error"]["message"]}" unless res.is_a?(Net::HTTPSuccess)
pp body["data"]
puts body["meta"]["credits_charged"]<?php
$query = http_build_query([
'query' => 'cooking',
]);
$ch = curl_init('https://socialtap.dev/v1/x/search_hashtags?' . $query);
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ['x-api-key: ' . getenv('SOCIALTAP_API_KEY')],
]);
$body = json_decode(curl_exec($ch), true);
if (curl_getinfo($ch, CURLINFO_RESPONSE_CODE) >= 400) {
throw new RuntimeException($body['error']['code'] . ': ' . $body['error']['message']);
}
print_r($body['data']);
echo $body['meta']['credits_charged'], PHP_EOL;package main
import (
"encoding/json"
"fmt"
"log"
"net/http"
"net/url"
"os"
)
func main() {
q := url.Values{}
q.Set("query", "cooking")
req, err := http.NewRequest("GET", "https://socialtap.dev/v1/x/search_hashtags?"+q.Encode(), nil)
if err != nil {
log.Fatal(err)
}
req.Header.Set("x-api-key", os.Getenv("SOCIALTAP_API_KEY"))
res, err := http.DefaultClient.Do(req)
if err != nil {
log.Fatal(err)
}
defer res.Body.Close()
var body struct {
Data json.RawMessage `json:"data"`
Page json.RawMessage `json:"page"`
Meta map[string]any `json:"meta"`
Error *struct {
Code string `json:"code"`
Message string `json:"message"`
} `json:"error"`
}
if err := json.NewDecoder(res.Body).Decode(&body); err != nil {
log.Fatal(err)
}
if body.Error != nil {
log.Fatalf("%s: %s", body.Error.Code, body.Error.Message)
}
fmt.Println(string(body.Data), body.Meta["credits_charged"])
}curl 'https://socialtap.dev/v1/x/search_hashtags?query=cooking' \
-H "x-api-key: $SOCIALTAP_API_KEY"GET https://socialtap.dev/v1/x/search_hashtagsDocs const params = new URLSearchParams({
query: "coffee roaster",
});
const res = await fetch(`https://socialtap.dev/v1/x/search_posts?${params}`, {
headers: { "x-api-key": process.env.SOCIALTAP_API_KEY ?? "" },
});
const body = await res.json();
if (!res.ok) throw new Error(`${body.error.code}: ${body.error.message}`);
const { data, page, meta } = body;
console.log(data, meta.credits_charged);import os
import requests
res = requests.get(
"https://socialtap.dev/v1/x/search_posts",
params={"query": "coffee roaster"},
headers={"x-api-key": os.environ["SOCIALTAP_API_KEY"]},
)
body = res.json()
if not res.ok:
raise RuntimeError(f"{body['error']['code']}: {body['error']['message']}")
data, page, meta = body["data"], body["page"], body["meta"]
print(data, meta["credits_charged"])require "json"
require "net/http"
uri = URI("https://socialtap.dev/v1/x/search_posts")
uri.query = URI.encode_www_form('query' => 'coffee roaster')
req = Net::HTTP::Get.new(uri)
req["x-api-key"] = ENV.fetch("SOCIALTAP_API_KEY")
res = Net::HTTP.start(uri.host, uri.port, use_ssl: uri.scheme == "https") { |http| http.request(req) }
body = JSON.parse(res.body)
raise "#{body["error"]["code"]}: #{body["error"]["message"]}" unless res.is_a?(Net::HTTPSuccess)
pp body["data"]
puts body["meta"]["credits_charged"]<?php
$query = http_build_query([
'query' => 'coffee roaster',
]);
$ch = curl_init('https://socialtap.dev/v1/x/search_posts?' . $query);
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ['x-api-key: ' . getenv('SOCIALTAP_API_KEY')],
]);
$body = json_decode(curl_exec($ch), true);
if (curl_getinfo($ch, CURLINFO_RESPONSE_CODE) >= 400) {
throw new RuntimeException($body['error']['code'] . ': ' . $body['error']['message']);
}
print_r($body['data']);
echo $body['meta']['credits_charged'], PHP_EOL;package main
import (
"encoding/json"
"fmt"
"log"
"net/http"
"net/url"
"os"
)
func main() {
q := url.Values{}
q.Set("query", "coffee roaster")
req, err := http.NewRequest("GET", "https://socialtap.dev/v1/x/search_posts?"+q.Encode(), nil)
if err != nil {
log.Fatal(err)
}
req.Header.Set("x-api-key", os.Getenv("SOCIALTAP_API_KEY"))
res, err := http.DefaultClient.Do(req)
if err != nil {
log.Fatal(err)
}
defer res.Body.Close()
var body struct {
Data json.RawMessage `json:"data"`
Page json.RawMessage `json:"page"`
Meta map[string]any `json:"meta"`
Error *struct {
Code string `json:"code"`
Message string `json:"message"`
} `json:"error"`
}
if err := json.NewDecoder(res.Body).Decode(&body); err != nil {
log.Fatal(err)
}
if body.Error != nil {
log.Fatalf("%s: %s", body.Error.Code, body.Error.Message)
}
fmt.Println(string(body.Data), body.Meta["credits_charged"])
}curl -G 'https://socialtap.dev/v1/x/search_posts' \
--data-urlencode 'query=coffee roaster' \
-H "x-api-key: $SOCIALTAP_API_KEY"GET https://socialtap.dev/v1/x/search_postsDocs Other platforms, same key.
Posts and profiles come back in the same fields wherever they're from.
- 31 endpoints
TikTok
Posts, profiles, comments and more
- 28 endpoints
Instagram
Posts, profiles, comments and more
- 14 endpoints
Facebook
Posts, profiles, comments and more
- 6 endpoints
YouTube
Posts, profiles, comments and more
- 13 endpoints
Reddit
Posts, profiles, comments and more
- 6 endpoints
Threads
Posts, profiles and comments
- 12 endpoints
Spotify
Tracks, artists, playlists and more
- 10 endpoints
Amazon
Products, posts, profiles and more
- 10 endpoints
Apple Music
Tracks, artists, playlists and more
- 10 endpoints
Pinterest
Pins, profiles, boards and more
- 7 endpoints
Rumble
Posts, profiles, comments and more
- 5 endpoints
Bluesky
Posts, profiles and comments
- 5 endpoints
Twitch
Videos, profiles, transcripts and more
- 4 endpoints
LinkedIn
Posts and profiles
- 4 endpoints
Telegram
Posts and channels
- 4 endpoints
TikTok Shop
Products and reviews
- 3 endpoints
Kwai
Posts and profiles
- 3 endpoints
Snapchat
Spotlights, profiles and comments
- 3 endpoints
SoundCloud
Tracks and artists
- 3 endpoints
Truth Social
Posts and profiles
- 2 endpoints
Kick
Posts and transcripts
- 1 endpoint
Komi
Pages
- 1 endpoint
Lnk.Bio
Profiles
- 1 endpoint
Linkme
Profiles
- 1 endpoint
Linktree
Profiles
- 1 endpoint
Pillar
Pages
- 3 endpoints
TikTok Ad Library
Ads
- 5 endpoints
Facebook Ad Library
Ads, advertisers and transcripts
- 4 endpoints
Facebook Events
Events
- 3 endpoints
Facebook Marketplace
Listings and places
- 6 endpoints
Google Ads Transparency Center
Ads and advertisers
- 2 endpoints
LinkedIn Ad Library
Ads
Can I download the video from a tweet?
Are the follower counts exact?
Does the X (Twitter) Hashtag Search API return how many posts use a hashtag?
What do I send?
Is the data live?
What does null mean in a response?
Are the fields the same on every platform?
What happens when a platform changes its pages?
Do you read private or logged-in content?
Can my AI agent use it?
Try it on a X link you have.
Get a key and send your first request in a minute. The same key works on every platform.
- No credit card
- Failed requests are free
- Works on all 218 endpoints