{"openapi":"3.0.0","info":{"title":"ReelsBuilder API","version":"1.0.0","description":"Comprehensive API documentation for ReelsBuilder v5 - AI-powered video generation platform. Public M2M runtime endpoints are mounted under /api/v1 on the server/ Express control plane. Mutating POST requests may include an Idempotency-Key header; matching retries within 24 hours replay the cached response with X-Idempotent-Replay: true.","contact":{"name":"ReelsBuilder Support","email":"admin@reelsbuilder.ai"},"license":{"name":"MIT","url":"https://opensource.org/licenses/MIT"}},"servers":[{"url":"http://localhost:3001","description":"Development server"},{"url":"https://api.reelsbuilder.ai","description":"Production server"}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","in":"header","name":"X-API-Key"},"BearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT"}},"parameters":{"IdempotencyKey":{"name":"Idempotency-Key","in":"header","required":false,"schema":{"type":"string","minLength":8,"maxLength":256},"description":"Optional key for safe POST retries. Reusing the same key with the same request body within 24 hours returns the original response and X-Idempotent-Replay: true; reusing it with a different body returns 409."}},"schemas":{"Error":{"type":"object","properties":{"success":{"type":"boolean","example":false},"message":{"type":"string","example":"Error message"},"error":{"type":"string","example":"Detailed error information"}}},"SuccessResponse":{"type":"object","properties":{"success":{"type":"boolean","example":true},"message":{"type":"string","example":"Operation completed successfully"}}},"ClipGenerationRequest":{"type":"object","required":["video_url","user_id"],"properties":{"video_url":{"type":"string","format":"uri","description":"URL of the video to generate clips from","example":"https://www.youtube.com/watch?v=dQw4w9WgXcQ"},"video_type":{"type":"integer","minimum":1,"maximum":12,"default":2,"description":"Video source type:\n1 - Remote file, 2 - YouTube, 3 - Google Drive, 4 - Vimeo,\n5 - StreamYard, 6 - TikTok, 7 - Twitter, 8 - Rumble,\n9 - Twitch, 10 - Loom, 11 - Facebook, 12 - LinkedIn\n","example":2},"finalVideo_type":{"type":"string","enum":["Wide","Vertical","Fit"],"default":"Vertical","description":"Output video format — Wide (16:9), Vertical (9:16), Fit (1:1). Legacy aliases such as Portrait or Shorts are normalized server-side."},"numberOfClips":{"type":"integer","minimum":1,"maximum":10,"default":3,"description":"Number of clips to generate"},"captions":{"type":"boolean","default":true,"description":"Whether to include captions in clips"},"user_id":{"type":"string","description":"Unique identifier for the user","example":"507f1f77bcf86cd799439011"},"ext":{"type":"string","description":"File extension for remote files","example":"mp4"},"templateId":{"oneOf":[{"type":"integer"},{"type":"string"}],"description":"Template ID for clip styling","example":123}}},"ClipResponse":{"type":"object","properties":{"success":{"type":"boolean","example":true},"message":{"type":"string","example":"Clip generation started successfully"},"taskId":{"type":"string","description":"Unique identifier for the clip generation task","example":"task_abc123"},"videoId":{"type":"string","description":"Database ID of the video record","example":"507f1f77bcf86cd799439011"}}}}},"tags":[{"name":"AI Video","description":"AI-powered video generation endpoints"},{"name":"Reddit Video","description":"Reddit story video generation"},{"name":"Social Accounts","description":"Social media account management"},{"name":"Social Posts","description":"Social media post management"},{"name":"Schedules","description":"Post scheduling management"},{"name":"Analytics","description":"Analytics and reporting"},{"name":"UGC","description":"User-generated content"},{"name":"AI Story","description":"AI story generation"},{"name":"Videos","description":"Video management"},{"name":"Clips","description":"Video clip processing"}],"paths":{"/api/clip-video":{"post":{"tags":["Clips"],"summary":"Generate video clips from source video","description":"Extract and generate multiple clips from a source video using AI-powered analysis","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ClipGenerationRequest"},"examples":{"youtube":{"summary":"Generate clips from YouTube video","value":{"video_url":"https://www.youtube.com/watch?v=dQw4w9WgXcQ","video_type":2,"finalVideo_type":"Vertical","numberOfClips":3,"captions":true,"user_id":"507f1f77bcf86cd799439011"}},"remote_file":{"summary":"Generate clips from remote file","value":{"video_url":"https://example.com/video.mp4","video_type":1,"finalVideo_type":"Wide","numberOfClips":5,"captions":true,"user_id":"507f1f77bcf86cd799439011","ext":"mp4","templateId":123}}}}}},"responses":{"200":{"description":"Clip generation started successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ClipResponse"}}}},"400":{"description":"Invalid request data or insufficient credits","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"User not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}]}},"/api/stock-clips":{"get":{"summary":"Search and list stock clips","tags":["Stock Clips"]}},"/api/stock-clips/stats":{"get":{"summary":"Get stock clip library statistics","tags":["Stock Clips"]}},"/api/stock-clips/presigned-url":{"post":{"summary":"Get a presigned URL for direct upload to R2","tags":["Stock Clips"],"parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}]}},"/api/stock-clips/direct-upload":{"post":{"summary":"Upload a clip directly (presigned URL + register in one step)","tags":["Stock Clips"],"parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}]}},"/api/stock-clips/confirm-upload":{"post":{"summary":"Confirm that a clip was successfully uploaded","tags":["Stock Clips"],"parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}]}},"/api/stock-clips/pending":{"get":{"summary":"Get pending clips awaiting download/upload","tags":["Stock Clips"]}},"/api/stock-clips/artgrid/import":{"post":{"summary":"Import clip metadata from ArtGrid (creates pending records)","tags":["Stock Clips","ArtGrid"],"parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}]}},"/api/stock-clips/artgrid/single":{"post":{"summary":"Import a single clip from ArtGrid metadata","tags":["Stock Clips","ArtGrid"],"parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}]}},"/api/stock-clips/{clipId}/upload":{"post":{"summary":"Upload a downloaded clip file for a pending record","tags":["Stock Clips"],"parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}]}},"/api/stock-clips/{id}":{"get":{"summary":"Get a single stock clip by ID","tags":["Stock Clips"]},"patch":{"summary":"Update a stock clip's metadata","tags":["Stock Clips"]},"delete":{"summary":"Delete a stock clip","tags":["Stock Clips"]}},"/api/stock-clips/map-metadata":{"post":{"summary":"Preview how ArtGrid metadata will be mapped (doesn't save)","tags":["Stock Clips","ArtGrid"],"parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}]}},"/api/stock-clips/{id}/increment-usage":{"post":{"summary":"Increment usage count for a clip","tags":["Stock Clips"],"parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}]}},"/api/v1/health":{"get":{"tags":["Health"],"summary":"Public v1 health check","responses":{"200":{"description":"v1 API is reachable on the server/ Express runtime"}}}},"/api/v1/videos/text-to-video":{"post":{"tags":["AI Video"],"summary":"Generate an AI text-to-video job","security":[{"ApiKeyAuth":[]}],"responses":{"200":{"description":"Existing text-to-video response"},"401":{"description":"Missing or invalid API key"},"409":{"description":"Idempotency-Key reused with a different body"}},"parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}]}},"/api/v1/videos/magic":{"post":{"tags":["Videos"],"summary":"Generate a brand-aware Magic Video through the server runtime","security":[{"ApiKeyAuth":[]}],"responses":{"200":{"description":"Existing generation response"},"401":{"description":"Missing or invalid API key"},"409":{"description":"Idempotency-Key reused with a different body"}},"parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}]}},"/api/v1/clipper/youtube":{"post":{"tags":["Clips"],"summary":"Generate clips from a YouTube URL","security":[{"ApiKeyAuth":[]}],"responses":{"200":{"description":"Existing clipper response"},"401":{"description":"Missing or invalid API key"},"409":{"description":"Idempotency-Key reused with a different body"}},"parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}]}},"/api/v1/post":{"post":{"tags":["Social Posts"],"summary":"Post a video through the existing social-post runtime","security":[{"ApiKeyAuth":[]}],"responses":{"200":{"description":"Existing social post response"},"401":{"description":"Missing or invalid API key"},"409":{"description":"Idempotency-Key reused with a different body"}},"parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}]}},"/api/v1/jobs":{"post":{"tags":["Jobs"],"summary":"Create an async generation or publish job","security":[{"ApiKeyAuth":[]}],"responses":{"201":{"description":"Async job created"},"401":{"description":"Missing or invalid API key"},"409":{"description":"Idempotency-Key reused with a different body"}},"parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}]}},"/api/v1/jobs/{jobId}":{"get":{"tags":["Jobs"],"summary":"Fetch an async job","security":[{"ApiKeyAuth":[]}],"parameters":[{"name":"jobId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Async job found"},"401":{"description":"Missing or invalid API key"},"404":{"description":"Async job not found"}}}}}}