GraphQL API | Uthana API Docs

On this page

The Uthana GraphQL API provides a flexible way to query and mutate animation data.

Endpoint

https://uthana.com/graphql

Authentication

Include your API key in the basic Authorization header, base64-encoded with a colon:

AUTH_STRING=$(echo -n "your-api-key:" | base64)
curl -H "Authorization: Basic $AUTH_STRING" \
     https://uthana.com/graphql

or in the query string (plaintext):

https://uthana.com/graphql?apikey=your-api-key

Schema

Queries

type Query {
  org: Org
  user: User
  locomotion_styles: [String!]!
  motion_download_allowed(character_id: String, motion_id: String): MotionDownloadAllowed
  characters: [Character!]
  motion(id: String): Motion
  motions(character_id: String, app_ids: [String!], methods: [String]): [Motion!]
  label_search(query: String, limit: Int = 20): [LabelSearchResult!]
  job(job_id: String): Job
  jobs(method: String): [Job!]
}

Org

query Org {
  org {
    id
    name
    motion_download_secs_per_month
    motion_download_secs_per_month_remaining
    characters_allowed
    characters_allowed_remaining
    users {
      id
      name
      email
      email_verified
      tz
      roles
    }
  }
}

User

query User {
  user {
    id
    name
    email
    email_verified
    tz
    roles
    created
    updated
    org {
      id
      name
    }
  }
}

MotionDownloadAllowed

Return value for motion_download_allowed (input ids are the query arguments character_id and motion_id, not fields on this type).

query MotionDownloadAllowed($character_id: String, $motion_id: String) {
  motion_download_allowed(character_id: $character_id, motion_id: $motion_id) {
    allowed
    reason
  }
}

Character

query Character($id: String!) {
  character(id: $id) {
    id
    name
    org_id
    created
    updated
    deleted
    assets {
      id
      filename
    }
  }
}

Characters

query Characters {
  characters {
    id
    name
    # ...etc. (see Character object)
  }
}

Motion

{ MotionRating }
{ MotionFavorite }
query Motion($id: String!) {
  motion(id: $id) {
    id
    name
    tags
    assets {
      id
      filename
    }
    rating {
      user_id
      score
      created
    }
    favorite {
      user_id
      created
    }
    created
    updated
    deleted
  }
}

Motions

query Motions {
  motions {
    id
    name
    # ...etc. (see Motion object)
  }
}

Asset

Job

query Job($id: String!) {
  job(id: $id) {
    id
    status
    started_at
    ended_at
    result
  }
}

Jobs

query Jobs {
  jobs {
    id
    # ...etc. (see Job object)
  }
}

Mutations

The following mutations are available for creating and modifying data:

create_text_to_motion

Generate a motion from a text prompt.

mutation {
  create_text_to_motion(
    prompt: String!
    model: String # "text-to-motion" (default) or "text-to-motion-bucmd"
    foot_ik: Boolean = false
  ) {
    motion {
      id
      name
    }
  }
}

create_text_to_motion_job

Create an async text-to-motion job using text-to-motion-3.0.

mutation {
  create_text_to_motion_job(
    prompt: String!
    model: String!
    character_id: String
    length: Float
    rewrite_prompt: Boolean
  ) {
    job {
      id
      status
      est_processing_time
    }
  }
}

create_video_to_motion

Generate a motion from a 2D video file.

mutation {
  create_video_to_motion(
    file: Upload!
    motion_name: String!
    character_id: String
    model: String
  ) {
    job {
      id
      status
    }
  }
}

create_character

Upload a new character. Auto-rigging is handled automatically if the character doesn't have a rig.

mutation {
  create_character(
    file: Upload!
    name: String!
    auto_rig: Boolean = true # optional, defaults to true
    root: String # internal use only
  ) {
    character {
      id
      name
    }
  }
}

create_enhanced_stitched_motion

Stitch two motions together with detailed pose and spatial data for high-quality transitions. This is the primary stitching API.

MotionStitchInput:

StitchParamsInput (each of prefix and suffix):

Field Type Required Description
prompt String Yes Text hint for the transition. Use "" for deterministic baseline.
motion_id String Yes Motion ID.
stitch_loop Boolean Yes Use false for standard stitching.
stitch_duration Float Yes Transition duration in seconds (0.1–3.0). Recommended: 2.0.
motion_duration Float Yes Total motion duration in seconds.
motion_lower_trim_time Float Yes Lower trim time in seconds.
motion_upper_trim_time Float Yes Upper trim time in seconds. For prefix, use motion_duration - 0.051 to avoid exact-end sampling.
motion_lower_trim_fraction Float Yes Lower trim as fraction [0.0–1.0].
motion_upper_trim_fraction Float Yes Upper trim as fraction [0.0–1.0].
root_node_world_pos Vector3Input Yes Root node world position {x, y, z}.
root_node_world_rot QuaternionInput Yes Root node world rotation {x, y, z, w}.
at_zero_time PelvisStateInput Yes Pelvis state at time 0.
at_lower_trim_time PelvisStateInput Yes Pelvis state at lower trim time.
at_upper_trim_time PelvisStateInput Yes Pelvis state at upper trim time.

PelvisStateInput:pelvis_world_pos (Vector3), pelvis_world_rot (Quaternion), hips_forward_facing_world_yaw (Float, radians).

mutation CreateEnhancedStitchedMotion($stitch_input: MotionStitchInput!) {
  create_enhanced_stitched_motion(stitch_input: $stitch_input) {
    motion {
      id
      name
    }
  }
}
}

create_stitched_motion

Legacy stitch endpoint. Prefer create_enhanced_stitched_motion for better quality and control.

mutation {
  create_stitched_motion(
    leading_motion_id: String!
    trailing_motion_id: String!
    duration: Float = 0.5
  ) {
    motion {
      id
      name
    }
  }
}
}

trim_and_loop_motion

Trim and optionally loop a motion.

mutation {
  trim_and_loop_motion(
    motion_id: String!
    motion_name: String
    start: Float!
    end: Float!
    loop: "progressive" | "cyclical"
  ) {
    motion {
      id
      name
    }
  }
}

rate_motion

Rate a motion or label.

mutation {
  rate_motion(
    label_id: String
    motion_id: String!
    score: Int! # must be 0 or 1
  ) {
    rating {
      score
      user_id
    }
  }
}

update_motion

Update a motion's name and/or deletion status.

mutation {
  update_motion(
    deleted: Boolean
    motion_id: String!
    name: String
  ) {
    motion {
      id
      name
      deleted
    }
  }
}
}

## Example queries

### Get motion details

```graphql
query GetMotion($id: String!) {
  motion(id: $id) {
    id
    name
    created
    updated
    org_id
    priority
    tags
    motion_viewer
    training
    assets {
      id
      filename
    }
    labels {
      id
      description
      start
      end
    }
    rating {
      score
      user_id
    }
  }
}

List motions

query ListMotions {
  motions(methods: ["TextToMotion"]) {
    id
    name
    org_id
    created
    assets {
      filename
    }
  }
}

List locomotion styles

Returns every style_id accepted by create_locomotion. See the Locomotion capability for end-to-end usage.

query ListLocomotionStyles {
  locomotion_styles
}

List locomotion motions

Filter the motions list to clips created with the locomotion generator:

query ListLocomotionMotions {
  motions(methods: ["Locomotion"]) {
    id
    name
  }
}

List jobs

query ListJobs {
  jobs(method: "VideoToMotion") {
    id
    status
    est_processing_time
  }
}

Generate locomotion

mutation GenerateLocomotion {
  create_locomotion(
    character_id: "your-character-id"
    strides: 2
    move_speed: 1.3
    style_id: "neutral_male_a"
    travel_angle: 0
  ) {
    motion {
      id
      name
    }
  }
}
}

Generate motion from text (text-to-motion)

mutation GenerateTextMotion {
  create_text_to_motion(prompt: "walk casually", model: "text-to-motion", foot_ik: true) {
    motion {
      id
      name
    }
  }
}
}