SplitStep API — Client Guide

Submit videos for processing and receive results via webhook

Overview

This guide walks through how to submit a video for processing using the SplitStep API. You submit a job and receive results via a webhook when the job completes or fails.

Prerequisites

You will need:

  • An API key
  • Python with the click and requests packages installed
  • The send_client.py script
  • A job request JSON file (see the example provided below)

Submitting a Job

Run the script from your terminal. Your API key can be passed via the SPLITSTEP_API_KEY environment variable (recommended) or directly with the --api-key flag:

# Using the SPLITSTEP_API_KEY environment variable (recommended)
SPLITSTEP_API_KEY=your_key python send_client.py path/to/job_request.json

# Or passing the key directly
python send_client.py path/to/job_request.json --api-key your_key

The script will print the immediate queuing response as JSON, for example:

{
  "job_id": "a1b2c3d4-...",
  "video_id": "your_match_id",
  "status": "queued",
  "message": "Job queued successfully"
}

If a required field is missing or invalid, the API will reject the request immediately with an error, for example:

{
  "detail": "Webhook URL is required"
}

Job Request Format

The job request is a JSON file with the following fields.

Field Type Description
MatchID string A unique identifier for this video.
VideoUrl string (URL) A publicly accessible URL to the video file (e.g. an Azure Blob SAS URL).
WebhookUrl string (URL) The URL that will receive a POST request when the job completes or fails. See Webhook Responses below.
InitialTopPlayer string Name of the player starting at the top of the court at the beginning of the video.
InitialBottomPlayer string Name of the player starting at the bottom of the court at the beginning of the video.
StartTime float Time in seconds from the start of the video to begin processing.
EndTime float Time in seconds from the start of the video to end processing.
SetGameScores array of [number, number] The game scores for each set, from the perspective of the top and bottom player respectively. Each entry is a two-element array [top_player_games, bottom_player_games]. For example, a match won 6–4, 6–1 by the top player would be [[6, 4], [6, 1]].
FixedCamera boolean Whether the camera is stationary (e.g. on a tripod or fence mount) throughout the match.
Ad boolean Whether advantage scoring is used. If true, a player must win two consecutive points after deuce to win the game.

Example

{
    "MatchID": "my_match_001",
    "VideoUrl": "https://example.blob.core.windows.net/videos/match.mp4?...",
    "WebhookUrl": "https://your-server.com/webhook/splitstep",
    "InitialTopPlayer": "Smith",
    "InitialBottomPlayer": "Jones",
    "StartTime": 120.0,
    "EndTime": 3600.0,
    "SetGameScores": [[6, 3], [7, 5]],
    "FixedCamera": true,
    "Ad": false
}

Video Guidelines

Specification Requirement
Resolution 1080p (1920×1080) or higher
Frame rate 30 fps minimum, 60 fps recommended
Format MP4 (H.264) preferred
File size Less than 5 GB
Length Adjust StartTime and EndTime to cover complete games, consistent with the set game scores provided in SetGameScores
Mode Singles only — doubles matches are not supported at this time

Webhook Responses

You will receive two webhook notifications per job: one when the job is first queued, and one when processing completes or fails.

Job Queued

Sent immediately after a successful submission:

{
  "job_id": "a1b2c3d4-...",
  "video_id": "my_match_001",
  "status": "queued",
  "message": "Job queued successfully"
}

Job Completed

Sent when processing finishes successfully:

{
  "job_id": "a1b2c3d4-...",
  "video_id": "my_match_001",
  "status": "job_completed",
  "message": "Job completed successfully",
  "sas_url": "https://...",
  "trimmed_video_url": "https://..."
}
Field Description
sas_url Azure Blob SAS URL to a JSON file containing the stroke-by-stroke analysis results, valid for 7 days.
trimmed_video_url Azure Blob SAS URL to the trimmed and re-encoded video used for processing, valid for 7 days.

Job Failed

Sent if an error occurs at any stage of processing:

{
  "job_id": "a1b2c3d4-...",
  "video_id": "my_match_001",
  "status": "job_failed",
  "message": "Failed to download video: <error details>"
}

The message field identifies which processing step failed and includes the underlying error message.

send_client.py

#!/usr/bin/env python3
import json

import click
import requests


@click.command()
@click.argument("job_request_path", type=click.Path(exists=True))
@click.option("--api-key", envvar="SPLITSTEP_API_KEY", required=True)
def send(job_request_path, api_key):
    """Send a job request to the SplitStep API.

    Parameters
    ----------
    job_request_path : str
        Path to a JSON file containing the job request payload.
    api_key : str
        API key for authenticating with the API. Falls back to the
        SPLITSTEP_API_KEY environment variable.
    """
    with open(job_request_path, "r") as f:
        data = json.load(f)

    response = requests.post(
        "https://api.example.com/jobs",  # dummy endpoint — replace with your assigned URL
        headers={"X-Api-Key": api_key, "Content-Type": "application/json"},
        json=data,
    )

    click.echo(json.dumps(response.json(), indent=2))


if __name__ == "__main__":
    send()

Ready to Get Started?

Contact us to get your API key and start processing matches.

Get in Touch