Accessing web API data through max js/maxurl objects

There’s surprisingly little documentation online or in the maxurl help file for establishing a connection between an API online and a max patch. I’ve spent the past few days searching around the Cycling 74 forums and reading wikis/docs on dev sites for implementing APIs.

Here’s what I think I know so far:

  1. You can access an API through [maxurl] if you have the specific URL and string of relevant commands within the URL. Example: would theoretically log me in and authenticate to the API, and the command is to find the channel information on my twitch channel.
  2. You usually have to register an application to use it. I don’t currently have webspace for a redirect URL. So… that’s a problem
  3. Once [maxurl] gets a page, it prints to a dict object. Not sure where to go from there. Do I modify the dict object to get my data, or does it all happen in the URL address string?

I realize there’s examples of sonifying all sorts of data online, but not much documentation on the steps to get there. My end goal is a sort of “twitch plays pokemon” but built around live, crowd sourced audio-visuals and generative music sequencers. Ideally, users log into my chat, and commands/text is sent back to Max. Max sonifies that data and creates visuals in jitter, those get sent back to Twitch through OBS (open broadcasting software).

Any help is appreciated. This would be a great grad student project for me to do… (I have a lot more free time than when I was working 50hrs a week)

Thanks for your time y’all!


First off, I love the idea!

Are you set on using MAX on the server? It seems like it’s possible but it also seems like it would be easier to get an instance of web audio API or the like running, or even run instances on the client and use a back-end just for data (maybe you’ve been told this already).

Pure Data on the Web is also a thing (not sure how supported it is), which could also support a client audio engine I imagine, and existing MAX patches could potentially be converted with Cyclone

Never done sound on the web so certainly not an expert but it seems like a MAX-based technique may be more work than it’s worth.

Thanks for the input!

I don’t know pure data much at all, and I’m specifically looking to feed my audio-visual generation back into the twitch stream itself.

To do this, the best way in my mind is to generate all of it locally by pulling chat data from the API into Max. After all the routing and magic happens, it just gets streamed back to Twitch from OBS with a short delay.

So ideally, you type text into my twitch chat, Max routes and generates audio visuals, and then you see it maybe two seconds later in the actual stream feed. You could have max look for certain words for sonification and visualization, but also take pure data like the ascii values, averages of character count, capitalization, etc, into account for generating stuff.

I don’t want the user to have to load a separate page. I think it could work if you just embedded the same twitch feed into a separate web page… but then why not just use IRC or something more easily connectable (I imagine I could pull IRC chat with UDP messages?)

  1. Once [maxurl] gets a page, it prints to a dict object. Not sure where to go from there. Do I modify the dict object to get my data, or does it all happen in the URL address string?

Try routing the output of the maxurl to another dict object to store the data to it and then do a get key message (replace key with whatever key you want in the dictionary) and it’s value should come out of the second outlet of the dict object. Just remember that the key gets prepended to the output so it might be a good idea to route the output of the dict object through a route key.

PS: Ideally you’d use the maxurl object to access an API that would return a json file containing the data. I’m not sure it’d be a great idea to parse html inside Max.


Thanks. I got most of that part down, I’m pretty familiar with the dict object already. Just was wondering if you could modify the request to the API by looking at the dict object. It doesn’t print any relevant information for that, though.

Most of it seems to be set up from the server/API side. Routing and stuff within max is not a problem, but I just can’t seem to get the data. Dev documentation on most API sites is terrible.

Ah, I apologize. I thought you were struggling with the dict object itself and how it works.

Yeah, the API will only give you what it’s designed to. If the API documentation doesn’t mention how to get what you want then you might need to roll your own solution.

If you want to run everything locally maybe you can use a python script to scrape, parse the website (using BeautifulSoap or something), get the info and send it to max via OSC. That might be easier than setting up a Heroku app, getting it to generate a json file etc.


Interesting. I think if I really want to save my own time I should just find someone willing to do the API part of this project… I don’t know if I want to learn a whole scripting language to accomplish this or not. (Although… it would be a useful skill to know for the future…)

dumb answer: just send OSC (or raw UDP or whatever) between max, and a node app (or python or whatever) and do your API stuff there, in a well-supported environment.

doing involved REST stuff in max with [maxurl] seems like a recipe for Pain. no callback/promise mechanism, &c… just because you can make web browser in max doesn’t make it the right tool for building a web app, when highly appropriate free tools abound. (IMHO of course)

(@andrew , no more than JS is the right tool for processing sound BTW… i have recently been doing pretty heavy application of web audio and web ASM for professional reasons, not for playing/exploring, and have reached agreement with opinion expressed here. in addition ScriptProcessorNode is now long deprecated but without a replacement API - Audio Workers were defined, but never implemented… then replaced with Audio Worklets, which are still not implemented fully or reliably… making it all rather shaky territory for anything but toy applications.)

nevertheless, if you don’t have it yet, picking up some JS proficiency is painless and indeed useful in this day and age.


1 Like

Thanks for the advice. I noticed some other implementations of this idea use processing/puredata to interface with an API and then it sends back to Max as well.

Would that be a solution, or are you more talking about making a shell program in purely JS to interface with it?

Gonna bump this old topic. Maybe someone can help here. I’m working on a project that feeds data from an API into Max to modulate certain sounds. Currently, I’m using Python to get the data, dumping that to two text files, and then reading those text docs into Max. Perhaps I can do this all natively in Max via maxurl? However, I’m having some trouble. This is my simple Max test patch:


The problem is, I need to do some parsing of the resultant key. This is what it outputs:
"body" : "{\"channels\": [22.87124252319336, 153.02964782714844], \"hz\": 59.98602294921875, \"voltage\": [122.7942123413086, 123.16279602050781]}",

I’ve tried all variety of get body::channels to no avail.

I need to just extract the “channels” data from this key, ideally as two separate floating point outputs. Anyone have ideas? Or better to just keep doing that heavy lifting in Python (maybe with pyOSC to get rid of the text files)?

do the parsing in a js object?

Super difficult to help without having a patch. Can you upload something?

I’ve seen some js out there that just does this without using maxurl - as @zebra mentioned, but can’t seem to find it now.

Edit - I know someone who is doing a lot of this and just emailed them to ask… will let you know if anything useful comes back.

So it was actually a combo of maxurl and some js.

Here is a screenshot:

And there is a route object after the js object.

The script itself:

parser.js (6.1 KB)

I can’t claim credit for it, but think it was found somewhere on the C74 forums.

Hope that helps!

1 Like

I actually ended up solving this with some zl.slice and regex. JS would’ve probably been more elegant, as this definitely fits the “it’s not stupid if it works” category of solutions.


Most of my solutions!