Skip to main content

Templates

Templates are the core building block of Peako Studio. A template defines the structure of your video — tracks, blocks, timing, and canvas settings — without any actual content. Content is filled in at render time.

Template Structure

A template contains:

  • Composition — canvas size, fps, duration, background
  • Tracks — layers (video, audio, text, sticker)
  • Blocks — fillable placeholders within each track
  • Transitions — effects between adjacent blocks
  • Effects — visual filters on individual blocks

Block Types

TypeDescriptionFilled with
videoVideo contentsrc_url or upload_url
imageImage contentsrc_url or upload_url
audioAudio tracksrc_url or upload_url
textStatic texttext or rich_text
subtitleTimed captionscaptions, auto_transcribe, or text
transitionVisual transition between blocks(no fill — auto-applied)

Duration Modes

ModeBehavior
lockedBlock uses its template-defined duration. Asset is trimmed or padded to fit.
trim_to_assetBlock duration stretches to match the actual asset length.
stretch_to_slotAsset is stretched/compressed to fill the block's defined duration.

Transform Coordinates

All position values use normalized coordinates (0.0–1.0):

  • x: 0.0, y: 0.0 = top-left corner
  • x: 0.5, y: 0.5 = center
  • width: 1.0, height: 1.0 = full canvas
  • x: 0.1, y: 0.8, width: 0.8, height: 0.2 = 80% wide bar near the bottom

Create Template

POST /api/templates

Create a new template with a composition structure and named blocks.

Headers:

  • X-API-Key: <your-api-key> (required)
  • Content-Type: application/json

Request Body:

{
"name": "Social Media Short",
"description": "9:16 vertical video with subtitles",
"thumbnail": "https://peako.shin0x.space/assets/thumb-uuid.jpg",
"composition": {
"fps": 30,
"durationSec": 15,
"size": {
"width": 1080,
"height": 1920
},
"background": {
"type": "color",
"value": "#000000"
},
"tracks": [
{
"id": "track-video",
"type": "video",
"name": "Main Video",
"isBaseLayer": true,
"zIndex": 0,
"items": [
{
"itemType": "block",
"blockId": "hero-video",
"type": "video",
"label": "Hero Video",
"required": true,
"durationMode": "locked",
"startSec": 0,
"durationSec": 15,
"transform": {
"x": 0,
"y": 0,
"width": 1,
"height": 1,
"opacity": 1
}
}
]
},
{
"id": "track-subtitles",
"type": "text",
"name": "Subtitles",
"zIndex": 2,
"items": [
{
"itemType": "block",
"blockId": "subtitle-main",
"type": "subtitle",
"label": "Auto-Generated Subtitles",
"required": false,
"durationMode": "locked",
"startSec": 0,
"durationSec": 15,
"transform": {
"x": 0.05,
"y": 0.75,
"width": 0.9,
"height": 0.2
}
}
]
}
],
"transitions": [],
"effects": [],
"audioMix": {
"masterVolume": 1.0
}
}
}

Composition Fields:

FieldTypeRequiredDescription
fpsnumberFrames per second (1–120)
durationSecnumberTotal duration in seconds (> 0)
size.widthnumberCanvas width in pixels
size.heightnumberCanvas height in pixels
background.typestring"color" or "image"
background.valuestringHex color (e.g. "#000000") or image URL
tracksarrayArray of track objects (max 20)
transitionsarrayTransition definitions
effectsarrayGlobal effect definitions
audioMix.masterVolumenumberMaster volume (0.0–1.0, default 1.0)

Track Object Fields:

FieldTypeRequiredDescription
idstringUnique track ID
typestring"video", "audio", "text", "sticker"
namestringDisplay name
isBaseLayerbooleanIf true, this is the full-canvas base layer
zIndexnumberRender order (0 = bottom)
state.mutedbooleanMute audio on this track
state.hiddenbooleanHide this track in render
itemsarrayArray of block items

Block Item Fields:

FieldTypeRequiredDescription
itemTypestringMust be "block"
blockIdstringUnique ID for this block — referenced during render
typestring"video", "image", "audio", "text", "subtitle"
labelstringHuman-readable label
requiredbooleanIf true, must be filled at render time
durationModestring"locked", "trim_to_asset", or "stretch_to_slot"
startSecnumberStart time in the timeline (≥ 0)
durationSecnumberDuration in the timeline (> 0)
transform.xnumberHorizontal position (0.0–1.0)
transform.ynumberVertical position (0.0–1.0)
transform.widthnumberWidth as fraction of canvas (0.0–1.0)
transform.heightnumberHeight as fraction of canvas (0.0–1.0)
transform.opacitynumberOpacity (0.0–1.0, default 1.0)
transform.rotationnumberRotation in degrees
effectsarrayEffects applied to this block

Response (201 — Created):

{
"id": "template-550e8400-e29b-41d4-a716-446655440000",
"name": "Social Media Short",
"description": "9:16 vertical video with subtitles",
"thumbnail": "https://peako.shin0x.space/assets/thumb-uuid.jpg",
"variableSchema": {},
"createdAt": 1709767500000
}

Error Codes:

  • 400 — Invalid composition structure or validation failed
  • 401 — Missing or invalid API key

Get Template

GET /api/templates/:id

Retrieve the full template including composition structure and blockSchema.

Path Parameters:

  • id — template ID

Headers:

  • X-API-Key: <your-api-key> (required)

Response:

{
"id": "template-uuid",
"name": "Social Media Short",
"description": "9:16 vertical video with subtitles",
"thumbnail": "https://peako.shin0x.space/assets/thumb-uuid.jpg",
"composition": {
"fps": 30,
"durationSec": 15,
"size": { "width": 1080, "height": 1920 },
"background": { "type": "color", "value": "#000000" },
"tracks": [ ... ]
},
"blockSchema": {
"hero-video": {
"blockId": "hero-video",
"type": "video",
"label": "Hero Video",
"required": true,
"durationMode": "locked",
"position": { "startSec": 0, "durationSec": 15 },
"trackIndex": 0
},
"subtitle-main": {
"blockId": "subtitle-main",
"type": "subtitle",
"label": "Auto-Generated Subtitles",
"required": false,
"durationMode": "locked",
"position": { "startSec": 0, "durationSec": 15 },
"trackIndex": 1
}
},
"createdAt": 1709767500000
}
tip

Always call GET /api/templates/:id and inspect blockSchema before rendering. It tells you exactly which blocks exist, what type they are, and whether they're required.

Error Codes:

  • 401 — Missing or invalid API key
  • 404 — Template not found

List Templates

GET /api/templates

List all templates belonging to the authenticated user.

Headers:

  • X-API-Key: <your-api-key> (required)

Response:

[
{
"id": "template-uuid-1",
"name": "Social Media Short",
"description": "9:16 vertical video with subtitles",
"thumbnail": "https://peako.shin0x.space/assets/thumb.jpg",
"createdAt": 1709767500000
},
{
"id": "template-uuid-2",
"name": "Product Demo",
"description": null,
"thumbnail": null,
"createdAt": 1709767400000
}
]

Notes:

  • Returns summaries only (no composition or blockSchema)
  • Sorted by createdAt descending (newest first)

Update Template

PUT /api/templates/:id

Update template name, description, thumbnail, or composition. All fields are optional.

Headers:

  • X-API-Key: <your-api-key> (required)
  • Content-Type: application/json

Request Body (all fields optional):

{
"name": "Updated Name",
"description": "New description",
"thumbnail": "https://peako.shin0x.space/assets/new-thumb.jpg",
"composition": { ... }
}

Response: Same as Create Template response.

Error Codes:

  • 400 — Validation failed
  • 401 — Missing or invalid API key
  • 404 — Template not found

Delete Template

DELETE /api/templates/:id

Permanently delete a template.

Headers:

  • X-API-Key: <your-api-key> (required)

Response:

{
"id": "template-uuid",
"status": "deleted"
}

Error Codes:

  • 401 — Missing or invalid API key
  • 404 — Template not found

Next: Rendering