curl -X DELETE \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "User-Agent: my-app-name/1.0" \
"https://api.simkl.com/sync/playback/10916890?client_id=YOUR_CLIENT_ID&app-name=my-app-name&app-version=1.0"# Get a real id from GET /sync/playback/{type} first. Never pass 0.
import httpx
playback_id = 10916890
params = {
"client_id": "YOUR_CLIENT_ID",
"app-name": "my-app-name",
"app-version": "1.0",
}
headers = {
"Authorization": f"Bearer {ACCESS_TOKEN}",
"User-Agent": "my-app-name/1.0",
}
r = httpx.delete( # <-- must be .delete(), not .post() or .get()
f"https://api.simkl.com/sync/playback/{playback_id}",
params=params,
headers=headers,
)
if r.status_code == 204:
print("deleted")
elif r.status_code == 404:
print("already gone" if r.json()["error"] == "empty" else "bad id shape")// Get a real id from GET /sync/playback/{type} first. Never pass 0.
const playbackId = 10916890;
const qs = new URLSearchParams({
client_id: "YOUR_CLIENT_ID",
"app-name": "my-app-name",
"app-version": "1.0",
});
const res = await fetch(
`https://api.simkl.com/sync/playback/${playbackId}?${qs}`,
{
method: "DELETE", // <-- must be DELETE, not POST or GET
headers: {
Authorization: `Bearer ${ACCESS_TOKEN}`,
"User-Agent": "my-app-name/1.0",
},
}
);
if (res.status === 204) {
console.log("deleted");
} else if (res.status === 404) {
const { error } = await res.json();
console.warn(error === "empty" ? "already gone" : "bad id shape");
}const options = {
method: 'DELETE',
headers: {'User-Agent': '<user-agent>', Authorization: 'Bearer <token>'}
};
fetch('https://api.simkl.com/sync/playback/{id}?client_id=', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));val client = OkHttpClient()
val request = Request.Builder()
.url("https://api.simkl.com/sync/playback/{id}?client_id=")
.delete(null)
.addHeader("User-Agent", "<user-agent>")
.addHeader("Authorization", "Bearer <token>")
.build()
val response = client.newCall(request).execute()import Foundation
let url = URL(string: "https://api.simkl.com/sync/playback/{id}")!
var components = URLComponents(url: url, resolvingAgainstBaseURL: true)!
let queryItems: [URLQueryItem] = [
URLQueryItem(name: "client_id", value: ""),
]
var queryAllowed = CharacterSet.urlQueryAllowed
queryAllowed.remove(charactersIn: "&=+#")
let encodedQuery = queryItems.map { "\($0.name.addingPercentEncoding(withAllowedCharacters: queryAllowed)!)=\(($0.value ?? "").addingPercentEncoding(withAllowedCharacters: queryAllowed)!)" }.joined(separator: "&")
components.percentEncodedQuery = components.percentEncodedQuery.map { $0 + "&" + encodedQuery } ?? encodedQuery
var request = URLRequest(url: components.url!)
request.httpMethod = "DELETE"
request.timeoutInterval = 10
request.allHTTPHeaderFields = [
"User-Agent": "<user-agent>",
"Authorization": "Bearer <token>"
]
let (data, _) = try await URLSession.shared.data(for: request)
print(String(decoding: data, as: UTF8.self))HttpResponse<String> response = Unirest.delete("https://api.simkl.com/sync/playback/{id}?client_id=")
.header("User-Agent", "<user-agent>")
.header("Authorization", "Bearer <token>")
.asString();const url = 'https://api.simkl.com/sync/playback/{id}?client_id=';
const options = {
method: 'DELETE',
headers: {'User-Agent': '<user-agent>', Authorization: 'Bearer <token>'}
};
fetch(url, options)
.then(res => res.json())
.then(json => console.log(json))
.catch(err => console.error(err));package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.simkl.com/sync/playback/{id}?client_id="
req, _ := http.NewRequest("DELETE", url, nil)
req.Header.Add("User-Agent", "<user-agent>")
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}using RestSharp;
var options = new RestClientOptions("https://api.simkl.com/sync/playback/{id}?client_id=");
var client = new RestClient(options);
var request = new RestRequest("");
request.AddHeader("User-Agent", "<user-agent>");
request.AddHeader("Authorization", "Bearer <token>");
var response = await client.DeleteAsync(request);
Console.WriteLine("{0}", response.Content);
using RestSharp;
var options = new RestClientOptions("https://api.simkl.com/sync/playback/{id}?client_id=");
var client = new RestClient(options);
var request = new RestRequest("");
request.AddHeader("User-Agent", "<user-agent>");
request.AddHeader("Authorization", "Bearer <token>");
var response = await client.DeleteAsync(request);
Console.WriteLine("{0}", response.Content);
<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.simkl.com/sync/playback/{id}?client_id=",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "DELETE",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"User-Agent: <user-agent>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}require 'uri'
require 'net/http'
url = URI("https://api.simkl.com/sync/playback/{id}?client_id=")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Delete.new(url)
request["User-Agent"] = '<user-agent>'
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_body$headers=@{}
$headers.Add("User-Agent", "<user-agent>")
$headers.Add("Authorization", "Bearer <token>")
$response = Invoke-WebRequest -Uri 'https://api.simkl.com/sync/playback/{id}?client_id=' -Method DELETE -Headers $headersCURL *hnd = curl_easy_init();
curl_easy_setopt(hnd, CURLOPT_CUSTOMREQUEST, "DELETE");
curl_easy_setopt(hnd, CURLOPT_WRITEDATA, stdout);
curl_easy_setopt(hnd, CURLOPT_URL, "https://api.simkl.com/sync/playback/{id}?client_id=");
struct curl_slist *headers = NULL;
headers = curl_slist_append(headers, "User-Agent: <user-agent>");
headers = curl_slist_append(headers, "Authorization: Bearer <token>");
curl_easy_setopt(hnd, CURLOPT_HTTPHEADER, headers);
CURLcode ret = curl_easy_perform(hnd);CURL *hnd = curl_easy_init();
curl_easy_setopt(hnd, CURLOPT_CUSTOMREQUEST, "DELETE");
curl_easy_setopt(hnd, CURLOPT_WRITEDATA, stdout);
curl_easy_setopt(hnd, CURLOPT_URL, "https://api.simkl.com/sync/playback/{id}?client_id=");
struct curl_slist *headers = NULL;
headers = curl_slist_append(headers, "User-Agent: <user-agent>");
headers = curl_slist_append(headers, "Authorization: Bearer <token>");
curl_easy_setopt(hnd, CURLOPT_HTTPHEADER, headers);
CURLcode ret = curl_easy_perform(hnd);Delete Playback
Removes a saved playback session by its id. HTTP method is DELETE — using POST or GET against this URL will not delete and will instead hit the list handler. Get the IDs from GET /sync/playback/{type}.
Possible responses
| Status | error | When |
|---|---|---|
204 | — | Session deleted. |
404 | empty | The id is numeric but does not match any playback session for this user. |
404 | url_failed | The id segment is missing, 0, or non-numeric (e.g. notanumber, abc123). |
Use DELETE and pass a real positive integer id. Calling POST or GET /sync/playback/<id> does not delete anything — non-DELETE requests to this URL return the user’s paused-playback list instead, the same shape as GET /sync/playback. Always explicitly send DELETE, and pass an id you got from GET /sync/playback/{type}. DELETE /sync/playback/0, DELETE /sync/playback (no id), and DELETE /sync/playback/<non-numeric> all return 404 url_failed.
Scrobble guide — full walkthrough
Real-time playback tracking — /start, /pause, /stop lifecycle, paused-playback resumption across devices, when scrobble auto-completes, and the difference between /scrobble/checkin (fire-and-forget) and /scrobble/start (active tracking).
curl -X DELETE \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "User-Agent: my-app-name/1.0" \
"https://api.simkl.com/sync/playback/10916890?client_id=YOUR_CLIENT_ID&app-name=my-app-name&app-version=1.0"# Get a real id from GET /sync/playback/{type} first. Never pass 0.
import httpx
playback_id = 10916890
params = {
"client_id": "YOUR_CLIENT_ID",
"app-name": "my-app-name",
"app-version": "1.0",
}
headers = {
"Authorization": f"Bearer {ACCESS_TOKEN}",
"User-Agent": "my-app-name/1.0",
}
r = httpx.delete( # <-- must be .delete(), not .post() or .get()
f"https://api.simkl.com/sync/playback/{playback_id}",
params=params,
headers=headers,
)
if r.status_code == 204:
print("deleted")
elif r.status_code == 404:
print("already gone" if r.json()["error"] == "empty" else "bad id shape")// Get a real id from GET /sync/playback/{type} first. Never pass 0.
const playbackId = 10916890;
const qs = new URLSearchParams({
client_id: "YOUR_CLIENT_ID",
"app-name": "my-app-name",
"app-version": "1.0",
});
const res = await fetch(
`https://api.simkl.com/sync/playback/${playbackId}?${qs}`,
{
method: "DELETE", // <-- must be DELETE, not POST or GET
headers: {
Authorization: `Bearer ${ACCESS_TOKEN}`,
"User-Agent": "my-app-name/1.0",
},
}
);
if (res.status === 204) {
console.log("deleted");
} else if (res.status === 404) {
const { error } = await res.json();
console.warn(error === "empty" ? "already gone" : "bad id shape");
}const options = {
method: 'DELETE',
headers: {'User-Agent': '<user-agent>', Authorization: 'Bearer <token>'}
};
fetch('https://api.simkl.com/sync/playback/{id}?client_id=', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));val client = OkHttpClient()
val request = Request.Builder()
.url("https://api.simkl.com/sync/playback/{id}?client_id=")
.delete(null)
.addHeader("User-Agent", "<user-agent>")
.addHeader("Authorization", "Bearer <token>")
.build()
val response = client.newCall(request).execute()import Foundation
let url = URL(string: "https://api.simkl.com/sync/playback/{id}")!
var components = URLComponents(url: url, resolvingAgainstBaseURL: true)!
let queryItems: [URLQueryItem] = [
URLQueryItem(name: "client_id", value: ""),
]
var queryAllowed = CharacterSet.urlQueryAllowed
queryAllowed.remove(charactersIn: "&=+#")
let encodedQuery = queryItems.map { "\($0.name.addingPercentEncoding(withAllowedCharacters: queryAllowed)!)=\(($0.value ?? "").addingPercentEncoding(withAllowedCharacters: queryAllowed)!)" }.joined(separator: "&")
components.percentEncodedQuery = components.percentEncodedQuery.map { $0 + "&" + encodedQuery } ?? encodedQuery
var request = URLRequest(url: components.url!)
request.httpMethod = "DELETE"
request.timeoutInterval = 10
request.allHTTPHeaderFields = [
"User-Agent": "<user-agent>",
"Authorization": "Bearer <token>"
]
let (data, _) = try await URLSession.shared.data(for: request)
print(String(decoding: data, as: UTF8.self))HttpResponse<String> response = Unirest.delete("https://api.simkl.com/sync/playback/{id}?client_id=")
.header("User-Agent", "<user-agent>")
.header("Authorization", "Bearer <token>")
.asString();const url = 'https://api.simkl.com/sync/playback/{id}?client_id=';
const options = {
method: 'DELETE',
headers: {'User-Agent': '<user-agent>', Authorization: 'Bearer <token>'}
};
fetch(url, options)
.then(res => res.json())
.then(json => console.log(json))
.catch(err => console.error(err));package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.simkl.com/sync/playback/{id}?client_id="
req, _ := http.NewRequest("DELETE", url, nil)
req.Header.Add("User-Agent", "<user-agent>")
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}using RestSharp;
var options = new RestClientOptions("https://api.simkl.com/sync/playback/{id}?client_id=");
var client = new RestClient(options);
var request = new RestRequest("");
request.AddHeader("User-Agent", "<user-agent>");
request.AddHeader("Authorization", "Bearer <token>");
var response = await client.DeleteAsync(request);
Console.WriteLine("{0}", response.Content);
using RestSharp;
var options = new RestClientOptions("https://api.simkl.com/sync/playback/{id}?client_id=");
var client = new RestClient(options);
var request = new RestRequest("");
request.AddHeader("User-Agent", "<user-agent>");
request.AddHeader("Authorization", "Bearer <token>");
var response = await client.DeleteAsync(request);
Console.WriteLine("{0}", response.Content);
<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.simkl.com/sync/playback/{id}?client_id=",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "DELETE",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"User-Agent: <user-agent>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}require 'uri'
require 'net/http'
url = URI("https://api.simkl.com/sync/playback/{id}?client_id=")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Delete.new(url)
request["User-Agent"] = '<user-agent>'
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_body$headers=@{}
$headers.Add("User-Agent", "<user-agent>")
$headers.Add("Authorization", "Bearer <token>")
$response = Invoke-WebRequest -Uri 'https://api.simkl.com/sync/playback/{id}?client_id=' -Method DELETE -Headers $headersCURL *hnd = curl_easy_init();
curl_easy_setopt(hnd, CURLOPT_CUSTOMREQUEST, "DELETE");
curl_easy_setopt(hnd, CURLOPT_WRITEDATA, stdout);
curl_easy_setopt(hnd, CURLOPT_URL, "https://api.simkl.com/sync/playback/{id}?client_id=");
struct curl_slist *headers = NULL;
headers = curl_slist_append(headers, "User-Agent: <user-agent>");
headers = curl_slist_append(headers, "Authorization: Bearer <token>");
curl_easy_setopt(hnd, CURLOPT_HTTPHEADER, headers);
CURLcode ret = curl_easy_perform(hnd);CURL *hnd = curl_easy_init();
curl_easy_setopt(hnd, CURLOPT_CUSTOMREQUEST, "DELETE");
curl_easy_setopt(hnd, CURLOPT_WRITEDATA, stdout);
curl_easy_setopt(hnd, CURLOPT_URL, "https://api.simkl.com/sync/playback/{id}?client_id=");
struct curl_slist *headers = NULL;
headers = curl_slist_append(headers, "User-Agent: <user-agent>");
headers = curl_slist_append(headers, "Authorization: Bearer <token>");
curl_easy_setopt(hnd, CURLOPT_HTTPHEADER, headers);
CURLcode ret = curl_easy_perform(hnd);Authorizations
Preferred form: your client_id as a URL query parameter on every request. Self-describing in logs and curl commands. See Headers and required parameters.
A user access_token, sent as Authorization: Bearer .... Required for endpoints that read or modify the user's library, scrobble session, ratings, settings, or playbacks. Every flow returns the same kind of token. See Set up authentication.
Headers
Descriptive identifier for your app, ideally name/version. Examples: PlexMediaServer/1.43.1.10540, kodi-simkl/0.9.2, MyApp/2.4.1 (https://myapp.com).
Path Parameters
The numeric playback-session id to delete. Must be a positive integer — pass values returned in the id field of GET /sync/playback/{type}. Non-numeric ids return 404 url_failed; the literal value 0 is interpreted as "no id" and falls through to the list handler (see Warning above).
x >= 1Query Parameters
Your client_id from your Simkl developer settings. Required on every request.
Short, lowercase identifier for your app (e.g. plex-scrobbler, kodi-bridge). Helps Simkl identify which apps are using the API.
Your app's current version (e.g. 1.0, 2.4.1). Helps Simkl debug issues you report.
Response
Session deleted.
Was this page helpful?