REST Gateway Quick Start

Get up and running with the OpenCue REST Gateway for HTTP/REST API access to your render farm.

Table of contents
  1. Overview
    1. What you’ll learn
    2. Prerequisites
  2. Step 1: Start the OpenCue Stack
  3. Step 2: Deploy the REST Gateway
    1. Generate a JWT Secret
    2. Build the REST Gateway Image
    3. Run the REST Gateway
    4. Verify the Gateway is Running
  4. Step 3: Generate a JWT Token
    1. Using Python (Recommended)
    2. Using Pure Bash (Alternative)
  5. Step 4: Make Your First API Call
    1. Get All Shows
    2. Get Jobs for a Show
    3. Get Available Hosts
  6. Step 5: Browse the API in Swagger UI
    1. Authorize
    2. Send a request
  7. Step 6: Basic Operations
    1. Find a Specific Show
    2. Find a Specific Job
    3. Pause a Job
    4. Resume a Job
    5. Get Frames for a Job
    6. Retry a Failed Frame
  8. Quick Reference
    1. Environment Setup
    2. Common Endpoints
    3. URL Pattern
    4. Documentation Routes
  9. Troubleshooting
    1. 401 Unauthorized
    2. Connection Refused
    3. 502 Bad Gateway
    4. Empty Response
  10. Using with Scripts
    1. Bash Script Example
    2. Python Script Example
  11. Deploy with OpenCueWeb
  12. Next Steps
  13. Related Documentation

Overview

The OpenCue REST Gateway provides HTTP/REST endpoints for OpenCue’s gRPC API. It enables web applications, scripts, and HTTP clients to interact with your render farm without requiring gRPC clients.

What you’ll learn

  • How to deploy the REST Gateway
  • How to authenticate with JWT tokens
  • How to make your first API calls
  • How to browse and test the API in Swagger UI
  • Basic job and show operations

Prerequisites

Before you begin, ensure you have:

  • OpenCue stack running (Cuebot and PostgreSQL)
  • Docker installed on your system
  • curl for testing API calls
  • Python 3 (optional, for JWT token generation)

Step 1: Start the OpenCue Stack

If you don’t have OpenCue running yet, start it from the repository root:

# Clone OpenCue if needed
git clone https://github.com/AcademySoftwareFoundation/OpenCue.git
cd OpenCue

# Create required directories
mkdir -p /tmp/rqd/logs /tmp/rqd/shots

# Start OpenCue stack
docker compose up -d

# Verify services are running
docker compose ps

Wait for the services to be healthy before proceeding.


Step 2: Deploy the REST Gateway

The REST Gateway is deployed separately from the main OpenCue stack.

Generate a JWT Secret

# Generate a secure JWT secret
export JWT_SECRET=$(openssl rand -base64 32)
echo "Your JWT_SECRET: $JWT_SECRET"
echo "Save this - you'll need it for API authentication"

Build the REST Gateway Image

# From OpenCue root directory
docker build -f rest_gateway/Dockerfile -t opencue/rest-gateway:latest .

Run the REST Gateway

docker run -d --name opencue-rest-gateway \
  --network opencue_default \
  -p 8448:8448 \
  -e CUEBOT_ENDPOINT=cuebot:8443 \
  -e JWT_SECRET="$JWT_SECRET" \
  -e REST_PORT=8448 \
  -e LOG_LEVEL=info \
  opencue/rest-gateway:latest

Verify the Gateway is Running

# Test connectivity (expects 401 - this confirms the service is up)
response=$(curl -s -o /dev/null -w "%{http_code}" http://localhost:8448/)
if [ "$response" = "401" ]; then
    echo "REST Gateway is running (401 expected without auth)"
else
    echo "REST Gateway may not be running (got HTTP $response)"
fi

Step 3: Generate a JWT Token

All REST Gateway API endpoints require JWT authentication. The Swagger UI on /swagger/ is the only exception; it serves documentation without a token. Generate a token using Python:

# Install PyJWT if needed
pip install PyJWT

# Generate token
export JWT_TOKEN=$(python3 -c "
import jwt
import datetime
import os

secret = os.getenv('JWT_SECRET')
payload = {
    'user': 'quickstart',
    'exp': datetime.datetime.now(datetime.timezone.utc) + datetime.timedelta(hours=24)
}
print(jwt.encode(payload, secret, algorithm='HS256'))
")

echo "Your JWT_TOKEN: $JWT_TOKEN"

Using Pure Bash (Alternative)

# Generate a simple test token
export JWT_TOKEN=$(python3 -c "
import base64, hmac, hashlib, json, time, os

secret = os.getenv('JWT_SECRET', 'test-secret')
header = {'alg': 'HS256', 'typ': 'JWT'}
payload = {'sub': 'quickstart', 'exp': int(time.time()) + 86400}

h = base64.urlsafe_b64encode(json.dumps(header).encode()).decode().rstrip('=')
p = base64.urlsafe_b64encode(json.dumps(payload).encode()).decode().rstrip('=')
m = f'{h}.{p}'
s = base64.urlsafe_b64encode(hmac.new(secret.encode(), m.encode(), hashlib.sha256).digest()).decode().rstrip('=')
print(f'{m}.{s}')
")

Step 4: Make Your First API Call

Get All Shows

curl -X POST http://localhost:8448/show.ShowInterface/GetShows \
  -H "Authorization: Bearer $JWT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{}'

Expected response:

{
  "shows": {
    "shows": [
      {
        "id": "00000000-0000-0000-0000-000000000000",
        "name": "testing",
        "active": true,
        "bookingEnabled": true,
        "dispatchEnabled": true
      }
    ]
  }
}

Get Jobs for a Show

curl -X POST http://localhost:8448/job.JobInterface/GetJobs \
  -H "Authorization: Bearer $JWT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"r": {"show": {"name": "testing"}}}'

Get Available Hosts

curl -X POST http://localhost:8448/host.HostInterface/GetHosts \
  -H "Authorization: Bearer $JWT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{}'

Step 5: Browse the API in Swagger UI

Rather than working from curl alone, open the built-in Swagger UI:

open http://localhost:8448/swagger/

One OpenAPI definition is generated per OpenCue .proto file, and each appears in the Select a definition menu in the top bar. A definition can hold more than one interface: Job Service alone covers JobInterface, LayerInterface, FrameInterface, and GroupInterface. Pick one to browse it:

Swagger UI showing the ShowInterface endpoints

Authorize

Click Authorize and paste the $JWT_TOKEN you generated in Step 3. The Bearer prefix is optional; the page adds it for you.

The Authorize dialog

Once authorized, the padlocks on each endpoint close and every request you send from the page carries your token:

Swagger UI after authorizing

Send a request

Expand an endpoint, click Try it out, edit the JSON body if needed, and click Execute. Swagger UI shows the exact curl command it ran, the request URL, and the live response from your farm:

A live 200 response from GetShows

The curl command is copy-pasteable, which makes the Swagger UI a quick way to build up requests before scripting them.

Note: The Swagger UI is served without authentication so the API can be browsed. The API endpoints themselves still require a token. If your gateway is reachable beyond a trusted network, disable the UI with SWAGGER_ENABLED=false.


Step 6: Basic Operations

Find a Specific Show

curl -X POST http://localhost:8448/show.ShowInterface/FindShow \
  -H "Authorization: Bearer $JWT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"name": "testing"}'

Find a Specific Job

curl -X POST http://localhost:8448/job.JobInterface/FindJob \
  -H "Authorization: Bearer $JWT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"name": "testing-job-name"}'

Pause a Job

JOB_ID="your-job-id-here"

curl -X POST http://localhost:8448/job.JobInterface/Pause \
  -H "Authorization: Bearer $JWT_TOKEN" \
  -H "Content-Type: application/json" \
  -d "{\"job\": {\"id\": \"$JOB_ID\"}}"

Resume a Job

curl -X POST http://localhost:8448/job.JobInterface/Resume \
  -H "Authorization: Bearer $JWT_TOKEN" \
  -H "Content-Type: application/json" \
  -d "{\"job\": {\"id\": \"$JOB_ID\"}}"

Get Frames for a Job

curl -X POST http://localhost:8448/job.JobInterface/GetFrames \
  -H "Authorization: Bearer $JWT_TOKEN" \
  -H "Content-Type: application/json" \
  -d "{\"job\": {\"id\": \"$JOB_ID\"}, \"req\": {\"include_finished\": true, \"page\": 1, \"limit\": 100}}"

Retry a Failed Frame

FRAME_ID="your-frame-id-here"

curl -X POST http://localhost:8448/frame.FrameInterface/Retry \
  -H "Authorization: Bearer $JWT_TOKEN" \
  -H "Content-Type: application/json" \
  -d "{\"frame\": {\"id\": \"$FRAME_ID\"}}"

Quick Reference

Environment Setup

# Set these variables for easier testing
export GATEWAY_URL="http://localhost:8448"
export JWT_SECRET="your-jwt-secret"
export JWT_TOKEN="your-generated-token"

Common Endpoints

Operation Endpoint Method
List shows show.ShowInterface/GetShows POST
Find show show.ShowInterface/FindShow POST
List jobs job.JobInterface/GetJobs POST
Find job job.JobInterface/FindJob POST
Pause job job.JobInterface/Pause POST
Resume job job.JobInterface/Resume POST
Kill job job.JobInterface/Kill POST
Get frames job.JobInterface/GetFrames POST
Retry frame frame.FrameInterface/Retry POST
Kill frame frame.FrameInterface/Kill POST
List hosts host.HostInterface/GetHosts POST
Find host host.HostInterface/FindHost POST

URL Pattern

All endpoints follow this pattern:

POST http://<gateway-host>:8448/<interface>/<method>

Documentation Routes

Route Purpose Auth required
/swagger/ Interactive Swagger UI No
/swagger/specs/<name>.swagger.json A single OpenAPI definition No
/swagger/assets/ Swagger UI JavaScript and CSS No

The full list of definitions is discovered automatically; GET /swagger/ reflects whatever the gateway was built with. It holds 18 definitions and 304 endpoints, of which 273 are routed. Cue, Monitoring, RenderPartition, Report and Rqd are listed but return 404, and Criterion Service contains no endpoints. See Definitions the Gateway Does Not Route.


Troubleshooting

401 Unauthorized

Problem: API returns 401 error

Solutions:

  1. Verify JWT token is not expired
  2. Check JWT_SECRET matches between token and gateway
  3. Ensure Authorization: Bearer <token> header is correct
# Verify your secret matches
docker logs opencue-rest-gateway | grep -i jwt

Connection Refused

Problem: Cannot connect to gateway

Solutions:

  1. Check gateway container is running:
    docker ps | grep rest-gateway
    
  2. Verify port mapping:
    docker port opencue-rest-gateway
    
  3. Check gateway logs:
    docker logs opencue-rest-gateway
    

502 Bad Gateway

Problem: Gateway cannot connect to Cuebot

Solutions:

  1. Verify Cuebot is running and healthy
  2. Check CUEBOT_ENDPOINT environment variable
  3. Ensure containers are on same network:
    docker network inspect opencue_default
    

Empty Response

Problem: API returns empty data

Solutions:

  1. Check if data exists (e.g., shows created, jobs submitted)
  2. Verify filter parameters are correct
  3. Try without filters first

Using with Scripts

Bash Script Example

#!/bin/bash
# list_jobs.sh - List all jobs for a show

SHOW_NAME="${1:-testing}"

curl -s -X POST http://localhost:8448/job.JobInterface/GetJobs \
  -H "Authorization: Bearer $JWT_TOKEN" \
  -H "Content-Type: application/json" \
  -d "{\"r\": {\"show\": {\"name\": \"$SHOW_NAME\"}}}" | jq '.jobs.jobs[] | {name, state, user}'

Python Script Example

Note: pip install requests required to run the script below!

#!/usr/bin/env python3
# list_shows.py - List all shows

import requests
import os

GATEWAY_URL = os.getenv('GATEWAY_URL', 'http://localhost:8448')
JWT_TOKEN = os.getenv('JWT_TOKEN')

headers = {
    'Authorization': f'Bearer {JWT_TOKEN}',
    'Content-Type': 'application/json'
}

response = requests.post(
    f'{GATEWAY_URL}/show.ShowInterface/GetShows',
    headers=headers,
    json={}
)

shows = response.json().get('shows', {}).get('shows', [])
for show in shows:
    print(f"Show: {show['name']} (active: {show.get('active', False)})")

Deploy with OpenCueWeb

For a complete web interface, deploy OpenCueWeb alongside the REST Gateway using the cueweb profile:

# Start core services + Web UI (REST Gateway + OpenCueWeb)
docker compose --profile cueweb up -d

This deploys:

  • OpenCueWeb: http://localhost:3000
  • REST Gateway: http://localhost:8448
  • Cuebot: localhost:8443
  • RQD: localhost:8444
  • PostgreSQL: localhost:5432

Next Steps

Now that the REST Gateway is running:

  1. Explore the API: Try different endpoints from the REST API Reference
  2. Build integrations: Create scripts or applications using the API
  3. Deploy OpenCueWeb: Set up the web interface for browser access
  4. Production setup: Review Deploying REST Gateway for production configuration


Back to top