Files
songs2vid/docs/api/endpoints.md
T
Atakan Doğan Özban 54bbf8b574 Close OSS self-host gaps: in-repo API docs, legal notes, and packaging.
Add MIT license and docs/api, strip SaaS status/admin remnants from robots and footer, align env/compose/README with payment-free product truth.
2026-08-03 07:36:08 +02:00

7.8 KiB
Raw Blame History

Endpoints

Set these for the examples below:

export BASE_URL="http://localhost:3000"          # local / self-hosted app
export API_KEY="s2yt_live_your_key_here"

Live HTML docs: docs.songs2vid.com/docs/api/endpoints.

Discovery

curl "$BASE_URL/api/v1"

Returns the endpoint list and requirements (no auth). No billing routes are listed or implemented.

Upload a file (two-step)

curl -X POST "$BASE_URL/api/v1/upload" \
  -H "Authorization: Bearer $API_KEY" \
  -F "file=@cover.jpg" \
  -F "type=image"
curl -X POST "$BASE_URL/api/v1/upload" \
  -H "Authorization: Bearer $API_KEY" \
  -F "file=@track1.mp3" \
  -F "type=audio"
# Optional: PNG watermark logo
curl -X POST "$BASE_URL/api/v1/upload" \
  -H "Authorization: Bearer $API_KEY" \
  -F "file=@logo.png" \
  -F "type=logo"
# Optional: custom font (.ttf / .otf, max 10 MB)
curl -X POST "$BASE_URL/api/v1/upload" \
  -H "Authorization: Bearer $API_KEY" \
  -F "file=@Brand.ttf" \
  -F "type=font"

Request fields

Field Required Notes
file Yes Multipart file
type Yes image | audio | logo | font

Allowed files

type Formats Max size
image JPEG, PNG, WebP, GIF 500 MB
audio MP3, WAV, FLAC 500 MB
logo PNG only 500 MB
font .ttf / .otf 10 MB

Response

{
  "path": "/uploads/.../track.mp3",
  "filename": "track.mp3",
  "size": 4123456,
  "audioTags": {
    "title": "Song Title",
    "artist": "Artist Name",
    "album": "Album",
    "genre": "Electronic",
    "year": "2024"
  }
}

audioTags is present for MP3 when tags are readable; otherwise null.

Self-hosted unlocks per-track covers, custom watermarks/fonts, and art-track layouts. Max batch size: 100. Watermarks are optional — nothing forces the default Songs2VID badge.

curl -X POST "$BASE_URL/api/v1/jobs" \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "imagePath": "/uploads/.../cover.jpg",
    "items": [{
      "audioPath": "/uploads/.../track.mp3",
      "audioFilename": "track.mp3",
      "metadata": {
        "title": "My Artist - My Track (Official Audio)",
        "songTitle": "My Track",
        "artist": "My Artist",
        "description": "",
        "tags": "electronic",
        "privacy": "PUBLIC",
        "categoryId": "10",
        "resolution": "1920x1080",
        "notifySubscribers": true,
        "madeForKids": false,
        "embeddable": true,
        "creativeCommons": false,
        "includeWatermark": true,
        "layout": {
          "template": "COVER_LEFT_TEXT_RIGHT",
          "blurAmount": 60,
          "blurOpacity": 85,
          "textPadding": 48,
          "titleArtistGap": 12,
          "textOffsetX": 0,
          "textOffsetY": 0
        },
        "watermark": {
          "mode": "default",
          "fontKey": "montserrat",
          "position": "bottom-right",
          "offsetX": 24,
          "offsetY": 24
        },
        "playlistId": null
      }
    }]
  }'

Success response

{
  "jobId": "clxxxxxxxx",
  "itemCount": 1,
  "status": "PENDING",
  "playlist": null
}

Metadata fields

Field Type Notes
title string YouTube video title
songTitle string | null On-video song title for art-track (max 120)
artist string | null On-video artist line (max 80)
description string YouTube description
tags string Comma-separated
privacy string PUBLIC | PRIVATE | UNLISTED
categoryId string YouTube category ID
resolution string See resolutions below
notifySubscribers boolean YouTube notify flag
madeForKids boolean Made for kids
embeddable boolean Allow embedding
creativeCommons boolean CC vs standard YouTube license
includeWatermark boolean Apply watermark settings
imagePath string | null Per-track cover
playlistId string | null Existing playlist ID
layout object Art-track layout
watermark object Watermark settings

Snake_case aliases are accepted for layout/watermark fields.

Resolutions

Value Aspect
1920x1080 16:9
1280x720 16:9
854x480 16:9
720x720 1:1
640x360 16:9
426x240 16:9

YouTube categories

ID Name
1 Film & Animation
2 Autos & Vehicles
10 Music
15 Pets & Animals
17 Sports
19 Travel & Events
20 Gaming
22 People & Blogs
23 Comedy
24 Entertainment
25 News & Politics
26 Howto & Style
27 Education
28 Science & Technology
29 Nonprofits & Activism

Watermark fields

watermark.mode: none | default | text | logo

  • none — no overlay
  • default — built-in Songs2VID badge PNG (assets/watermark.png)
  • logo — requires prior type=logo upload; set logoPath
  • text — custom string (max 80); set text

watermark.position: top-left | top-right | bottom-left | bottom-right | center

watermark.offsetX / offsetY: 0200 (default 20)

watermark.fontKey: system | inter | montserrat | roboto | oswald | playfair | custom (styles art-track text and text watermarks)

Art-track layouts

metadata.layout.template:

Enum Description
COVER_LEFT_TEXT_RIGHT Cover left, title & artist right
COVER_TOP_TEXT_BOTTOM Cover top, title & artist below
COVER_RIGHT_TEXT_LEFT Cover right, title & artist left
CENTERED_COMPACT Centered cover + text stack

Fine-tuning (defaults in parentheses): blurAmount (55), blurOpacity (100), textPadding (48), titleArtistGap (10), textOffsetX (0), textOffsetY (0).

YouTube playlists

curl "$BASE_URL/api/v1/playlists" \
  -H "Authorization: Bearer $API_KEY"
curl -X POST "$BASE_URL/api/v1/playlists" \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"title":"My Album","description":"From Songs2VID","privacy":"unlisted"}'

Or pass createPlaylist on a job / batch body to create a playlist and attach all videos.

One-shot batch (small packs only)

curl -X POST "$BASE_URL/api/v1/jobs/batch" \
  -H "Authorization: Bearer $API_KEY" \
  -F "image=@cover.jpg" \
  -F "audio=@track1.mp3" \
  -F "audio=@track2.mp3" \
  -F 'metadata={"defaults":{"privacy":"PUBLIC"},"items":[{"title":"Track One"},{"title":"Track Two"}]}'

Prefer two-step upload + jobs for larger packs.

Poll job status

curl "$BASE_URL/api/v1/jobs/JOB_ID" \
  -H "Authorization: Bearer $API_KEY"
curl "$BASE_URL/api/v1/jobs?limit=10" \
  -H "Authorization: Bearer $API_KEY"

GET /api/v1/jobs accepts limit (default 20, max 100).

Job statuses

Status Meaning
PENDING Queued
PROCESSING Encoding or uploading
COMPLETED All items succeeded
FAILED All items failed
PARTIAL Mix of completed and failed

Item statuses

Status Meaning
PENDING Waiting
ENCODING FFmpeg building video
UPLOADING Uploading to YouTube
COMPLETED Live (youtubeVideoId set)
FAILED Failed (error message)

YouTube channel daily upload caps are enforced by Google, not Songs2VID.

HTTP errors

Status When
400 Validation error
401 Missing or invalid API key
403 YouTube not connected, or request not allowed
404 Job not found
429 API rate limit exceeded

There is no 402 payment / credits status in OSS.