POST /media/resolve analisa uma URL pública e retorna metadados normalizados para seu app. Requer escopo media:resolve.
Quando usar
- Exibir título, thumbnail e duração antes do download
- Listar formatos disponíveis para o usuário escolher
- Obter
data.idpara usar comomedia_idno download
Exemplos
curl https://api.shappire.tools/v1/media/resolve \
-H "X-API-Key: $SHAPPIRE_API_KEY" \
-H "Content-Type: application/json" \
-d '{"url":"https://www.tiktok.com/@user/video/7123456789012345678"}'
const API_KEY = process.env.SHAPPIRE_API_KEY;
const BASE = 'https://api.shappire.tools/v1';
export async function resolveMedia(url) {
const res = await fetch(`${BASE}/media/resolve`, {
method: 'POST',
headers: {
'X-API-Key': API_KEY,
'Content-Type': 'application/json',
},
body: JSON.stringify({ url }),
});
if (!res.ok) {
const err = await res.json();
throw new Error(err.error?.message ?? res.statusText);
}
const { data } = await res.json();
return data;
}
import os
import requests
API_KEY = os.environ["SHAPPIRE_API_KEY"]
BASE = "https://api.shappire.tools/v1"
def resolve_media(url: str) -> dict:
response = requests.post(
f"{BASE}/media/resolve",
headers={"X-API-Key": API_KEY},
json={"url": url},
timeout=30,
)
response.raise_for_status()
return response.json()["data"]
package shappire
import (
"bytes"
"encoding/json"
"fmt"
"net/http"
"os"
)
const baseURL = "https://api.shappire.tools/v1"
type resolveResponse struct {
Data map[string]interface{} `json:"data"`
}
func ResolveMedia(url string) (map[string]interface{}, error) {
body, _ := json.Marshal(map[string]string{"url": url})
req, err := http.NewRequest(http.MethodPost, baseURL+"/media/resolve", bytes.NewReader(body))
if err != nil {
return nil, err
}
req.Header.Set("X-API-Key", os.Getenv("SHAPPIRE_API_KEY"))
req.Header.Set("Content-Type", "application/json")
resp, err := http.DefaultClient.Do(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()
if resp.StatusCode >= 400 {
return nil, fmt.Errorf("resolve failed: %s", resp.Status)
}
var out resolveResponse
if err := json.NewDecoder(resp.Body).Decode(&out); err != nil {
return nil, err
}
return out.Data, nil
}
<?php
$apiKey = getenv('SHAPPIRE_API_KEY');
$base = 'https://api.shappire.tools/v1';
function resolveMedia(string $url): array {
global $apiKey, $base;
$ch = curl_init("$base/media/resolve");
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
"X-API-Key: $apiKey",
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode(['url' => $url]),
]);
$body = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($status >= 400) {
throw new RuntimeException("resolve failed ($status): $body");
}
return json_decode($body, true)['data'];
}
require 'net/http'
require 'json'
API_KEY = ENV.fetch('SHAPPIRE_API_KEY')
BASE = 'https://api.shappire.tools/v1'
def resolve_media(url)
uri = URI("#{BASE}/media/resolve")
req = Net::HTTP::Post.new(uri)
req['X-API-Key'] = API_KEY
req['Content-Type'] = 'application/json'
req.body = { url: url }.to_json
res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) { |http| http.request(req) }
raise res.body unless res.is_a?(Net::HTTPSuccess)
JSON.parse(res.body)['data']
end
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
public class ShappireClient {
private static final String BASE = "https://api.shappire.tools/v1";
private final String apiKey;
private final HttpClient client = HttpClient.newHttpClient();
public ShappireClient(String apiKey) {
this.apiKey = apiKey;
}
public String resolveMedia(String url) throws Exception {
String body = String.format("{\"url\":\"%s\"}", url);
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(BASE + "/media/resolve"))
.header("X-API-Key", apiKey)
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(body))
.build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
if (response.statusCode() >= 400) {
throw new RuntimeException("resolve failed: " + response.body());
}
return response.body();
}
}
Resposta
{
"data": {
"id": "med_a1b2c3d4",
"platform": "tiktok",
"type": "video",
"title": "Título do vídeo",
"thumbnail": "https://...",
"duration": 42,
"author": {
"name": "Autor",
"username": "@user"
},
"formats": [
{
"id": "video_best",
"type": "video",
"quality": "best",
"container": "mp4"
},
{
"id": "audio_best",
"type": "audio",
"quality": "best",
"container": "mp3"
}
]
}
}
O campo
data.id é o identificador público (med_...). Envie como media_id em POST /media/download.Erros comuns
| Código | Causa |
|---|---|
invalid_url | URL malformada ou não HTTP(S) |
unsupported_platform | Host não suportado (inclui YouTube) |
media_unavailable | Conteúdo removido ou restrito |
forbidden | Chave sem escopo media:resolve |
TTL do resolve
Odata.id expira após 1 hora por padrão (API_MEDIA_RESOLVE_TTL_SECONDS=3600). Se receber media_not_found no download, execute resolve novamente.
Próximo passo: Download assíncrono