On this page

Get started with the Uthana API in minutes. This guide will help you create your first AI-powered animation.

**Official clients:**

- Python: [`uthana`](https://github.com/Uthana/uthana-python-client) — `pip install uthana`
- JavaScript/TypeScript: [`@uthana/client`](https://github.com/Uthana/uthana-js-client) — `npm install @uthana/client`

## Using Context7 with the Uthana API

[Context7](https://context7.com/) helps LLMs and AI code editors pull **up-to-date documentation and code examples** (instead of relying on stale training data). It's designed for AI assistants like Cursor / Claude Code.

1. Install Context7 in your IDE: [Context7 Installation](https://github.com/upstash/context7#installation)
2. Add Uthana as a source: [https://context7.com/websites/uthana_api](https://context7.com/websites/uthana_api) (library id: `/websites/uthana_api`)
3. Use it in your prompts (example): "How do I create a text-to-motion animation with the Uthana API? use context7 library /websites/uthana_api"

## Prerequisites

- An Uthana account ([sign up for free here](/content/user/signup/index.html))
- An API key (get it from [your account settings](/content/app/account/index.html) once logged in)

## Step 1: Install the client

- Shell
- Python
- TypeScript
- React
- C#

```
# No install needed — use curl directly.
# For the Python client: pip install uthana
```

```
pip install uthana
```

Python async

All Python methods are **async** by default. The examples on this page use `async`/`await` wrapped in `asyncio.run(main())`. Every method also has a `_sync` variant (e.g. `ttm.create_sync(...)`) if you need a synchronous call.

```
npm install @uthana/client
```

```
npm install @uthana/react @uthana/client @tanstack/react-query
```

There is no official C# client. Use raw GraphQL and HTTP requests — see each step below for C# examples.

## Step 2: Authenticate

Connect the client using your API key and confirm the key is valid.

- Shell
- Python
- TypeScript
- React
- C#

```
API_KEY="your-api-key"

curl 'https://uthana.com/graphql' \
  -u $API_KEY: \
  -H "Content-Type: application/json" \
  -d '{"query": "{ __typename }"}'
```

You should see `{"data":{"__typename":"Query"}}`.

```
from uthana import Uthana

client = Uthana("your-api-key")

user = client.org.get_user_sync()
print(user.get("name"), user.get("email"))
```

```
import { UthanaClient } from "@uthana/client";

const client = new UthanaClient(process.env.UTHANA_API_KEY!);

const user = await client.org.getUser();
console.log(user.name, user.email);
```

Wrap your app in `UthanaProvider` once (typically in your root layout). All Uthana hooks work inside it automatically.

```
import { UthanaProvider, useUthanaUser } from "@uthana/react";

function App() {
  return (
    <UthanaProvider apiKey={process.env.REACT_APP_UTHANA_API_KEY!}>
      <UserInfo />
    </UthanaProvider>
  );
}

function UserInfo() {
  const { user } = useUthanaUser();
  return <p>{user ? `Hello, ${user.name}` : "Loading..."}</p>;
}
```

```
using System.Net.Http;
using System.Text;
using System.Text.Json;

private const string ApiUrl = "https://uthana.com/graphql";
private readonly string _apiKey = "your-api-key";

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

var request = new { query = "{ __typename }" };
var json = JsonSerializer.Serialize(request);
var content = new StringContent(json, Encoding.UTF8, "application/json");

var response = await _httpClient.PostAsync(ApiUrl, content);
var responseJson = await response.Content.ReadAsStringAsync();
Console.WriteLine(responseJson);
```

## Step 3: Prepare your character model

(Note: You can skip this step if you're using the default character, "Tar", with the character ID `cXi2eAP19XwQ`.)

To generate motion for your character, you need to upload a 3D character model in FBX (.fbx) or glTF (.glb/.gltf) format. The easiest way to do this when you're just getting started is to use the [Web UI](/content/app/index.html).

1. Go to the [Web UI](/content/app/index.html) and sign in.
2. Click the Upload character button.
3. Upload your character model in FBX (.fbx) or glTF (.glb/.gltf) format.
4. Verify that the character is loaded correctly by viewing or generating a motion.
5. Copy the character ID from the URL: `https://uthana.com/app/<character-id>/<motion-id>`.
6. Save the character ID for later use.

You can also upload a character via the API — see [Auto-rig / add a character](/content/docs/api/capabilities/auto-rig-and-add-character/index.html).

### Auto-rigging

If your character doesn't have a skeleton rig, Uthana will automatically attempt to create one. Auto-rigging typically takes an additional 30-60 seconds and allows you to use characters that weren't originally rigged for animation.

## Step 4: Generate a motion from text

- Shell
- Python
- TypeScript
- React
- C#

```
curl 'https://uthana.com/graphql' \
  -u your-api-key: \
  -H "Content-Type: application/json" \
  -d '{
    "query": "mutation { create_text_to_motion(prompt: \"A person walking down the street\") { motion { id name } } }"
  }'
```

```
import asyncio
from uthana import Uthana

client = Uthana("your-api-key")

async def main():
    result = await client.ttm.create("a person walking down the street")
    print(result.character_id, result.motion_id)

asyncio.run(main())
```

```
const result = await client.ttm.create("a person walking down the street");
console.log(result.character_id, result.motion_id);
```

```
import { useUthanaTtm } from "@uthana/react";

function GenerateButton() {
  const ttm = useUthanaTtm();

return (
    <button onClick={() => ttm.mutate({ prompt: "a person walking down the street" })} disabled={ttm.isPending}>
      {ttm.isPending ? "Generating..." : "Generate motion"}
    </button>
  );
}
}
```

```
var query = @"
    mutation {
        create_text_to_motion(prompt: \"A person walking down the street\") {
            motion {
                id
                name
            }
        }
    }";

var request = new { query = query };
var json = JsonSerializer.Serialize(request);
var content = new StringContent(json, Encoding.UTF8, "application/json");

var response = await _httpClient.PostAsync(ApiUrl, content);
response.EnsureSuccessStatusCode();

var responseJson = await response.Content.ReadAsStringAsync();
var result = JsonSerializer.Deserialize<GraphQLResponse<CreateTextToMotionData>>(responseJson);

var motion = result.Data.CreateTextToMotion.Motion;
Console.WriteLine($"Created motion: {motion.Id} - {motion.Name}");
```

Text-to-motion results are returned in the `result` object.

## Step 5: Download your motion

- Shell
- Python
- TypeScript
- React
- C#

```
CHARACTER_ID="cXi2eAP19XwQ"  # Default character, or use your own
MOTION_ID="<motion-id-from-step-4>"

# Download the motion as FBX (includes character mesh, filename is customizable)
curl -L "https://uthana.com/motion/file/motion_viewer/$CHARACTER_ID/$MOTION_ID/fbx/motion.fbx" \
  -u your-api-key: \
  -o motion.fbx

# Download the motion as GLB (includes character mesh, filename is customizable)
curl -L "https://uthana.com/motion/file/motion_viewer/$CHARACTER_ID/$MOTION_ID/glb/motion.glb" \
  -u your-api-key: \
  -o motion.glb

# Download at 30 FPS
curl -L "https://uthana.com/motion/file/motion_viewer/$CHARACTER_ID/$MOTION_ID/fbx/motion.fbx?fps=30" \
  -u your-api-key: \
  -o motion-30fps.fbx

# Download the motion-only GLB (animation data without character mesh, filename is customizable)
curl -L "https://uthana.com/motion/animation/motion_viewer/$CHARACTER_ID/$MOTION_ID/glb/motion.glb" \
  -u your-api-key: \
  -o motion-only.glb
```

```
import asyncio
from uthana import Uthana

client = Uthana("your-api-key")

async def main():
    result = await client.ttm.create("a person walking down the street")
    data = await client.motions.download(
        result.character_id,
        result.motion_id,
        output_format="glb",
        fps=30,
    )
    with open("motion.glb", "wb") as f:
        f.write(data)

asyncio.run(main())
```

```
const buffer = await client.motions.download(result.character_id, result.motion_id, {
  output_format: "glb",
  fps: 30,
});

// Node.js: write to disk
import { writeFileSync } from "fs";
writeFileSync("motion.glb", Buffer.from(buffer));

// Browser: create a download link
const url = URL.createObjectURL(new Blob([buffer], { type: "model/gltf-binary" }));
```

```
import { useUthanaClient } from "@uthana/react";

function DownloadButton({ characterId, motionId }: { characterId: string; motionId: string }) {
  const client = useUthanaClient();

async function download() {
    const buffer = await client.motions.download(characterId, motionId, {
      output_format: "glb",
      fps: 30,
    });
    const url = URL.createObjectURL(new Blob([buffer], { type: "model/gltf-binary" }));
    const a = document.createElement("a");
    a.href = url;
    a.download = "motion.glb";
    a.click();
  }

return <button onClick={download}>Download GLB</button>;
}
```

```
private const string CHARACTER_ID = "cXi2eAP19XwQ"; // Default character, or use your own
var motionId = "<motion-id-from-step-4>";

var downloadUrl = $"https://uthana.com/motion/file/motion_viewer/{CHARACTER_ID}/{motionId}/glb/motion.glb?fps=30";
var downloadResponse = await _httpClient.GetAsync(downloadUrl);
downloadResponse.EnsureSuccessStatusCode();

var motionData = await downloadResponse.Content.ReadAsByteArrayAsync();
await File.WriteAllBytesAsync("motion.glb", motionData);
```

## Next steps

- Explore [Capabilities](/content/docs/api/capabilities/text-to-motion/index.html) for detailed tutorials on each feature
- [Review the API reference](/content/docs/api/graphql/index.html) for complete schema documentation
- [Get support](/content/docs/api/support/index.html) for common questions and troubleshooting
- [Join our Discord](https://discord.gg/PbMzMPSyTG) for community support

- [Using Context7 with the Uthana API](/content/docs/api#using-context7-with-the-uthana-api-/index.html)
- [Prerequisites](/content/docs/api#prerequisites/index.html)
- [Step 1: Install the client](/content/docs/api#step-1-install-the-client/index.html)
- [Step 2: Authenticate](/content/docs/api#step-2-authenticate/index.html)
- [Step 3: Prepare your character model](/content/docs/api#step-3-prepare-your-character-model/index.html)
  - [Auto-rigging](/content/docs/api#auto-rigging/index.html)
- [Step 4: Generate a motion from text](/content/docs/api#step-4-generate-a-motion-from-text/index.html)
- [Step 5: Download your motion](/content/docs/api#step-5-download-your-motion/index.html)
- [Next steps](/content/docs/api#next-steps/index.html)
