Skip to main content

Endpoints

caution

The Weave API is available to customers on the Weave Enterprise plan only

The following sections list the endpoints that are available for the Weave API. All of the endpoints use the same base URL and are versioned under /v1.

Discovery endpoints​

GET tools​

Lists the tools available to the token's workspace. Use it to discover the tool_id values you pass to the other endpoints. Only published shared tools are listed — unpublished workflows and tools kept in a member's personal space are not.

HTTP endpoint​

GET https://developer.api.weavy.ai/v1/tools

Headers

X-Figma-Token: [WEAVE API TOKEN]

Example response body

{
"tools": [
{
"id": "wf_xyz",
"name": "Hero image generator"
},
{
"id": "wf_abc",
"name": "Product shot upscaler"
}
]
}

Response fields

FieldDescription
tools
Tool[]
The workspace's published tools, ordered by name. Empty when the workspace has no published tools.

Tool fields​

FieldDescription
id
String
The tool's ID. Pass it as :tool_id to GET inspect, POST runs, GET runs, and POST cancel runs.
name
String
The tool's name, as shown in the Weave editor.

GET inspect​

Describes a tool's inputs and outputs. Call this endpoint before building a POST runs request: it tells you which id values are inputs, what each input accepts, and what outputs to expect.

HTTP endpoint​

GET https://developer.api.weavy.ai/v1/tools/:tool_id/inspect

:tool_id is a required path parameter, the ID of the tool to inspect.

Query parameters

ParameterDescription
tool_version
Number
Optional. The published tool version to describe, as an integer of 1 or greater. Defaults to the latest published version. Pass the same version to POST runs, which defaults the same way, so a version published between the two calls isn't run instead.

GET https://developer.api.weavy.ai/v1/tools/:tool_id/inspect?tool_version=12

Headers

X-Figma-Token: [WEAVE API TOKEN]

Example response body

{
"tool_version": 12,
"inputs": [
{
"id": "b97a8c27-2dbe-4159-b5d5-33df6a329ea3",
"type": "string",
"name": "Prompt",
"default_value": { "type": "string", "value": "a red panda in space" }
},
{
"id": "3f2504e0-4f89-4d3a-9a0c-0305e82c3301",
"type": "integer",
"name": "Strength",
"number_range": { "min": 0, "max": 100 },
"default_value": { "type": "integer", "value": 60 }
},
{
"id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
"type": "seed",
"name": "Seed",
"default_value": { "type": "seed", "is_random": true }
},
{
"id": "1ff8a7b5-2c3d-4e6f-8a1b-9c0d2e3f4a5b",
"type": "selector",
"name": "Style",
"values": ["bold", "muted"],
"default_value": { "type": "selector", "value": "bold" }
},
{
"id": "6fa459ea-ee8a-4ca4-894e-db77e160355e",
"type": "iterator",
"name": "Colors",
"default_value": { "type": "iterator", "value": ["red", "green", "blue"] }
},
{
"id": "2d8e4f6a-9b1c-4d3e-8f5a-7c6b0e9d2a14",
"type": "media",
"name": "Reference image",
"default_value": null
}
],
"outputs": [
{
"id": "b3f9c2a1-7d4e-4f86-a0b5-2e8c91d4f7a6",
"name": "Hero image",
"output_type": "image",
"input_ids": [
"b97a8c27-2dbe-4159-b5d5-33df6a329ea3",
"3f2504e0-4f89-4d3a-9a0c-0305e82c3301",
"2d8e4f6a-9b1c-4d3e-8f5a-7c6b0e9d2a14"
]
}
]
}

Response fields

FieldDescription
tool_version
Number
The tool version this response describes: the version you asked for, or the latest published version when tool_version was omitted.
inputs
Input[]
The inputs you can supply on POST runs, in the order the tool author arranged them.
outputs
Output[]
One entry per output node in the tool.

Input fields​

FieldDescription
id
String
The input's ID. Pass this back as inputs[].id on POST runs.
type
String
The input type, such as string or selector. Each type determines the value fields you send for that input on POST runs; see input types.
name
String
The author-set label for the input. Omitted when the input has no name.
description
String
The author-provided description of the input. Omitted when the input has no description.
default_value
Object
The value this input was published with, or null when nothing usable is saved for it. It is the same shape you send as value on POST runs — the same type discriminator and fields, described in input types — so it can be passed straight back, or sent as use_default instead. Reflects the version named by tool_version.
values
String[]
The allowed options to choose from. Present for selector inputs.
number_range
Object
Advisory min and max bounds for integer inputs: { "min": number, "max": number }. Either bound can be omitted.

Output fields​

FieldDescription
id
String
The output node's ID. Matches outputs[].id on the run status response.
name
String
The author-set output name. Defaults to "default" if unset. Matches outputs[].name on the run status response.
output_type
String
The inferred media type: image, video, text, or any when the type can't be statically inferred. Not authoritative. The actual output's assets[].type is.
input_ids
String[]
IDs of the inputs entries that flow into this output.

Runs endpoints​

The following endpoints are used to start, monitor, cancel, and price runs of a tool.

POST runs​

Starts one or more runs of a tool. Execution is asynchronous: the endpoint returns 202 Accepted with the created runs, and you poll GET runs for progress and results.

HTTP endpoint​

POST https://developer.api.weavy.ai/v1/tools/:tool_id/runs

:tool_id is a required path parameter, the ID of the tool to run.

Headers

X-Figma-Token: [WEAVE API TOKEN]
Content-Type: application/json

Parameters

Body parameterDescription
tool_version
Number
The tool version to run. If omitted, the latest published version is used.
count
Number
The number of runs to start, between 1 and 10. Defaults to 1. Useful for generating variations of the same inputs.
inputs
Object[]
Required. The input values for the run. Every input from the GET inspect response must appear exactly once. Each entry is an object with an id and then either a value object or use_default. The value object carries a type discriminator plus the fields for that type; see input types. See using published defaults for use_default.
webhook
Object
An object with a url (an HTTPS URL). When set, Weave sends a POST to it as each run reaches a terminal state, so you can receive results instead of polling. See webhooks.

Using published defaults​

Each entry in inputs sets its input in one of two ways:

FieldDescription
id
String
Required. The ID of the input to set, from the GET inspect response.
value
Object
The value to run with. See input types.
use_default
Boolean
Set to true to run this input with the value the tool was published with, instead of supplying one. Mutually exclusive with value.

Supply exactly one of value or use_default per entry. Sending both is a 400, and so is omitting both, since every tool input must be given a value.

The default used is the default_value reported by GET inspect for the version you are running, so inspect that version to see what a defaulted input will run with. An input whose default_value is null has nothing saved to fall back to: use_default on it returns 400, and you have to send an explicit value.

The snippet below shows the two forms side by side and omits the tool's other inputs for brevity; a real request has to carry every one of them.

{
"inputs": [
{
"id": "b97a8c27-2dbe-4159-b5d5-33df6a329ea3",
"value": { "type": "string", "value": "a red panda in space" }
},
{
"id": "3f2504e0-4f89-4d3a-9a0c-0305e82c3301",
"use_default": true
}
]
}

Input types​

Every value object carries a type field that matches the input's type from GET inspect, along with the fields listed below.

Input typeValue fields
stringvalue (string)
integervalue (number)
booleanvalue (boolean)
seedis_random, value (number, used when is_random is not true)
mediavalue (asset URL or data URI) or asset_id, kind (image, video, audio, or 3d)
selectorvalue (string or number, one of the node values)
iteratorvalue (string array, max 100), run_mode
media_iteratorvalue (array of { "url" or "asset_id", "kind" }, max 100), run_mode
arrayvalue (string array)

A media input takes the file either as value — a URL the API can fetch, or a base64 data URI — or as asset_id, the handle for a file you uploaded through the assets endpoints. Provide exactly one of value or asset_id. Sending both or neither results in a 400. Entries of a media_iterator value take url or asset_id the same way.

kind is one of image, video, audio, or 3d, and is optional in both cases, but it resolves differently. With value, it is inferred from the URL's extension, and a URL it cannot be inferred from is a 400 — so pass kind explicitly for URLs without one. With asset_id, it comes from the content_type declared when the file was uploaded, so it never needs to be sent. An explicit kind always wins.

For iterator and media_iterator inputs, value is the list to iterate over and the run fans out per entry. run_mode is either "parallel" or "matrix", but it is not yet honored: the iterator mode is fixed by the tool. See the examples for how iterators shape the run's outputs.

Example request body

{
"tool_version": 12,
"count": 3,
"inputs": [
{
"id": "b97a8c27-2dbe-4159-b5d5-33df6a329ea3",
"value": { "type": "string", "value": "a red panda in space" }
},
{
"id": "3f2504e0-4f89-4d3a-9a0c-0305e82c3301",
"use_default": true
},
{
"id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
"value": { "type": "seed", "is_random": true }
},
{
"id": "1ff8a7b5-2c3d-4e6f-8a1b-9c0d2e3f4a5b",
"value": { "type": "selector", "value": "bold" }
},
{
"id": "6fa459ea-ee8a-4ca4-894e-db77e160355e",
"value": { "type": "iterator", "value": ["red", "green", "blue"] }
},
{
"id": "2d8e4f6a-9b1c-4d3e-8f5a-7c6b0e9d2a14",
"value": { "type": "media", "value": "https://example.com/panda.png", "kind": "image" }
}
],
"webhook": { "url": "https://example.com/weave-callback" }
}

Example response body

202 Accepted

{
"runs": [
{
"id": "run_abc123",
"tool_id": "wf_xyz",
"status": "running"
},
{
"id": "run_abc124",
"tool_id": "wf_xyz",
"status": "running"
}
]
}

This request sets all six inputs the GET inspect example reports: five explicitly, and Strength with use_default, which runs it at the value the tool was published with.

The response is always { "runs": [...] }, even when count is 1. Each run starts asynchronously, so status is always running here. Poll GET runs for progress and results.

GET runs​

Returns the status of one or more runs, including their outputs once a run completes.

Any API token in a workspace can retrieve runs started with an API token in that workspace. Runs started by users in the Weave app are not visible to the Weave API.

HTTP endpoint​

GET https://developer.api.weavy.ai/v1/tools/:tool_id/runs?run_ids=a,b

run_ids is a required, comma-separated list of run IDs as returned by POST runs.

Headers

X-Figma-Token: [WEAVE API TOKEN]

Example response body

{
"runs": [
{
"id": "run_abc123",
"tool_id": "wf_xyz",
"status": "completed",
"created_at": "2026-05-06T10:00:00Z",
"completed_at": "2026-05-06T10:00:42Z",
"outputs": [
{
"id": "b3f9c2a1-7d4e-4f86-a0b5-2e8c91d4f7a6",
"name": "Hero image",
"assets": [
{ "type": "image", "url": "https://cdn.figma.com/..." }
]
},
{
"id": "4a7d1e93-6c82-4f15-b0a9-3e5d8c2b7f60",
"name": "Caption",
"assets": [
{ "type": "text", "text": "A red panda floating in space." }
]
}
]
}
],
"workspace_credits_remaining": 850
}

Response fields

FieldDescription
runs
Object[]
One entry per requested run. See the run fields below.
workspace_credits_remaining
Number
The workspace's remaining credit balance.

Run fields​

FieldDescription
id
String
The run ID.
tool_id
String
The ID of the tool that produced the run.
status
String
One of running, completed, failed, or canceled.
progress_percentage
Number
Progress of the run from 0 to 100. Omitted for terminal statuses.
created_at
String
When the run was created.
completed_at
String
When the run completed or failed. Only present once the run reaches completed or failed.
canceled_at
String
When the run was canceled. Only present once the run reaches canceled.
outputs
Object[]
The run's outputs. See the output fields below. Empty if no outputs were produced.
error
Object
A run-level error: { "message": string }. Present when the run's status is failed.

Output fields​

Each entry in outputs represents one output node of the tool. When no iterator is involved, there is one entry per output node. When an iterator is involved, there is one entry per output node per iteration. See the examples for iterator output shapes.

FieldDescription
id
String
The output node's ID. Matches outputs[].id from the GET inspect response.
name
String
The output node's name. Defaults to "default" if unset.
iteration_index
Number
The iterator fan-out index for this output branch. For a tool with a single iterator it is the position of the value in the list you sent, so 0 is the first value. Absent for non-iterator runs. For a tool with more than one iterator it identifies the branch but is not a positional index — match outputs by grouping on it rather than decoding it.
assets
Object[]
The generated assets. Each asset has a type of image, video, audio, 3d, text, or unknown. Media assets (image, video, audio, 3d) carry a url. text assets carry a text value. unknown assets may carry either.

Webhooks​

Instead of polling GET runs, you can supply webhook.url on POST runs to be notified when a run finishes. Weave sends one POST to that URL for each run as it reaches a terminal state (completed or failed). The url must be HTTPS. Delivery is best-effort — retried a few times on failure, with redirects not followed — so treat it as a prompt to fetch results, not a guaranteed, exactly-once signal.

The callback is not signed, so a receiver cannot distinguish it from a forged request. Treat its body as untrusted: use it as a signal to call GET runs with the run IDs you started, and take the results from that response.

Request​

The callback is a JSON POST. Weave sets the following headers:

Content-Type: application/json
X-Weavy-Delivery-Id: [UNIQUE DELIVERY ID]
X-Weavy-Timestamp: [ISO 8601 TIMESTAMP]

Example request body

{
"event": "run.completed",
"delivery_id": "whd_abc123",
"run": {
"id": "run_abc123",
"tool_id": "wf_xyz",
"status": "completed",
"created_at": "2026-05-06T10:00:00Z",
"completed_at": "2026-05-06T10:00:42Z",
"outputs": [
{
"id": "b3f9c2a1-7d4e-4f86-a0b5-2e8c91d4f7a6",
"name": "Hero image",
"assets": [
{ "type": "image", "url": "https://cdn.figma.com/..." }
]
}
]
}
}

Body fields

FieldDescription
event
String
run.completed or run.failed.
delivery_id
String
A unique ID for this delivery, also sent in the X-Weavy-Delivery-Id header.
run
Object
The run that reached a terminal state, in the same shape as a GET runs entry. See the run fields.

POST cancel runs​

Cancels one or more runs. run_ids is a comma-separated list, mirroring GET runs.

HTTP endpoint​

POST https://developer.api.weavy.ai/v1/tools/:tool_id/runs/cancel?run_ids=a,b

Headers

X-Figma-Token: [WEAVE API TOKEN]

Example response body

The response uses the same shape as GET runs: each requested run is returned with its current status.

{
"runs": [
{
"id": "run_abc123",
"tool_id": "wf_xyz",
"status": "canceled",
"created_at": "2026-05-06T10:00:00Z",
"canceled_at": "2026-05-06T10:00:05Z"
},
{
"id": "run_abc124",
"tool_id": "wf_xyz",
"status": "completed",
"created_at": "2026-05-06T10:00:00Z",
"completed_at": "2026-05-06T10:00:42Z",
"outputs": [
{
"id": "b3f9c2a1-7d4e-4f86-a0b5-2e8c91d4f7a6",
"name": "Hero image",
"assets": [
{ "type": "image", "url": "https://cdn.figma.com/..." }
]
}
]
}
],
"workspace_credits_remaining": 820
}

A run that has already reached a terminal status can't be canceled. It is returned with its existing status rather than canceled.

POST cost​

Returns the estimated credit cost of running a tool, without starting anything. It takes the same body as POST runs, so you can price the exact request you're about to send. No run is created and no credits are spent.

HTTP endpoint​

POST https://developer.api.weavy.ai/v1/tools/:tool_id/cost

:tool_id is a required path parameter, the ID of the tool to price.

Headers

X-Figma-Token: [WEAVE API TOKEN]
Content-Type: application/json

Parameters

Body parameterDescription
tool_version
Number
The tool version to price. If omitted, the latest published version is used.
inputs
Object[]
Required. The input values to price, in the same form POST runs takes them: every input from the GET inspect response must appear exactly once, with either a value object or use_default. See input types and using published defaults.

The cost endpoint shares the same input validation rules as the POST runs endpoint. As a result, unrunnable requests cannot be priced: the API returns a 400 Bad Request.

Example request body

{
"tool_version": 3,
"inputs": [
{
"id": "b97a8c27-2dbe-4159-b5d5-33df6a329ea3",
"value": { "type": "string", "value": "a red panda in space" }
},
{
"id": "3f2504e0-4f89-4d3a-9a0c-0305e82c3301",
"use_default": true
}
]
}

Example response body

200 OK

{
"estimated_credit_cost": 12
}

Response fields

FieldDescription
estimated_credit_cost
Number
The estimated credit cost of a single run with these inputs. null when the cost depends on values only known at run time — an iterator whose item count this request does not pin, or a priced model parameter fed by an upstream node whose output is not yet known.

A null cost is not an error: the request is priceable only once the run is underway. Treat it as "unknown before the run", not as "free".

Assets endpoints​

A media input can take a file you upload to Weave instead of a URL the API fetches. Uploading is a three-step flow:

  1. POST uploads to declare the file and get a single-use write URL.
  2. PUT the file to that URL.
  3. POST commit to make the asset usable.

The asset_id from step 1 is only accepted as a run input once step 3 succeeds.

POST uploads​

Declares a file and returns the URL to write it to. The upload URL is signed for the exact file_size and content_type you declare here, so both must match the file you send.

HTTP endpoint​

POST https://developer.api.weavy.ai/v1/assets/uploads

Headers

X-Figma-Token: [WEAVE API TOKEN]
Content-Type: application/json

Example request body

{
"file_name": "panda.png",
"file_size": 182734,
"content_type": "image/png"
}

Request fields

FieldDescription
file_name
String
Required. The original file name, up to 255 characters. Stored for reference only — it does not affect how the file is processed.
file_size
Number
Required. The exact size of the file in bytes, from 1 to 524288000 (500 MiB).
content_type
String
Required. The media type of the file, one of the accepted content types.

Example response body

{
"asset_id": "9c85f3a1-2d47-4b6e-8f10-5a3c7d9e1b24",
"upload_url": "https://storage.figma.com/weave-uploads/...",
"content_type": "image/png",
"expires_at": "2026-05-06T22:00:00Z"
}

Response fields

FieldDescription
asset_id
String
The handle for the asset. Pass it as asset_id on a media input once the upload is committed.
upload_url
String
The single-use URL to PUT the file to. See uploading the file.
content_type
String
The content type the upload URL is signed for. Send exactly this value as the Content-Type header on the PUT.
expires_at
String
The time after which upload_url stops working, 12 hours after it is issued. Start a new upload if it expires.

Uploading the file​

PUT the file body to upload_url. The URL is signed, so it carries its own authorization — do not send your X-Figma-Token with it.

Headers

Both of these headers are required on the PUT. The upload is rejected if either is missing or does not match.

Content-Type: [CONTENT TYPE FROM THE INITIATE RESPONSE]
If-None-Match: *
HeaderDescription
Content-Type
String
Required. Exactly the content_type returned by POST uploads. The URL is signed for this value, so a different or missing type fails the upload.
If-None-Match
String
Required, and always the literal *. It makes the write fail rather than overwrite if something is already stored at the destination.

Example request

curl -X PUT "$UPLOAD_URL" \
-H "Content-Type: image/png" \
-H "If-None-Match: *" \
--data-binary @panda.png

The body must also be exactly file_size bytes, and the URL works only once — a second PUT to the same URL fails.

Accepted content types​

content_type is the media type you send, not the file's extension. Each accepted type below lists the file format it corresponds to, so an MP3 is uploaded as audio/mpeg, a QuickTime movie as video/quicktime, and a glTF binary as model/gltf-binary. A file whose format is not listed cannot be uploaded — pass it to a media input as a URL instead.

Content typeFile formatExtensionInput kind
image/pngPNG.pngimage
image/jpegJPEG.jpg, .jpegimage
image/webpWebP.webpimage
video/mp4MPEG-4.mp4video
video/quicktimeQuickTime.movvideo
video/webmWebM.webmvideo
audio/mpegMP3.mp3audio
audio/wavWAV.wavaudio
model/gltf-binaryglTF binary.glb3d
model/objWavefront OBJ.obj3d
model/fbxFBX.fbx3d
model/plyPLY.ply3d

image/jpg is accepted as an alias for image/jpeg. The Input kind column is the kind the file resolves to on a media input, which is why kind never has to be sent alongside an asset_id. Note that .m4v is not accepted, even though it is an MPEG-4 container — upload it as .mp4.

POST commit​

Finishes an upload and makes the asset usable as a media input. Call it once the PUT to upload_url has succeeded. It verifies that what landed matches what was declared, then marks the asset committed.

HTTP endpoint​

POST https://developer.api.weavy.ai/v1/assets/uploads/:asset_id/commit

:asset_id is a required path parameter, the asset_id returned by POST uploads.

Headers

X-Figma-Token: [WEAVE API TOKEN]

There is no request body.

Example response body

{
"asset_id": "9c85f3a1-2d47-4b6e-8f10-5a3c7d9e1b24",
"status": "committed"
}

Response fields

FieldDescription
asset_id
String
The handle for the asset. Pass it as asset_id on a media input of POST runs.
status
String
The lifecycle state of the asset. Always committed on success.

The call is idempotent: committing an already-committed asset returns the same response. It returns 409 if the file has not been uploaded yet — retry once the PUT succeeds — or if the asset was rejected because what landed did not match what was declared, in which case start a new upload.

Using the asset on a run

Only the media input is shown; a real request also sets the tool's other inputs.

{
"inputs": [
{
"id": "2d8e4f6a-9b1c-4d3e-8f5a-7c6b0e9d2a14",
"value": { "type": "media", "asset_id": "9c85f3a1-2d47-4b6e-8f10-5a3c7d9e1b24", "kind": "image" }
}
]
}

Errors​

When a request can't be completed, the Weave API returns an HTTP error status with a JSON body describing the problem. This response covers the request itself, such as an invalid token or a tool that can't be found. It is separate from the run-level error field in the GET runs response, which reports a run that started and then failed.

Status codes​

Error codesDescription
400The request body or query parameters failed validation. GET tools does not return this status, as it takes no body or query parameters. On POST commit it means :asset_id is not a valid UUID.
401The X-Figma-Token header is missing or the token is invalid.
404No tool with the given ID is accessible to the token, or the workflow is not configured as a tool. On POST commit it means no asset with the given ID belongs to the token's workspace. GET tools and POST uploads do not return this status, as they take no ID.
409The asset can't be committed yet: the file has not been uploaded, or the upload was rejected because what landed did not match what was declared. Only POST commit returns this status.
429The token has exceeded its rate limit for this endpoint. Retry after the number of seconds in the Retry-After header.
500An unexpected error occurred on the server.

Error response body​

Example response body

400 Bad Request

{
"statusCode": 400,
"internalErrorCode": 4001,
"message": "The request body failed validation.",
"fieldsErrors": [
"inputs.0.value.value must be a string"
],
"timestamp": "2026-05-06T10:00:00Z",
"correlationId": "req_8f2c1a"
}

Response fields

FieldDescription
statusCode
Number
The HTTP status code, mirroring the response status.
internalErrorCode
Number
A numeric internal code identifying the specific failure.
message
String
A human-readable description of the error.
fieldsErrors
String[]
Field-level validation messages. Empty for errors that aren't validation failures.
timestamp
String
When the error was produced.
correlationId
String
The request correlation ID, when available. Include it when reporting an issue.