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

# Input and Output

> BizyAir API input parameter schema, file upload to OSS, commit flow, and output file object_url with 15-day validity.

## Input Parameters and Schema

`input_values` is the task's input parameter object. Keys follow the format `NodeID:NodeName.FieldName`, and values can be strings, numbers, booleans, etc. The available fields depend on the workflow structure associated with the `web_app_id`.

### How to find the schema

1. Go to the BizyAir AI Apps page
2. Click the target AI app to open its detail page
3. Click the `API` button in the top-left corner
4. In the API call dialog, review the full list of `input_values` fields and their example values
5. Switch to the `Shell` / `Python` / `JavaScript` tabs to copy a complete code snippet

### Common field patterns

| Field type        | Example key                                 | Description                                     |
| ----------------- | ------------------------------------------- | ----------------------------------------------- |
| Text prompt       | `84:CLIPTextEncode.text`                    | Main prompt for text-to-image or image-to-image |
| Random seed       | `88:KSampler.seed`                          | Controls result reproducibility                 |
| Image width       | `81:EmptySD3LatentImage.width`              | Output image width                              |
| Image height      | `81:EmptySD3LatentImage.height`             | Output image height                             |
| Sampling steps    | `2:BizyAir_BasicScheduler.steps`            | Number of sampler steps                         |
| LLM user prompt   | `4:BizyAirSiliconCloudLLMAPI.user_prompt`   | User input for an LLM node                      |
| LLM system prompt | `4:BizyAirSiliconCloudLLMAPI.system_prompt` | System prompt for an LLM node                   |

## File Upload

When a workflow requires images, audio, or video as input (e.g. image-to-image, image-to-video), you must first upload the file to BizyAir OSS, then pass the returned `url` as the value of the corresponding `input_values` field.

### Step 1: Get upload credentials

```bash theme={null}
curl -G "https://api.bizyair.ai/v1/upload/token" \
  -H "Authorization: Bearer $BIZYAIR_API_KEY" \
  --data-urlencode "file_name=example.webp" \
  --data-urlencode "file_type=inputs_temp"
```

Response:

```json theme={null}
{
  "code": 20000, "message": "Ok", "status": true,
  "data": {
    "file": {
      "object_key": "inputs/20250911/abc123.webp",
      "access_key_id": "STS.xxxx",
      "access_key_secret": "xxxx",
      "security_token": "xxxx"
    },
    "storage": {
      "endpoint": "oss-cn-shanghai.aliyuncs.com",
      "bucket": "bizyair-prod",
      "region": "oss-cn-shanghai"
    }
  }
}
```

<Note>
  `file_name` must include the file extension — the server uses it to determine the file type. The returned STS credentials are **temporary**; do not persist them or expose them in frontend code.
</Note>

### Step 2: Upload the file to Alibaba Cloud OSS

Use the returned credentials to PUT the file directly to OSS. See [Alibaba Cloud OSS Simple Upload](https://help.aliyun.com/zh/oss/simple-upload) for details.

**Python example**:

```python theme={null}
import os
import alibabacloud_oss_v2 as oss

def upload_to_oss(region, endpoint, bucket, object_key, file_path,
                  access_key_id, access_key_secret, security_token):
    os.environ["ALIBABA_CLOUD_ACCESS_KEY_ID"] = access_key_id
    os.environ["ALIBABA_CLOUD_ACCESS_KEY_SECRET"] = access_key_secret
    os.environ["ALIBABA_CLOUD_SECURITY_TOKEN"] = security_token

    cfg = oss.config.load_default()
    cfg.credentials_provider = oss.credentials.EnvironmentVariableCredentialsProvider()
    normalized_region = region[4:] if region.startswith("oss-") else region
    cfg.region = normalized_region
    cfg.endpoint = endpoint or f"oss-{normalized_region}.aliyuncs.com"

    client = oss.Client(cfg)
    return client.put_object_from_file(
        oss.PutObjectRequest(bucket=bucket, key=object_key),
        file_path
    )
```

**Node.js example**:

```javascript theme={null}
const OSS = require("ali-oss");

async function uploadToOss({region, endpoint, bucket, objectKey, filePath,
                            accessKeyId, accessKeySecret, securityToken}) {
  const normalizedRegion = region.startsWith("oss-") ? region.slice(4) : region;
  const client = new OSS({
    region: normalizedRegion,
    endpoint: endpoint || `oss-${normalizedRegion}.aliyuncs.com`,
    accessKeyId, accessKeySecret, stsToken: securityToken, bucket,
  });
  return await client.put(objectKey, filePath);
}
```

### Step 3: Register the input resource

After the OSS upload succeeds, call the `commit` endpoint to register the file and obtain a `url` that the workflow can reference.

```bash theme={null}
curl -X POST "https://meta.bizyair.ai/v1/input_resource/commit" \
  -H "Authorization: Bearer $BIZYAIR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "example.webp",
    "object_key": "inputs/20250911/abc123.webp"
  }'
```

Response:

```json theme={null}
{
  "code": 20000, "message": "Ok", "status": true,
  "data": {
    "id": 1711,
    "name": "example.webp",
    "ext": ".webp",
    "url": "https://storage.bizyair.ai/inputs/20250911/abc123.webp"
  }
}
```

The returned `url` can then be passed as the value of the corresponding field in `input_values` when creating a task.

## Output Files and Object URLs

After a task completes successfully, `outputs[].object_url` provides a temporary download link for the result file:

* **Domain**: `https://storage.bizyair.ai/outputs/...`
* **Default validity**: **15 days** (the `expired_at` field in the response gives the exact time)
* **After expiry**: cannot be recovered

<Tip>
  In production, download the file to your own object storage (OSS / S3) as soon as you receive the `object_url` to avoid link expiration.
</Tip>

## Task Duration Breakdown

The task result includes a `cost_times` object with detailed durations for each stage (in milliseconds):

| Field                    | Description                                                    |
| ------------------------ | -------------------------------------------------------------- |
| `inference_cost_time`    | Pure inference duration                                        |
| `running_cost_time`      | Total running duration (includes inference + node transitions) |
| `total_cost_time`        | Total task duration (includes queuing + preparing + running)   |
| `real_cpu_cost_time`     | Actual CPU time consumed                                       |
| `real_gpu_cost_time`     | Actual GPU time consumed                                       |
| `real_total_cost_time`   | Actual total time consumed                                     |
| `real_bizyair_cost_time` | Internal system processing time                                |

<Note>
  Billing is based solely on `inference_cost_time` (the inference phase). All other stages are free of charge.
</Note>
