Remote API Operations
Every operation the Remote API offers, generated from MAGDA's operation
registry. The same catalogue is published as an OpenRPC 1.3
document, magda-openrpc.json, for client generators and API tools. A
running MAGDA returns the same operations and schemas from system.describe.
Parameters go by name in params. The types below are a summary: the OpenRPC document carries
each parameter's and result's full JSON Schema, including ranges, enums and size limits. Scope
is the permission the named client needs. A transport-scoped method is carried out by the
WebSocket connection itself rather than the project, and has no MCP tool.
Any method can also fail with the errors listed at the end of this page.
system
| Method |
Summary |
Scope |
Required params |
Optional params |
system.describe |
List the API version and every available operation |
read |
— |
— |
engine
| Method |
Summary |
Scope |
Required params |
Optional params |
engine.health |
Read engine binding, callback load, xruns, and recent problems |
read |
— |
— |
engine.renderRange |
Render an explicit project range to an absolute path |
edit |
path string
range object
format "wav" | "flac" | "opus" | "mp3"
sampleRate 44100 | 48000 | 88200 | 96000 | 176400 | 192000
bitDepth 16 | 24 | 32
dither "none" | "tpdf" | "shaped"
normalise boolean
normaliseToDb number
includeMasterEffects boolean
includeTrackEffects boolean
realTime boolean
tailSeconds number
overwritePolicy "fail" | "replace" |
bitrateKbps enum
vbrQuality integer |
engine.masterCapture.start |
Capture the true master callback output |
edit |
path string
format "wav" | "flac"
bitDepth 16 | 24 | 32
overwritePolicy "fail" | "replace" |
— |
engine.masterCapture.stop |
Stop and finalise one owned master capture |
edit |
jobId string |
— |
engine.masterCapture.status |
Read master-capture capability and activity |
read |
— |
— |
meters
| Method |
Summary |
Scope |
Required params |
Optional params |
meters.read |
Read one bounded track and master peak snapshot |
read |
— |
— |
jobs
| Method |
Summary |
Scope |
Required params |
Optional params |
jobs.list |
List asynchronous jobs owned by this connection |
read |
— |
— |
jobs.get |
Inspect one asynchronous job owned by this connection |
read |
jobId string |
— |
jobs.cancel |
Cancel one owned asynchronous job |
read |
jobId string |
— |
tracks
| Method |
Summary |
Scope |
Required params |
Optional params |
tracks.freeze |
Freeze a track: render it offline and play the render in its place |
edit |
trackId integer |
— |
tracks.unfreeze |
Unfreeze a track so its devices play live again |
edit |
trackId integer |
— |
tracks.list |
List tracks |
read |
— |
— |
tracks.get |
Get one track |
read |
trackId one of several shapes |
— |
tracks.create |
Create a track |
edit |
name string
type "audio" | "group" | "aux" | "chord" |
— |
tracks.createFromPreset |
Create a track from a saved track-chain preset |
edit |
presetId string |
— |
tracks.applyPreset |
Apply an opaque chain preset to an existing track |
edit |
trackId integer
presetId string |
— |
tracks.update |
Update track mixer, display, or input state |
edit |
trackId integer |
name string
volume number
pan number
muted boolean
soloed boolean
colourArgb integer
recordArmed boolean
inputMonitor "off" | "in" | "auto" |
tracks.delete |
Delete a track |
edit |
trackId integer |
— |
tracks.group |
Group tracks under a new group track |
edit |
trackIds array of integer
name string |
— |
tracks.move |
Move a track to a one-based position in the track list |
edit |
trackId integer
position integer |
— |
capture
| Method |
Summary |
Scope |
Required params |
Optional params |
capture.recentMaster |
KEEP: what was just played, as notes on the track that heard them when a MIDI device was played, else as master audio on a new track. A transport pass lands where it was heard, a phrase played while stopped at the playhead; at most bars bars (default: the Capture Length setting). Fails when the capture buffer is off |
edit |
— |
bars integer |
project
| Method |
Summary |
Scope |
Required params |
Optional params |
project.get |
Get safe project metadata |
read |
— |
— |
project.new |
Create an untitled project |
edit |
— |
discardUnsavedChanges boolean |
project.close |
Close the current project |
edit |
— |
discardUnsavedChanges boolean |
project.open |
Open a project from an absolute path |
edit |
path string
dirtyPolicy "fail" | "discard"
autosavePolicy "fail" | "recover" | "ignore"
missingMediaPolicy "fail" | "allow"
unavailableDevicePolicy "fail" | "allow" |
— |
project.save |
Save the project to its existing target |
edit |
— |
— |
project.saveAs |
Save to an absolute path |
edit |
path string
overwritePolicy "fail" | "replace"
mediaPolicy "copy" | "move" |
— |
project.setTempo |
Set the project tempo |
edit |
tempo number |
— |
project.setTimeSignature |
Set the project time signature |
edit |
numerator integer
denominator 1 | 2 | 4 | 8 | 16 | 32 |
— |
project.setLoopRange |
Set the project loop range in beats |
edit |
startBeat number
endBeat number |
— |
trackPresets
| Method |
Summary |
Scope |
Required params |
Optional params |
trackPresets.list |
List saved track-chain presets by opaque id |
read |
— |
— |
chordTrack
| Method |
Summary |
Scope |
Required params |
Optional params |
chordTrack.get |
Get the singleton chord track and ordered progression |
read |
— |
— |
chordTrack.ensure |
Create the singleton chord track when absent |
edit |
— |
— |
chordTrack.replaceProgression |
Replace the chord track's structured progression |
edit |
chords array of object |
voicing "root"
inversion 0
octave integer |
chordTrack.detect |
Detect a structured progression in a MIDI clip range |
read |
sourceClipId integer
startBeat number
endBeat number
windowBeats number |
— |
chordTrack.extract |
Detect and atomically materialise a chord-track progression |
edit |
sourceClipId integer
startBeat number
endBeat number
windowBeats number
destinationStartBeat number
populatedPolicy "fail" | "replace" | "merge"
voicing "root"
octave integer |
— |
chordTrack.sendToTrack |
Bake an addressed progression to a normal MIDI track |
edit |
sourceClipId integer
targetTrackId integer
startBeat number
occupiedPolicy "fail" | "replace"
voicing "source"
instrumentPolicy "preserve_target" | "require_existing" |
— |
routing
| Method |
Summary |
Scope |
Required params |
Optional params |
routing.endpoints.list |
List safe audio and MIDI routing endpoints |
read |
— |
— |
routing.get |
Get one track's audio and MIDI routing |
read |
trackId integer |
— |
routing.set |
Atomically set track audio and MIDI routes and MIDI channels. Any number of tracks may send their MIDI Out to one track; a channel of 0 is any in, as it is out |
edit |
trackId integer |
audioInputEndpointId string
midiInputEndpointId string
audioOutputEndpointId string
midiOutputEndpointId string
midiInputChannel integer
midiOutputChannel integer |
sends
| Method |
Summary |
Scope |
Required params |
Optional params |
sends.list |
List one track's sends |
read |
trackId integer |
— |
sends.create |
Create an atomic track send |
edit |
trackId integer
destinationEndpointId string |
level number
enabled boolean
position "pre_fader" | "post_fader" |
sends.update |
Update an atomic track send |
edit |
sendId string |
destinationEndpointId string
level number
enabled boolean
position "pre_fader" | "post_fader" |
sends.remove |
Remove an atomic track send |
edit |
sendId string |
— |
sidechains
| Method |
Summary |
Scope |
Required params |
Optional params |
sidechains.list |
List device and rack sidechains and their capabilities |
read |
— |
trackId one of several shapes |
sidechains.get |
Inspect one device or rack sidechain and its capabilities |
read |
ownerPath object |
— |
sidechains.set |
Atomically configure or clear one device or rack sidechain |
edit |
ownerPath object |
sourceEndpointId one of several shapes
type "audio" | "midi"
tapPoint "preFx" | "postFader"
gainDb number
enabled boolean
listen boolean
channelMapping "automatic" |
clips
| Method |
Summary |
Scope |
Required params |
Optional params |
clips.list |
List clips with optional track and view filters |
read |
— |
trackId integer
view "arrangement" | "session" |
clips.get |
Get one clip |
read |
clipId integer |
— |
clips.createMidi |
Create a MIDI clip |
edit |
lengthBeats number
placement object |
— |
clips.loadSample |
Load an audio file as a clip, as a drop onto a track does |
edit |
samplePath string
placement object |
— |
clips.addMidiNote |
Add a note to a MIDI clip |
edit |
clipId integer
note integer
velocity integer
startBeat number
lengthBeats number |
— |
clips.listMidiEvents |
List every expressive MIDI event in a clip |
read |
clipId integer |
— |
clips.addMidiEvents |
Atomically add MIDI events |
edit |
clipId integer
events array of one of several shapes |
— |
clips.updateMidiEvents |
Atomically update MIDI events by id |
edit |
clipId integer
events array of one of several shapes |
— |
clips.replaceMidiEvents |
Atomically replace every MIDI event in a clip |
edit |
clipId integer
events array of one of several shapes |
— |
clips.deleteMidiEvents |
Atomically delete MIDI events by id |
edit |
clipId integer
eventIds array of integer |
— |
clips.delete |
Delete a clip |
edit |
clipId integer |
— |
clips.move |
Move a clip to an arrangement position or session slot |
edit |
clipId integer
destination object |
— |
clips.resize |
Resize a clip from its start or end edge |
edit |
clipId integer
lengthBeats number
edge "start" | "end" |
— |
clips.duplicate |
Duplicate a clip to an arrangement position or session slot |
edit |
clipId integer
destination object |
— |
clips.update |
Update clip name, enabled state, or groove (played as a time bend) |
edit |
clipId integer |
name string
enabled boolean
grooveTemplate string |
clips.updateAudio |
Update an audio clip's playback mode, looping, source tempo, stretch, reverse, and fades |
edit |
clipId integer |
playback "free" | "beat"
looping boolean
sourceBpm number
stretch "off" | "signalsmith" | "soundtouch" | "soundtouch_hq"
reversed boolean
fadeInSeconds number
fadeOutSeconds number
fadeInCurve "linear" | "convex" | "concave" | "s_curve"
fadeOutCurve "linear" | "convex" | "concave" | "s_curve" |
clips.transpose |
Transpose every note in a MIDI clip by semitones |
edit |
clipId integer
semitones integer |
— |
clips.quantize |
Quantize a MIDI clip's notes to a beat grid; all notes when noteIndices is absent |
edit |
clipId integer
gridResolution number |
noteIndices array of integer
mode "start" | "length" | "start_and_length" |
clips.sliceNotes |
Slice a MIDI clip's notes into equal subdivisions; all notes when noteIndices is absent |
edit |
clipId integer
subdivisions integer |
noteIndices array of integer |
devices
| Method |
Summary |
Scope |
Required params |
Optional params |
devices.list |
List safe device and rack graph metadata |
read |
— |
trackId integer |
devices.catalog |
List devices that can be added, by catalogue id |
read |
— |
— |
devices.applyPreset |
Apply an opaque preset to an existing device |
edit |
devicePath object
presetId string |
— |
devices.replace |
Atomically replace a device while preserving its chain slot |
edit |
devicePath object
catalogId string |
presetId string |
devices.add |
Add a device from the catalogue to a track's FX chain or a rack chain |
edit |
catalogId string |
trackId integer
parentPath object
index integer |
devices.remove |
Remove a device |
edit |
devicePath object |
— |
devices.setBypassed |
Set a device's bypass state |
edit |
devicePath object
bypassed boolean |
— |
devices.setInsert |
Route an External Insert and set its MIDI CC knobs |
edit |
devicePath object |
sendDevice string
returnDevice string
midiChannel integer
ccDevice string
manualAdjustMs number
ccKnobs array of integer |
devices.move |
Move a device within its chain |
edit |
devicePath object
toIndex integer |
— |
devices.listParameters |
List a device's parameters, in real units, with customization flags |
read |
devicePath object |
— |
devices.setParameter |
Set one device parameter, in real units |
edit |
devicePath object
parameterIndex integer
value number |
— |
devices.setParameterConfig |
Update a device's saved parameter customization: the visible / mini-mixer / AI-agent selections and the per-plugin AI prompt |
edit |
devicePath object |
visibleParameters array of integer
miniMixerParameters array of integer
aiAgentParameters array of integer
aiPrompt string
parameterOverrides array of object |
devices.openEditor |
Open a device's plugin editor window |
edit |
devicePath object |
— |
pads
| Method |
Summary |
Scope |
Required params |
Optional params |
pads.list |
List all 64 slots of a Drum Grid |
read |
gridPath object |
— |
pads.create |
Create an empty pad chain |
edit |
gridPath object
padIndex integer |
— |
pads.setDevice |
Replace a pad voice with a catalogue device |
edit |
gridPath object
padIndex integer
catalogId string |
— |
pads.setSample |
Replace a pad voice with a sampler using a host-local audio file |
edit |
gridPath object
padIndex integer
samplePath string |
— |
pads.clear |
Clear one pad |
edit |
gridPath object
padIndex integer |
— |
pads.swap |
Swap two single-note pads |
edit |
gridPath object
padA integer
padB integer |
— |
pads.update |
Edit pad notes, level, pan, switches, and output bus |
edit |
gridPath object
padIndex integer |
lowNote integer
highNote integer
rootNote integer
levelDb number
pan number
muted boolean
solo boolean
bypassed boolean |
devicePresets
| Method |
Summary |
Scope |
Required params |
Optional params |
devicePresets.list |
List presets for a device by opaque id |
read |
devicePath object |
— |
mods
| Method |
Summary |
Scope |
Required params |
Optional params |
mods.list |
List modulators on a device |
read |
devicePath object |
— |
mods.create |
Create a device modulator |
edit |
devicePath object
type "lfo" | "envelope" | "random" | "follower" |
waveform "sine" | "triangle" | "square" | "saw" | "reverse_saw" | "custom"
name string
rate number
enabled boolean
tempoSync boolean
syncDivision enum
oneShot boolean
attackMs number
decayMs number
sustain number
releaseMs number
parameterIndex integer
amount number
bipolar boolean |
mods.update |
Update a device modulator |
edit |
devicePath object
modId integer |
name string
type "lfo" | "envelope" | "random" | "follower"
waveform "sine" | "triangle" | "square" | "saw" | "reverse_saw" | "custom"
rate number
enabled boolean
tempoSync boolean
syncDivision enum
oneShot boolean
attackMs number
decayMs number
sustain number
releaseMs number |
mods.remove |
Remove a device modulator |
edit |
devicePath object
modId integer |
— |
mods.link |
Link a modulator to an AI-enabled device parameter |
edit |
devicePath object
modId integer
parameterIndex integer
amount number |
bipolar boolean |
mods.unlink |
Remove a modulator's parameter link |
edit |
devicePath object
modId integer
parameterIndex integer |
— |
macros
| Method |
Summary |
Scope |
Required params |
Optional params |
macros.list |
List device macros and their links |
read |
devicePath object |
— |
macros.setValue |
Set a device macro value |
edit |
devicePath object
macroIndex integer
value number |
— |
macros.link |
Link a macro to an AI-enabled device parameter |
edit |
devicePath object
macroIndex integer
parameterIndex integer
amount number |
bipolar boolean |
macros.unlink |
Remove a macro's parameter link |
edit |
devicePath object
macroIndex integer
parameterIndex integer |
— |
racks
| Method |
Summary |
Scope |
Required params |
Optional params |
racks.create |
Create a rack on a track or inside a rack chain |
edit |
name string |
trackId integer
parentPath object Exactly one of: trackId, parentPath |
racks.remove |
Remove a rack at any nesting depth |
edit |
— |
trackId integer
rackId integer
rackPath object Exactly one of: trackId + rackId, rackPath |
racks.setBypassed |
Set rack bypass |
edit |
bypassed boolean |
trackId integer
rackId integer
rackPath object Exactly one of: trackId + rackId, rackPath |
racks.update |
Update a rack at any nesting depth |
edit |
rackPath object |
bypassed boolean
volumeDb number
chainSelector number |
chains
| Method |
Summary |
Scope |
Required params |
Optional params |
chains.create |
Create a chain inside a rack at any nesting depth |
edit |
rackPath object
name string |
— |
chains.remove |
Remove a chain from a rack at any nesting depth |
edit |
chainPath object |
— |
chains.update |
Update a chain at any nesting depth |
edit |
chainPath object |
name string
outputIndex integer
muted boolean
solo boolean
bypassed boolean
volumeDb number
pan number
zones object |
selection
| Method |
Summary |
Scope |
Required params |
Optional params |
selection.get |
Get the current selection |
read |
— |
— |
selection.set |
Replace the current track, clip, or note selection |
edit |
trackId one of several shapes
clipId integer | null
clipIds array of integer
automationLaneId integer | null
automationClipId integer | null
noteClipId integer | null
noteIndices array of integer |
— |
transport
| Method |
Summary |
Scope |
Required params |
Optional params |
transport.get |
Get transport state |
read |
— |
— |
transport.play |
Start playback |
transport |
— |
— |
transport.stop |
Stop playback |
transport |
— |
— |
transport.setRecording |
Set recording state |
transport |
recording boolean |
— |
transport.setLoopEnabled |
Set transport loop state |
transport |
enabled boolean |
— |
transport.seek |
Seek the transport in beats |
transport |
positionBeats number |
— |
transport.seekRelative |
Move the transport by beats or bars, clamped at zero |
transport |
— |
deltaBeats number
deltaBars integer Exactly one of: deltaBeats, deltaBars |
session
| Method |
Summary |
Scope |
Required params |
Optional params |
session.get |
Get scenes, tracks, and every session slot state |
read |
— |
— |
session.createScene |
Create a durable session scene |
edit |
— |
index integer
name string
colourArgb integer |
session.updateScene |
Atomically update session scene metadata |
edit |
sceneId integer |
name string
colourArgb integer At least one of: name, colourArgb |
session.moveScene |
Move a session scene by stable id |
edit |
sceneId integer
toIndex integer |
— |
session.duplicateScene |
Duplicate a scene with explicit clip-copy behaviour |
edit |
sceneId integer
copyClips boolean |
— |
session.deleteScene |
Delete a scene with an explicit populated-slot policy |
edit |
sceneId integer
populatedPolicy "fail" | "deleteClips" | "moveClips" |
destinationSceneId integer Allowed combinations: see x-params-schema. |
session.launchClip |
Launch a session clip |
session |
clipId integer |
— |
session.stopClip |
Stop a session clip |
session |
clipId integer |
— |
session.stopTrack |
Stop the active session clip on a track |
session |
trackId integer |
— |
session.stopAll |
Stop all session clips |
session |
— |
— |
session.launchScene |
Launch a session scene |
session |
sceneIndex integer |
— |
session.updateClipSettings |
Atomically update session clip launch behaviour |
edit |
clipId integer |
launchMode "trigger" | "toggle"
launchQuantize enum
followAction "none" | "next" | "previous" | "random" | "stop" | "again"
followActionDelayBeats number
followActionLoopCount integer At least one of: launchMode, launchQuantize, followAction, followActionDelayBeats, followActionLoopCount |
session.returnToArrangement |
Return one or every track to arrangement playback |
session |
— |
trackId integer |
session.recordingCapabilities |
Inspect Session recording support and stop policy |
read |
— |
— |
session.armSlotRecording |
Arm or unarm an empty addressed Session slot |
session |
trackId integer
sceneId integer
armed boolean
occupiedPolicy "fail" |
— |
session.beginSlotRecording |
Begin a queued slot take as an asynchronous job |
session |
trackId integer
sceneId integer
occupiedPolicy "fail" |
— |
session.stopSlotRecording |
Stop a slot take and complete its recording job |
session |
jobId string |
— |
session.beginPerformanceCapture |
Capture launched Session performance into Arrangement as an asynchronous job |
session |
— |
— |
session.stopPerformanceCapture |
Stop and commit a Session performance capture |
session |
jobId string |
— |
automation
| Method |
Summary |
Scope |
Required params |
Optional params |
automation.listLanes |
List every automation lane in the project |
read |
— |
— |
automation.getLane |
Get an automation lane |
read |
laneId integer |
— |
automation.createLane |
Create an automation lane |
edit |
target object
type "absolute" | "clip_based" |
— |
automation.addPoint |
Add a point to an automation lane |
edit |
laneId integer
beatPosition number
value number
curve "linear" | "bezier" | "step" | "hard_corner" |
— |
automation.setPoints |
Replace every point on an absolute automation lane |
edit |
laneId integer
points array of object |
— |
automation.clearLane |
Remove all points from an automation lane |
edit |
laneId integer |
— |
automation.deleteLane |
Delete an automation lane and its clips |
edit |
laneId integer |
— |
automation.listClips |
List automation clips, optionally filtered by lane |
read |
— |
laneId integer |
automation.getClip |
Get an automation clip |
read |
clipId integer |
— |
automation.createClip |
Create a clip on a clip-based automation lane |
edit |
laneId integer
startBeat number
lengthBeats number |
— |
automation.deleteClip |
Delete an automation clip |
edit |
clipId integer |
— |
automation.moveClip |
Move an automation clip |
edit |
clipId integer
startBeat number |
— |
automation.resizeClip |
Resize an automation clip from either edge |
edit |
clipId integer
lengthBeats number
edge "start" | "end" |
— |
automation.duplicateClip |
Duplicate an automation clip after its source |
edit |
clipId integer |
— |
automation.updateClip |
Update automation clip metadata, looping, or points |
edit |
clipId integer |
name string
colourArgb integer
looping boolean
loopLengthBeats number
points array of object |
grooves
| Method |
Summary |
Scope |
Required params |
Optional params |
grooves.list |
List groove template names |
read |
— |
— |
grooves.upsert |
Create or replace a groove template; latenessProportions is one entry per grid slot, -1..1 of the slot length |
edit |
name string
notesPerBeat integer
latenessProportions array of number |
parameterized boolean |
focused
| Method |
Summary |
Scope |
Required params |
Optional params |
focused.get |
Get the focused device or rack and its macro page |
read |
— |
— |
focused.setMacro |
Write a normalized value to a macro on the focused device |
edit |
index integer
value number |
— |
focused.cycleDevice |
Move device focus to the previous or next top-level chain node |
edit |
direction -1 | 1 |
— |
midi
| Method |
Summary |
Scope |
Required params |
Optional params |
midi.listOutputPorts |
List available MIDI output port names |
read |
— |
— |
midi.send |
Send one channel message to a MIDI output, as status-first raw bytes |
hardware-midi |
port string
bytes array of integer |
— |
midi.sendSysEx |
Send a SysEx payload to a MIDI output; F0/F7 framing is added |
hardware-midi |
port string
bytes array of integer |
— |
subscriptions
| Method |
Summary |
Scope |
Required params |
Optional params |
subscriptions.subscribe |
Start receiving change events for the given topics, with an initial snapshot (transport-scoped) |
read |
topics array of enum |
snapshot boolean |
subscriptions.unsubscribe |
Stop receiving change events; no topics means every topic (transport-scoped) |
read |
— |
topics array of enum |
subscriptions.list |
List the topics this connection is subscribed to (transport-scoped) |
read |
— |
— |
subscriptions.resync |
Re-send a complete snapshot for the subscribed topics (transport-scoped) |
read |
— |
topics array of enum |
Errors
| JSON-RPC code |
error.data.code |
Meaning |
-32700 |
— |
Malformed JSON. |
-32600 |
invalid_request |
Invalid JSON-RPC framing or unsupported route. |
-32601 |
unknown_operation |
Unknown method. |
-32602 |
validation_failed |
params did not satisfy the method's input schema. |
-32603 |
internal_error |
Unexpected server failure. |
-32001 |
not_found |
A referenced project entity does not exist. |
-32002 |
conflict |
State or revision conflicts with the request. |
-32003 |
timeout |
The request missed its deadline. |
-32004 |
cancelled |
Work was cancelled. |
-32005 |
— |
Connection request rate or in-flight limit exceeded. |
-32006 |
permission_denied |
The client's grant does not include the method's scope. |