> ## Documentation Index
> Fetch the complete documentation index at: https://docs.framelane.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Render one frame of a shader

> Queue a one-frame preview (a PNG, not billed) of the shader on a full-canvas shape over a three-hue fill, at `time` with `params`. Poll the returned job with GET /v1/renders/{id}, as for any preview.



## OpenAPI

````yaml /openapi.json post /v1/shaders/{shader_id}/probe
openapi: 3.1.0
info:
  title: Framelane API
  description: >
    Framelane renders video and runs AI media tasks from a single declarative
    request.


    ### Getting access (self-serve, no human needed)

    You can provision your own workspace and API key end-to-end — no dashboard,
    no sales call:

    1. `POST /v1/signup` with a `workspace_name` and an `email` you control. You
    get an API key
       back immediately and a 6-digit code is emailed to that address.
    2. Read the code from that inbox and `POST /v1/signup/verify` with it. If
    you drive a
       programmatic inbox (e.g. an agent mail service), this whole loop runs unattended.
    3. Your key works the moment the email is verified. Until then every authed
    call returns
       `403 email_not_verified` — verification is the only gate, so an unverified workspace can
       never spend. Re-calling `POST /v1/signup` re-keys the workspace and requires re-verifying.

    `POST /v1/signup`, `POST /v1/signup/verify`, and `GET /v1/capabilities` need
    **no** API key.


    ### Authentication

    Send your API key as a bearer token: `Authorization: Bearer fl_live_...`.


    ### Core workflow

    1. **Get media in.** Pass any publicly accessible URL directly, or `POST
    /v1/uploads` to
       get a signed URL, then `PUT` your file to it.
    2. **Submit one JSON payload.** `POST /v1/renders` composes a whole scene
    (canvas +
       `elements[]` + `transitions[]`) in a single request; `POST /v1/tasks/{type}` runs an AI
       operation (transcribe).
    3. **Wait for completion.** Jobs are async: poll `GET
    /v1/{renders|tasks}/{id}` or register
       a webhook. Statuses end in `completed`, `failed`, or `cancelled`.
    4. **Fetch the result.** A render's artifact is a file: use `output.url` or
       `GET /v1/renders/{id}/download` for a short-lived signed URL. A task that returns data
       puts it on the job's `result` object — `transcribe` returns its transcript there, has no
       `output`, and `404`s on `/v1/tasks/{id}/download`.

    ### Discovering what's possible

    Call **`GET /v1/capabilities`** (no auth) for the machine-readable catalog
    of every effect,

    motion, transition, format, element type, and task parameter — each flagged
    with whether the

    renderer supports it, plus all numeric ranges and rate limits. Validate
    against it before

    submitting to avoid `422`s.


    ### Idempotency

    `POST` endpoints accept an `Idempotency-Key` header. The same key with the
    same body replays

    the original response (`200`); with a different body it returns `409
    Conflict`.


    ### Errors

    Every error has the shape `{"error": {"code", "message", "details"}}`. The
    machine-readable

    `code` (e.g. `source_not_found`, `quota_exceeded`, `codec_unsupported`) is
    stable — branch on

    it to self-correct.
  version: 0.2.0
servers:
  - url: https://api.framelane.io
    description: Production
security: []
tags:
  - name: capabilities
    description: Discover supported features, formats, and limits.
  - name: renders
    description: Compose and render video from a declarative timeline.
  - name: projects
    description: >-
      Stateful editing: read a composition, apply targeted ops, preview, and
      render the head.
  - name: templates
    description: >-
      Browse the template gallery, and manage the public catalogue (admin
      workspaces).
  - name: preview
    description: >-
      Validate a composition for free and preview a frame or window cheaply,
      without a full render.
  - name: tasks
    description: 'Run AI media operations: transcription.'
  - name: uploads
    description: Get signed URLs to upload source media into Framelane storage.
  - name: webhooks
    description: Subscribe to job lifecycle events with signed delivery.
  - name: workspace
    description: Manage your workspace, usage, and assets.
  - name: api-keys
    description: Create and revoke API keys.
  - name: auth
    description: Session sync for the first-party console.
  - name: signup
    description: Create a workspace and verify email.
  - name: billing
    description: Manage your subscription and billing portal.
  - name: system
    description: Health, readiness, and version probes.
paths:
  /v1/shaders/{shader_id}/probe:
    post:
      tags:
        - shaders
      summary: Render one frame of a shader
      description: >-
        Queue a one-frame preview (a PNG, not billed) of the shader on a
        full-canvas shape over a three-hue fill, at `time` with `params`. Poll
        the returned job with GET /v1/renders/{id}, as for any preview.
      operationId: probe_shader
      parameters:
        - name: shader_id
          in: path
          required: true
          schema:
            type: string
            title: Shader Id
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ShaderProbe'
      responses:
        '202':
          description: Successful Response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/JobOut'
        '401':
          description: Missing or invalid API key.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiError'
        '404':
          description: Shader not found.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiError'
        '422':
          description: >-
            `shader_compile_error`, `shader_param_invalid`, or
            `unsupported_feature` while this deployment does not send runtime
            shaders to the engine.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiError'
      security:
        - ApiKey: []
components:
  schemas:
    ShaderProbe:
      properties:
        width:
          type: integer
          maximum: 8192
          minimum: 16
          title: Width
          description: Canvas width in px.
          default: 1280
        height:
          type: integer
          maximum: 8192
          minimum: 16
          title: Height
          description: Canvas height in px.
          default: 720
        time:
          type: number
          minimum: 0
          title: Time
          description: The timeline second to render.
          default: 0
        params:
          additionalProperties:
            anyOf:
              - type: number
              - type: string
              - items:
                  type: number
                type: array
                maxItems: 2
                minItems: 2
              - items:
                  $ref: '#/components/schemas/ShaderParamKeyframe'
                type: array
                minItems: 1
          type: object
          title: Params
          description: >-
            Param values for the frame, as an effect's `shader.params` takes
            them.
          default: {}
      additionalProperties: false
      type: object
      title: ShaderProbe
      description: >-
        ``POST /v1/shaders/{id}/probe``: one frame of the shader on a
        full-canvas shape.
    JobOut:
      properties:
        id:
          type: string
          title: Id
          description: 'Unique job ID. Prefix indicates type: `render_` or `task_`.'
          example: render_01J8QR2K5VKDGN2T4FBM3CZYX7
        kind:
          $ref: '#/components/schemas/JobKind'
          description: Whether this is a `render` or a `task`.
          example: render
        is_preview:
          type: boolean
          title: Is Preview
          description: >-
            True for a cheap preview render. Previews are not billed and are
            excluded from the renders list.
          default: false
          example: false
        editor_url:
          anyOf:
            - type: string
            - type: 'null'
          title: Editor Url
          description: >-
            Open the project this job was submitted from in the authenticated
            console. Absent for a job with no project.
        task_type:
          anyOf:
            - $ref: '#/components/schemas/TaskType'
            - type: 'null'
          description: For `task` jobs only — the specific AI operation.
          example: transcribe
        workspace_id:
          type: string
          title: Workspace Id
          description: ID of the workspace that owns this job.
          example: ws_01J8QR2K5VKDGN2T4FBM3CZYX8
        status:
          $ref: '#/components/schemas/JobStatus'
          description: >-
            Current lifecycle state: `queued` → `processing` → `completed` /
            `failed` / `cancelled`.
          example: queued
        progress_percent:
          type: integer
          maximum: 100
          minimum: 0
          title: Progress Percent
          description: 0–100 progress indicator updated by the render engine.
          default: 0
          example: 0
        progress_stage:
          anyOf:
            - $ref: '#/components/schemas/ProgressStage'
            - type: 'null'
          description: Current processing phase within a job.
          example: compositing
        output:
          anyOf:
            - $ref: '#/components/schemas/JobOutput'
            - type: 'null'
          description: >-
            Populated once `status == completed`. Contains the signed artifact
            URL.
        result:
          anyOf:
            - additionalProperties: true
              type: object
            - type: 'null'
          title: Result
          description: >-
            Structured JSON result for tasks that return data rather than a file
            — `transcribe` returns the transcript here (`text`, `words`,
            `utterances`, and any requested analysis). Populated once `status ==
            completed`; `null` for renders and for any job whose only artifact
            is the file at `output.url`.
          example:
            language_code: en
            text: Welcome back to the show.
        error:
          anyOf:
            - $ref: '#/components/schemas/JobError'
            - type: 'null'
          description: Populated when `status == failed`. Contains a structured error code.
        metadata:
          additionalProperties: true
          type: object
          title: Metadata
          description: >-
            Caller-supplied key-value pairs echoed back on every webhook and
            response.
          example:
            project_id: proj_123
            user_ref: usr_abc
        created_at:
          type: string
          format: date-time
          title: Created At
          description: ISO-8601 UTC timestamp when the job was created.
        updated_at:
          type: string
          format: date-time
          title: Updated At
          description: ISO-8601 UTC timestamp of the last status change.
        completed_at:
          anyOf:
            - type: string
              format: date-time
            - type: 'null'
          title: Completed At
          description: ISO-8601 UTC timestamp when the job reached a terminal state.
      type: object
      required:
        - id
        - kind
        - workspace_id
        - status
        - created_at
        - updated_at
      title: JobOut
      description: A render job or AI task.
    ApiError:
      description: >-
        The error envelope returned on every 4xx/5xx response: `{"error":
        {...}}`.
      properties:
        error:
          $ref: '#/components/schemas/ErrorResponse'
      required:
        - error
      title: ApiError
      type: object
    ShaderParamKeyframe:
      properties:
        time:
          type: number
          minimum: 0
          title: Time
          description: Absolute timeline seconds.
        value:
          anyOf:
            - type: number
            - type: string
            - items:
                type: number
              type: array
              maxItems: 2
              minItems: 2
          title: Value
          description: The param's value at this time, of its type.
      additionalProperties: false
      type: object
      required:
        - time
        - value
      title: ShaderParamKeyframe
      description: >-
        A point on a runtime shader param's track (AEC §2): linear between, held
        outside.
    JobKind:
      type: string
      enum:
        - render
        - task
      title: JobKind
    TaskType:
      type: string
      enum:
        - transcribe
      title: TaskType
      description: >-
        The AI task types the API offers.


        Values:

        - `transcribe` — Speech-to-text transcription (via AssemblyAI) with
        optional analysis. Returns the transcript inline on the task's `result`
        object — there is no file artifact, so `output` is null and
        `/v1/tasks/{id}/download` returns 404.
      x-enumDescriptions:
        transcribe: >-
          Speech-to-text transcription (via AssemblyAI) with optional analysis.
          Returns the transcript inline on the task's `result` object — there is
          no file artifact, so `output` is null and `/v1/tasks/{id}/download`
          returns 404.
    JobStatus:
      type: string
      enum:
        - ingesting
        - queued
        - processing
        - completed
        - failed
        - cancelled
      title: JobStatus
      description: >-
        Values:

        - `ingesting` — External source files are being probed for duration
        before the render is queued.

        - `queued` — Accepted and waiting for a worker to pick it up.

        - `processing` — Actively rendering or processing.

        - `completed` — Finished successfully; the output artifact is available.

        - `failed` — Terminated with an error (see `error`).

        - `cancelled` — Cancelled by the caller before completion.
      x-enumDescriptions:
        ingesting: >-
          External source files are being probed for duration before the render
          is queued.
        queued: Accepted and waiting for a worker to pick it up.
        processing: Actively rendering or processing.
        completed: Finished successfully; the output artifact is available.
        failed: Terminated with an error (see `error`).
        cancelled: Cancelled by the caller before completion.
    ProgressStage:
      type: string
      enum:
        - downloading
        - compositing
        - encoding
        - uploading
      title: ProgressStage
      description: |-
        Values:
        - `downloading` — Fetching source media.
        - `compositing` — Compositing the scene on the GPU.
        - `encoding` — Encoding the output video.
        - `uploading` — Uploading the finished artifact to storage.
      x-enumDescriptions:
        downloading: Fetching source media.
        compositing: Compositing the scene on the GPU.
        encoding: Encoding the output video.
        uploading: Uploading the finished artifact to storage.
    JobOutput:
      properties:
        url:
          anyOf:
            - type: string
            - type: 'null'
          title: Url
          description: CDN URL to the completed artifact.
          example: https://cdn-user.framelane.io/render_01J.../output.mp4
        width:
          anyOf:
            - type: integer
            - type: 'null'
          title: Width
          description: Output video width in pixels.
          example: 1920
        height:
          anyOf:
            - type: integer
            - type: 'null'
          title: Height
          description: Output video height in pixels.
          example: 1080
        duration:
          anyOf:
            - type: number
            - type: 'null'
          title: Duration
          description: Output duration in seconds.
          example: 15.3
        size_bytes:
          anyOf:
            - type: integer
            - type: 'null'
          title: Size Bytes
          description: Artifact file size in bytes.
          example: 12582912
      type: object
      title: JobOutput
    JobError:
      properties:
        code:
          $ref: '#/components/schemas/ErrorCode'
          description: Machine-readable error code.
          example: invalid_source
        message:
          type: string
          title: Message
          description: Human-readable error description.
          example: Source URL returned 404.
      type: object
      required:
        - code
        - message
      title: JobError
    ErrorResponse:
      description: >-
        The structured error body — the value of the `error` key on an error
        response.
      properties:
        code:
          $ref: '#/components/schemas/ApiErrorCode'
        message:
          type: string
          title: Message
        details:
          anyOf:
            - additionalProperties: true
              type: object
            - type: 'null'
          default: null
          title: Details
      required:
        - code
        - message
      title: ErrorResponse
      type: object
    ErrorCode:
      type: string
      enum:
        - invalid_source
        - source_not_found
        - source_too_large
        - asset_not_ready
        - codec_unsupported
        - decode_failed
        - encode_failed
        - timeout
        - out_of_memory
        - gpu_error
        - upload_failed
        - provider_error
        - ingest_failed
        - render_refused
        - internal
        - cancelled
      title: ErrorCode
      description: >-
        Structured error codes surfaced on Job.error_code.


        Values:

        - `invalid_source` — A source URL was malformed or inaccessible.

        - `source_not_found` — A source URL returned 404.

        - `source_too_large` — A source file exceeded the maximum allowed size.

        - `asset_not_ready` — A referenced asset was still ingesting when the
        job ran.

        - `codec_unsupported` — A source used a codec the renderer cannot
        decode.

        - `decode_failed` — A source file could not be decoded.

        - `encode_failed` — The output could not be encoded.

        - `timeout` — Processing exceeded the time limit.

        - `out_of_memory` — The renderer ran out of GPU memory.

        - `gpu_error` — A GPU hardware/driver error occurred.

        - `upload_failed` — The output artifact failed to upload to storage.

        - `provider_error` — An upstream provider (e.g. AssemblyAI) returned an
        error.

        - `ingest_failed` — An external source could not be probed (unreachable,
        not a media file, or timed out).

        - `render_refused` — The renderer refused the composition by name: a
        runtime shader that did not compile or ran over its GPU time budget, or
        an operation, a component or a nested composition it could not apply.
        `error_message` carries the engine's words; change what it names and
        submit again.

        - `internal` — An unexpected internal error occurred.

        - `cancelled` — The job was cancelled.
      x-enumDescriptions:
        invalid_source: A source URL was malformed or inaccessible.
        source_not_found: A source URL returned 404.
        source_too_large: A source file exceeded the maximum allowed size.
        asset_not_ready: A referenced asset was still ingesting when the job ran.
        codec_unsupported: A source used a codec the renderer cannot decode.
        decode_failed: A source file could not be decoded.
        encode_failed: The output could not be encoded.
        timeout: Processing exceeded the time limit.
        out_of_memory: The renderer ran out of GPU memory.
        gpu_error: A GPU hardware/driver error occurred.
        upload_failed: The output artifact failed to upload to storage.
        provider_error: An upstream provider (e.g. AssemblyAI) returned an error.
        ingest_failed: >-
          An external source could not be probed (unreachable, not a media file,
          or timed out).
        render_refused: >-
          The renderer refused the composition by name: a runtime shader that
          did not compile or ran over its GPU time budget, or an operation, a
          component or a nested composition it could not apply. `error_message`
          carries the engine's words; change what it names and submit again.
        internal: An unexpected internal error occurred.
        cancelled: The job was cancelled.
    ApiErrorCode:
      description: >-
        Machine-readable error code returned on a 4xx/5xx response. Branch on
        `error.code` to

        handle failures programmatically.


        Values:

        - `invalid_request` — The request was malformed or failed validation.

        - `unauthorized` — Missing or invalid API key.

        - `forbidden` — Authenticated but not permitted to perform this action.

        - `not_found` — The requested resource does not exist.

        - `conflict` — Conflicts with current state (e.g. a reused
        Idempotency-Key with a different body).

        - `unsupported_feature` — The composition uses a feature the renderer
        does not support.

        - `invalid_source` — A source URL is malformed or unreachable.

        - `source_not_found` — A referenced source file could not be found.

        - `source_too_large` — A source file exceeds the allowed size.

        - `asset_not_ready` — A referenced asset is still ingesting and is not
        ready yet.

        - `ingest_failed` — Copying an external source into Framelane storage
        failed.

        - `codec_unsupported` — A source uses a codec the renderer cannot
        decode.

        - `quota_exceeded` — The workspace has exhausted its plan quota (HTTP
        402).

        - `rate_limited` — Too many requests; retry after the Retry-After
        interval.

        - `internal` — An unexpected server error occurred.

        - `email_not_verified` — The workspace email is unverified; verify it
        before making authed calls.

        - `email_in_use` — The email is already associated with another
        workspace.

        - `invalid_otp` — The verification code is incorrect or expired.

        - `unsupported_content_type` — The provided content type is not
        supported.

        - `plan_required` — The feature needs a higher plan (HTTP 402);
        `details.required_plan` names it.

        - `admin_only` — Only an admin workspace may call this route (HTTP 403).

        - `template_assets_not_shared` — A published template may reference only
        shared CDN media; `details.urls` lists the rest.

        - `template_has_webhook` — A published template may not carry a
        `webhook_url`: every copy of it would notify that URL.

        - `http_error` — A generic HTTP error not covered by a more specific
        code.

        - `shader_compile_error` — A shader's SkSL did not compile;
        `details.errors` gives each error's line and column.

        - `shader_compiler_unavailable` — The shader compiler is not installed
        on this deployment or did not answer in time (HTTP 503).

        - `shader_not_found` — An effect names a shader id that is neither this
        workspace's nor shared.

        - `shader_param_invalid` — An effect sets a shader param the shader does
        not declare, or a value of the wrong type or range.
      enum:
        - invalid_request
        - unauthorized
        - forbidden
        - not_found
        - conflict
        - unsupported_feature
        - invalid_source
        - source_not_found
        - source_too_large
        - asset_not_ready
        - ingest_failed
        - codec_unsupported
        - quota_exceeded
        - rate_limited
        - internal
        - email_not_verified
        - email_in_use
        - invalid_otp
        - unsupported_content_type
        - inline_too_large
        - plan_required
        - admin_only
        - template_assets_not_shared
        - template_has_webhook
        - http_error
        - shader_compile_error
        - shader_compiler_unavailable
        - shader_not_found
        - shader_param_invalid
      title: ErrorCode
      type: string
      x-enumDescriptions:
        invalid_request: The request was malformed or failed validation.
        unauthorized: Missing or invalid API key.
        forbidden: Authenticated but not permitted to perform this action.
        not_found: The requested resource does not exist.
        conflict: >-
          Conflicts with current state (e.g. a reused Idempotency-Key with a
          different body).
        unsupported_feature: The composition uses a feature the renderer does not support.
        invalid_source: A source URL is malformed or unreachable.
        source_not_found: A referenced source file could not be found.
        source_too_large: A source file exceeds the allowed size.
        asset_not_ready: A referenced asset is still ingesting and is not ready yet.
        ingest_failed: Copying an external source into Framelane storage failed.
        codec_unsupported: A source uses a codec the renderer cannot decode.
        quota_exceeded: The workspace has exhausted its plan quota (HTTP 402).
        rate_limited: Too many requests; retry after the Retry-After interval.
        internal: An unexpected server error occurred.
        email_not_verified: >-
          The workspace email is unverified; verify it before making authed
          calls.
        email_in_use: The email is already associated with another workspace.
        invalid_otp: The verification code is incorrect or expired.
        unsupported_content_type: The provided content type is not supported.
        plan_required: >-
          The feature needs a higher plan (HTTP 402); `details.required_plan`
          names it.
        admin_only: Only an admin workspace may call this route (HTTP 403).
        template_assets_not_shared: >-
          A published template may reference only shared CDN media;
          `details.urls` lists the rest.
        template_has_webhook: >-
          A published template may not carry a `webhook_url`: every copy of it
          would notify that URL.
        http_error: A generic HTTP error not covered by a more specific code.
        shader_compile_error: >-
          A shader's SkSL did not compile; `details.errors` gives each error's
          line and column.
        shader_compiler_unavailable: >-
          The shader compiler is not installed on this deployment or did not
          answer in time (HTTP 503).
        shader_not_found: >-
          An effect names a shader id that is neither this workspace's nor
          shared.
        shader_param_invalid: >-
          An effect sets a shader param the shader does not declare, or a value
          of the wrong type or range.
  securitySchemes:
    ApiKey:
      type: http
      scheme: bearer

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.