{"openapi":"3.1.0","info":{"title":"FreeRap Template API","version":"1.0.0","summary":"Generate a template video from a reference image. Create a task, then query its status to retrieve the finished video.","description":"Generate a template video from a reference image. Create a task, then query its status to retrieve the finished video.\n\nThe template supplies the prompt, reference video, and soundtrack. Clients supply the reference image and generation settings. Callback URLs are not supported; query the task for results.\n\nSuccessful calls use HTTP 200 with code 0, message ok, and a data object. Request errors use code -1 and message. A successful query can report a failed generation in data.status.\n\nModels: basic supports 480p and 720p. pro and ultra also support 1080p. Only priced combinations for the chosen template are available. GET /api/template-prices lists current combinations and template metadata. Duration and aspect ratio are template-controlled: omit duration and aspect_ratio. image_url, effect, slots, prompt, reference_video_urls, callBackUrl, and unknown fields are rejected with HTTP 400.\n\nBase URL: https://freerapvideo.com\n\nSend the Authorization header on both task endpoints. Use the full sk_ key from Settings → API. A missing or invalid key returns HTTP 401. Never expose the key in browser code.\n\nHTML: https://freerapvideo.com/docs/api\nMarkdown: https://freerapvideo.com/docs/api.md"},"servers":[{"url":"https://freerapvideo.com"}],"security":[{"bearerAuth":[]}],"paths":{"/api/v1/templates/{campaign}/generations":{"post":{"operationId":"createTemplateGeneration","summary":"Create a task","description":"Starts an asynchronous video generation for an active template. HTTP 200 confirms task creation; the video is still processing.","parameters":[{"name":"campaign","in":"path","required":true,"description":"On Admin template slug. The example is bulin. Duration is template-fixed to that template.","schema":{"type":"string"},"example":"bulin"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateGenerationRequest"}}}},"responses":{"200":{"description":"Generation accepted. credits_charged equals credits_estimate because that amount is reserved at create.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateGenerationResponse"},"example":{"code":0,"message":"ok","data":{"taskId":"550e8400-e29b-41d4-a716-446655440000","status":"processing","credits_estimate":30,"credits_charged":30}}}}},"400":{"description":"Invalid JSON, fields, image, model, resolution, or duration. Correct the request before retrying.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"401":{"description":"Missing or invalid API key. Check the Authorization header and key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"402":{"description":"Insufficient FreeRap balance. No task is started. Add credits, then create the task.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"403":{"description":"Template has no price for this model/resolution. Choose a priced combination from /api/template-prices.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"Template is unavailable, or task is missing, deleted, inaccessible, or not API-created. Check the slug or task ID and account. Stop querying an unavailable task.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Request rate or 30-task in-flight limit exceeded. Honor Retry-After if present, or wait for running tasks to finish.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}},"headers":{"Retry-After":{"description":"Seconds to wait when the per-key burst limit fires. Absent when the in-flight cap is full.","schema":{"type":"string"}}}},"500":{"description":"Unexpected server error. Retry queries later. A create may already have started; avoid duplicate submissions.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"503":{"description":"Credit pricing, storage, or generation service is unavailable. Retry later; contact support if it persists.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/api/v1/generations/{taskId}":{"get":{"operationId":"getTemplateGeneration","summary":"Query a task","description":"Returns the current status of an API-created task belonging to the API key’s user. No request body. Use the same key as creation, or another valid key belonging to the same user.","parameters":[{"name":"taskId","in":"path","required":true,"description":"taskId returned by Create.","schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Current task state. HTTP 200 means the query succeeded; data.status determines whether generation succeeded.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GenerationStatusResponse"},"examples":{"success":{"value":{"code":0,"message":"ok","data":{"taskId":"550e8400-e29b-41d4-a716-446655440000","status":"success","campaign":"bulin","costCredits":30,"credits_estimate":30,"credits_charged":30,"createdAt":"2026-10-31T00:00:00.000Z","videos":["https://media.example.com/generated/video.mp4"]}}},"failed":{"value":{"code":0,"message":"ok","data":{"taskId":"550e8400-e29b-41d4-a716-446655440000","status":"failed","campaign":"bulin","costCredits":0,"credits_estimate":30,"credits_charged":0,"createdAt":"2026-10-31T00:00:00.000Z","videos":[],"error":"Video generation failed."}}}}}}},"401":{"description":"Missing or invalid API key. Check the Authorization header and key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"404":{"description":"Template is unavailable, or task is missing, deleted, inaccessible, or not API-created. Check the slug or task ID and account. Stop querying an unavailable task.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"429":{"description":"Request rate or 30-task in-flight limit exceeded. Honor Retry-After if present, or wait for running tasks to finish.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}},"headers":{"Retry-After":{"description":"Seconds to wait when the per-key burst limit fires. Absent when the in-flight cap is full.","schema":{"type":"string"}}}},"500":{"description":"Unexpected server error. Retry queries later. A create may already have started; avoid duplicate submissions.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}}},"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"sk_","description":"API key from /settings/api. Send Authorization: Bearer sk_…. Keys that do not start with sk_ are rejected with 401."}},"schemas":{"CreateGenerationRequest":{"type":"object","additionalProperties":false,"description":"Send exactly the configured imageSlots non-empty HTTPS URLs, in @Image1…N order. Only Admin-priced model×resolution cells work; see GET /api/template-prices.","required":["reference_image_urls"],"properties":{"reference_image_urls":{"type":"array","minItems":1,"maxItems":5,"description":"reference_image_urls must contain exactly N publicly accessible HTTPS image URLs, where N is the template imageSlots value returned by GET /api/template-prices (1–5). Each URL must serve JPEG, PNG, or WebP, up to 10 MB by default, on port 443. Empty strings, null entries, missing entries, and extra entries return HTTP 400. The server retrieves and stores each image before generation. Local files, private network addresses, and URLs requiring authentication are not supported.","items":{"type":"string","minLength":1,"maxLength":2048},"examples":[["https://cdn.example.com/face.jpg"]]},"model":{"type":"string","enum":["basic","pro","ultra"],"description":"basic | pro | ultra. Default: pro. Must be priced for this template and resolution.","examples":["pro"]},"resolution":{"type":"string","enum":["480p","720p","1080p"],"description":"480p | 720p | 1080p. Default: 720p. basic allows 480p and 720p. pro and ultra also allow 1080p. Must be priced for the selected model.","examples":["720p"]}}},"CreateGenerationResponse":{"type":"object","additionalProperties":false,"description":"Successful calls use HTTP 200 with code 0, message ok, and a data object. Request errors use code -1 and message. A successful query can report a failed generation in data.status.","required":["code","message","data"],"properties":{"code":{"type":"integer","const":0},"message":{"type":"string","const":"ok"},"data":{"type":"object","additionalProperties":false,"required":["taskId","status","credits_estimate","credits_charged"],"properties":{"taskId":{"type":"string","format":"uuid"},"status":{"type":"string","const":"processing"},"credits_estimate":{"type":"integer"},"credits_charged":{"type":"integer","description":"Credits reserved at create. Equals credits_estimate on this response."}}}}},"GenerationStatusResponse":{"type":"object","additionalProperties":false,"description":"Successful calls use HTTP 200 with code 0, message ok, and a data object. Request errors use code -1 and message. A successful query can report a failed generation in data.status.","required":["code","message","data"],"properties":{"code":{"type":"integer","const":0},"message":{"type":"string","const":"ok"},"data":{"$ref":"#/components/schemas/GenerationStatus"}}},"GenerationStatus":{"type":"object","additionalProperties":false,"required":["taskId","status","costCredits","credits_estimate","credits_charged","createdAt","videos"],"properties":{"taskId":{"type":"string","format":"uuid"},"status":{"type":"string","enum":["pending","processing","success","failed","canceled"]},"campaign":{"type":"string","description":"Public template slug. Any Admin template with status on."},"costCredits":{"type":"integer"},"credits_estimate":{"type":"integer"},"credits_charged":{"type":"integer","description":"Reserved amount while pending or processing, and after success. After failed or canceled, the failure fee kept (0 unless an admin failure fee is set)."},"createdAt":{"type":"string","format":"date-time"},"videos":{"type":"array","items":{"type":"string"},"description":"Site-hosted URLs after a successful copy. Empty until then."},"error":{"type":"string"}}},"ErrorEnvelope":{"type":"object","additionalProperties":false,"description":"Live error body uses code -1 and message. HTTP status is 400, 401, 402, 403, 404, 429, 500, or 503. FreeRap keeps the HTTP status as the contract.","required":["code","message"],"properties":{"code":{"type":"integer","const":-1},"message":{"type":"string"}}}}}}