On this page

## Not yet in the official clients

The Unitree G1 CSV export is not yet covered by the official Python (`uthana`) or JavaScript (`@uthana/client`) clients. Use the raw HTTP examples below with your API key for Basic auth.

Use this export when you want to run a Uthana-generated motion on a **Unitree G1** humanoid robot. The result is a `.csv` file containing the robot trajectory for the selected motion.

You still provide both IDs in the URL:

- **`motionId`** selects the motion to export.
- **`characterId`** is required for access, quotas, and billing. It does not change the output format—the response is always for **Unitree G1**.

For standard character animation files, use [Download a motion](/content/docs/api/capabilities/downloading-motion/index.html) instead.

## HTTP endpoint and filename

Send a `GET` request with Basic auth using your API key:

```
https://uthana.com/motion/file/motion_viewer/{characterId}/{motionId}/csv/{anyname}.csv
```

The last path segment is only part of the route. You can use any `.csv` name there, such as `export.csv`.

The response sets this **download filename** in `Content-Disposition`:

```
unitree_g1_{characterId}-{motionId}.csv
```

Save the file with that name, or read the `Content-Disposition` header from your HTTP client. The response body is plain `text/csv`.

## Query parameters

- **`fps`:**`24`, `30`, or `60`. If omitted, the export uses **30 FPS**.

Unitree G1 CSV downloads do not support any other query parameters.

## Using the CSV on a Unitree G1

The downloaded `.csv` is intended to be consumed by your robot-side playback or control workflow. In practice, you will usually:

1. Download the CSV from Uthana.
2. Copy it to the development computer or runtime environment you use with the G1.
3. Load the CSV in your own playback/controller code and send the trajectory through the appropriate Unitree control interface.

For robot setup, networking, SDK installation, and controller integration, use Unitree's G1 developer documentation as the source of truth: [Unitree G1 developer docs](https://support.unitree.com/home/en/G1_developer).

## Latency and timeouts

This export can take longer than a typical FBX or GLB download. As a rough planning estimate, expect a 10s motion to take 5-10 seconds to process.

## Example requests

- Shell
- Python
- TypeScript
- C#

```
API_KEY="YOUR_API_KEY"
CHARACTER_ID="cXi2eAP19XwQ"
MOTION_ID="your-motion-id"

# Optional: ?fps=30|24|60
curl -L "https://uthana.com/motion/file/motion_viewer/${CHARACTER_ID}/${MOTION_ID}/csv/motion.csv?fps=30" \
  -u "$API_KEY:" \
  -o "unitree_g1_${CHARACTER_ID}-${MOTION_ID}.csv"
```

```
import requests

API_KEY = "YOUR_API_KEY"
CHARACTER_ID = "cXi2eAP19XwQ"
MOTION_ID = "your-motion-id"

url = f"https://uthana.com/motion/file/motion_viewer/{CHARACTER_ID}/{MOTION_ID}/csv/export.csv?fps=30"
response = requests.get(url, auth=(API_KEY, ""), timeout=600)
response.raise_for_status()
out_name = f"unitree_g1_{CHARACTER_ID}-{MOTION_ID}.csv"
with open(out_name, "wb") as f:
    f.write(response.content)
```

```
const API_KEY = "YOUR_API_KEY";
const CHARACTER_ID = "cXi2eAP19XwQ";
const MOTION_ID = "your-motion-id";

const authString = btoa(`${API_KEY}:`);
const url = `https://uthana.com/motion/file/motion_viewer/${CHARACTER_ID}/${MOTION_ID}/csv/export.csv?fps=30`;

const response = await fetch(url, {
  headers: { Authorization: `Basic ${authString}` },
});
if (!response.ok) throw new Error(String(response.status));
const buffer = await response.arrayBuffer();
// Save as unitree_g1_{CHARACTER_ID}-${MOTION_ID}.csv
```

```
var apiKey = "YOUR_API_KEY";
var characterId = "cXi2eAP19XwQ";
var motionId = "your-motion-id";
var downloadUrl = $"https://uthana.com/motion/file/motion_viewer/{characterId}/{motionId}/csv/motion.csv?fps=30";

var auth = Convert.ToBase64String(Encoding.UTF8.GetBytes($"{apiKey}:"));
_httpClient.DefaultRequestHeaders.Authorization =
    new System.Net.Http.Headers.AuthenticationHeaderValue("Basic", auth);

var response = await _httpClient.GetAsync(downloadUrl);
response.EnsureSuccessStatusCode();
var bytes = await response.Content.ReadAsByteArrayAsync();
// Save as unitree_g1_{characterId}-{motionId}.csv
```
