Variáveis de ambiente
export SHAPPIRE_API_KEY=shp_live_SUA_CHAVE
Cliente mínimo (fetch)
const API_KEY = process.env.SHAPPIRE_API_KEY;
const BASE = 'https://api.shappire.tools/v1';
async function shappireRequest(path, options = {}) {
const res = await fetch(`${BASE}${path}`, {
...options,
headers: {
'X-API-Key': API_KEY,
'Content-Type': 'application/json',
...options.headers,
},
});
const body = await res.json();
if (!res.ok) {
throw new Error(body.error?.message ?? res.statusText);
}
return body.data;
}
Resolver + download + polling
async function downloadFromUrl(url) {
const media = await shappireRequest('/media/resolve', {
method: 'POST',
body: JSON.stringify({ url }),
});
const format = media.formats.find((f) => f.type === 'video')?.id ?? 'video_best';
const queued = await fetch(`${BASE}/media/download`, {
method: 'POST',
headers: { 'X-API-Key': API_KEY, 'Content-Type': 'application/json' },
body: JSON.stringify({ media_id: media.id, format }),
});
const { data: jobRef } = await queued.json();
return waitForJob(jobRef.job_id);
}
async function waitForJob(jobId) {
for (let i = 0; i < 100; i++) {
const job = await shappireRequest(`/jobs/${jobId}`);
if (job.status === 'completed') return job;
if (job.status === 'failed') throw new Error(job.error?.message);
await new Promise((r) => setTimeout(r, 3000));
}
throw new Error('timeout');
}
Com axios
import axios from 'axios';
const client = axios.create({
baseURL: 'https://api.shappire.tools/v1',
headers: { 'X-API-Key': process.env.SHAPPIRE_API_KEY },
});
const { data: media } = await client.post('/media/resolve', {
url: 'https://www.tiktok.com/@user/video/7123456789012345678',
});
const { data: job } = await client.post('/media/download', {
media_id: media.id,
format: 'video_best',
});
Tratamento de rate limit
async function withRetry(fn, max = 5) {
for (let attempt = 0; attempt < max; attempt++) {
try {
return await fn();
} catch (err) {
if (!String(err.message).includes('Too many requests')) throw err;
const reset = Number(err.resetAt ?? 60);
await new Promise((r) => setTimeout(r, reset * 1000));
}
}
}
Express.js (backend)
import express from 'express';
const app = express();
app.post('/api/download', async (req, res) => {
try {
const job = await downloadFromUrl(req.body.url);
res.json({ download_url: job.result.download_url });
} catch (err) {
res.status(502).json({ error: err.message });
}
});
Nunca chame a API Shappire direto do browser — a chave vazaria no cliente.