# Estimate inference price

POST

/v2/workspaces/{workspace\_id}/inferences/estimate

```bash
curl --request POST \
  --url https://api.app.layer.ai/api/v2/workspaces/:workspace_id/inferences/estimate \
  --header 'Authorization: Bearer <token>' \
  --header 'Content-Type: application/json' \
  --data '{
  "base_model_id": "<string>",
  "reference_sets": [],
  "modality": "text",
  "prompt": "<string>",
  "width": 0,
  "height": 0,
  "batch_size": 4,
  "num_inference_steps": 0,
  "guidance_scale": 0,
  "prompt_strength": 0,
  "quality": "low",
  "sharpness": 0,
  "duration_seconds": 0,
  "generate_audio": true,
  "keep_audio": true,
  "fps": 0,
  "video_effects": [],
  "use_ta_pose": true,
  "pose_mode": "A_POSE",
  "include_textures": true,
  "quad_mesh": true,
  "pbr_materials": true,
  "low_poly": true,
  "generate_parts": true,
  "face_limit": 0,
  "stability": 0,
  "use_speaker_boost": true,
  "similarity_boost": 0,
  "style_exaggeration": 0,
  "speed": 0,
  "upscale_ratio": 0,
  "creativity": 0,
  "resemblance": 0,
  "vectorize": true,
  "remove_background": true,
  "reframe": true,
  "refill": true,
  "guidance_files": []
}'
```

```python
import requests


url = "https://api.app.layer.ai/api/v2/workspaces/:workspace_id/inferences/estimate"


payload = {
    "base_model_id": "<string>",
    "reference_sets": [],
    "modality": "text",
    "prompt": "<string>",
    "width": 0,
    "height": 0,
    "batch_size": 4,
    "num_inference_steps": 0,
    "guidance_scale": 0,
    "prompt_strength": 0,
    "quality": "low",
    "sharpness": 0,
    "duration_seconds": 0,
    "generate_audio": True,
    "keep_audio": True,
    "fps": 0,
    "video_effects": [],
    "use_ta_pose": True,
    "pose_mode": "A_POSE",
    "include_textures": True,
    "quad_mesh": True,
    "pbr_materials": True,
    "low_poly": True,
    "generate_parts": True,
    "face_limit": 0,
    "stability": 0,
    "use_speaker_boost": True,
    "similarity_boost": 0,
    "style_exaggeration": 0,
    "speed": 0,
    "upscale_ratio": 0,
    "creativity": 0,
    "resemblance": 0,
    "vectorize": True,
    "remove_background": True,
    "reframe": True,
    "refill": True,
    "guidance_files": []
}
headers = {
    "Authorization": "Bearer <token>",
    "Content-Type": "application/json"
}


response = requests.post(url, json=payload, headers=headers)


print(response.json())
```

```js
const url = 'https://api.app.layer.ai/api/v2/workspaces/:workspace_id/inferences/estimate';
const options = {
  method: 'POST',
  headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
  body: '{"base_model_id":"<string>","reference_sets":[],"modality":"text","prompt":"<string>","width":0,"height":0,"batch_size":4,"num_inference_steps":0,"guidance_scale":0,"prompt_strength":0,"quality":"low","sharpness":0,"duration_seconds":0,"generate_audio":true,"keep_audio":true,"fps":0,"video_effects":[],"use_ta_pose":true,"pose_mode":"A_POSE","include_textures":true,"quad_mesh":true,"pbr_materials":true,"low_poly":true,"generate_parts":true,"face_limit":0,"stability":0,"use_speaker_boost":true,"similarity_boost":0,"style_exaggeration":0,"speed":0,"upscale_ratio":0,"creativity":0,"resemblance":0,"vectorize":true,"remove_background":true,"reframe":true,"refill":true,"guidance_files":[]}'
};


try {
  const response = await fetch(url, options);
  const data = await response.json();
  console.log(data);
} catch (error) {
  console.error(error);
}
```

```go
package main


import (
  "fmt"
  "strings"
  "net/http"
  "io"
)


func main() {


  url := "https://api.app.layer.ai/api/v2/workspaces/:workspace_id/inferences/estimate"


  payload := strings.NewReader("{\n  \"base_model_id\": \"<string>\",\n  \"reference_sets\": [],\n  \"modality\": \"text\",\n  \"prompt\": \"<string>\",\n  \"width\": 0,\n  \"height\": 0,\n  \"batch_size\": 4,\n  \"num_inference_steps\": 0,\n  \"guidance_scale\": 0,\n  \"prompt_strength\": 0,\n  \"quality\": \"low\",\n  \"sharpness\": 0,\n  \"duration_seconds\": 0,\n  \"generate_audio\": true,\n  \"keep_audio\": true,\n  \"fps\": 0,\n  \"video_effects\": [],\n  \"use_ta_pose\": true,\n  \"pose_mode\": \"A_POSE\",\n  \"include_textures\": true,\n  \"quad_mesh\": true,\n  \"pbr_materials\": true,\n  \"low_poly\": true,\n  \"generate_parts\": true,\n  \"face_limit\": 0,\n  \"stability\": 0,\n  \"use_speaker_boost\": true,\n  \"similarity_boost\": 0,\n  \"style_exaggeration\": 0,\n  \"speed\": 0,\n  \"upscale_ratio\": 0,\n  \"creativity\": 0,\n  \"resemblance\": 0,\n  \"vectorize\": true,\n  \"remove_background\": true,\n  \"reframe\": true,\n  \"refill\": true,\n  \"guidance_files\": []\n}")


  req, _ := http.NewRequest("POST", url, payload)


  req.Header.Add("Authorization", "Bearer <token>")
  req.Header.Add("Content-Type", "application/json")


  res, _ := http.DefaultClient.Do(req)


  defer res.Body.Close()
  body, _ := io.ReadAll(res.Body)


  fmt.Println(res)
  fmt.Println(string(body))


}
```

```php
<?php


$curl = curl_init();


curl_setopt_array($curl, [
  CURLOPT_URL => "https://api.app.layer.ai/api/v2/workspaces/:workspace_id/inferences/estimate",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "POST",
  CURLOPT_POSTFIELDS => json_encode([
    'base_model_id' => '<string>',
    'reference_sets' => [


    ],
    'modality' => 'text',
    'prompt' => '<string>',
    'width' => 0,
    'height' => 0,
    'batch_size' => 4,
    'num_inference_steps' => 0,
    'guidance_scale' => 0,
    'prompt_strength' => 0,
    'quality' => 'low',
    'sharpness' => 0,
    'duration_seconds' => 0,
    'generate_audio' => null,
    'keep_audio' => null,
    'fps' => 0,
    'video_effects' => [


    ],
    'use_ta_pose' => null,
    'pose_mode' => 'A_POSE',
    'include_textures' => null,
    'quad_mesh' => null,
    'pbr_materials' => null,
    'low_poly' => null,
    'generate_parts' => null,
    'face_limit' => 0,
    'stability' => 0,
    'use_speaker_boost' => null,
    'similarity_boost' => 0,
    'style_exaggeration' => 0,
    'speed' => 0,
    'upscale_ratio' => 0,
    'creativity' => 0,
    'resemblance' => 0,
    'vectorize' => null,
    'remove_background' => null,
    'reframe' => null,
    'refill' => null,
    'guidance_files' => [


    ]
  ]),
  CURLOPT_HTTPHEADER => [
    "Authorization: Bearer <token>",
    "Content-Type: application/json"
  ],
]);


$response = curl_exec($curl);
$err = curl_error($curl);


curl_close($curl);


if ($err) {
  echo "cURL Error #:" . $err;
} else {
  echo $response;
}
```

```java
OkHttpClient client = new OkHttpClient();


MediaType mediaType = MediaType.parse("application/json");
RequestBody body = RequestBody.create(mediaType, "{\n  \"base_model_id\": \"<string>\",\n  \"reference_sets\": [],\n  \"modality\": \"text\",\n  \"prompt\": \"<string>\",\n  \"width\": 0,\n  \"height\": 0,\n  \"batch_size\": 4,\n  \"num_inference_steps\": 0,\n  \"guidance_scale\": 0,\n  \"prompt_strength\": 0,\n  \"quality\": \"low\",\n  \"sharpness\": 0,\n  \"duration_seconds\": 0,\n  \"generate_audio\": true,\n  \"keep_audio\": true,\n  \"fps\": 0,\n  \"video_effects\": [],\n  \"use_ta_pose\": true,\n  \"pose_mode\": \"A_POSE\",\n  \"include_textures\": true,\n  \"quad_mesh\": true,\n  \"pbr_materials\": true,\n  \"low_poly\": true,\n  \"generate_parts\": true,\n  \"face_limit\": 0,\n  \"stability\": 0,\n  \"use_speaker_boost\": true,\n  \"similarity_boost\": 0,\n  \"style_exaggeration\": 0,\n  \"speed\": 0,\n  \"upscale_ratio\": 0,\n  \"creativity\": 0,\n  \"resemblance\": 0,\n  \"vectorize\": true,\n  \"remove_background\": true,\n  \"reframe\": true,\n  \"refill\": true,\n  \"guidance_files\": []\n}");
Request request = new Request.Builder()
  .url("https://api.app.layer.ai/api/v2/workspaces/:workspace_id/inferences/estimate")
  .post(body)
  .addHeader("Authorization", "Bearer <token>")
  .addHeader("Content-Type", "application/json")
  .build();


Response response = client.newCall(request).execute();
```

```ruby
require 'uri'
require 'net/http'


url = URI("https://api.app.layer.ai/api/v2/workspaces/:workspace_id/inferences/estimate")


http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true


request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n  \"base_model_id\": \"<string>\",\n  \"reference_sets\": [],\n  \"modality\": \"text\",\n  \"prompt\": \"<string>\",\n  \"width\": 0,\n  \"height\": 0,\n  \"batch_size\": 4,\n  \"num_inference_steps\": 0,\n  \"guidance_scale\": 0,\n  \"prompt_strength\": 0,\n  \"quality\": \"low\",\n  \"sharpness\": 0,\n  \"duration_seconds\": 0,\n  \"generate_audio\": true,\n  \"keep_audio\": true,\n  \"fps\": 0,\n  \"video_effects\": [],\n  \"use_ta_pose\": true,\n  \"pose_mode\": \"A_POSE\",\n  \"include_textures\": true,\n  \"quad_mesh\": true,\n  \"pbr_materials\": true,\n  \"low_poly\": true,\n  \"generate_parts\": true,\n  \"face_limit\": 0,\n  \"stability\": 0,\n  \"use_speaker_boost\": true,\n  \"similarity_boost\": 0,\n  \"style_exaggeration\": 0,\n  \"speed\": 0,\n  \"upscale_ratio\": 0,\n  \"creativity\": 0,\n  \"resemblance\": 0,\n  \"vectorize\": true,\n  \"remove_background\": true,\n  \"reframe\": true,\n  \"refill\": true,\n  \"guidance_files\": []\n}"


response = http.request(request)
puts response.read_body
```

```csharp
var client = new RestClient("https://api.app.layer.ai/api/v2/workspaces/:workspace_id/inferences/estimate");
var request = new RestRequest("", Method.Post);
request.AddHeader("Authorization", "Bearer <token>");
request.AddHeader("Content-Type", "application/json");
request.AddParameter("application/json", "{\n  \"base_model_id\": \"<string>\",\n  \"reference_sets\": [],\n  \"modality\": \"text\",\n  \"prompt\": \"<string>\",\n  \"width\": 0,\n  \"height\": 0,\n  \"batch_size\": 4,\n  \"num_inference_steps\": 0,\n  \"guidance_scale\": 0,\n  \"prompt_strength\": 0,\n  \"quality\": \"low\",\n  \"sharpness\": 0,\n  \"duration_seconds\": 0,\n  \"generate_audio\": true,\n  \"keep_audio\": true,\n  \"fps\": 0,\n  \"video_effects\": [],\n  \"use_ta_pose\": true,\n  \"pose_mode\": \"A_POSE\",\n  \"include_textures\": true,\n  \"quad_mesh\": true,\n  \"pbr_materials\": true,\n  \"low_poly\": true,\n  \"generate_parts\": true,\n  \"face_limit\": 0,\n  \"stability\": 0,\n  \"use_speaker_boost\": true,\n  \"similarity_boost\": 0,\n  \"style_exaggeration\": 0,\n  \"speed\": 0,\n  \"upscale_ratio\": 0,\n  \"creativity\": 0,\n  \"resemblance\": 0,\n  \"vectorize\": true,\n  \"remove_background\": true,\n  \"reframe\": true,\n  \"refill\": true,\n  \"guidance_files\": []\n}", ParameterType.RequestBody);
var response = client.Execute(request);
```

* Production

> **Changed in v2.** This endpoint’s contract differs from v1\. See the [v2 migration guide](/docs/migration) for the request and response changes before you switch.

Estimate the Creative Units cost of an inference with given parameters. Prices through the same reference-set translation and model selection as the execute endpoint, so the price matches what execution charges for identical inputs.

Reference-set errors: `REFERENCE_SET_NOT_FOUND` (404 — unknown, deleted, or outside this workspace’s reach), `NO_COMPATIBLE_MODEL` (422 — no enabled base model can apply these sets), `REFERENCE_SET_REQUIRED` (422 — the chosen model needs an applicable set), `REFERENCE_SET_CONFLICT` (422 — two sets supply the same singular adapter), and `INPUT_FILE_REQUIRED` (422 — the sets select an edit-only model with no asset to edit).

## Authorizations

* **[bearerAuth](/docs/v2/rest-api#bearerauth)**

## Parameters

### Path Parameters

**workspace\_id**

required

_Workspace Id_

Id of the workspace that owns the resource.

string format: uuid

Id of the workspace that owns the resource.

## Request Bodyrequired

_EstimateInferencePriceV2Request_

REST request body for estimating inference price. workspace\_id comes from path.

object

**base\_model\_id**

Any of:

**string**

string

**null**

null

**reference\_sets**

_Reference Sets_

Reference sets to apply, up to 10.

Array<object>

default: <= 10 items

_InferenceReferenceSetInput_object

**set\_id**

required

_Set Id_

Reference set ID from GET /v2/workspaces/{workspace\_id}/reference-sets.

string format: uuid

**weight**

_Weight_

Weight for the set’s LoRA adapter when one applies. Ignored for sets applied as reference images or prompt text.

number

default: 1 <= 2

**modality**

Any of:

**Modality**

_Modality_

string

Allowed values: text image audio video three\_d playable

**null**

null

**prompt**

Any of:

**string**

string

<= 100000 characters

**null**

null

**width**

Any of:

**integer**

integer

\> 0

**null**

null

**height**

Any of:

**integer**

integer

\> 0

**null**

null

**batch\_size**

_Batch Size_

Number of outputs (1-16).

integer

default: 4 \>= 1 <= 16

**num\_inference\_steps**

Any of:

**integer**

integer

\> 0

**null**

null

**guidance\_scale**

Any of:

**number**

number

**null**

null

**prompt\_strength**

Any of:

**number**

number

<= 1

**null**

null

**quality**

Any of:

**string**

string

Allowed values: low medium high

**null**

null

**sharpness**

Any of:

**number**

number

**null**

null

**duration\_seconds**

Any of:

**number**

number

\> 0

**null**

null

**generate\_audio**

Any of:

**boolean**

boolean

**null**

null

**keep\_audio**

Any of:

**boolean**

boolean

**null**

null

**fps**

Any of:

**integer**

integer

\> 0

**null**

null

**video\_effects**

_Video Effects_

Video effects to apply.

Array<object>

default: 

_ForgeVideoEffectInput_object

**type**

required

_VideoEffectType_

Video effect type. See model capabilities for supported effects per model.

string

Allowed values: general orbit\_360 action\_run agent\_reveal arc arc\_left baseball\_kick basketball\_dunks boxing buckle\_up building\_explosion bullet\_time car\_chasing car\_explosion car\_grip catch catwalk crane\_down crane\_over\_the\_head crane\_up crash\_zoom\_in crash\_zoom\_out dirty\_lens disintegration dolly\_in dolly\_left dolly\_out dolly\_right dolly\_zoom\_in dolly\_zoom\_out double\_dolly downhill\_pov dutch\_angle eyes\_in face\_punch fisheye flying focus\_change fpv\_drone glam handheld head\_tracking hyperlapse invisible jib\_down jib\_up kiss lazy\_susan lens\_crack lens\_flare levitation low\_shutter melting moonwalk\_left moonwalk\_right mouth\_in object\_pov overhead push\_to\_glass rap\_flex robo\_arm set\_on\_fire skateboard\_glide skateboarding skateboard\_kickflip skateboard\_ollie skate\_cruise ski\_carving ski\_powder snorricam snowboard\_carving snowboard\_powder soul\_jump static super\_dolly\_in super\_dolly\_out tentacles through\_object\_in through\_object\_out thunder\_god tilt\_down tilt\_up timelapse\_human timelapse\_landscape turning\_metal whip\_pan wiggle wind\_to\_face yoyo\_zoom zoom\_in zoom\_out

**weight**

Any of:

**number**

number

<= 100

**null**

null

**use\_ta\_pose**

Any of:

**boolean**

boolean

**null**

null

**pose\_mode**

Any of:

**PoseMode**

_PoseMode_

Canonical rest pose a character-mesh model is asked to generate in. `A_POSE` places the arms angled down at roughly 45°; `T_POSE` holds them straight out to the sides. Only meaningful for models that advertise the `pose_modes` capability (e.g. Meshy V7).

Deliberately a light top-level module (like `base_model_id`), NOT under `pkg.models.inference`: the Blueprint definition layer registers this as a BlueprintType and migrates legacy node ports, and must do so without pulling in the heavy `pkg.models.inference` package, which would perturb the Temporal workflow-sandbox import graph and split pydantic class identity.

string

Allowed values: A\_POSE T\_POSE

**null**

null

**include\_textures**

Any of:

**boolean**

boolean

**null**

null

**quad\_mesh**

Any of:

**boolean**

boolean

**null**

null

**pbr\_materials**

Any of:

**boolean**

boolean

**null**

null

**low\_poly**

Any of:

**boolean**

boolean

**null**

null

**generate\_parts**

Any of:

**boolean**

boolean

**null**

null

**face\_limit**

Any of:

**integer**

integer

\> 0

**null**

null

**stability**

Any of:

**number**

number

<= 1

**null**

null

**use\_speaker\_boost**

Any of:

**boolean**

boolean

**null**

null

**similarity\_boost**

Any of:

**number**

number

<= 1

**null**

null

**style\_exaggeration**

Any of:

**number**

number

<= 1

**null**

null

**speed**

Any of:

**number**

number

\> 0

**null**

null

**upscale\_ratio**

Any of:

**number**

number

**null**

null

**creativity**

Any of:

**number**

number

**null**

null

**resemblance**

Any of:

**number**

number

**null**

null

**vectorize**

Any of:

**boolean**

boolean

**null**

null

**remove\_background**

Any of:

**boolean**

boolean

**null**

null

**reframe**

Any of:

**boolean**

boolean

**null**

null

**refill**

Any of:

**boolean**

boolean

**null**

null

**guidance\_files**

_Guidance Files_

Reference images/files to guide generation.

Array<object>

default: <= 20 items

_ForgeGuidanceFileInput_object

**file\_id**

required

_File Id_

File ID of an uploaded file.

string format: uuid

**type**

required

_GuidanceFileType_

Guidance type. See model capabilities for supported types per model.

string

Allowed values: init\_image reference\_image scribble color\_sketch pose depth canny softedge\_hed segmentation lineart face ip\_adapter first\_frame last\_frame init\_video reference\_video init\_mesh texture\_image element\_frontal\_image element\_reference\_image element\_video init\_audio reference\_audio

**weight**

Any of:

**number**

number

<= 1

**null**

null

## Responses

### 200

Successful Response

_EstimateInferencePriceV2Output_object

**estimated\_price\_creative\_units**

required

_Estimated Price Creative Units_

Total estimated Creative Units price for this run.

number

**workspace\_balance\_creative\_units**

required

_Workspace Balance Creative Units_

Usable Creative Units balance (total balance minus reserved by in-progress generations).

number

**estimated\_remaining\_balance\_creative\_units**

required

_Estimated Remaining Balance Creative Units_

Usable balance after subtracting the estimated price. Can be negative.

number

**has\_sufficient\_creative\_units**

required

_Has Sufficient Creative Units_

Whether the workspace has enough available Creative Units to cover the estimated price.

boolean

**base\_model\_id**

required

_Base Model Id_

Base model this price refers to, resolved or auto-picked.

string

**auto\_picked**

required

_Auto Picked_

True when no base\_model\_id was supplied — the base model was selected from the reference sets.

boolean

**reference\_set\_contributions**

_Reference Set Contributions_

Per-set summary of what each reference set would contribute to this run.

Array<object>

default: 

_ForgeReferenceSetContribution_object

**set\_id**

Any of:

**string**

string format: uuid

**null**

null

**lora\_applied**

_Lora Applied_

True when a LoRA finetune was applied for this set.

boolean

**animation\_applied**

_Animation Applied_

True when an animation (Meshy rigging action) finetune was applied for this set.

boolean

**voice\_applied**

_Voice Applied_

True when a voice (ElevenLabs) finetune was applied for this set.

boolean

**mapped\_asset\_count**

_Mapped Asset Count_

Number of assets successfully mapped to guidance inputs.

integer

0

**prompt\_fallback\_applied**

_Prompt Fallback Applied_

True when the set fell back to prompt-only representation.

boolean

**lora\_available\_but\_incompatible**

_Lora Available But Incompatible_

True when SBMC has a LoRA for this set on another base model but not the one used.

boolean

**skipped\_not\_applicable**

_Skipped Not Applicable_

True when the set isn’t applicable to the chosen model (its modality / applicable base models exclude it) so no LoRA or assets were applied.

boolean

**reference\_sets\_degraded**

_Reference Sets Degraded_

True when at least one attached reference set would not meaningfully contribute on the selected model.

boolean

**reference\_sets\_warning**

Any of:

**string**

string

**null**

null

##### Example

```json
{
  "reference_set_contributions": [],
  "reference_sets_degraded": false
}
```

### 401

Unauthenticated — missing or invalid Bearer token.

object

**type**

required

string

**title**

required

string

**status**

required

integer

**detail**

required

string

##### Example

```json
{
  "type": "https://api.layer.ai/errors/ERROR_CODE",
  "title": "Error Title",
  "status": 400,
  "detail": "Human-readable description."
}
```

### 403

Forbidden — insufficient permissions.

object

**type**

required

string

**title**

required

string

**status**

required

integer

**detail**

required

string

##### Example

```json
{
  "type": "https://api.layer.ai/errors/ERROR_CODE",
  "title": "Error Title",
  "status": 400,
  "detail": "Human-readable description."
}
```

### 404

Resource not found.

object

**type**

required

string

**title**

required

string

**status**

required

integer

**detail**

required

string

##### Example

```json
{
  "type": "https://api.layer.ai/errors/ERROR_CODE",
  "title": "Error Title",
  "status": 400,
  "detail": "Human-readable description."
}
```

### 422

Invalid input parameters.

object

**type**

required

string

**title**

required

string

**status**

required

integer

**detail**

required

string

##### Example

```json
{
  "type": "https://api.layer.ai/errors/ERROR_CODE",
  "title": "Error Title",
  "status": 400,
  "detail": "Human-readable description."
}
```

### 429

Rate limited — too many concurrent requests.

object

**type**

required

string

**title**

required

string

**status**

required

integer

**detail**

required

string

##### Example

```json
{
  "type": "https://api.layer.ai/errors/ERROR_CODE",
  "title": "Error Title",
  "status": 400,
  "detail": "Human-readable description."
}
```

### 500

Internal server error.

object

**type**

required

string

**title**

required

string

**status**

required

integer

**detail**

required

string

##### Example

```json
{
  "type": "https://api.layer.ai/errors/ERROR_CODE",
  "title": "Error Title",
  "status": 400,
  "detail": "Human-readable description."
}
```
