Skip to content

Latest commit

 

History

History
286 lines (213 loc) · 15.1 KB

File metadata and controls

286 lines (213 loc) · 15.1 KB

Uplift Sample API App (NodeJS Version)

This is a simple sample app that shows how you can use the Uplift APIs with NodeJS.

Prerequisites

Installing Node.js

To run this sample app, you'll need Node.js installed on your system.

  1. Minimum Node.js Version: The application requires Node.js 16 or higher.
  2. Where to Download Node.js:
    • Visit the Node.js official website.
    • Download and install the LTS (Long-Term Support) version, which is recommended for most users.

Folder Structure

The Node.js app organizes the files as follows:

nodejs/
├── app.js                # Main script to start the data export process
├── captures.js           # Script to list captures and fetch a capture by id
├── athletes.js           # Script to list/get and (optionally) create/update/delete athletes
├── api.js                # Contains functions for API interaction
├── file.js               # Contains file handling and CSV export logic
├── env.example.json      # Template for env.json (copy and add your API key)
├── package.json          # Node.js dependencies and scripts
└── README.md             # This file

Sample API App

Installing Dependencies

Install the dependencies using npm in this directory.

$ npm install

Setting Up API Keys

In this directory, copy the provided template env.example.json to a new file named env.json, then fill in your API key:

$ cp env.example.json env.json

env.json is git-ignored so your key is never committed. The template looks like this:

   {
     "UPLIFT_API_KEY": "your_api_key_here",
     "UPLIFT_API_URL": "https://api.uplift.ai/v1"
   }
  • UPLIFT_API_KEY: Your API key (format starting with sk). Sent as a Bearer token in the Authorization header. Generate one in the Uplift Platform under Settings → API Keys (Developer section); see the Authentication guide.
  • UPLIFT_API_URL: The API base URL (https://api.uplift.ai/v1). Every sample derives its endpoint from this base by appending the resource path (/data/export, /athletes, /captures).

Setting the Variables

Before starting the app, you need to set the following variables in the app.js file. These are critical for defining the data export process:

  1. Categories (Activity and Movement): A list of activities and movements for which you want to retrieve data.

    • Example:
      const categories = [
        { activity: "baseball", movement: "hitting" },
        { activity: "baseball", movement: "pitching" }
      ];
  2. Time Range (Start and End Time): Set the start and end time in epoch format for the data you wish to retrieve.

    • Example:
      let startTime = 1604807785; // 24 hours ago
      let endTime = Math.floor(Date.now() / 1000); // Current time
  3. Date Mode: Define how to filter the data. You can choose between last_modified or capture_time.

    • Example:
      let dateMode = "last_modified"; // Use 'capture_time' for the actual capture time
  4. Pagination Settings: Set the pagination parameters to control how many rows to fetch and skip.

    • Example:
      let offset = 0; // Default is 0
      let limit = 500; // Maximum rows per request (default is 500)

Make sure to adjust these variables according to the data you're interested in exporting. The following parameters are passed to the createExportJob function:

const data = {
  activity: category.activity,
  movement: category.movement,
  startTime,
  endTime,
  dateMode
};

The createExportJob function also supports additional data filtering options through the following optional parameters:

  • athletes: Filter data by specific athlete IDs
  • metrics: Limit the export to specific metrics
  • row_filter_column: Specify a column to filter rows

For more details, please refer to the API Reference.

Here is an example that includes these optional parameters:

const data = {
  activity: category.activity,
  movement: category.movement,
  startTime,
  endTime,
  dateMode,
  athletes: [
    "athlete_id1",
    "athlete_id2"
  ],
  metrics: [
    "metric1",
    "metric2"
  ],
  row_filter_column: "column_name"
};

Starting the App

Once you've installed the dependencies, set up the API key, and configured the variables in app.js, you can start the app by running the following command in your terminal:

$ node app.js

For more details on how the app works, the usage, and the output of the export process, please refer to the Sample App Usage (NodeJS and Python) section in the main README.md.

Captures

captures.js demonstrates the read-only Captures endpoints: listing captures for your organization and fetching a single capture by id. A capture represents a single recorded movement (a video and its analysis).

Note: Creating a capture by uploading a video (POST /captures) is an Enterprise feature and is intentionally not covered by this sample. See Create Capture.

List Captures — GET /captures

Returns a paginated list of captures, sorted newest first (by capture time). All query parameters are optional:

Parameter Description
athlete_id UUID; restrict to captures for that athlete. Returns 400 when the athlete is not in your organization.
source When set to api, only captures with source equal to api are returned.
status One of awaiting_upload, processing, completed, error.
activity Case-insensitive filter on activity (e.g. baseball).
movement Case-insensitive filter on movement (e.g. hitting).
limit Page size; integer 1–500. Defaults to 100.
offset Rows to skip; non-negative integer. Defaults to 0.

A successful 200 response returns:

{
  "captures": [ /* array of Capture objects */ ],
  "total_count": 42,
  "offset": 0,
  "limit": 100
}

total_count is the distinct capture count matching your filters. A capture linked to more than one athlete may appear more than once in captures[].

The list scenario pages through all captures — it advances offset by the number of rows returned and keeps requesting until a page comes back empty (the same pagination pattern app.js uses for export results). Add filters inside the scenario's filters object.

Get Capture — GET /captures/{captureId}

Returns a single Capture object. The capture must belong to your organization and must not be deleted, otherwise a 404 is returned.

The Capture object

Field Type Description
session_id string Capture identifier.
athlete_id string | null Athlete id when the capture is linked to an athlete.
activity string | null Activity label (casing matches the stored value).
movement string | null Movement label (casing matches the stored value).
status string One of awaiting_upload, processing, completed, error.
error string | null Error summary when applicable.
capture_time string | null ISO 8601 capture time when available.
fps_detected number | null Detected frame rate when available.

Beyond these fixed fields, a capture may include additional top-level movement dimension fields based on its activity and movement (for example, handedness for baseball/hitting). See the movement dimensions catalog.

Poll a capture until it finishes processing

A capture moves through awaiting_uploadprocessingcompleted (or error). The poll scenario fetches a capture by id every few seconds until it reaches a terminal status — the same polling approach app.js uses to wait for an export job to complete.

Running the captures sample

captures.js is organized as independent scenarios. Choose one by editing the SCENARIO constant at the top of the file, set CAPTURE_ID when the scenario needs it, then run:

$ node captures.js        # or: npm run captures
SCENARIO What it does
list Pages through captures in your organization (full pagination loop).
get Fetches a single capture by CAPTURE_ID.
poll Polls CAPTURE_ID until it finishes processing.

For full endpoint reference, see List Captures and Get Capture.

Athletes

athletes.js is organized as independent scenarios — one for each thing you'd want to do with the Athletes API (list, get, create, update, delete, or a full lifecycle). Choose one by editing the SCENARIO constant at the top of the file.

List Athletes — GET /athletes

Returns the organization's athletes. All query parameters are optional:

Parameter Description
limit Page size. Defaults to 100.
offset Rows to skip. Defaults to 0.
sorted_by Sort field: first_name, last_name, or date_of_birth.
custom Any custom organization attribute (e.g. sport, team). Multiple attributes are combined with logical AND; an unmatched value returns an empty array.

A successful 200 response returns { "athletes": [ /* Athlete objects */ ] }. The list scenario pages through all athletes, advancing offset until a page comes back empty. Add filters inside the scenario's filters object.

Get Athlete — GET /athletes/{athleteId}

Returns { "athlete": { ... } } for a single athlete.

Create Athlete — POST /athletes

Only first_name is required. Returns { "athlete": { ... } } including the generated id. Supported fields:

Field Type Notes
first_name string Required.
last_name string
date_of_birth string YYYY-MM-DD.
email string
phone string
gender string male, female, non-binary, prefer_not_to_say.
height integer Inches.
weight integer Pounds (lbs).
dominant_arm string left, right, both.
dominant_leg string left, right, both.
activity string baseball, softball, tennis, basketball, golf.
positions string[] Requires activity. Valid positions depend on the activity.
competition_level string youth, high_school, college, professional.
custom_attributes object String → string key-value pairs.

Update Athlete — POST /athletes/{athleteId}

Send only the fields you want to change. Returns { "athlete": { ... } }.

Delete Athlete — DELETE /athletes/{athleteId}

Returns { "message": "..." } confirming the deletion.

Running the athletes sample

Choose a scenario by editing the SCENARIO constant at the top of athletes.js, set ATHLETE_ID when the scenario needs it, then run:

$ node athletes.js        # or: npm run athletes
SCENARIO What it does
list Pages through every athlete (full pagination loop).
get Fetches a single athlete by ATHLETE_ID.
create Creates a sample athlete and prints its new id.
update Updates a field on ATHLETE_ID (shows before/after).
delete Deletes ATHLETE_ID.
lifecycle Runs create → get → update → delete end to end on a throwaway athlete.

Note: create, update, delete, and lifecycle modify your data. lifecycle is self-contained — it creates its own athlete and deletes it at the end — so it's a safe way to see the full write flow.

For full endpoint reference, see Create, List, Get, Update, and Delete.

More Info

For additional information and explanations, please refer to the comments within the files.