POST
/api/public/v1/scrape/tiktok/profile#
Creator profile details.
Returns profile_api
Parameters
Request
cURL
Python
Node
Ruby
PHP
Go
Copy
curl -X POST https://socialholmes.com/api/public/v1/scrape/tiktok/profile \
-H "Authorization: Bearer $SOCIALHOLMES_KEY" \
-H "Content-Type: application/json" \
-d ' { "parameters" : { "username" : "nasa" }} '
import os
import requests
run = requests. post (
"https://socialholmes.com/api/public/v1/scrape/tiktok/profile" ,
headers={ "Authorization" : f"Bearer {os.environ['SOCIALHOLMES_KEY']}" },
json={ "parameters" : { "username" : "nasa" }},
). json ()
print ( run[ "id" ], run[ "status" ])
const response = await fetch ( "https://socialholmes.com/api/public/v1/scrape/tiktok/profile" , {
method: "POST" ,
headers: {
Authorization: `Bearer ${process.env.SOCIALHOLMES_KEY}` ,
"Content-Type" : "application/json" ,
},
body: JSON . stringify ({ parameters: { username: "nasa" } }),
})
const run = await response. json ()
console. log ( run. id, run. status)
require "net/http"
require "json"
response = Net:: HTTP . post (
URI ( "https://socialholmes.com/api/public/v1/scrape/tiktok/profile" ),
{ parameters: { username: "nasa" } }. to_json,
"Authorization" => "Bearer #{ENV.fetch('SOCIALHOLMES_KEY')}" ,
"Content-Type" => "application/json"
)
run = JSON . parse ( response. body)
puts run[ "id" ], run[ "status" ]
<?php
$ch = curl_init ( "https://socialholmes.com/api/public/v1/scrape/tiktok/profile" );
curl_setopt_array ( $ch, [
CURLOPT_POST => true ,
CURLOPT_RETURNTRANSFER => true ,
CURLOPT_HTTPHEADER => [
"Authorization: Bearer " . getenv ( "SOCIALHOLMES_KEY" ),
"Content-Type: application/json" ,
],
CURLOPT_POSTFIELDS => json_encode ([ "parameters" => [ "username" => "nasa" ]]),
]);
$run = json_decode ( curl_exec ( $ch), true );
echo $run[ "id" ], " " , $run[ "status" ];
package main
import (
"bytes"
"encoding/json"
"fmt"
"net/http"
"os"
)
func main () {
body, _ := json. Marshal ( map [ string ] any {
"parameters" : map [ string ] string { "username" : "nasa" },
})
req, _ := http. NewRequest ( "POST" , "https://socialholmes.com/api/public/v1/scrape/tiktok/profile" , bytes. NewReader ( body))
req. Header. Set ( "Authorization" , "Bearer " + os. Getenv ( "SOCIALHOLMES_KEY" ))
req. Header. Set ( "Content-Type" , "application/json" )
res, _ := http. DefaultClient. Do ( req)
defer res. Body. Close ()
var run map [ string ] any
json. NewDecoder ( res. Body). Decode (& run)
fmt. Println ( run[ "id" ], run[ "status" ])
}
Response
202 Accepted
Copy
{
"id" : "8f14e45f-ceea-467a-9c2e-1b0f5a4c7d21" ,
"status" : "queued" ,
"platform" : "tiktok" ,
"endpoint" : "profile" ,
"target" : "nasa" ,
"url" : "https://www.tiktok.com/@nasa" ,
"result_count" : 0 ,
"created_at" : "2026-08-27T17:55:29Z"
}
This endpoint errs towards returning more rather than less, so expect a few extra rows alongside what you asked for. Everything still comes back typed and parsed the same way.
POST
/api/public/v1/scrape/tiktok/posts#
A creator's video feed. Use `limit` to say how many you want.
Returns video_feed_api
Parameters
Takes limit — how many results you want. The run is sized from it, and you are billed for exactly that many.
Request
cURL
Python
Node
Ruby
PHP
Go
Copy
curl -X POST https://socialholmes.com/api/public/v1/scrape/tiktok/posts \
-H "Authorization: Bearer $SOCIALHOLMES_KEY" \
-H "Content-Type: application/json" \
-d ' { "parameters" : { "username" : "nasa" }, "limit" : 25 } '
import os
import requests
run = requests. post (
"https://socialholmes.com/api/public/v1/scrape/tiktok/posts" ,
headers={ "Authorization" : f"Bearer {os.environ['SOCIALHOLMES_KEY']}" },
json={ "parameters" : { "username" : "nasa" }, "limit" : 25 },
). json ()
print ( run[ "id" ], run[ "status" ])
const response = await fetch ( "https://socialholmes.com/api/public/v1/scrape/tiktok/posts" , {
method: "POST" ,
headers: {
Authorization: `Bearer ${process.env.SOCIALHOLMES_KEY}` ,
"Content-Type" : "application/json" ,
},
body: JSON . stringify ({ parameters: { username: "nasa" }, limit: 25 }),
})
const run = await response. json ()
console. log ( run. id, run. status)
require "net/http"
require "json"
response = Net:: HTTP . post (
URI ( "https://socialholmes.com/api/public/v1/scrape/tiktok/posts" ),
{ parameters: { username: "nasa" }, limit: 25 }. to_json,
"Authorization" => "Bearer #{ENV.fetch('SOCIALHOLMES_KEY')}" ,
"Content-Type" => "application/json"
)
run = JSON . parse ( response. body)
puts run[ "id" ], run[ "status" ]
<?php
$ch = curl_init ( "https://socialholmes.com/api/public/v1/scrape/tiktok/posts" );
curl_setopt_array ( $ch, [
CURLOPT_POST => true ,
CURLOPT_RETURNTRANSFER => true ,
CURLOPT_HTTPHEADER => [
"Authorization: Bearer " . getenv ( "SOCIALHOLMES_KEY" ),
"Content-Type: application/json" ,
],
CURLOPT_POSTFIELDS => json_encode ([ "parameters" => [ "username" => "nasa" ], "limit" => 25 ]),
]);
$run = json_decode ( curl_exec ( $ch), true );
echo $run[ "id" ], " " , $run[ "status" ];
package main
import (
"bytes"
"encoding/json"
"fmt"
"net/http"
"os"
)
func main () {
body, _ := json. Marshal ( map [ string ] any {
"parameters" : map [ string ] string { "username" : "nasa" },
"limit" : 25 ,
})
req, _ := http. NewRequest ( "POST" , "https://socialholmes.com/api/public/v1/scrape/tiktok/posts" , bytes. NewReader ( body))
req. Header. Set ( "Authorization" , "Bearer " + os. Getenv ( "SOCIALHOLMES_KEY" ))
req. Header. Set ( "Content-Type" , "application/json" )
res, _ := http. DefaultClient. Do ( req)
defer res. Body. Close ()
var run map [ string ] any
json. NewDecoder ( res. Body). Decode (& run)
fmt. Println ( run[ "id" ], run[ "status" ])
}
Response
202 Accepted
Copy
{
"id" : "8f14e45f-ceea-467a-9c2e-1b0f5a4c7d21" ,
"status" : "queued" ,
"platform" : "tiktok" ,
"endpoint" : "posts" ,
"target" : "nasa" ,
"url" : "https://www.tiktok.com/@nasa" ,
"result_count" : 0 ,
"created_at" : "2026-08-27T17:55:29Z"
}
This endpoint errs towards returning more rather than less, so expect a few extra rows alongside what you asked for. Everything still comes back typed and parsed the same way.
POST
/api/public/v1/scrape/tiktok/liked#
Videos a creator has liked. Use `limit` to say how many you want.
Returns video_feed_api
Parameters
Takes limit — how many results you want. The run is sized from it, and you are billed for exactly that many.
Request
cURL
Python
Node
Ruby
PHP
Go
Copy
curl -X POST https://socialholmes.com/api/public/v1/scrape/tiktok/liked \
-H "Authorization: Bearer $SOCIALHOLMES_KEY" \
-H "Content-Type: application/json" \
-d ' { "parameters" : { "username" : "nasa" }, "limit" : 25 } '
import os
import requests
run = requests. post (
"https://socialholmes.com/api/public/v1/scrape/tiktok/liked" ,
headers={ "Authorization" : f"Bearer {os.environ['SOCIALHOLMES_KEY']}" },
json={ "parameters" : { "username" : "nasa" }, "limit" : 25 },
). json ()
print ( run[ "id" ], run[ "status" ])
const response = await fetch ( "https://socialholmes.com/api/public/v1/scrape/tiktok/liked" , {
method: "POST" ,
headers: {
Authorization: `Bearer ${process.env.SOCIALHOLMES_KEY}` ,
"Content-Type" : "application/json" ,
},
body: JSON . stringify ({ parameters: { username: "nasa" }, limit: 25 }),
})
const run = await response. json ()
console. log ( run. id, run. status)
require "net/http"
require "json"
response = Net:: HTTP . post (
URI ( "https://socialholmes.com/api/public/v1/scrape/tiktok/liked" ),
{ parameters: { username: "nasa" }, limit: 25 }. to_json,
"Authorization" => "Bearer #{ENV.fetch('SOCIALHOLMES_KEY')}" ,
"Content-Type" => "application/json"
)
run = JSON . parse ( response. body)
puts run[ "id" ], run[ "status" ]
<?php
$ch = curl_init ( "https://socialholmes.com/api/public/v1/scrape/tiktok/liked" );
curl_setopt_array ( $ch, [
CURLOPT_POST => true ,
CURLOPT_RETURNTRANSFER => true ,
CURLOPT_HTTPHEADER => [
"Authorization: Bearer " . getenv ( "SOCIALHOLMES_KEY" ),
"Content-Type: application/json" ,
],
CURLOPT_POSTFIELDS => json_encode ([ "parameters" => [ "username" => "nasa" ], "limit" => 25 ]),
]);
$run = json_decode ( curl_exec ( $ch), true );
echo $run[ "id" ], " " , $run[ "status" ];
package main
import (
"bytes"
"encoding/json"
"fmt"
"net/http"
"os"
)
func main () {
body, _ := json. Marshal ( map [ string ] any {
"parameters" : map [ string ] string { "username" : "nasa" },
"limit" : 25 ,
})
req, _ := http. NewRequest ( "POST" , "https://socialholmes.com/api/public/v1/scrape/tiktok/liked" , bytes. NewReader ( body))
req. Header. Set ( "Authorization" , "Bearer " + os. Getenv ( "SOCIALHOLMES_KEY" ))
req. Header. Set ( "Content-Type" , "application/json" )
res, _ := http. DefaultClient. Do ( req)
defer res. Body. Close ()
var run map [ string ] any
json. NewDecoder ( res. Body). Decode (& run)
fmt. Println ( run[ "id" ], run[ "status" ])
}
Response
202 Accepted
Copy
{
"id" : "8f14e45f-ceea-467a-9c2e-1b0f5a4c7d21" ,
"status" : "queued" ,
"platform" : "tiktok" ,
"endpoint" : "liked" ,
"target" : "nasa" ,
"url" : "https://www.tiktok.com/@nasa" ,
"result_count" : 0 ,
"created_at" : "2026-08-27T17:55:29Z"
}
This endpoint errs towards returning more rather than less, so expect a few extra rows alongside what you asked for. Everything still comes back typed and parsed the same way.
POST
/api/public/v1/scrape/tiktok/reposts#
Videos a creator has reposted. Use `limit` to say how many you want.
Returns video_feed_api
Parameters
Takes limit — how many results you want. The run is sized from it, and you are billed for exactly that many.
Request
cURL
Python
Node
Ruby
PHP
Go
Copy
curl -X POST https://socialholmes.com/api/public/v1/scrape/tiktok/reposts \
-H "Authorization: Bearer $SOCIALHOLMES_KEY" \
-H "Content-Type: application/json" \
-d ' { "parameters" : { "username" : "nasa" }, "limit" : 25 } '
import os
import requests
run = requests. post (
"https://socialholmes.com/api/public/v1/scrape/tiktok/reposts" ,
headers={ "Authorization" : f"Bearer {os.environ['SOCIALHOLMES_KEY']}" },
json={ "parameters" : { "username" : "nasa" }, "limit" : 25 },
). json ()
print ( run[ "id" ], run[ "status" ])
const response = await fetch ( "https://socialholmes.com/api/public/v1/scrape/tiktok/reposts" , {
method: "POST" ,
headers: {
Authorization: `Bearer ${process.env.SOCIALHOLMES_KEY}` ,
"Content-Type" : "application/json" ,
},
body: JSON . stringify ({ parameters: { username: "nasa" }, limit: 25 }),
})
const run = await response. json ()
console. log ( run. id, run. status)
require "net/http"
require "json"
response = Net:: HTTP . post (
URI ( "https://socialholmes.com/api/public/v1/scrape/tiktok/reposts" ),
{ parameters: { username: "nasa" }, limit: 25 }. to_json,
"Authorization" => "Bearer #{ENV.fetch('SOCIALHOLMES_KEY')}" ,
"Content-Type" => "application/json"
)
run = JSON . parse ( response. body)
puts run[ "id" ], run[ "status" ]
<?php
$ch = curl_init ( "https://socialholmes.com/api/public/v1/scrape/tiktok/reposts" );
curl_setopt_array ( $ch, [
CURLOPT_POST => true ,
CURLOPT_RETURNTRANSFER => true ,
CURLOPT_HTTPHEADER => [
"Authorization: Bearer " . getenv ( "SOCIALHOLMES_KEY" ),
"Content-Type: application/json" ,
],
CURLOPT_POSTFIELDS => json_encode ([ "parameters" => [ "username" => "nasa" ], "limit" => 25 ]),
]);
$run = json_decode ( curl_exec ( $ch), true );
echo $run[ "id" ], " " , $run[ "status" ];
package main
import (
"bytes"
"encoding/json"
"fmt"
"net/http"
"os"
)
func main () {
body, _ := json. Marshal ( map [ string ] any {
"parameters" : map [ string ] string { "username" : "nasa" },
"limit" : 25 ,
})
req, _ := http. NewRequest ( "POST" , "https://socialholmes.com/api/public/v1/scrape/tiktok/reposts" , bytes. NewReader ( body))
req. Header. Set ( "Authorization" , "Bearer " + os. Getenv ( "SOCIALHOLMES_KEY" ))
req. Header. Set ( "Content-Type" , "application/json" )
res, _ := http. DefaultClient. Do ( req)
defer res. Body. Close ()
var run map [ string ] any
json. NewDecoder ( res. Body). Decode (& run)
fmt. Println ( run[ "id" ], run[ "status" ])
}
Response
202 Accepted
Copy
{
"id" : "8f14e45f-ceea-467a-9c2e-1b0f5a4c7d21" ,
"status" : "queued" ,
"platform" : "tiktok" ,
"endpoint" : "reposts" ,
"target" : "nasa" ,
"url" : "https://www.tiktok.com/@nasa" ,
"result_count" : 0 ,
"created_at" : "2026-08-27T17:55:29Z"
}
This endpoint errs towards returning more rather than less, so expect a few extra rows alongside what you asked for. Everything still comes back typed and parsed the same way.
POST
/api/public/v1/scrape/tiktok/stories#
A creator's active stories. Use `limit` to say how many you want.
Returns video_feed_api
Parameters
Takes limit — how many results you want. The run is sized from it, and you are billed for exactly that many.
Request
cURL
Python
Node
Ruby
PHP
Go
Copy
curl -X POST https://socialholmes.com/api/public/v1/scrape/tiktok/stories \
-H "Authorization: Bearer $SOCIALHOLMES_KEY" \
-H "Content-Type: application/json" \
-d ' { "parameters" : { "username" : "nasa" }, "limit" : 25 } '
import os
import requests
run = requests. post (
"https://socialholmes.com/api/public/v1/scrape/tiktok/stories" ,
headers={ "Authorization" : f"Bearer {os.environ['SOCIALHOLMES_KEY']}" },
json={ "parameters" : { "username" : "nasa" }, "limit" : 25 },
). json ()
print ( run[ "id" ], run[ "status" ])
const response = await fetch ( "https://socialholmes.com/api/public/v1/scrape/tiktok/stories" , {
method: "POST" ,
headers: {
Authorization: `Bearer ${process.env.SOCIALHOLMES_KEY}` ,
"Content-Type" : "application/json" ,
},
body: JSON . stringify ({ parameters: { username: "nasa" }, limit: 25 }),
})
const run = await response. json ()
console. log ( run. id, run. status)
require "net/http"
require "json"
response = Net:: HTTP . post (
URI ( "https://socialholmes.com/api/public/v1/scrape/tiktok/stories" ),
{ parameters: { username: "nasa" }, limit: 25 }. to_json,
"Authorization" => "Bearer #{ENV.fetch('SOCIALHOLMES_KEY')}" ,
"Content-Type" => "application/json"
)
run = JSON . parse ( response. body)
puts run[ "id" ], run[ "status" ]
<?php
$ch = curl_init ( "https://socialholmes.com/api/public/v1/scrape/tiktok/stories" );
curl_setopt_array ( $ch, [
CURLOPT_POST => true ,
CURLOPT_RETURNTRANSFER => true ,
CURLOPT_HTTPHEADER => [
"Authorization: Bearer " . getenv ( "SOCIALHOLMES_KEY" ),
"Content-Type: application/json" ,
],
CURLOPT_POSTFIELDS => json_encode ([ "parameters" => [ "username" => "nasa" ], "limit" => 25 ]),
]);
$run = json_decode ( curl_exec ( $ch), true );
echo $run[ "id" ], " " , $run[ "status" ];
package main
import (
"bytes"
"encoding/json"
"fmt"
"net/http"
"os"
)
func main () {
body, _ := json. Marshal ( map [ string ] any {
"parameters" : map [ string ] string { "username" : "nasa" },
"limit" : 25 ,
})
req, _ := http. NewRequest ( "POST" , "https://socialholmes.com/api/public/v1/scrape/tiktok/stories" , bytes. NewReader ( body))
req. Header. Set ( "Authorization" , "Bearer " + os. Getenv ( "SOCIALHOLMES_KEY" ))
req. Header. Set ( "Content-Type" , "application/json" )
res, _ := http. DefaultClient. Do ( req)
defer res. Body. Close ()
var run map [ string ] any
json. NewDecoder ( res. Body). Decode (& run)
fmt. Println ( run[ "id" ], run[ "status" ])
}
Response
202 Accepted
Copy
{
"id" : "8f14e45f-ceea-467a-9c2e-1b0f5a4c7d21" ,
"status" : "queued" ,
"platform" : "tiktok" ,
"endpoint" : "stories" ,
"target" : "nasa" ,
"url" : "https://www.tiktok.com/@nasa" ,
"result_count" : 0 ,
"created_at" : "2026-08-27T17:55:29Z"
}
This endpoint errs towards returning more rather than less, so expect a few extra rows alongside what you asked for. Everything still comes back typed and parsed the same way.
POST
/api/public/v1/scrape/tiktok/followers#
Accounts that follow this creator. Use `limit` to say how many you want.
Returns user_feed_api
Parameters
Takes limit — how many results you want. The run is sized from it, and you are billed for exactly that many.
Request
cURL
Python
Node
Ruby
PHP
Go
Copy
curl -X POST https://socialholmes.com/api/public/v1/scrape/tiktok/followers \
-H "Authorization: Bearer $SOCIALHOLMES_KEY" \
-H "Content-Type: application/json" \
-d ' { "parameters" : { "username" : "nasa" }, "limit" : 25 } '
import os
import requests
run = requests. post (
"https://socialholmes.com/api/public/v1/scrape/tiktok/followers" ,
headers={ "Authorization" : f"Bearer {os.environ['SOCIALHOLMES_KEY']}" },
json={ "parameters" : { "username" : "nasa" }, "limit" : 25 },
). json ()
print ( run[ "id" ], run[ "status" ])
const response = await fetch ( "https://socialholmes.com/api/public/v1/scrape/tiktok/followers" , {
method: "POST" ,
headers: {
Authorization: `Bearer ${process.env.SOCIALHOLMES_KEY}` ,
"Content-Type" : "application/json" ,
},
body: JSON . stringify ({ parameters: { username: "nasa" }, limit: 25 }),
})
const run = await response. json ()
console. log ( run. id, run. status)
require "net/http"
require "json"
response = Net:: HTTP . post (
URI ( "https://socialholmes.com/api/public/v1/scrape/tiktok/followers" ),
{ parameters: { username: "nasa" }, limit: 25 }. to_json,
"Authorization" => "Bearer #{ENV.fetch('SOCIALHOLMES_KEY')}" ,
"Content-Type" => "application/json"
)
run = JSON . parse ( response. body)
puts run[ "id" ], run[ "status" ]
<?php
$ch = curl_init ( "https://socialholmes.com/api/public/v1/scrape/tiktok/followers" );
curl_setopt_array ( $ch, [
CURLOPT_POST => true ,
CURLOPT_RETURNTRANSFER => true ,
CURLOPT_HTTPHEADER => [
"Authorization: Bearer " . getenv ( "SOCIALHOLMES_KEY" ),
"Content-Type: application/json" ,
],
CURLOPT_POSTFIELDS => json_encode ([ "parameters" => [ "username" => "nasa" ], "limit" => 25 ]),
]);
$run = json_decode ( curl_exec ( $ch), true );
echo $run[ "id" ], " " , $run[ "status" ];
package main
import (
"bytes"
"encoding/json"
"fmt"
"net/http"
"os"
)
func main () {
body, _ := json. Marshal ( map [ string ] any {
"parameters" : map [ string ] string { "username" : "nasa" },
"limit" : 25 ,
})
req, _ := http. NewRequest ( "POST" , "https://socialholmes.com/api/public/v1/scrape/tiktok/followers" , bytes. NewReader ( body))
req. Header. Set ( "Authorization" , "Bearer " + os. Getenv ( "SOCIALHOLMES_KEY" ))
req. Header. Set ( "Content-Type" , "application/json" )
res, _ := http. DefaultClient. Do ( req)
defer res. Body. Close ()
var run map [ string ] any
json. NewDecoder ( res. Body). Decode (& run)
fmt. Println ( run[ "id" ], run[ "status" ])
}
Response
202 Accepted
Copy
{
"id" : "8f14e45f-ceea-467a-9c2e-1b0f5a4c7d21" ,
"status" : "queued" ,
"platform" : "tiktok" ,
"endpoint" : "followers" ,
"target" : "nasa" ,
"url" : "https://www.tiktok.com/@nasa" ,
"result_count" : 0 ,
"created_at" : "2026-08-27T17:55:29Z"
}
This endpoint errs towards returning more rather than less, so expect a few extra rows alongside what you asked for. Everything still comes back typed and parsed the same way.
POST
/api/public/v1/scrape/tiktok/following#
Accounts this creator follows. Use `limit` to say how many you want.
Returns user_feed_api
Parameters
Takes limit — how many results you want. The run is sized from it, and you are billed for exactly that many.
Request
cURL
Python
Node
Ruby
PHP
Go
Copy
curl -X POST https://socialholmes.com/api/public/v1/scrape/tiktok/following \
-H "Authorization: Bearer $SOCIALHOLMES_KEY" \
-H "Content-Type: application/json" \
-d ' { "parameters" : { "username" : "nasa" }, "limit" : 25 } '
import os
import requests
run = requests. post (
"https://socialholmes.com/api/public/v1/scrape/tiktok/following" ,
headers={ "Authorization" : f"Bearer {os.environ['SOCIALHOLMES_KEY']}" },
json={ "parameters" : { "username" : "nasa" }, "limit" : 25 },
). json ()
print ( run[ "id" ], run[ "status" ])
const response = await fetch ( "https://socialholmes.com/api/public/v1/scrape/tiktok/following" , {
method: "POST" ,
headers: {
Authorization: `Bearer ${process.env.SOCIALHOLMES_KEY}` ,
"Content-Type" : "application/json" ,
},
body: JSON . stringify ({ parameters: { username: "nasa" }, limit: 25 }),
})
const run = await response. json ()
console. log ( run. id, run. status)
require "net/http"
require "json"
response = Net:: HTTP . post (
URI ( "https://socialholmes.com/api/public/v1/scrape/tiktok/following" ),
{ parameters: { username: "nasa" }, limit: 25 }. to_json,
"Authorization" => "Bearer #{ENV.fetch('SOCIALHOLMES_KEY')}" ,
"Content-Type" => "application/json"
)
run = JSON . parse ( response. body)
puts run[ "id" ], run[ "status" ]
<?php
$ch = curl_init ( "https://socialholmes.com/api/public/v1/scrape/tiktok/following" );
curl_setopt_array ( $ch, [
CURLOPT_POST => true ,
CURLOPT_RETURNTRANSFER => true ,
CURLOPT_HTTPHEADER => [
"Authorization: Bearer " . getenv ( "SOCIALHOLMES_KEY" ),
"Content-Type: application/json" ,
],
CURLOPT_POSTFIELDS => json_encode ([ "parameters" => [ "username" => "nasa" ], "limit" => 25 ]),
]);
$run = json_decode ( curl_exec ( $ch), true );
echo $run[ "id" ], " " , $run[ "status" ];
package main
import (
"bytes"
"encoding/json"
"fmt"
"net/http"
"os"
)
func main () {
body, _ := json. Marshal ( map [ string ] any {
"parameters" : map [ string ] string { "username" : "nasa" },
"limit" : 25 ,
})
req, _ := http. NewRequest ( "POST" , "https://socialholmes.com/api/public/v1/scrape/tiktok/following" , bytes. NewReader ( body))
req. Header. Set ( "Authorization" , "Bearer " + os. Getenv ( "SOCIALHOLMES_KEY" ))
req. Header. Set ( "Content-Type" , "application/json" )
res, _ := http. DefaultClient. Do ( req)
defer res. Body. Close ()
var run map [ string ] any
json. NewDecoder ( res. Body). Decode (& run)
fmt. Println ( run[ "id" ], run[ "status" ])
}
Response
202 Accepted
Copy
{
"id" : "8f14e45f-ceea-467a-9c2e-1b0f5a4c7d21" ,
"status" : "queued" ,
"platform" : "tiktok" ,
"endpoint" : "following" ,
"target" : "nasa" ,
"url" : "https://www.tiktok.com/@nasa" ,
"result_count" : 0 ,
"created_at" : "2026-08-27T17:55:29Z"
}
This endpoint errs towards returning more rather than less, so expect a few extra rows alongside what you asked for. Everything still comes back typed and parsed the same way.
POST
/api/public/v1/scrape/tiktok/video#
A single video and its comments.
Returns video_detail_api
Parameters
Request
cURL
Python
Node
Ruby
PHP
Go
Copy
curl -X POST https://socialholmes.com/api/public/v1/scrape/tiktok/video \
-H "Authorization: Bearer $SOCIALHOLMES_KEY" \
-H "Content-Type: application/json" \
-d ' { "parameters" : { "video_id" : "7212345678901234567" }} '
import os
import requests
run = requests. post (
"https://socialholmes.com/api/public/v1/scrape/tiktok/video" ,
headers={ "Authorization" : f"Bearer {os.environ['SOCIALHOLMES_KEY']}" },
json={ "parameters" : { "video_id" : "7212345678901234567" }},
). json ()
print ( run[ "id" ], run[ "status" ])
const response = await fetch ( "https://socialholmes.com/api/public/v1/scrape/tiktok/video" , {
method: "POST" ,
headers: {
Authorization: `Bearer ${process.env.SOCIALHOLMES_KEY}` ,
"Content-Type" : "application/json" ,
},
body: JSON . stringify ({ parameters: { video_id: "7212345678901234567" } }),
})
const run = await response. json ()
console. log ( run. id, run. status)
require "net/http"
require "json"
response = Net:: HTTP . post (
URI ( "https://socialholmes.com/api/public/v1/scrape/tiktok/video" ),
{ parameters: { video_id: "7212345678901234567" } }. to_json,
"Authorization" => "Bearer #{ENV.fetch('SOCIALHOLMES_KEY')}" ,
"Content-Type" => "application/json"
)
run = JSON . parse ( response. body)
puts run[ "id" ], run[ "status" ]
<?php
$ch = curl_init ( "https://socialholmes.com/api/public/v1/scrape/tiktok/video" );
curl_setopt_array ( $ch, [
CURLOPT_POST => true ,
CURLOPT_RETURNTRANSFER => true ,
CURLOPT_HTTPHEADER => [
"Authorization: Bearer " . getenv ( "SOCIALHOLMES_KEY" ),
"Content-Type: application/json" ,
],
CURLOPT_POSTFIELDS => json_encode ([ "parameters" => [ "video_id" => "7212345678901234567" ]]),
]);
$run = json_decode ( curl_exec ( $ch), true );
echo $run[ "id" ], " " , $run[ "status" ];
package main
import (
"bytes"
"encoding/json"
"fmt"
"net/http"
"os"
)
func main () {
body, _ := json. Marshal ( map [ string ] any {
"parameters" : map [ string ] string { "video_id" : "7212345678901234567" },
})
req, _ := http. NewRequest ( "POST" , "https://socialholmes.com/api/public/v1/scrape/tiktok/video" , bytes. NewReader ( body))
req. Header. Set ( "Authorization" , "Bearer " + os. Getenv ( "SOCIALHOLMES_KEY" ))
req. Header. Set ( "Content-Type" , "application/json" )
res, _ := http. DefaultClient. Do ( req)
defer res. Body. Close ()
var run map [ string ] any
json. NewDecoder ( res. Body). Decode (& run)
fmt. Println ( run[ "id" ], run[ "status" ])
}
Response
202 Accepted
Copy
{
"id" : "8f14e45f-ceea-467a-9c2e-1b0f5a4c7d21" ,
"status" : "queued" ,
"platform" : "tiktok" ,
"endpoint" : "video" ,
"target" : "7212345678901234567" ,
"url" : "https://www.tiktok.com/video/7212345678901234567" ,
"result_count" : 0 ,
"created_at" : "2026-08-27T17:55:29Z"
}
This endpoint errs towards returning more rather than less, so expect a few extra rows alongside what you asked for. Everything still comes back typed and parsed the same way.
POST
/api/public/v1/scrape/tiktok/replies#
Replies to one comment. Use `limit` to say how many you want.
Returns comment_reply_api
Parameters
Takes limit — how many results you want. The run is sized from it, and you are billed for exactly that many.
Request
cURL
Python
Node
Ruby
PHP
Go
Copy
curl -X POST https://socialholmes.com/api/public/v1/scrape/tiktok/replies \
-H "Authorization: Bearer $SOCIALHOLMES_KEY" \
-H "Content-Type: application/json" \
-d ' { "parameters" : { "video_id" : "7212345678901234567" , "comment_id" : "7213456789012345678" }, "limit" : 25 } '
import os
import requests
run = requests. post (
"https://socialholmes.com/api/public/v1/scrape/tiktok/replies" ,
headers={ "Authorization" : f"Bearer {os.environ['SOCIALHOLMES_KEY']}" },
json={ "parameters" : { "video_id" : "7212345678901234567" , "comment_id" : "7213456789012345678" }, "limit" : 25 },
). json ()
print ( run[ "id" ], run[ "status" ])
const response = await fetch ( "https://socialholmes.com/api/public/v1/scrape/tiktok/replies" , {
method: "POST" ,
headers: {
Authorization: `Bearer ${process.env.SOCIALHOLMES_KEY}` ,
"Content-Type" : "application/json" ,
},
body: JSON . stringify ({ parameters: { video_id: "7212345678901234567" , comment_id: "7213456789012345678" }, limit: 25 }),
})
const run = await response. json ()
console. log ( run. id, run. status)
require "net/http"
require "json"
response = Net:: HTTP . post (
URI ( "https://socialholmes.com/api/public/v1/scrape/tiktok/replies" ),
{ parameters: { video_id: "7212345678901234567" , comment_id: "7213456789012345678" }, limit: 25 }. to_json,
"Authorization" => "Bearer #{ENV.fetch('SOCIALHOLMES_KEY')}" ,
"Content-Type" => "application/json"
)
run = JSON . parse ( response. body)
puts run[ "id" ], run[ "status" ]
<?php
$ch = curl_init ( "https://socialholmes.com/api/public/v1/scrape/tiktok/replies" );
curl_setopt_array ( $ch, [
CURLOPT_POST => true ,
CURLOPT_RETURNTRANSFER => true ,
CURLOPT_HTTPHEADER => [
"Authorization: Bearer " . getenv ( "SOCIALHOLMES_KEY" ),
"Content-Type: application/json" ,
],
CURLOPT_POSTFIELDS => json_encode ([ "parameters" => [ "video_id" => "7212345678901234567" , "comment_id" => "7213456789012345678" ], "limit" => 25 ]),
]);
$run = json_decode ( curl_exec ( $ch), true );
echo $run[ "id" ], " " , $run[ "status" ];
package main
import (
"bytes"
"encoding/json"
"fmt"
"net/http"
"os"
)
func main () {
body, _ := json. Marshal ( map [ string ] any {
"parameters" : map [ string ] string { "video_id" : "7212345678901234567" , "comment_id" : "7213456789012345678" },
"limit" : 25 ,
})
req, _ := http. NewRequest ( "POST" , "https://socialholmes.com/api/public/v1/scrape/tiktok/replies" , bytes. NewReader ( body))
req. Header. Set ( "Authorization" , "Bearer " + os. Getenv ( "SOCIALHOLMES_KEY" ))
req. Header. Set ( "Content-Type" , "application/json" )
res, _ := http. DefaultClient. Do ( req)
defer res. Body. Close ()
var run map [ string ] any
json. NewDecoder ( res. Body). Decode (& run)
fmt. Println ( run[ "id" ], run[ "status" ])
}
Response
202 Accepted
Copy
{
"id" : "8f14e45f-ceea-467a-9c2e-1b0f5a4c7d21" ,
"status" : "queued" ,
"platform" : "tiktok" ,
"endpoint" : "replies" ,
"target" : "7212345678901234567" ,
"url" : "https://www.tiktok.com/video/7212345678901234567?comment_id=7213456789012345678" ,
"result_count" : 0 ,
"created_at" : "2026-08-27T17:55:29Z"
}
This endpoint errs towards returning more rather than less, so expect a few extra rows alongside what you asked for. Everything still comes back typed and parsed the same way.
POST
/api/public/v1/scrape/tiktok/hashtag#
Videos under a hashtag. Use `limit` to say how many you want.
Returns video_feed_api
Parameters
Takes limit — how many results you want. The run is sized from it, and you are billed for exactly that many.
Request
cURL
Python
Node
Ruby
PHP
Go
Copy
curl -X POST https://socialholmes.com/api/public/v1/scrape/tiktok/hashtag \
-H "Authorization: Bearer $SOCIALHOLMES_KEY" \
-H "Content-Type: application/json" \
-d ' { "parameters" : { "tag" : "spacex" }, "limit" : 25 } '
import os
import requests
run = requests. post (
"https://socialholmes.com/api/public/v1/scrape/tiktok/hashtag" ,
headers={ "Authorization" : f"Bearer {os.environ['SOCIALHOLMES_KEY']}" },
json={ "parameters" : { "tag" : "spacex" }, "limit" : 25 },
). json ()
print ( run[ "id" ], run[ "status" ])
const response = await fetch ( "https://socialholmes.com/api/public/v1/scrape/tiktok/hashtag" , {
method: "POST" ,
headers: {
Authorization: `Bearer ${process.env.SOCIALHOLMES_KEY}` ,
"Content-Type" : "application/json" ,
},
body: JSON . stringify ({ parameters: { tag: "spacex" }, limit: 25 }),
})
const run = await response. json ()
console. log ( run. id, run. status)
require "net/http"
require "json"
response = Net:: HTTP . post (
URI ( "https://socialholmes.com/api/public/v1/scrape/tiktok/hashtag" ),
{ parameters: { tag: "spacex" }, limit: 25 }. to_json,
"Authorization" => "Bearer #{ENV.fetch('SOCIALHOLMES_KEY')}" ,
"Content-Type" => "application/json"
)
run = JSON . parse ( response. body)
puts run[ "id" ], run[ "status" ]
<?php
$ch = curl_init ( "https://socialholmes.com/api/public/v1/scrape/tiktok/hashtag" );
curl_setopt_array ( $ch, [
CURLOPT_POST => true ,
CURLOPT_RETURNTRANSFER => true ,
CURLOPT_HTTPHEADER => [
"Authorization: Bearer " . getenv ( "SOCIALHOLMES_KEY" ),
"Content-Type: application/json" ,
],
CURLOPT_POSTFIELDS => json_encode ([ "parameters" => [ "tag" => "spacex" ], "limit" => 25 ]),
]);
$run = json_decode ( curl_exec ( $ch), true );
echo $run[ "id" ], " " , $run[ "status" ];
package main
import (
"bytes"
"encoding/json"
"fmt"
"net/http"
"os"
)
func main () {
body, _ := json. Marshal ( map [ string ] any {
"parameters" : map [ string ] string { "tag" : "spacex" },
"limit" : 25 ,
})
req, _ := http. NewRequest ( "POST" , "https://socialholmes.com/api/public/v1/scrape/tiktok/hashtag" , bytes. NewReader ( body))
req. Header. Set ( "Authorization" , "Bearer " + os. Getenv ( "SOCIALHOLMES_KEY" ))
req. Header. Set ( "Content-Type" , "application/json" )
res, _ := http. DefaultClient. Do ( req)
defer res. Body. Close ()
var run map [ string ] any
json. NewDecoder ( res. Body). Decode (& run)
fmt. Println ( run[ "id" ], run[ "status" ])
}
Response
202 Accepted
Copy
{
"id" : "8f14e45f-ceea-467a-9c2e-1b0f5a4c7d21" ,
"status" : "queued" ,
"platform" : "tiktok" ,
"endpoint" : "hashtag" ,
"target" : "spacex" ,
"url" : "https://www.tiktok.com/tag/spacex" ,
"result_count" : 0 ,
"created_at" : "2026-08-27T17:55:29Z"
}
This endpoint errs towards returning more rather than less, so expect a few extra rows alongside what you asked for. Everything still comes back typed and parsed the same way.
POST
/api/public/v1/scrape/tiktok/search#
Videos matching a search. Use `limit` to say how many you want.
Returns video_feed_api
Parameters
Takes limit — how many results you want. The run is sized from it, and you are billed for exactly that many.
Request
cURL
Python
Node
Ruby
PHP
Go
Copy
curl -X POST https://socialholmes.com/api/public/v1/scrape/tiktok/search \
-H "Authorization: Bearer $SOCIALHOLMES_KEY" \
-H "Content-Type: application/json" \
-d ' { "parameters" : { "query" : "mars landing" }, "limit" : 25 } '
import os
import requests
run = requests. post (
"https://socialholmes.com/api/public/v1/scrape/tiktok/search" ,
headers={ "Authorization" : f"Bearer {os.environ['SOCIALHOLMES_KEY']}" },
json={ "parameters" : { "query" : "mars landing" }, "limit" : 25 },
). json ()
print ( run[ "id" ], run[ "status" ])
const response = await fetch ( "https://socialholmes.com/api/public/v1/scrape/tiktok/search" , {
method: "POST" ,
headers: {
Authorization: `Bearer ${process.env.SOCIALHOLMES_KEY}` ,
"Content-Type" : "application/json" ,
},
body: JSON . stringify ({ parameters: { query: "mars landing" }, limit: 25 }),
})
const run = await response. json ()
console. log ( run. id, run. status)
require "net/http"
require "json"
response = Net:: HTTP . post (
URI ( "https://socialholmes.com/api/public/v1/scrape/tiktok/search" ),
{ parameters: { query: "mars landing" }, limit: 25 }. to_json,
"Authorization" => "Bearer #{ENV.fetch('SOCIALHOLMES_KEY')}" ,
"Content-Type" => "application/json"
)
run = JSON . parse ( response. body)
puts run[ "id" ], run[ "status" ]
<?php
$ch = curl_init ( "https://socialholmes.com/api/public/v1/scrape/tiktok/search" );
curl_setopt_array ( $ch, [
CURLOPT_POST => true ,
CURLOPT_RETURNTRANSFER => true ,
CURLOPT_HTTPHEADER => [
"Authorization: Bearer " . getenv ( "SOCIALHOLMES_KEY" ),
"Content-Type: application/json" ,
],
CURLOPT_POSTFIELDS => json_encode ([ "parameters" => [ "query" => "mars landing" ], "limit" => 25 ]),
]);
$run = json_decode ( curl_exec ( $ch), true );
echo $run[ "id" ], " " , $run[ "status" ];
package main
import (
"bytes"
"encoding/json"
"fmt"
"net/http"
"os"
)
func main () {
body, _ := json. Marshal ( map [ string ] any {
"parameters" : map [ string ] string { "query" : "mars landing" },
"limit" : 25 ,
})
req, _ := http. NewRequest ( "POST" , "https://socialholmes.com/api/public/v1/scrape/tiktok/search" , bytes. NewReader ( body))
req. Header. Set ( "Authorization" , "Bearer " + os. Getenv ( "SOCIALHOLMES_KEY" ))
req. Header. Set ( "Content-Type" , "application/json" )
res, _ := http. DefaultClient. Do ( req)
defer res. Body. Close ()
var run map [ string ] any
json. NewDecoder ( res. Body). Decode (& run)
fmt. Println ( run[ "id" ], run[ "status" ])
}
Response
202 Accepted
Copy
{
"id" : "8f14e45f-ceea-467a-9c2e-1b0f5a4c7d21" ,
"status" : "queued" ,
"platform" : "tiktok" ,
"endpoint" : "search" ,
"target" : "mars landing" ,
"url" : "https://www.tiktok.com/search?q=mars+landing" ,
"result_count" : 0 ,
"created_at" : "2026-08-27T17:55:29Z"
}
This endpoint errs towards returning more rather than less, so expect a few extra rows alongside what you asked for. Everything still comes back typed and parsed the same way.
POST
/api/public/v1/scrape/tiktok/search_users#
Creators matching a search. Use `limit` to say how many you want.
Returns user_feed_api
Parameters
Takes limit — how many results you want. The run is sized from it, and you are billed for exactly that many.
Request
cURL
Python
Node
Ruby
PHP
Go
Copy
curl -X POST https://socialholmes.com/api/public/v1/scrape/tiktok/search_users \
-H "Authorization: Bearer $SOCIALHOLMES_KEY" \
-H "Content-Type: application/json" \
-d ' { "parameters" : { "query" : "nasa" }, "limit" : 25 } '
import os
import requests
run = requests. post (
"https://socialholmes.com/api/public/v1/scrape/tiktok/search_users" ,
headers={ "Authorization" : f"Bearer {os.environ['SOCIALHOLMES_KEY']}" },
json={ "parameters" : { "query" : "nasa" }, "limit" : 25 },
). json ()
print ( run[ "id" ], run[ "status" ])
const response = await fetch ( "https://socialholmes.com/api/public/v1/scrape/tiktok/search_users" , {
method: "POST" ,
headers: {
Authorization: `Bearer ${process.env.SOCIALHOLMES_KEY}` ,
"Content-Type" : "application/json" ,
},
body: JSON . stringify ({ parameters: { query: "nasa" }, limit: 25 }),
})
const run = await response. json ()
console. log ( run. id, run. status)
require "net/http"
require "json"
response = Net:: HTTP . post (
URI ( "https://socialholmes.com/api/public/v1/scrape/tiktok/search_users" ),
{ parameters: { query: "nasa" }, limit: 25 }. to_json,
"Authorization" => "Bearer #{ENV.fetch('SOCIALHOLMES_KEY')}" ,
"Content-Type" => "application/json"
)
run = JSON . parse ( response. body)
puts run[ "id" ], run[ "status" ]
<?php
$ch = curl_init ( "https://socialholmes.com/api/public/v1/scrape/tiktok/search_users" );
curl_setopt_array ( $ch, [
CURLOPT_POST => true ,
CURLOPT_RETURNTRANSFER => true ,
CURLOPT_HTTPHEADER => [
"Authorization: Bearer " . getenv ( "SOCIALHOLMES_KEY" ),
"Content-Type: application/json" ,
],
CURLOPT_POSTFIELDS => json_encode ([ "parameters" => [ "query" => "nasa" ], "limit" => 25 ]),
]);
$run = json_decode ( curl_exec ( $ch), true );
echo $run[ "id" ], " " , $run[ "status" ];
package main
import (
"bytes"
"encoding/json"
"fmt"
"net/http"
"os"
)
func main () {
body, _ := json. Marshal ( map [ string ] any {
"parameters" : map [ string ] string { "query" : "nasa" },
"limit" : 25 ,
})
req, _ := http. NewRequest ( "POST" , "https://socialholmes.com/api/public/v1/scrape/tiktok/search_users" , bytes. NewReader ( body))
req. Header. Set ( "Authorization" , "Bearer " + os. Getenv ( "SOCIALHOLMES_KEY" ))
req. Header. Set ( "Content-Type" , "application/json" )
res, _ := http. DefaultClient. Do ( req)
defer res. Body. Close ()
var run map [ string ] any
json. NewDecoder ( res. Body). Decode (& run)
fmt. Println ( run[ "id" ], run[ "status" ])
}
Response
202 Accepted
Copy
{
"id" : "8f14e45f-ceea-467a-9c2e-1b0f5a4c7d21" ,
"status" : "queued" ,
"platform" : "tiktok" ,
"endpoint" : "search_users" ,
"target" : "nasa" ,
"url" : "https://www.tiktok.com/search/user?q=nasa" ,
"result_count" : 0 ,
"created_at" : "2026-08-27T17:55:29Z"
}
This endpoint errs towards returning more rather than less, so expect a few extra rows alongside what you asked for. Everything still comes back typed and parsed the same way.
POST
/api/public/v1/scrape/tiktok/search_hashtags#
Hashtags matching a search, with their view counts. Use `limit` to say how many you want.
Returns hashtag_api
Parameters
Takes limit — how many results you want. The run is sized from it, and you are billed for exactly that many.
Request
cURL
Python
Node
Ruby
PHP
Go
Copy
curl -X POST https://socialholmes.com/api/public/v1/scrape/tiktok/search_hashtags \
-H "Authorization: Bearer $SOCIALHOLMES_KEY" \
-H "Content-Type: application/json" \
-d ' { "parameters" : { "query" : "space" }, "limit" : 25 } '
import os
import requests
run = requests. post (
"https://socialholmes.com/api/public/v1/scrape/tiktok/search_hashtags" ,
headers={ "Authorization" : f"Bearer {os.environ['SOCIALHOLMES_KEY']}" },
json={ "parameters" : { "query" : "space" }, "limit" : 25 },
). json ()
print ( run[ "id" ], run[ "status" ])
const response = await fetch ( "https://socialholmes.com/api/public/v1/scrape/tiktok/search_hashtags" , {
method: "POST" ,
headers: {
Authorization: `Bearer ${process.env.SOCIALHOLMES_KEY}` ,
"Content-Type" : "application/json" ,
},
body: JSON . stringify ({ parameters: { query: "space" }, limit: 25 }),
})
const run = await response. json ()
console. log ( run. id, run. status)
require "net/http"
require "json"
response = Net:: HTTP . post (
URI ( "https://socialholmes.com/api/public/v1/scrape/tiktok/search_hashtags" ),
{ parameters: { query: "space" }, limit: 25 }. to_json,
"Authorization" => "Bearer #{ENV.fetch('SOCIALHOLMES_KEY')}" ,
"Content-Type" => "application/json"
)
run = JSON . parse ( response. body)
puts run[ "id" ], run[ "status" ]
<?php
$ch = curl_init ( "https://socialholmes.com/api/public/v1/scrape/tiktok/search_hashtags" );
curl_setopt_array ( $ch, [
CURLOPT_POST => true ,
CURLOPT_RETURNTRANSFER => true ,
CURLOPT_HTTPHEADER => [
"Authorization: Bearer " . getenv ( "SOCIALHOLMES_KEY" ),
"Content-Type: application/json" ,
],
CURLOPT_POSTFIELDS => json_encode ([ "parameters" => [ "query" => "space" ], "limit" => 25 ]),
]);
$run = json_decode ( curl_exec ( $ch), true );
echo $run[ "id" ], " " , $run[ "status" ];
package main
import (
"bytes"
"encoding/json"
"fmt"
"net/http"
"os"
)
func main () {
body, _ := json. Marshal ( map [ string ] any {
"parameters" : map [ string ] string { "query" : "space" },
"limit" : 25 ,
})
req, _ := http. NewRequest ( "POST" , "https://socialholmes.com/api/public/v1/scrape/tiktok/search_hashtags" , bytes. NewReader ( body))
req. Header. Set ( "Authorization" , "Bearer " + os. Getenv ( "SOCIALHOLMES_KEY" ))
req. Header. Set ( "Content-Type" , "application/json" )
res, _ := http. DefaultClient. Do ( req)
defer res. Body. Close ()
var run map [ string ] any
json. NewDecoder ( res. Body). Decode (& run)
fmt. Println ( run[ "id" ], run[ "status" ])
}
Response
202 Accepted
Copy
{
"id" : "8f14e45f-ceea-467a-9c2e-1b0f5a4c7d21" ,
"status" : "queued" ,
"platform" : "tiktok" ,
"endpoint" : "search_hashtags" ,
"target" : "space" ,
"url" : "https://www.tiktok.com/search?q=space" ,
"result_count" : 0 ,
"created_at" : "2026-08-27T17:55:29Z"
}
This endpoint errs towards returning more rather than less, so expect a few extra rows alongside what you asked for. Everything still comes back typed and parsed the same way.
POST
/api/public/v1/scrape/tiktok/sound#
One sound — its title, artist and how many videos use it.
Returns sound_api
Parameters
Request
cURL
Python
Node
Ruby
PHP
Go
Copy
curl -X POST https://socialholmes.com/api/public/v1/scrape/tiktok/sound \
-H "Authorization: Bearer $SOCIALHOLMES_KEY" \
-H "Content-Type: application/json" \
-d ' { "parameters" : { "music_id" : "7678067441229990670" }} '
import os
import requests
run = requests. post (
"https://socialholmes.com/api/public/v1/scrape/tiktok/sound" ,
headers={ "Authorization" : f"Bearer {os.environ['SOCIALHOLMES_KEY']}" },
json={ "parameters" : { "music_id" : "7678067441229990670" }},
). json ()
print ( run[ "id" ], run[ "status" ])
const response = await fetch ( "https://socialholmes.com/api/public/v1/scrape/tiktok/sound" , {
method: "POST" ,
headers: {
Authorization: `Bearer ${process.env.SOCIALHOLMES_KEY}` ,
"Content-Type" : "application/json" ,
},
body: JSON . stringify ({ parameters: { music_id: "7678067441229990670" } }),
})
const run = await response. json ()
console. log ( run. id, run. status)
require "net/http"
require "json"
response = Net:: HTTP . post (
URI ( "https://socialholmes.com/api/public/v1/scrape/tiktok/sound" ),
{ parameters: { music_id: "7678067441229990670" } }. to_json,
"Authorization" => "Bearer #{ENV.fetch('SOCIALHOLMES_KEY')}" ,
"Content-Type" => "application/json"
)
run = JSON . parse ( response. body)
puts run[ "id" ], run[ "status" ]
<?php
$ch = curl_init ( "https://socialholmes.com/api/public/v1/scrape/tiktok/sound" );
curl_setopt_array ( $ch, [
CURLOPT_POST => true ,
CURLOPT_RETURNTRANSFER => true ,
CURLOPT_HTTPHEADER => [
"Authorization: Bearer " . getenv ( "SOCIALHOLMES_KEY" ),
"Content-Type: application/json" ,
],
CURLOPT_POSTFIELDS => json_encode ([ "parameters" => [ "music_id" => "7678067441229990670" ]]),
]);
$run = json_decode ( curl_exec ( $ch), true );
echo $run[ "id" ], " " , $run[ "status" ];
package main
import (
"bytes"
"encoding/json"
"fmt"
"net/http"
"os"
)
func main () {
body, _ := json. Marshal ( map [ string ] any {
"parameters" : map [ string ] string { "music_id" : "7678067441229990670" },
})
req, _ := http. NewRequest ( "POST" , "https://socialholmes.com/api/public/v1/scrape/tiktok/sound" , bytes. NewReader ( body))
req. Header. Set ( "Authorization" , "Bearer " + os. Getenv ( "SOCIALHOLMES_KEY" ))
req. Header. Set ( "Content-Type" , "application/json" )
res, _ := http. DefaultClient. Do ( req)
defer res. Body. Close ()
var run map [ string ] any
json. NewDecoder ( res. Body). Decode (& run)
fmt. Println ( run[ "id" ], run[ "status" ])
}
Response
202 Accepted
Copy
{
"id" : "8f14e45f-ceea-467a-9c2e-1b0f5a4c7d21" ,
"status" : "queued" ,
"platform" : "tiktok" ,
"endpoint" : "sound" ,
"target" : "7678067441229990670" ,
"url" : "https://www.tiktok.com/music/x-7678067441229990670" ,
"result_count" : 0 ,
"created_at" : "2026-08-27T17:55:29Z"
}
This endpoint errs towards returning more rather than less, so expect a few extra rows alongside what you asked for. Everything still comes back typed and parsed the same way.
POST
/api/public/v1/scrape/tiktok/sound_videos#
Videos using a sound. Use `limit` to say how many you want.
Returns video_feed_api
Parameters
Takes limit — how many results you want. The run is sized from it, and you are billed for exactly that many.
Request
cURL
Python
Node
Ruby
PHP
Go
Copy
curl -X POST https://socialholmes.com/api/public/v1/scrape/tiktok/sound_videos \
-H "Authorization: Bearer $SOCIALHOLMES_KEY" \
-H "Content-Type: application/json" \
-d ' { "parameters" : { "music_id" : "7678067441229990670" }, "limit" : 25 } '
import os
import requests
run = requests. post (
"https://socialholmes.com/api/public/v1/scrape/tiktok/sound_videos" ,
headers={ "Authorization" : f"Bearer {os.environ['SOCIALHOLMES_KEY']}" },
json={ "parameters" : { "music_id" : "7678067441229990670" }, "limit" : 25 },
). json ()
print ( run[ "id" ], run[ "status" ])
const response = await fetch ( "https://socialholmes.com/api/public/v1/scrape/tiktok/sound_videos" , {
method: "POST" ,
headers: {
Authorization: `Bearer ${process.env.SOCIALHOLMES_KEY}` ,
"Content-Type" : "application/json" ,
},
body: JSON . stringify ({ parameters: { music_id: "7678067441229990670" }, limit: 25 }),
})
const run = await response. json ()
console. log ( run. id, run. status)
require "net/http"
require "json"
response = Net:: HTTP . post (
URI ( "https://socialholmes.com/api/public/v1/scrape/tiktok/sound_videos" ),
{ parameters: { music_id: "7678067441229990670" }, limit: 25 }. to_json,
"Authorization" => "Bearer #{ENV.fetch('SOCIALHOLMES_KEY')}" ,
"Content-Type" => "application/json"
)
run = JSON . parse ( response. body)
puts run[ "id" ], run[ "status" ]
<?php
$ch = curl_init ( "https://socialholmes.com/api/public/v1/scrape/tiktok/sound_videos" );
curl_setopt_array ( $ch, [
CURLOPT_POST => true ,
CURLOPT_RETURNTRANSFER => true ,
CURLOPT_HTTPHEADER => [
"Authorization: Bearer " . getenv ( "SOCIALHOLMES_KEY" ),
"Content-Type: application/json" ,
],
CURLOPT_POSTFIELDS => json_encode ([ "parameters" => [ "music_id" => "7678067441229990670" ], "limit" => 25 ]),
]);
$run = json_decode ( curl_exec ( $ch), true );
echo $run[ "id" ], " " , $run[ "status" ];
package main
import (
"bytes"
"encoding/json"
"fmt"
"net/http"
"os"
)
func main () {
body, _ := json. Marshal ( map [ string ] any {
"parameters" : map [ string ] string { "music_id" : "7678067441229990670" },
"limit" : 25 ,
})
req, _ := http. NewRequest ( "POST" , "https://socialholmes.com/api/public/v1/scrape/tiktok/sound_videos" , bytes. NewReader ( body))
req. Header. Set ( "Authorization" , "Bearer " + os. Getenv ( "SOCIALHOLMES_KEY" ))
req. Header. Set ( "Content-Type" , "application/json" )
res, _ := http. DefaultClient. Do ( req)
defer res. Body. Close ()
var run map [ string ] any
json. NewDecoder ( res. Body). Decode (& run)
fmt. Println ( run[ "id" ], run[ "status" ])
}
Response
202 Accepted
Copy
{
"id" : "8f14e45f-ceea-467a-9c2e-1b0f5a4c7d21" ,
"status" : "queued" ,
"platform" : "tiktok" ,
"endpoint" : "sound_videos" ,
"target" : "7678067441229990670" ,
"url" : "https://www.tiktok.com/music/x-7678067441229990670" ,
"result_count" : 0 ,
"created_at" : "2026-08-27T17:55:29Z"
}
This endpoint errs towards returning more rather than less, so expect a few extra rows alongside what you asked for. Everything still comes back typed and parsed the same way.
POST
/api/public/v1/scrape/tiktok/trending#
What is trending in a country right now. Use `limit` to say how many you want.
Returns video_feed_api
Parameters
Takes limit — how many results you want. The run is sized from it, and you are billed for exactly that many.
Request
cURL
Python
Node
Ruby
PHP
Go
Copy
curl -X POST https://socialholmes.com/api/public/v1/scrape/tiktok/trending \
-H "Authorization: Bearer $SOCIALHOLMES_KEY" \
-H "Content-Type: application/json" \
-d ' { "parameters" : { "region" : "US" }, "limit" : 25 } '
import os
import requests
run = requests. post (
"https://socialholmes.com/api/public/v1/scrape/tiktok/trending" ,
headers={ "Authorization" : f"Bearer {os.environ['SOCIALHOLMES_KEY']}" },
json={ "parameters" : { "region" : "US" }, "limit" : 25 },
). json ()
print ( run[ "id" ], run[ "status" ])
const response = await fetch ( "https://socialholmes.com/api/public/v1/scrape/tiktok/trending" , {
method: "POST" ,
headers: {
Authorization: `Bearer ${process.env.SOCIALHOLMES_KEY}` ,
"Content-Type" : "application/json" ,
},
body: JSON . stringify ({ parameters: { region: "US" }, limit: 25 }),
})
const run = await response. json ()
console. log ( run. id, run. status)
require "net/http"
require "json"
response = Net:: HTTP . post (
URI ( "https://socialholmes.com/api/public/v1/scrape/tiktok/trending" ),
{ parameters: { region: "US" }, limit: 25 }. to_json,
"Authorization" => "Bearer #{ENV.fetch('SOCIALHOLMES_KEY')}" ,
"Content-Type" => "application/json"
)
run = JSON . parse ( response. body)
puts run[ "id" ], run[ "status" ]
<?php
$ch = curl_init ( "https://socialholmes.com/api/public/v1/scrape/tiktok/trending" );
curl_setopt_array ( $ch, [
CURLOPT_POST => true ,
CURLOPT_RETURNTRANSFER => true ,
CURLOPT_HTTPHEADER => [
"Authorization: Bearer " . getenv ( "SOCIALHOLMES_KEY" ),
"Content-Type: application/json" ,
],
CURLOPT_POSTFIELDS => json_encode ([ "parameters" => [ "region" => "US" ], "limit" => 25 ]),
]);
$run = json_decode ( curl_exec ( $ch), true );
echo $run[ "id" ], " " , $run[ "status" ];
package main
import (
"bytes"
"encoding/json"
"fmt"
"net/http"
"os"
)
func main () {
body, _ := json. Marshal ( map [ string ] any {
"parameters" : map [ string ] string { "region" : "US" },
"limit" : 25 ,
})
req, _ := http. NewRequest ( "POST" , "https://socialholmes.com/api/public/v1/scrape/tiktok/trending" , bytes. NewReader ( body))
req. Header. Set ( "Authorization" , "Bearer " + os. Getenv ( "SOCIALHOLMES_KEY" ))
req. Header. Set ( "Content-Type" , "application/json" )
res, _ := http. DefaultClient. Do ( req)
defer res. Body. Close ()
var run map [ string ] any
json. NewDecoder ( res. Body). Decode (& run)
fmt. Println ( run[ "id" ], run[ "status" ])
}
Response
202 Accepted
Copy
{
"id" : "8f14e45f-ceea-467a-9c2e-1b0f5a4c7d21" ,
"status" : "queued" ,
"platform" : "tiktok" ,
"endpoint" : "trending" ,
"target" : "US" ,
"url" : "https://www.tiktok.com/foryou?region=US" ,
"result_count" : 0 ,
"created_at" : "2026-08-27T17:55:29Z"
}
This endpoint errs towards returning more rather than less, so expect a few extra rows alongside what you asked for. Everything still comes back typed and parsed the same way.