Перейти до змісту

Робочий приклад

Це приймальний сценарій API, той, що має проходити від початку до кінця проти живого сервера: відео з диска стає запланованим постом YouTube, і скрипт чекає, доки він не стане live або failed. Ті самі шість викликів трьома мовами; оберіть вкладку, якою пишете. Коди й тіла відповідей — ті, що в openapi.json.

  • Ключ API зі write у середовищі як DROPSLATE_API_KEY.
  • Підключений канал YouTube (GET /accounts показує його id і status: "ok").
  • Відеофайл launch.mp4 у межах лімітів YouTube (Вимоги до медіа).
# Виклик Відповідь
1 GET /accounts 200 — id акаунта-цілі
2 POST /media/uploads {filename, mime, size} 201 — {mediaId, uploadUrl, expiresAt}
3 PUT uploadUrl з байтами 200 — URL підписаний сам по собі; без заголовка Authorization
4 GET /media/{id}, доки status не ready 200 — uploading → processing → ready або failed з failReason
5 POST /posts/plan, потім POST /posts із confirm: true 200 з рядками, потім 201 з posts[]
6 GET /posts/{id}, доки status не live або failed 200 — externalUrl або error
Terminal window
set -e
KEY="$DROPSLATE_API_KEY"; API="https://api.dropslate.top/v1"; AUTH="Authorization: Bearer $KEY"; JSON="Content-Type: application/json"
FILE=./launch.mp4
# 1) The channel to publish to
ACCOUNT_ID=$(curl -s "$API/accounts" -H "$AUTH" | jq -r '.accounts[] | select(.platform=="youtube" and .status=="ok") | .id' | head -1)
# 2) Reserve the upload
TICKET=$(curl -s -X POST "$API/media/uploads" -H "$AUTH" -H "$JSON" \
-d "{\"filename\":\"launch.mp4\",\"mime\":\"video/mp4\",\"size\":$(stat -c%s "$FILE")}")
MEDIA_ID=$(echo "$TICKET" | jq -r .mediaId); UPLOAD_URL=$(echo "$TICKET" | jq -r .uploadUrl)
# 3) Send the bytes (Content-Length must equal the size above)
curl -s -X PUT "$UPLOAD_URL" -H "Content-Type: video/mp4" --data-binary @"$FILE" > /dev/null
# 4) Wait for processing
until STATUS=$(curl -s "$API/media/$MEDIA_ID" -H "$AUTH" | jq -r .status); [ "$STATUS" = "ready" ]; do
[ "$STATUS" = "failed" ] && { curl -s "$API/media/$MEDIA_ID" -H "$AUTH" | jq -r .failReason; exit 1; }
sleep 5
done
# 5) Plan, then create
BODY=$(jq -n --arg a "$ACCOUNT_ID" --arg m "$MEDIA_ID" '{
targets:{accountIds:[$a]}, mediaIds:[$m],
title:"Launch day", text:"We are live. Details in the pinned comment.",
when:{publishAt:"2026-09-29T18:00", timezone:"Europe/Kiev"},
perPlatform:{youtube:{visibility:"unlisted", category:"28"}} }')
PLAN=$(curl -s -X POST "$API/posts/plan" -H "$AUTH" -H "$JSON" -d "$BODY")
[ "$(echo "$PLAN" | jq -r .ok)" = "true" ] || { echo "$PLAN" | jq -r .table; exit 1; }
POST_ID=$(echo "$BODY" | jq '.+{confirm:true}' | curl -s -X POST "$API/posts" -H "$AUTH" -H "$JSON" -d @- | jq -r '.posts[0].id')
# 6) Wait for the network's answer
until POST=$(curl -s "$API/posts/$POST_ID" -H "$AUTH"); S=$(echo "$POST" | jq -r .status); [ "$S" = "live" ] || [ "$S" = "failed" ]; do sleep 30; done
echo "$POST" | jq '{status, externalUrl, error, statusLine}'

Що означає кожна відповідь

Section titled “Що означає кожна відповідь”
  • Крок 2, 201. uploadUrl одноразовий і дійсний годину (expiresAt); mediaId уже є id файлу й не змінюється. Проблеми класу 413 повідомляються тут як 402 quota_exceeded, коли перевищено ліміт тарифу на файл чи сховище.
  • Крок 3. PUT не потребує заголовка Authorization — URL підписаний — і Content-Length має дорівнювати size; невідповідність відповідає size_mismatch, другий PUT — already_uploaded.
  • Крок 4. Відео проводить від секунд до хвилини в processing, поки читаються тривалість і мініатюра. failed називає причину, зазвичай формат, якого вид не приймає.
  • Крок 5, 200, потім 201. rows[].issues плану — там зʼявляються caption_too_long, aspect_unsupported або media_not_ready; quota.requested — скільки цей запит коштує проти місяця. POST /posts відповідає 409 confirm_required без прапорця і 402 quota_exceeded понад ліміт.
  • Крок 6. Пост, запланований наперед, лишається queued до свого часу; опитуйте не частіше ніж раз на хвилину. live несе externalUrl і, для YouTube, notes в останній події, коли мініатюру чи плейлист пропущено; failed несе error і, якщо воркер повторить сам, подію retriedByWorker з часом.
Помилка Причина Що робити
size_mismatch на PUT Content-Length відрізняється від size у кроці 2. Надішліть точну кількість байтів; зарезервуйте нове завантаження, якщо файл змінився.
already_uploaded Другий PUT на той самий URL. Перший вдався; продовжуйте з GET /media/{id}.
media_not_ready у плані Крок 4 пропущено. Спершу опитайте до ready.
youtube_title_required у плані Немає title для цілі YouTube. Додайте.
quota_exceeded на POST /media/uploads Файл понад ліміт тарифу на файл, або сховище повне. Free — 500 МБ на файл і 2 ГБ; див. Тарифи й ліміти.