REST API reference
Every VectorFast Render /v1 endpoint with its parameters, request body, response fields, and status codes, generated from the OpenAPI 3.1 document.
VectorFast Render API 0.1.0. Base URL: https://vectorfast.ai. The machine-readable document is GET /v1/openapi.json.
Authenticate every /v1 call except this document with an API key created in your account: Authorization: Bearer vf_live_….
Each key is limited to 60 requests per 60 seconds. Errors always have the shape {"error": {"code", "message", "docs"}}.
Billing is not connected yet: credits_charged is always 0 and GET /v1/usage reports credits_remaining: null.
Templates: launch-post, blog-post, social-square, achievement-card, invite-card, stat-card, changelog, quote-card. GET /v1/templates/{id} returns each one's params schema, examples and an agent_example (a prompt and the render call it should become). A template listed with status: "planned" cannot be rendered yet.
Endpoints
| Method | Path | Summary |
|---|---|---|
| GET | /v1/templates | List templates |
| GET | /v1/templates/{id} | Describe a template |
| POST | /v1/renders | Render an image |
| POST | /v1/previews | Render a watermarked preview |
| GET | /v1/usage | Usage for the current period |
| GET | /v1/brand-kits | List brand kits |
| POST | /v1/brand-kits | Create a brand kit |
| GET | /v1/brand-kits/{id} | Read a brand kit |
| PUT | /v1/brand-kits/{id} | Update a brand kit |
| DELETE | /v1/brand-kits/{id} | Delete a brand kit |
| POST | /v1/brand-kits/{id}/logo | Upload a logo |
| GET | /v1/openapi.json | This document |
Templates
Official templates, their param schemas and preview images.
List templates
GET /v1/templates
All catalog templates. preview_url is a signed /i/ URL of the English example at the default size.
Auth: Authorization: Bearer <API key>.
Response 200
| Field | Type | Required | Constraints | Description |
|---|---|---|---|---|
templates | TemplateListing[] | yes | — | — |
Status codes
| Status | Meaning |
|---|---|
| 200 | The catalog. |
| 401 | Missing, malformed, unknown or revoked API key (unauthorized). |
| 429 | More than 60 requests in 60 seconds for this API key (rate_limited); honour Retry-After. |
| 503 | The API is not configured or a dependency is down (render_unavailable). |
Describe a template
GET /v1/templates/{id}
Params JSON Schema (draft 2020-12, generated from the template's zod schema), sizes, examples and an agent prompt.
Auth: Authorization: Bearer <API key>.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
id | path | "launch-post" | "blog-post" | "social-square" | "achievement-card" | "invite-card" | "stat-card" | "changelog" | "quote-card" | yes | — |
Response 200 (TemplateDescription)
The template. Content types: application/json.
Status codes
| Status | Meaning |
|---|---|
| 200 | The template. |
| 401 | Missing, malformed, unknown or revoked API key (unauthorized). |
| 404 | The id is not in the catalog (template_not_found). |
| 429 | More than 60 requests in 60 seconds for this API key (rate_limited); honour Retry-After. |
| 503 | The API is not configured or a dependency is down (render_unavailable). |
Renders
Synchronous renders and watermarked previews.
Render an image
POST /v1/renders
Validates the template, params, format and size, then answers from the edge cache, the R2 cache or a fresh render (cached tells which).
Send Idempotency-Key to make retries safe: the same key with the same body returns the stored JSON for 24 hours (header Idempotent-Replayed: true); the same key with a different body answers 409 invalid_params.
Every call records one usage row (template, format, cached); params are never stored.
Auth: Authorization: Bearer <API key>.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
Idempotency-Key | header | string | no | Client-chosen retry key, printable ASCII without spaces. |
Request body (application/json)
| Field | Type | Required | Constraints | Description |
|---|---|---|---|---|
template | string | yes | pattern ^([a-z0-9-]{1,64})(?:@(\d{1,3}))?$ | — |
format | "png" | "jpeg" | "webp" | no | default "png" | — |
width | integer | no | 16–4096 | — |
height | integer | no | 16–4096 | — |
scale | 1 or 2 | no | default 1 | — |
brand_kit | string | no | 1–64 chars | — |
params | object | yes | — | — |
response | "url" | "binary" | no | default "url" | — |
Body of POST /v1/renders and POST /v1/previews. params must satisfy the template's own schema (see GET /v1/templates/{id} → params_schema, or the TemplateParams_* components).
Response 200 (RenderResponse)
| Field | Type | Required | Constraints | Description |
|---|---|---|---|---|
id | string | yes | pattern ^rnd_[0-9a-f]{32}$ | Render id; stable across idempotent replays. |
url | string (uri) | yes | — | Signed /i/{template}.{format} URL serving the same pixels. It never expires. |
cache_key | string | yes | pattern ^[0-9a-f]{64}$ | — |
cached | boolean | yes | — | True when a cache layer answered and nothing was rendered. |
credits_charged | 0 | yes | — | Always 0 in this phase: credits are connected in a later release. Cache hits will stay 0. |
width | integer | yes | — | — |
height | integer | yes | — | — |
scale | 1 | 2 | yes | — | — |
format | "png" | "jpeg" | "webp" | yes | — | — |
render_ms | number | yes | — | Renderer time (layout + raster + encode) for this request; 0 on cache hits. |
template_version | string | yes | — | <id>@<semver> of the template that produced the pixels. |
watermark | true | no | — | Present only on /v1/previews responses. |
Status codes
| Status | Meaning |
|---|---|
| 200 | The render. With response: "url" a JSON body; with response: "binary" the image bytes and the same facts in headers. |
| 400 | Invalid request body, params, size or Idempotency-Key (invalid_params). |
| 401 | Missing, malformed, unknown or revoked API key (unauthorized). |
| 404 | Unknown or planned template, or unknown brand kit (template_not_found, brand_kit_not_found). |
| 409 | Idempotency-Key reused with a different body (invalid_params). |
| 413 | Body larger than 256 KiB (invalid_params). |
| 429 | More than 60 requests in 60 seconds for this API key (rate_limited); honour Retry-After. |
| 500 | The renderer failed (render_failed). |
| 502 | Fonts could not be loaded (render_failed). |
| 503 | The API is not configured or a dependency is down (render_unavailable). |
Render a watermarked preview
POST /v1/previews
Same body and validation as /v1/renders; the image carries a translucent PREVIEW label, is cached at the edge only (never in R2), charges nothing and records no usage. Idempotency-Key is ignored.
Auth: Authorization: Bearer <API key>.
Request body (application/json)
| Field | Type | Required | Constraints | Description |
|---|---|---|---|---|
template | string | yes | pattern ^([a-z0-9-]{1,64})(?:@(\d{1,3}))?$ | — |
format | "png" | "jpeg" | "webp" | no | default "png" | — |
width | integer | no | 16–4096 | — |
height | integer | no | 16–4096 | — |
scale | 1 or 2 | no | default 1 | — |
brand_kit | string | no | 1–64 chars | — |
params | object | yes | — | — |
response | "url" | "binary" | no | default "url" | — |
Body of POST /v1/renders and POST /v1/previews. params must satisfy the template's own schema (see GET /v1/templates/{id} → params_schema, or the TemplateParams_* components).
Response 200 (RenderResponse)
| Field | Type | Required | Constraints | Description |
|---|---|---|---|---|
id | string | yes | pattern ^rnd_[0-9a-f]{32}$ | Render id; stable across idempotent replays. |
url | string (uri) | yes | — | Signed /i/{template}.{format} URL serving the same pixels. It never expires. |
cache_key | string | yes | pattern ^[0-9a-f]{64}$ | — |
cached | boolean | yes | — | True when a cache layer answered and nothing was rendered. |
credits_charged | 0 | yes | — | Always 0 in this phase: credits are connected in a later release. Cache hits will stay 0. |
width | integer | yes | — | — |
height | integer | yes | — | — |
scale | 1 | 2 | yes | — | — |
format | "png" | "jpeg" | "webp" | yes | — | — |
render_ms | number | yes | — | Renderer time (layout + raster + encode) for this request; 0 on cache hits. |
template_version | string | yes | — | <id>@<semver> of the template that produced the pixels. |
watermark | true | no | — | Present only on /v1/previews responses. |
Status codes
| Status | Meaning |
|---|---|
| 200 | The preview; watermark: true in JSON responses. |
| 400 | Invalid request body, params, size or Idempotency-Key (invalid_params). |
| 401 | Missing, malformed, unknown or revoked API key (unauthorized). |
| 404 | Unknown or planned template, or unknown brand kit (template_not_found, brand_kit_not_found). |
| 413 | Body larger than 256 KiB (invalid_params). |
| 429 | More than 60 requests in 60 seconds for this API key (rate_limited); honour Retry-After. |
| 500 | The renderer failed (render_failed). |
| 503 | The API is not configured or a dependency is down (render_unavailable). |
Brand kits
Versioned brand kits: colors, fonts and a logo that templates render with.
List brand kits
GET /v1/brand-kits
Your kits at their current version, oldest first (the first is the default for renders). With no kits of your own the list holds the read-only built-in default kit. limit is how many kits your plan includes.
Auth: Authorization: Bearer <API key>.
Response 200
| Field | Type | Required | Constraints | Description |
|---|---|---|---|---|
brand_kits | BrandKit[] | yes | — | — |
limit | integer | yes | — | — |
Status codes
| Status | Meaning |
|---|---|
| 200 | The kits. |
| 401 | Missing, malformed, unknown or revoked API key (unauthorized). |
| 429 | More than 60 requests in 60 seconds for this API key (rate_limited); honour Retry-After. |
| 503 | The API is not configured or a dependency is down (render_unavailable). |
Create a brand kit
POST /v1/brand-kits
Creates version 1. Colors and fonts you leave out start from the built-in kit. Font families must be Google Fonts families that load at weights 400 and 700; custom font uploads are not available yet.
Auth: Authorization: Bearer <API key>.
Request body (application/json)
| Field | Type | Required | Constraints | Description |
|---|---|---|---|---|
name | string | yes | 1–64 chars | — |
colors | object | no | — | — |
colors.background | string | no | pattern ^#(?:[0-9a-f]{3}|[0-9a-f]{6}|[0-9a-f]{8})$ | — |
colors.foreground | string | no | pattern ^#(?:[0-9a-f]{3}|[0-9a-f]{6}|[0-9a-f]{8})$ | — |
colors.muted | string | no | pattern ^#(?:[0-9a-f]{3}|[0-9a-f]{6}|[0-9a-f]{8})$ | — |
colors.accent | string | no | pattern ^#(?:[0-9a-f]{3}|[0-9a-f]{6}|[0-9a-f]{8})$ | — |
colors.accentForeground | string | no | pattern ^#(?:[0-9a-f]{3}|[0-9a-f]{6}|[0-9a-f]{8})$ | — |
colors.surface | string | no | pattern ^#(?:[0-9a-f]{3}|[0-9a-f]{6}|[0-9a-f]{8})$ | — |
fonts | object | no | — | — |
fonts.heading | object | no | — | — |
fonts.body | object | no | — | — |
Response 201 (BrandKit)
| Field | Type | Required | Constraints | Description |
|---|---|---|---|---|
id | string | yes | — | bk_ + 16 base32 characters, or default for the built-in kit. |
name | string | yes | — | — |
version | string | yes | — | <id>@<n>. Every save creates a new version; renders fold it into the cache key, so old images are never served for a changed kit. |
version_number | integer | yes | 1–∞ | — |
is_default | boolean | yes | — | The kit renders use when brand_kit is omitted: your oldest kit, or the built-in kit when you have none. |
read_only | boolean | yes | — | True only for the built-in default kit. |
colors | object | yes | — | — |
colors.background | string | yes | pattern ^#(?:[0-9a-f]{3}|[0-9a-f]{6}|[0-9a-f]{8})$ | — |
colors.foreground | string | yes | pattern ^#(?:[0-9a-f]{3}|[0-9a-f]{6}|[0-9a-f]{8})$ | — |
colors.muted | string | yes | pattern ^#(?:[0-9a-f]{3}|[0-9a-f]{6}|[0-9a-f]{8})$ | — |
colors.accent | string | yes | pattern ^#(?:[0-9a-f]{3}|[0-9a-f]{6}|[0-9a-f]{8})$ | — |
colors.accentForeground | string | yes | pattern ^#(?:[0-9a-f]{3}|[0-9a-f]{6}|[0-9a-f]{8})$ | — |
colors.surface | string | yes | pattern ^#(?:[0-9a-f]{3}|[0-9a-f]{6}|[0-9a-f]{8})$ | — |
fonts | object | yes | — | — |
fonts.heading | object | yes | — | — |
fonts.body | object | yes | — | — |
logo | object or null | yes | — | Set by POST /v1/brand-kits/{id}/logo. URLs are signed, immutable and never expire. |
logo.svg_url | string or null (uri) | yes | — | — |
logo.png_url | string or null (uri) | yes | — | — |
logo.source_format | "png" | "jpeg" | "svg" | yes | — | — |
logo.width | integer | yes | — | — |
logo.height | integer | yes | — | — |
logo.png_width | integer | yes | — | Twice width (capped at 4096). |
logo.png_height | integer | yes | — | — |
logo.path_count | integer | yes | — | — |
created_at | string or null (date-time) | yes | — | — |
updated_at | string or null (date-time) | yes | — | — |
Status codes
| Status | Meaning |
|---|---|
| 201 | The new kit. |
| 400 | Invalid request body, params, size or Idempotency-Key (invalid_params). |
| 401 | Missing, malformed, unknown or revoked API key (unauthorized). |
| 403 | Your plan's brand-kit limit is reached (brand_kit_limit_reached). |
| 413 | Body larger than 256 KiB (invalid_params). |
| 429 | More than 60 requests in 60 seconds for this API key (rate_limited); honour Retry-After. |
| 503 | The API is not configured or a dependency is down (render_unavailable). |
Read a brand kit
GET /v1/brand-kits/{id}
Auth: Authorization: Bearer <API key>.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
id | path | string | yes | Brand kit id. GET also accepts a pinned version such as bk_…@2 and the built-in default. |
Response 200 (BrandKit)
| Field | Type | Required | Constraints | Description |
|---|---|---|---|---|
id | string | yes | — | bk_ + 16 base32 characters, or default for the built-in kit. |
name | string | yes | — | — |
version | string | yes | — | <id>@<n>. Every save creates a new version; renders fold it into the cache key, so old images are never served for a changed kit. |
version_number | integer | yes | 1–∞ | — |
is_default | boolean | yes | — | The kit renders use when brand_kit is omitted: your oldest kit, or the built-in kit when you have none. |
read_only | boolean | yes | — | True only for the built-in default kit. |
colors | object | yes | — | — |
colors.background | string | yes | pattern ^#(?:[0-9a-f]{3}|[0-9a-f]{6}|[0-9a-f]{8})$ | — |
colors.foreground | string | yes | pattern ^#(?:[0-9a-f]{3}|[0-9a-f]{6}|[0-9a-f]{8})$ | — |
colors.muted | string | yes | pattern ^#(?:[0-9a-f]{3}|[0-9a-f]{6}|[0-9a-f]{8})$ | — |
colors.accent | string | yes | pattern ^#(?:[0-9a-f]{3}|[0-9a-f]{6}|[0-9a-f]{8})$ | — |
colors.accentForeground | string | yes | pattern ^#(?:[0-9a-f]{3}|[0-9a-f]{6}|[0-9a-f]{8})$ | — |
colors.surface | string | yes | pattern ^#(?:[0-9a-f]{3}|[0-9a-f]{6}|[0-9a-f]{8})$ | — |
fonts | object | yes | — | — |
fonts.heading | object | yes | — | — |
fonts.body | object | yes | — | — |
logo | object or null | yes | — | Set by POST /v1/brand-kits/{id}/logo. URLs are signed, immutable and never expire. |
logo.svg_url | string or null (uri) | yes | — | — |
logo.png_url | string or null (uri) | yes | — | — |
logo.source_format | "png" | "jpeg" | "svg" | yes | — | — |
logo.width | integer | yes | — | — |
logo.height | integer | yes | — | — |
logo.png_width | integer | yes | — | Twice width (capped at 4096). |
logo.png_height | integer | yes | — | — |
logo.path_count | integer | yes | — | — |
created_at | string or null (date-time) | yes | — | — |
updated_at | string or null (date-time) | yes | — | — |
Status codes
| Status | Meaning |
|---|---|
| 200 | The kit at its current (or pinned) version. |
| 401 | Missing, malformed, unknown or revoked API key (unauthorized). |
| 404 | No such kit or version on your account (brand_kit_not_found). |
| 429 | More than 60 requests in 60 seconds for this API key (rate_limited); honour Retry-After. |
| 503 | The API is not configured or a dependency is down (render_unavailable). |
Update a brand kit
PUT /v1/brand-kits/{id}
Saves a new version. Fields you leave out keep their current values; the logo only changes through POST /v1/brand-kits/{id}/logo. Earlier versions stay readable and renderable when pinned.
Auth: Authorization: Bearer <API key>.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
id | path | string | yes | Brand kit id. GET also accepts a pinned version such as bk_…@2 and the built-in default. |
Request body (application/json)
| Field | Type | Required | Constraints | Description |
|---|---|---|---|---|
name | string | no | 1–64 chars | — |
colors | object | no | — | — |
colors.background | string | no | pattern ^#(?:[0-9a-f]{3}|[0-9a-f]{6}|[0-9a-f]{8})$ | — |
colors.foreground | string | no | pattern ^#(?:[0-9a-f]{3}|[0-9a-f]{6}|[0-9a-f]{8})$ | — |
colors.muted | string | no | pattern ^#(?:[0-9a-f]{3}|[0-9a-f]{6}|[0-9a-f]{8})$ | — |
colors.accent | string | no | pattern ^#(?:[0-9a-f]{3}|[0-9a-f]{6}|[0-9a-f]{8})$ | — |
colors.accentForeground | string | no | pattern ^#(?:[0-9a-f]{3}|[0-9a-f]{6}|[0-9a-f]{8})$ | — |
colors.surface | string | no | pattern ^#(?:[0-9a-f]{3}|[0-9a-f]{6}|[0-9a-f]{8})$ | — |
fonts | object | no | — | — |
fonts.heading | object | no | — | — |
fonts.body | object | no | — | — |
Response 200 (BrandKit)
| Field | Type | Required | Constraints | Description |
|---|---|---|---|---|
id | string | yes | — | bk_ + 16 base32 characters, or default for the built-in kit. |
name | string | yes | — | — |
version | string | yes | — | <id>@<n>. Every save creates a new version; renders fold it into the cache key, so old images are never served for a changed kit. |
version_number | integer | yes | 1–∞ | — |
is_default | boolean | yes | — | The kit renders use when brand_kit is omitted: your oldest kit, or the built-in kit when you have none. |
read_only | boolean | yes | — | True only for the built-in default kit. |
colors | object | yes | — | — |
colors.background | string | yes | pattern ^#(?:[0-9a-f]{3}|[0-9a-f]{6}|[0-9a-f]{8})$ | — |
colors.foreground | string | yes | pattern ^#(?:[0-9a-f]{3}|[0-9a-f]{6}|[0-9a-f]{8})$ | — |
colors.muted | string | yes | pattern ^#(?:[0-9a-f]{3}|[0-9a-f]{6}|[0-9a-f]{8})$ | — |
colors.accent | string | yes | pattern ^#(?:[0-9a-f]{3}|[0-9a-f]{6}|[0-9a-f]{8})$ | — |
colors.accentForeground | string | yes | pattern ^#(?:[0-9a-f]{3}|[0-9a-f]{6}|[0-9a-f]{8})$ | — |
colors.surface | string | yes | pattern ^#(?:[0-9a-f]{3}|[0-9a-f]{6}|[0-9a-f]{8})$ | — |
fonts | object | yes | — | — |
fonts.heading | object | yes | — | — |
fonts.body | object | yes | — | — |
logo | object or null | yes | — | Set by POST /v1/brand-kits/{id}/logo. URLs are signed, immutable and never expire. |
logo.svg_url | string or null (uri) | yes | — | — |
logo.png_url | string or null (uri) | yes | — | — |
logo.source_format | "png" | "jpeg" | "svg" | yes | — | — |
logo.width | integer | yes | — | — |
logo.height | integer | yes | — | — |
logo.png_width | integer | yes | — | Twice width (capped at 4096). |
logo.png_height | integer | yes | — | — |
logo.path_count | integer | yes | — | — |
created_at | string or null (date-time) | yes | — | — |
updated_at | string or null (date-time) | yes | — | — |
Status codes
| Status | Meaning |
|---|---|
| 200 | The kit at its new version. |
| 400 | Invalid body, or the read-only built-in kit (invalid_params). |
| 401 | Missing, malformed, unknown or revoked API key (unauthorized). |
| 404 | No such kit on your account (brand_kit_not_found). |
| 409 | The kit changed while the request ran (brand_kit_conflict); read it and retry. |
| 413 | Body larger than 256 KiB (invalid_params). |
| 429 | More than 60 requests in 60 seconds for this API key (rate_limited); honour Retry-After. |
| 503 | The API is not configured or a dependency is down (render_unavailable). |
Delete a brand kit
DELETE /v1/brand-kits/{id}
Soft delete: the kit stops counting toward your limit, renders that name it answer 404, and its signed image URLs stop rendering on a cache miss.
Auth: Authorization: Bearer <API key>.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
id | path | string | yes | Brand kit id. GET also accepts a pinned version such as bk_…@2 and the built-in default. |
Response 200
| Field | Type | Required | Constraints | Description |
|---|---|---|---|---|
id | string | yes | — | — |
deleted | true | yes | — | — |
Status codes
| Status | Meaning |
|---|---|
| 200 | Deleted. |
| 400 | The read-only built-in kit (invalid_params). |
| 401 | Missing, malformed, unknown or revoked API key (unauthorized). |
| 404 | No such kit on your account (brand_kit_not_found). |
| 429 | More than 60 requests in 60 seconds for this API key (rate_limited); honour Retry-After. |
| 503 | The API is not configured or a dependency is down (render_unavailable). |
Upload a logo
POST /v1/brand-kits/{id}/logo
Send the file as the raw body with Content-Type: image/png, image/jpeg or image/svg+xml, or as multipart/form-data with a part named file. At most 5 MB and 4096×4096 pixels; the file name is ignored and never stored.
PNG and JPEG logos are traced to SVG with the same engine as the free VectorFast vectorizer, then cleaned (tiny fragments, near-duplicate colors, coordinate precision); the untouched trace is kept too. SVG logos skip tracing and are sanitized (scripts, event handlers, external links and embedded HTML are removed). Both get a 2x PNG. Tracing is a best-effort candidate, not an exact reconstruction of the original artwork.
Saves a new kit version; renders and signed URLs that name the kit use it from then on. Limited to 3 uploads a minute and 10 an hour per API key.
Auth: Authorization: Bearer <API key>.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
id | path | string | yes | Brand kit id. GET also accepts a pinned version such as bk_…@2 and the built-in default. |
Request body (image/png, image/jpeg, image/svg+xml, multipart/form-data)
| Field | Type | Required | Constraints | Description |
|---|---|---|---|---|
file | string (binary) | yes | — | — |
Response 200
| Field | Type | Required | Constraints | Description |
|---|---|---|---|---|
brand_kit | BrandKit | yes | — | — |
version | string | yes | — | — |
logo | BrandKit/properties/logo | yes | — | — |
Status codes
| Status | Meaning |
|---|---|
| 200 | The kit at the version that carries the logo. |
| 400 | Over 5 MB or 4096×4096, a body that does not match its Content-Type, an unreadable image, or the read-only built-in kit (invalid_params). |
| 401 | Missing, malformed, unknown or revoked API key (unauthorized). |
| 404 | No such kit on your account (brand_kit_not_found). |
| 409 | The kit changed while the upload ran (brand_kit_conflict); upload again. |
| 415 | Content-Type is not PNG, JPEG, SVG or multipart (invalid_params). |
| 429 | More than 3 uploads a minute or 10 an hour for this API key (rate_limited); honour Retry-After. |
| 500 | The pipeline or storage failed (render_failed). |
| 503 | The API is not configured or a dependency is down (render_unavailable). |
Account
Usage for the current API key's account.
Usage for the current period
GET /v1/usage
Renders counted in the current UTC calendar month for the key's account. credits_charged is 0 and credits_remaining is null until billing is connected, after which the period follows the subscription.
Auth: Authorization: Bearer <API key>.
Response 200 (Usage)
| Field | Type | Required | Constraints | Description |
|---|---|---|---|---|
period | object | yes | — | — |
period.start | string (date-time) | yes | — | — |
period.end | string (date-time) | yes | — | — |
renders | integer | yes | — | POST /v1/renders calls in the period, cache hits included. |
cached_renders | integer | yes | — | — |
credits_charged | 0 | yes | — | Always 0 until billing is connected. |
credits_remaining | integer or null | yes | — | null until billing is connected. |
Status codes
| Status | Meaning |
|---|---|
| 200 | Usage. |
| 401 | Missing, malformed, unknown or revoked API key (unauthorized). |
| 429 | More than 60 requests in 60 seconds for this API key (rate_limited); honour Retry-After. |
| 503 | The API is not configured or a dependency is down (render_unavailable). |
Meta
This document.
This document
GET /v1/openapi.json
Auth: none.
Response 200
The OpenAPI 3.1 document. Content types: application/json.
Status codes
| Status | Meaning |
|---|---|
| 200 | The OpenAPI 3.1 document. |
Errors
Every error body has the same shape; see Errors for what each code means and how to fix it.
| Field | Type | Required | Constraints | Description |
|---|---|---|---|---|
error | object | yes | — | — |
error.code | "invalid_params" | "unauthorized" | "insufficient_credits" | "template_not_found" | "brand_kit_not_found" | "brand_kit_limit_reached" | "brand_kit_conflict" | "not_found" | "rate_limited" | "render_failed" | "render_timeout" | "render_unavailable" | yes | — | — |
error.message | string | yes | — | Public-safe; names a field or rule, never echoes a value. |
error.docs | string (uri) | yes | — | — |
Updated 2026-10-30 · Markdown version
Authentication
How VectorFast Render API keys work, how to create, list, and revoke them, and the per-key rate limits for REST and MCP requests.
Signed URLs
How VectorFast Render signed image URLs work, the exact canonicalization and HMAC-SHA-256 rules, Node.js and Python examples, and how to keep the signing secret safe.