tash API Docs

REST API

Upload otomatis — single-shot untuk file < 4 MB, chunked untuk yang lebih besar. Maks 20 MB per file. Tanpa autentikasi.

01

Contoh kode

Langsung pakai — setiap contoh sudah handle dedup, small/large file, dan retry otomatis.

js
// Auto pilih single-shot atau chunked
const ENDPOINT   = 'https://stash.app';
const CHUNK_SIZE = 2097152;

async function stashUpload(file, expiry = '1d') {
  const sha = await sha256(file);
  const lookup = await fetch(`${ENDPOINT}/api/lookup`, {
    method:'POST', headers:{'content-type':'application/json'},
    body: JSON.stringify({ sha })
  }).then(r => r.json());
  if (lookup.hit) return lookup;

  if (file.size < CHUNK_SIZE) {
    const form = new FormData();
    form.append('file', file); form.append('expiry', expiry); form.append('sha', sha);
    return fetch(`${ENDPOINT}/api/upload`, { method:'POST', body:form }).then(r => r.json());
  }

  const uploadId = crypto.randomUUID().replace(/-/g,'').slice(0,16);
  const total    = Math.ceil(file.size / CHUNK_SIZE);
  let next = 0;
  await Promise.all(Array.from({ length:3 }, async () => {
    while (next < total) {
      const i = next++;
      const frm = new FormData();
      frm.append('uploadId', uploadId); frm.append('index', String(i));
      frm.append('total', String(total));
      frm.append('chunk', file.slice(i*CHUNK_SIZE, Math.min((i+1)*CHUNK_SIZE, file.size)), `part-${i}`);
      await fetch(`${ENDPOINT}/api/upload/chunk`, { method:'POST', body:frm });
    }
  }));
  return fetch(`${ENDPOINT}/api/upload/finish`, {
    method:'POST', headers:{'content-type':'application/json'},
    body: JSON.stringify({ uploadId, total, name:file.name, mime:file.type, size:file.size, sha, expiry })
  }).then(r => r.json());
}

async function sha256(file) {
  const d = await crypto.subtle.digest('SHA-256', await file.arrayBuffer());
  return Array.from(new Uint8Array(d)).map(b => b.toString(16).padStart(2,'0')).join('');
}

const r = await stashUpload(input.files[0], '1mo');
console.log(r.url, r.dl, r.preview);
02

POST /api/upload

Single-shot untuk file < 4 MB. Body: multipart/form-data.

Request body

fieldtipewajibketerangan
fileFileyamaks 4 MB
expirystring5m 1h 1d 1mo forever · default 1d
shahexSHA-256 untuk dedup otomatis
thumbIdstringdari /api/upload/thumb

Response 200

json
{
  "ok": true,
  "id": "abc123XYZ_",
  "url": "https://stash.app/f/abc123XYZ_",
  "dl": "https://stash.app/f/abc123XYZ_?dl=1",
  "preview": "https://stash.app/preview/abc123XYZ_",
  "name": "video.mp4",
  "size": 1843201,
  "mime": "video/mp4",
  "sha": "e3b0c44...",
  "uploaded_at": 1714521600000,
  "expires_at": 1714608000000
}
03

Chunked upload

Untuk file ≥ 4 MB. Kirim tiap chunk ke /chunk, lalu /finish.

POST /api/upload/chunk

fieldtipeketerangan
uploadIdstringID unik, sama untuk semua chunk
indexintegerurutan 0-based
totalintegertotal chunk
chunkFiledisarankan 2 MB per chunk

POST /api/upload/finish — body JSON

json
{ "uploadId":"abc...", "total":5, "name":"video.mp4", "mime":"video/mp4", "size":10485760, "sha":"<opsional>", "expiry":"1d" }
04

POST /api/lookup

Cek apakah file dengan SHA-256 tertentu sudah ada. Kalau hit, langsung pakai URL-nya.

bash
curl -s -X POST https://stash.app/api/lookup \
  -H 'content-type: application/json' \
  -d '{"sha":"e3b0c44..."}'
# hit  → { "hit": true,  "url": "...", "dl": "...", "preview": "..." }
# miss → { "hit": false }
05

GET /f/[id]

Stream file langsung. Mendukung Range header — kompatibel dengan <video> dan <audio>.

queryefek
?dl=1paksa download (Content-Disposition: attachment)
?raw=1skip halaman OG, langsung stream
html
<video src="https://stash.app/f/abc123XYZ_" controls></video>
<a href="https://stash.app/f/abc123XYZ_?dl=1">Unduh</a>
<a href="https://stash.app/preview/abc123XYZ_">Preview</a>
06

Batasan

20 MB
ukuran maks per file
4 MB
batas single-shot
2 MB
chunk ideal
5
pilihan masa berlaku
SHA-256
dedup otomatis
Range
streaming support