curl --request POST \
--url https://app.sideshift.app/api/oauth/v1/ads/codes \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"sparkCode": "<string>",
"requestId": "<string>",
"creatorId": "<string>",
"tiktokItemId": "<string>",
"sourcePostId": "<string>",
"sourcePostUrl": "<string>",
"sourcePlatform": "<string>",
"postTitle": "<string>",
"displayName": "<string>",
"expiresAt": "<string>"
}
'import requests
url = "https://app.sideshift.app/api/oauth/v1/ads/codes"
payload = {
"sparkCode": "<string>",
"requestId": "<string>",
"creatorId": "<string>",
"tiktokItemId": "<string>",
"sourcePostId": "<string>",
"sourcePostUrl": "<string>",
"sourcePlatform": "<string>",
"postTitle": "<string>",
"displayName": "<string>",
"expiresAt": "<string>"
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
sparkCode: '<string>',
requestId: '<string>',
creatorId: '<string>',
tiktokItemId: '<string>',
sourcePostId: '<string>',
sourcePostUrl: '<string>',
sourcePlatform: '<string>',
postTitle: '<string>',
displayName: '<string>',
expiresAt: '<string>'
})
};
fetch('https://app.sideshift.app/api/oauth/v1/ads/codes', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://app.sideshift.app/api/oauth/v1/ads/codes",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'sparkCode' => '<string>',
'requestId' => '<string>',
'creatorId' => '<string>',
'tiktokItemId' => '<string>',
'sourcePostId' => '<string>',
'sourcePostUrl' => '<string>',
'sourcePlatform' => '<string>',
'postTitle' => '<string>',
'displayName' => '<string>',
'expiresAt' => '<string>'
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://app.sideshift.app/api/oauth/v1/ads/codes"
payload := strings.NewReader("{\n \"sparkCode\": \"<string>\",\n \"requestId\": \"<string>\",\n \"creatorId\": \"<string>\",\n \"tiktokItemId\": \"<string>\",\n \"sourcePostId\": \"<string>\",\n \"sourcePostUrl\": \"<string>\",\n \"sourcePlatform\": \"<string>\",\n \"postTitle\": \"<string>\",\n \"displayName\": \"<string>\",\n \"expiresAt\": \"<string>\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://app.sideshift.app/api/oauth/v1/ads/codes")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"sparkCode\": \"<string>\",\n \"requestId\": \"<string>\",\n \"creatorId\": \"<string>\",\n \"tiktokItemId\": \"<string>\",\n \"sourcePostId\": \"<string>\",\n \"sourcePostUrl\": \"<string>\",\n \"sourcePlatform\": \"<string>\",\n \"postTitle\": \"<string>\",\n \"displayName\": \"<string>\",\n \"expiresAt\": \"<string>\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://app.sideshift.app/api/oauth/v1/ads/codes")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"sparkCode\": \"<string>\",\n \"requestId\": \"<string>\",\n \"creatorId\": \"<string>\",\n \"tiktokItemId\": \"<string>\",\n \"sourcePostId\": \"<string>\",\n \"sourcePostUrl\": \"<string>\",\n \"sourcePlatform\": \"<string>\",\n \"postTitle\": \"<string>\",\n \"displayName\": \"<string>\",\n \"expiresAt\": \"<string>\"\n}"
response = http.request(request)
puts response.read_body{}{
"error": {
"code": "invalid_request",
"message": "name is required",
"requestId": "req_..."
}
}{
"error": {
"code": "unauthorized",
"message": "Missing bearer access token",
"requestId": "req_..."
}
}{
"error": {
"code": "insufficient_scope",
"message": "Requires scope 'campaigns:write'",
"requestId": "req_..."
}
}{
"error": {
"code": "not_found",
"message": "Resource not found",
"requestId": "req_..."
}
}{
"error": {
"code": "idempotency_conflict",
"message": "Idempotency-Key was reused with a different request body",
"requestId": "req_..."
}
}{
"error": {
"code": "rate_limited",
"message": "Rate limit exceeded",
"requestId": "req_..."
}
}Save a TikTok Spark code a creator sent
Saves a Spark code that a creator sent outside SideShift. Give requestId to fulfill an open request. SideShift authorizes the code to your connected TikTok ad account and checks that it is for the expected video. The answer is the request, the saved identity and the authorization (identityId, itemId, expiresAt), never the code. Without a connected TikTok ad account, the save is refused with 409 conflict and meta.brandSetupRequired: true. Requires the ads:write scope and an Idempotency-Key.
curl --request POST \
--url https://app.sideshift.app/api/oauth/v1/ads/codes \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"sparkCode": "<string>",
"requestId": "<string>",
"creatorId": "<string>",
"tiktokItemId": "<string>",
"sourcePostId": "<string>",
"sourcePostUrl": "<string>",
"sourcePlatform": "<string>",
"postTitle": "<string>",
"displayName": "<string>",
"expiresAt": "<string>"
}
'import requests
url = "https://app.sideshift.app/api/oauth/v1/ads/codes"
payload = {
"sparkCode": "<string>",
"requestId": "<string>",
"creatorId": "<string>",
"tiktokItemId": "<string>",
"sourcePostId": "<string>",
"sourcePostUrl": "<string>",
"sourcePlatform": "<string>",
"postTitle": "<string>",
"displayName": "<string>",
"expiresAt": "<string>"
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
sparkCode: '<string>',
requestId: '<string>',
creatorId: '<string>',
tiktokItemId: '<string>',
sourcePostId: '<string>',
sourcePostUrl: '<string>',
sourcePlatform: '<string>',
postTitle: '<string>',
displayName: '<string>',
expiresAt: '<string>'
})
};
fetch('https://app.sideshift.app/api/oauth/v1/ads/codes', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://app.sideshift.app/api/oauth/v1/ads/codes",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'sparkCode' => '<string>',
'requestId' => '<string>',
'creatorId' => '<string>',
'tiktokItemId' => '<string>',
'sourcePostId' => '<string>',
'sourcePostUrl' => '<string>',
'sourcePlatform' => '<string>',
'postTitle' => '<string>',
'displayName' => '<string>',
'expiresAt' => '<string>'
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://app.sideshift.app/api/oauth/v1/ads/codes"
payload := strings.NewReader("{\n \"sparkCode\": \"<string>\",\n \"requestId\": \"<string>\",\n \"creatorId\": \"<string>\",\n \"tiktokItemId\": \"<string>\",\n \"sourcePostId\": \"<string>\",\n \"sourcePostUrl\": \"<string>\",\n \"sourcePlatform\": \"<string>\",\n \"postTitle\": \"<string>\",\n \"displayName\": \"<string>\",\n \"expiresAt\": \"<string>\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://app.sideshift.app/api/oauth/v1/ads/codes")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"sparkCode\": \"<string>\",\n \"requestId\": \"<string>\",\n \"creatorId\": \"<string>\",\n \"tiktokItemId\": \"<string>\",\n \"sourcePostId\": \"<string>\",\n \"sourcePostUrl\": \"<string>\",\n \"sourcePlatform\": \"<string>\",\n \"postTitle\": \"<string>\",\n \"displayName\": \"<string>\",\n \"expiresAt\": \"<string>\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://app.sideshift.app/api/oauth/v1/ads/codes")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"sparkCode\": \"<string>\",\n \"requestId\": \"<string>\",\n \"creatorId\": \"<string>\",\n \"tiktokItemId\": \"<string>\",\n \"sourcePostId\": \"<string>\",\n \"sourcePostUrl\": \"<string>\",\n \"sourcePlatform\": \"<string>\",\n \"postTitle\": \"<string>\",\n \"displayName\": \"<string>\",\n \"expiresAt\": \"<string>\"\n}"
response = http.request(request)
puts response.read_body{}{
"error": {
"code": "invalid_request",
"message": "name is required",
"requestId": "req_..."
}
}{
"error": {
"code": "unauthorized",
"message": "Missing bearer access token",
"requestId": "req_..."
}
}{
"error": {
"code": "insufficient_scope",
"message": "Requires scope 'campaigns:write'",
"requestId": "req_..."
}
}{
"error": {
"code": "not_found",
"message": "Resource not found",
"requestId": "req_..."
}
}{
"error": {
"code": "idempotency_conflict",
"message": "Idempotency-Key was reused with a different request body",
"requestId": "req_..."
}
}{
"error": {
"code": "rate_limited",
"message": "Rate limit exceeded",
"requestId": "req_..."
}
}Authorizations
OAuth 2.1 authorization code + PKCE (S256). Tokens are tenant-bound (company_id) and scoped. Discover endpoints via /.well-known/oauth-authorization-server.
Headers
Client-chosen key; replaying the same key + body returns the original response, a different body returns 409.
Body
The Spark code the creator sent.
The open Spark code request this code answers.
The numeric TikTok item ID of the video. Needed when no request or URL names the video.
Response
Success. Returns the request, identity and authorization.
The response is of type object.