Drive vfrey from your own code with a personal token. Edit scenes, render, and fetch the video.
This needs the hosted vfrey service, which is not live yet. This page says how the API will work. The OpenAPI file is the exact contract: when the service is live it is served at https://<console>/openapi.yaml, where <console> is the service address.
The public API lets your own code do what the console and the command line do: push or read hosted projects, apply structured edits to a scene, render it, fetch the video, and read Topics, Creators, and mail drafts. Every path starts with /api/v1. For TypeScript, the SDK wraps all of it.
A token acts as the person who made it, with that person’s role, and stops working when they leave the organization. Cookies are never read. Treat a token like a password: keep it in an environment variable, never in a scene or a repository.
An edit changes a scene’s index.html on the server. vfrey parses the file as text and writes it back. It never runs the scene, and an edit costs no credits. It needs the role that can push (member, admin, owner).Read the scene first. You get its HTML, its sha256, and the elements you can target.
GET /api/v1/cloud/projects/ID/scenes/NAMEPOST /api/v1/cloud/projects/ID/scenes/NAME/edits
Replaces an element’s text. Markup in the text is escaped, never parsed.
set_style
Sets one style from an allowed list (colors, fonts, size, position, opacity, transform, and similar). null clears it. No url(), braces, or markup.
replace_asset
Points an image at a png, jpg, webp, gif, or svg file already in the project, inside the same scene folder. Push the image first.
retime
Sets start and duration in seconds. Animations on the element move with it.
remove
Deletes an element. The scene’s root element cannot be removed.
Target each operation with exactly one of selector (a simple CSS selector: tag, #id, .class, [attr], combinators, no pseudo-classes) or id (a stable id from the read). A selector that matches several elements is refused unless you add "all": true.
All or none. Operations apply in order. If one fails, nothing is saved and the error names it by index.
ifMatch is the sha256 from your read. If the file changed since, you get a conflict and nothing is written.
dryRun: true returns the summary and the diff without saving.
The answer says what changed, with before and after for each operation, and the new sha256. An edit that changes nothing saves nothing and answers changed: false.
POST /api/v1/render/jobsGET /api/v1/render/jobs/IDGET /api/v1/render/jobs
To render a scene already in a project, send sceneRef (for example scenes/intro), the project’s localProjectId, your own runId, and a script. Send the same localProjectId and runId again and you get the same job, so a retry is safe. Statuses go queued, dispatched, running, then succeeded, rejected, failed, or timeout. When a job succeeds, its output is a video in the project that you download from a short-lived link. Costs are in Cloud rendering.
/api/v1 only grows: new endpoints, new optional fields, new response keys. Ignore keys you do not know. A breaking change ships as /api/v2, and v1 keeps working for at least six months.
When the service is live, the full contract is at https://<console>/openapi.yaml (OpenAPI 3.1). Point a code generator or an agent at it. Until then, this page and the SDK are the guide.