BOP 3.5.0: API, INSTRUMENTS AND FRONTEND Composition, inspection and edits work by fetching website URLs. No repository, installation or browser execution is required for those API operations. Audio rendering and audio reports run in the user's browser; a fetch-only agent cannot run them itself. POST is optional. The direct host accepts 15,000 encoded characters. Discovery: https://bop-api.sahildev.com/bop/api/v3 Example: https://sahildev.com/bop/for-ai/v3-example.json Schemas: https://bop-api.sahildev.com/bop/api/v3/schema/arrangement https://bop-api.sahildev.com/bop/api/v3/schema/edit https://bop-api.sahildev.com/bop/api/v3/schema/inspect https://bop-api.sahildev.com/bop/api/v3/schema/import Sound search: https://bop-api.sahildev.com/bop/api/v3/sounds?q=guitar&limit=8 Sound details: https://sahildev.com/bop/api/sounds/ Mix/synthesis guidance: https://sahildev.com/bop/sound-guide.txt RELEASE 3.5.0: BROWSER FEEDBACK AND ONE COORDINATED VERSION API responses include apiVersion:"3.5.0" and release:{version,api,instruments,frontend}, all "3.5.0". The /api/v3 path and score version:3 remain format/major contracts. Public release metadata: https://sahildev.com/bop/release.json New revision editor/player links pin the browser runtime and native song to their creation release. renderVersion identifies it; null means an older unpinned revision. Edits create a new revision using the current release. Save editable project/native files for retention beyond the revision service's expiration period. For audio feedback, ask the user to open File > Export > .json (audio report for agents), then share the report plus listening feedback. The browser measures the mix and each track locally at 48 kHz. It does not upload audio or call a render API. Reports include release, songSha256 (SHA-256 of the native URL fragment), barOrder, and passes. Each pass has a track number/name, summary and compact bar rows with columns given by barColumns: bar,passBar,startSeconds,rmsDbFS,samplePeakDbFS, clippedSamples. Null dB values mean digital silence. Repeated bars use passBar to distinguish occurrences. Use these measurements to find unexpected silence, sample clipping or large level changes. They are not LUFS, oversampled true peak, a masking detector or a musical-quality score. Do not claim to hear audio from the report. The same export dialog supports Full mix or one Audio track for an aligned WAV/MP3 stem. Use identical intro/loop/outro settings for all stems. Independent track renders have their own effects/output dynamics and may not sum exactly to the mix. SECTION EDITS AND REUSABLE MIXES The endpoint remains /api/v3 and project version remains 3. Discovery and responses report apiVersion:"3.5.0". Existing revision links continue to work. Reuse mix settings by adding a root mixes dictionary when composing: "mixes":{"distant":{"level":43,"reverb":67,"controls":{"brightnessHz":4000}}} Or save/replace one in an edit batch: {"op":"mixPreset","id":"distant","value":{"level":43,"reverb":67}} Preset fields: level, pan, reverb, atmosphere, controls. Maximum 32 presets. Inspect them with /revisions//mixes (or inspect view:"mixes"). Apply to several tracks and every chorus with one edit: {"op":"mix","tracks":["violin","sax"],"section":"chorus","use":"distant"} Add occurrence:2 for only the second chorus. bars:[1,4] is inclusive and relative to the section; omit section for absolute song bars. Omit selectors for global mix. Local mix remains bar-boundary switching, with at most 10 instruments per track. Inline controls override preset controls, even across shorthand/controls forms: {"op":"mix","tracks":["violin","sax"],"section":"chorus", "use":"distant","level":71,"controls":{"brightnessHz":8000}} A preset is copied when applied. Redefining it never retroactively changes music; apply it again to update a selection. Saved project sounds still pin exact timbres. tracks:[...] or tracks:"*" also works on performance and sound edits. Choose track OR tracks, never both. Wildcard means all tracks present at that step of the batch, including drums; choose explicit IDs when a control/sound is incompatible with drums. use is supported by mix and performance; it cannot be combined with clear:true. {"op":"performance","tracks":["violin","sax"],"section":"bridge", "use":"distant","expression":"swell"} The batch is atomic. It allows 100 operations AFTER expanding track groups. Every changes entry identifies its 1-based edit number and resolved track. affectedBars and noteBars are absolute inclusive ranges. mixChanges groups native before/after control values by bars, including actual quantization (e.g. level 40 may apply as 43). Arrays represent active layered instruments, in native order. At most 16 distinct mix-change groups are inlined; mixChangeCount gives the total. Use /mix for full settings. Empty affectedBars means no encoded bar changed; stored settings can still change. Reports are not a listening assessment. SOUND SEARCH /v3/sounds accepts q (words matched in sound names/categories/engines), category, engine, channelType (pitch or drum), limit (1-50, default 12) and offset. Exact filter values and next-page links are returned. Follow details for full editable settings. Search returns concise metadata, not every synthesis array. THE LOOP 1. Fetch discovery, this guide and the example. Choose a sound palette. 2. GET /bop/api/v3/compose/ on the direct host. 3. Save revision and links from the response. Inspect selected material. 4. GET /bop/api/v3/edit/. Send only changes. 5. Use the new revision for subsequent edits. Return links.editor or links.player to the listener. Fetch links.editor without following redirects to obtain its permanent, self-contained native song URL in the Location response header. All actions also accept //gzip/. GET allows 15,000 payload characters: count AFTER URL encoding, or count only the gzip token. Decoded JSON is limited to 1 MiB. Encode # as %23. Do not truncate a score to fit. Clients with POST can send application/json to / instead. HEAD reads existing views but does not create or edit revisions. POST bodies must arrive within 10 seconds. HTTP 429 includes Retry-After; retry the same request. The service admits at most four concurrent requests with a shared burst budget. Revisions are immutable, public to anyone holding the link, and retained for 30 days from creation. No account, private access control or public listing. Reading does not extend retention. Save links.source and links.score for backup; native song URLs embed the music and do not depend on revision retention. Edits branch from their requested parent, so concurrent agents cannot overwrite it. A failed batch publishes nothing. Edit operations run sequentially: each must leave a valid score. Keep the revision returned by the API, not an imagined ID. NEW MUSIC: BOP ARRANGEMENT VERSION 3 Required: format:"Bop arrangement", version:3, sections, form, tracks. Optional: title, tempo, key, scale, meter, loop, defaults, expressions, patterns, voicings, rhythms, sounds, mixes and performance. Title is at most 200 characters; meter defaults to 4. Sections map names to bar counts. form:"intro verse chorus verse outro" orders them; verse*2 repeats a section. The whole song may have at most 128 bars. Track/pattern/section IDs start with a letter, contain letters/digits/_/-, and have at most 48 characters. Put human-readable Unicode labels in track.name. There are at most 15 tracks; name is at most 64 characters. Saved authoring projects include a sounds dictionary containing the exact presets used by the revision. This pins instrument settings against later catalog changes and keeps source exports self-contained. You can also define a reusable custom sound: sounds:{mySound:{channelType:"pitch",settings:}}. Then use sound:"mySound" on tracks. A sound name resolves in this dictionary first, then the catalog. New compositions can omit sounds; the API captures used presets. Each track chooses sound by catalog ID, optional name, level, pan, reverb, atmosphere, controls, settings, expression, patterns and parts. defaults can supply sound, atmosphere, level, pan, reverb, controls and expression. Local settings win. Do not specify a control both directly and inside controls. level is 0-100, pan is -100 to 100, reverb is 0-100; inspect normalization warnings. Full native settings are available, not just the three shorthand controls. patterns may live globally or on a track; local names take precedence. A track can extends:"otherTrack" to reuse material and mix. Override its sound, controls or parts. Names and local bar overrides are not inherited. Keep inheritance acyclic. Changing inherited material intentionally changes descendants. parts map section IDs to pattern cycles. parts:{verse:"a b",chorus:"a a b c"}. Omitted/null parts are silent. "-" inserts one silent bar. A multi-bar pattern keeps its length. Cycles must divide the section's bar count exactly: an 8-bar section can repeat a 2-bar phrase four times, without four copies of the notes. Use {play:"a b",transpose:12,velocity:2,expression:"swell"} to transform a part. Use {use:"verse",transpose:-12} to derive a part from another section on that track. Arrays of references work too. Pattern and form strings accept name*repeat. PHRASES "D5:2 F5 E5 | A4:3 r" means two bars. Pitches use scientific names, including sharps and flats. Bare tokens last one beat; :duration is in quarter-note beats. r is a rest. [D4,F4,A4]:2 is a two-beat chord. One channel supports at most four simultaneous pitches with the same rhythm; independent voices use separate tracks. Durations can be fractions: :1/2, :1/3, :1/4. Timing uses a 1/24-beat grid. | pads to the next bar boundary; an incomplete final bar is padded with silence. A note can cross a bar: D4:8 becomes tied continuations. Native integer bend/ intensity pins sometimes need rounding at the split; the API reports that. For exact timing use arrays of [at,duration,pitch] or [at,duration,[pitches]]. An optional fourth element is expression. Objects can contain at, duration, pitch OR pitches, pins, expression and continues. Onsets are relative to the whole multi-bar phrase. Pins are [offsetBeats,bendSemitones,level0to3]; they begin at [0,0,level] and end at duration. Ordered events cannot overlap on one track. Use {notes:,bars:4} to retain trailing empty bars. A phrase has at most 384 note events. The project has at most 16,384 unique compiled note events. Pattern aliases: {use:"theme",transpose:12,velocity:2,expression:"soft"}. Named expressions include swell, taper, fade, soft and scoop; custom curves use fractions of note duration, not beats: expressions:{breath:[[0,0,1],[0.4,0,3],[1,0,1]]}. Apply expression:"breath" to a track, pattern or part. Intensity also drives the dynamic brightness of acoustic presets. Do not give piano a bowed swell or scoop. Percussion phrases accept kick, snare, ride, hat, shaker, soft-shaker or D0-D11. Choose a drum sound. V3 installs shaker voices on standard-drumset D9/D10 unless overridden explicitly. drums:{D9:"shaker"} or a sparse native drum object can customize a slot; custom spectrum arrays must contain exactly 30 values. REUSE HARMONY AND RHYTHM voicings:{Dm9:"D3 F3 C4 E4",A7:"A2 G3 C#4 E4"} names exact pitches. Names are references, not chord-symbol inference; you control register and voice leading. rhythms:{comp:[[0,1],[1.5,0.5],[3,0.5]]} defines a one-bar articulation. patterns:{chords:{harmony:"Dm9*2 A7 A7",rhythm:"comp",expression:"taper"}} assigns one bar per chord reference, applying the rhythm in each bar. Without rhythm, each bar contains one sustained chord. tones:[1] selects only the first pitch for a bass line; positions are 1-based, in the supplied order. Arpeggio rhythm: [[0,1,[1]],[1,1,[3]],[2,1,[2]],[3,1,[4]]]. A hit's tone selection overrides the pattern's tones. The same progression can drive different rhythms. For faster harmony: harmony:[["Dm9",2],["A7",2]]. Beat lengths must fill whole bars. The voicing at a note's onset governs its full duration; sustained notes are not automatically cut at a chord change. Transpose/velocity work as usual. INSPECTION GET /bop/api/v3/revisions/ returns a compact summary with form, duration, stable track IDs, names, pitch ranges, activity, applied basic mix, warnings and links. It does not send the whole score on every edit. Append /source, /score, /mix, /warnings, /notes or /analysis for a detailed view. For selected notes: /revisions//notes?tracks=lead,bass§ion=verse&occurrence=2&bars=1,4 Without section, bars are absolute song bars. With section, they are relative to that occurrence. Bars and occurrences are 1-based. Repeated section names require occurrence; the API refuses to guess. Notes allow at most 32 bars per request and default to the first eight. Responses identify the revision and absolute range. /analysis defaults to the full song and supports the same track/range selection. It reports bend-aware register, note activity, silent spans and identical bar runs. These are observations about encoded notes, not listening or quality scores. /mix accepts tracks; /source, /score and /warnings return the whole project. The inspect action accepts the same selection as JSON, plus revision and view. LOCAL MIX AND EXPRESSION To change only a passage, send: {op:"performance",track:"lead",section:"chorus",occurrence:2, level:86,controls:{brightnessHz:8000},expression:"swell"} Or {op:"mix",track:"guitar",bars:[9,16],level:43,reverb:33}. Compose can include performance:[{track:"lead",section:"chorus",...}] at root. Selectors are inclusive, 1-based bars relative to section (absolute if omitted). For performance/mix edits, omitting occurrence affects EVERY repeat of section; omitting both section and bars affects the whole track. This differs from note inspection/edits, where repeated sections require an occurrence. Local changes never propagate to tracks inheriting this track. All its active layers receive mix controls. Native imports support absolute bars or the single section "song". Mix changes at bar boundaries, using up to 10 native instrument variants per track; it is not continuous effect automation. Body EQ and other sound settings are preserved. controls.brightnessHz (62.5-16000) sets the first note low-pass cutoff, adding one if absent; pressure envelopes still modulate it. Higher opens existing overtones, but cannot create harmonics missing from the sound source. For harmonics/Picked String, controls.acousticMode selects the excitation model. Named sounds set an appropriate mode. Violin, viola, cello, flute, clarinet and tenor-sax use spectral sources with separate partial envelopes, register and dynamic layers. acousticTexture (0-100) adjusts noise; acousticMotion (0-100) adjusts sustained spectral evolution without changing vibrato. On spectral sources, settings.harmonics attenuates the profile (100 preserves, 0 removes). Use a fresh named sound to adopt the complete voicing; changing the mode alone retains old filters and harmonic settings. See sound-guide.txt for exact modes. The returned cutoff is quantized. /mix reports settings and active barRanges for each instrument; summary also includes these ranges. Empty ranges mean unused. expression shapes each note's intensity: swell, taper, fade, soft or a named zero-bend curve. It replaces the previous intensity contour; velocity:0..3 then scales it (3 unchanged). Matching tied notes are shaped as one gesture across selected bars. Selection edges bound the gesture. Pitch bends are retained, with warnings if new curve points require integer-bend rounding. Use note edits for pitch scoops. Softer note intensity also darkens pressure-sensitive presets; lower level instead when you want the same playing timbre at a quieter mix. At most 128 overrides. Later overlapping entries win mix controls and apply expression in order. Editing the identical selector merges its existing entry; use {op:"performance",track:"lead",section:"chorus",occurrence:2,clear:true} to remove that exact override and reveal underlying settings. Selection fields must match; clear removes both mix and expression. Source retains these compact overrides, while score/native exports contain fully rendered instruments/pins. EDITS: SEND {"revision":"","edits":[...operations...]} - {op:"mix",track:"lead",level:71,pan:0,reverb:33} - {op:"sound",track:"lead",sound:"violin",controls:{vibrato:"delayed"}} - {op:"rename",track:"lead",name:"Solo violin"}; ID stays lead. - {op:"note",track:"lead",section:"verse",occurrence:2,bar:1,at:0,set:{pitch:"E5"}} - {op:"note",track:"lead",bar:5,at:2,remove:true} - {op:"notes",track:"lead",bar:5,notes:"E5:2 F5 r"} - {op:"pattern",id:"theme",value:"D5:2 F5 E5 | A4:3 r"}; omit track for global. - {op:"voicing",id:"Dm9",value:"D3 F3 A3 E4"} - {op:"rhythm",id:"comp",value:[[0,1],[2.5,0.5]]} - {op:"part",track:"lead",section:"chorus",play:"theme answer"} - {op:"section",section:"bridge",bars:8}, then {op:"form",form:"verse bridge verse"} - {op:"addTrack",track:"bass",value:} or {op:"removeTrack",track:"bass"} - {op:"song",tempo:110,title:"Evening"}; key, scale and meter also supported. At most 100 operations per request. note/notes edits affect only the selected track and bar; they preserve other repetitions and inherited tracks. pattern, voicing and rhythm edits intentionally change their uses, while retaining local bar overrides. Use source to inspect authoring decisions after many edits. EXISTING MUSIC GET /bop/api/v3/import/ preserves the native score exactly, including instruments, note pins and names. The response assigns stable track IDs. Rename, performance, mix, sound, note, notes and song edits work; native imports do not contain named authoring patterns/sections, so pattern/part/form/voicing edits require an authoring project. Save source to keep that distinction. Existing native Bop links remain usable without this API. DOWNLOADS AND EDITOR HANDOFF Every revision response includes links.downloads: - source: project.json, preserves named v3 authoring choices and local overrides. - score: song.bop.txt, exact Bop score; load with File > Song text / LLM. - native: song.json, exact engine JSON; load with File > Import Song. - midi: song.mid, uses the same exporter as the editor, with one full song pass. - readout: readout.txt, symbolic review, not an exact editing format. MIDI approximates synth programs/effects, exports only the first instrument of layered patterns, maps only the first drumset to the GM percussion channel, and rearticulates tied bar boundaries. Use score/native for an exact sound-preserving round trip. MIDI is useful for notes, timing, names, tempo, pan and expression. Native editor links can always be reopened without a revision. In the editor, File > Song text / LLM > Agent handoff prepares the current song and website instructions for copying to an assistant. This does not upload the song. MUSICAL BRIEF Unless asked otherwise, aim for 90-210 seconds with moderate complexity. Duration is bars * meter * 60 / tempo. Develop a memorable motif, vary its answer, and use section entrances, register, rhythm and dynamics to create a clear arc. Let bass, melody and percussion repeat at different rates. A quiet bridge and deliberate ending often do more than extra notes. Arrange silence, not just sound. Keep accompaniment below the lead, give winds breath space, let plucks decay, and use restrained contact noise only where gestures justify it. Check duration, register, applied mix and warnings after composition and revisions. Follow the user's taste over these defaults. Do not claim to hear audio from reading notes. ERRORS ok:false includes code, error, and where available path and hint. No edit is published on failure. Fix the cited input; inspect the parent instead of resending an entire song blindly. Capacity/expiry errors require a saved source or retry, not pretending the revision exists. Successful normalization appears in warnings; read /warnings for complete structured values. Acoustic reference atlas: https://sahildev.com/bop/timbre-atlas/catalog.json Violin findings: https://sahildev.com/bop/timbre-atlas/findings.txt Per-preset JSON includes real recording provenance, spectral measurements and control directions. Method: https://sahildev.com/bop/timbre-atlas/method.txt