Skip to content

REST API

Producer Pal includes a REST API for building custom scripts, automation, and integrations using plain HTTP requests — no MCP SDK needed. It also works as an alternative interface for coding agents: download this page as Markdown (button at the top) and give it to your agent for a complete reference.

The REST API runs on the same server as the MCP endpoint (default port 3350) and is available whenever the Producer Pal Max for Live device is running.

This is for developers

Most users don't need the REST API. The normal way to use Producer Pal is through an AI chat client like Claude Desktop — see the Installation guide to get started.

Endpoints

List Tools

GET http://localhost:3350/api/tools

Returns all enabled tools with their JSON Schema input definitions:

json
{
  "tools": [
    {
      "name": "ppal-read-live-set",
      "title": "Read Live Set",
      "description": "Read an overview of the Live Set...",
      "annotations": { "readOnlyHint": true, "destructiveHint": false },
      "inputSchema": { "type": "object", "properties": { ... } }
    }
  ]
}

Call a Tool

POST http://localhost:3350/api/tools/{toolName}
Content-Type: application/json

{ "trackIndex": 0, "include": ["session-clips"] }

Returns:

json
{ "result": "...", "isError": false }
  • 200 with isError: false — tool ran successfully
  • 200 with isError: true — tool ran but reported an error (e.g. invalid path, execution error)
  • 404 — unknown or disabled tool
  • 400 — invalid input (includes validation details)

Warnings from the Live API appear inline in the result text, prefixed with WARNING:. The ppal-update-* tools use this when updating multiple objects — if any individual operation fails or is inapplicable (e.g. setting quantize on an audio clip), it emits a warning and continues with the rest.

Quick Start with curl

bash
# Read the Live Set overview
curl -X POST http://localhost:3350/api/tools/ppal-read-live-set \
  -H 'Content-Type: application/json' -d '{}'

# Read track 0 with all clips
curl -X POST http://localhost:3350/api/tools/ppal-read-track \
  -H 'Content-Type: application/json' \
  -d '{"trackIndex": 0, "include": ["session-clips", "arrangement-clips"]}'

# List available tools
curl http://localhost:3350/api/tools

Sample Scripts

These scripts have no dependencies — they use only built-in HTTP libraries. Copy and modify them for your own integrations.

Node.js

Requires Node.js 18+ (for built-in fetch).

js
#!/usr/bin/env node

// Producer Pal REST API example (Node.js, no dependencies)
// Requires Node.js 18+ for built-in fetch
//
// Usage: node producer-pal.mjs

const BASE_URL = "http://localhost:3350";

/** List all available tools */
async function listTools() {
  const res = await fetch(`${BASE_URL}/api/tools`);
  if (!res.ok) throw new Error(`HTTP ${res.status}: ${await res.text()}`);
  const body = await res.json();
  return body.tools;
}

/** Call a Producer Pal tool by name */
async function callTool(name, args = {}) {
  const res = await fetch(`${BASE_URL}/api/tools/${name}`, {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify(args),
  });
  if (!res.ok) throw new Error(`HTTP ${res.status}: ${await res.text()}`);
  return res.json();
}

// --- Example usage ---

async function main() {
  // List available tools
  console.log("Available tools:");
  const tools = await listTools();
  for (const tool of tools) {
    console.log(`  ${tool.name} - ${tool.description.slice(0, 60)}...`);
  }

  // Inspect a tool's input schema
  const readTrack = tools.find((t) => t.name === "ppal-read-track");
  console.log(`\nSchema for ${readTrack.name}:`);
  console.log(JSON.stringify(readTrack.inputSchema, null, 2));

  // Read tracks in the Live Set
  console.log("\nReading tracks...");
  const tracks = await callTool("ppal-read-live-set");
  console.log(tracks.result);

  // Read a specific track with all clips
  console.log("\nReading track 0 with clips...");
  const track = await callTool("ppal-read-track", {
    trackIndex: 0,
    include: ["session-clips", "arrangement-clips"],
  });
  console.log(track.result);
}

main().catch((err) => {
  if (err.cause?.code === "ECONNREFUSED") {
    console.error(
      "Could not connect to Producer Pal. Is Ableton Live running with the Producer Pal device?",
    );
  } else {
    console.error(err);
  }
  process.exit(1);
});

Python

Works with Python 3.6+ (no dependencies).

py
#!/usr/bin/env python3

"""Producer Pal REST API example (Python, no dependencies).

Usage: python producer_pal.py
"""

import json
import sys
import urllib.error
import urllib.request

BASE_URL = "http://localhost:3350"


def list_tools():
    """List all available tools."""
    req = urllib.request.Request(f"{BASE_URL}/api/tools")
    with urllib.request.urlopen(req) as res:
        return json.loads(res.read())["tools"]


def call_tool(name, args=None):
    """Call a Producer Pal tool by name."""
    data = json.dumps(args or {}).encode()
    req = urllib.request.Request(
        f"{BASE_URL}/api/tools/{name}",
        data=data,
        headers={"Content-Type": "application/json"},
        method="POST",
    )
    with urllib.request.urlopen(req) as res:
        return json.loads(res.read())


def main():
    # List available tools
    print("Available tools:")
    tools = list_tools()
    for tool in tools:
        print(f"  {tool['name']} - {tool['description'][:60]}...")

    # Inspect a tool's input schema
    read_track = next(t for t in tools if t["name"] == "ppal-read-track")
    print(f"\nSchema for {read_track['name']}:")
    print(json.dumps(read_track["inputSchema"], indent=2))

    # Read tracks in the Live Set
    print("\nReading tracks...")
    tracks = call_tool("ppal-read-live-set")
    print(tracks["result"])

    # Read a specific track with all clips
    print("\nReading track 0 with clips...")
    track = call_tool("ppal-read-track", {
        "trackIndex": 0,
        "include": ["session-clips", "arrangement-clips"],
    })
    print(track["result"])


if __name__ == "__main__":
    try:
        main()
    except urllib.error.URLError as e:
        if "Connection refused" in str(e.reason):
            print(
                "Could not connect to Producer Pal."
                " Is Ableton Live running with the Producer Pal device?",
                file=sys.stderr,
            )
        else:
            raise
        sys.exit(1)

Tool Reference

Use the list tools endpoint to discover all available tools and their input schemas at runtime. You can also browse the full tool documentation on the Features page.

Raw Live API

The ppal-raw-live-api tool provides direct access to the Ableton Live Object Model for development, scripting, and debugging. It is always available via the REST API regardless of tool configuration.

WARNING

This is a development tool for scripting and debugging. It can read and modify any Live Set property — use it with care.

Request structure

The path parameter sets the initial Live Object Model object to operate on (e.g., "live_set", "live_set tracks 0", "live_set tracks 0 clip_slots 1 clip"). The operations array is then executed sequentially on that object. Use goto to navigate to a different object mid-sequence.

Available operation types:

TypeProperties usedDescription
get_property / getpropertyRead a property value
set_property / setproperty, valueWrite a property value
call_method / callmethod, args (optional)Call a method
gotovalue (path)Navigate to a different object
infoGet object info
getPropertypropertyAlias for get_property
getChildIdsproperty (child type)Get child object IDs
existsCheck if the object exists
getColorRead object color
setColorvalue (hex string)Write object color

Examples

bash
# Get the tempo
curl -X POST http://localhost:3350/api/tools/ppal-raw-live-api \
  -H 'Content-Type: application/json' \
  -d '{
    "path": "live_set",
    "operations": [{"type": "get_property", "property": "tempo"}]
  }'

# Set the tempo to 140 BPM
curl -X POST http://localhost:3350/api/tools/ppal-raw-live-api \
  -H 'Content-Type: application/json' \
  -d '{
    "path": "live_set",
    "operations": [{"type": "set_property", "property": "tempo", "value": 140}]
  }'

# Fire scene 0
curl -X POST http://localhost:3350/api/tools/ppal-raw-live-api \
  -H 'Content-Type: application/json' \
  -d '{
    "path": "live_set",
    "operations": [{"type": "call", "method": "fire_scene_at_index", "args": [0]}]
  }'

# Chain multiple operations on one object
curl -X POST http://localhost:3350/api/tools/ppal-raw-live-api \
  -H 'Content-Type: application/json' \
  -d '{
    "path": "live_set tracks 0",
    "operations": [
      {"type": "get", "property": "name"},
      {"type": "get", "property": "color_index"},
      {"type": "get", "property": "has_midi_input"}
    ]
  }'

INFO

This tool is always available via the REST API. It is only available via MCP when the ENABLE_RAW_LIVE_API environment variable is set at build time (npm run build:debug).

Tips

  • The inputSchema in the tool list response is standard JSON Schema, so you can use it for client-side validation or code generation.
  • The REST API shares the same tool configuration as MCP — tools enabled or disabled on the device apply to both interfaces.
  • The REST API has no authentication (same as the MCP endpoint). It is designed for use on localhost or trusted networks only.

Released under the GPL-3.0 License.