Upload Submission to AI Plotter
Upload Submission to AI Plotter
- file_1
- file_2
- file_3
- file_4
- file_5
- file_6
- file_7
- file_8
- file_9
- file_10
- qr_code
- public_url
- token
Not everyone owns an AxiDraw, and that's what Upload Submission to AI Plotter is for. It collects up to ten files - the PENPLOTTER_FILE outputs from Image/SVG/Video to Submission File - and POSTs them to a plotter service backend, which plots them for you. On success it returns a public_url and a token from the service, plus a qr_code image of that URL so a scanner can find your submission. It's the bridge from "I made this in ComfyUI" to "a machine somewhere will draw it."
Honest framing: this node is tied to a specific backend. Its default api_endpoint is https://aiplotter.devine.be, and the author is a Belgian creative technologist whose work reads like it came out of the Devine creative-technology program - this looks like the upload half of a classroom or studio project, not a generic public API. You need a real api_key for that backend for it to do anything.
How it works
The node does three things. First it bundles whatever file slots you filled (any of file_1 through file_10) into a multipart POST to {api_endpoint}/api/v1/submissions, sending each file's name, bytes and MIME type with a Bearer API key in the header. Then it expects the backend to answer with JSON containing a public_url (and a token); anything else - empty key, no files, a non-2xx response - raises a RuntimeError with the HTTP status and a slice of the body. Finally it renders that URL into a QR code using Python's qrcode library.
The inputs you actually set:
api_key- required, and empty by default. Get one from whoever runs the endpoint.api_endpoint- the service URL; the Devine default is fine if that's your service.error_correction- QR error-correction level: L/M/Q/H (default M). Higher levels survive more damage but make denser codes. Q is a sensible choice if the code might be printed, creased, or scanned from a distance.box_size(1–50, default 10) - QR module size in pixels. Bump it if the preview looks too small to scan.project- a label for your own reference; the code notes the actual project is derived server-side from the API key.
The outputs are qr_code (the QR as an IMAGE), public_url and token (strings). Wire qr_code into the QR Code Preview node - the pack even pushes the image to the browser immediately after the upload succeeds, so you see your QR while long-running downstream nodes (like a real plot) are still going.
Install
It's in the ComfyUI PenPlotter pack. ComfyUI Manager → search "ComfyUI PenPlotter", or:
cd ComfyUI/custom_nodes
git clone https://github.com/wouterverweirder/comfyui-penplotter
Restart ComfyUI. This node specifically pulls in requests and qrcode[pil] (plus Pillow); the pack's full requirements are numpy>=2.3.4, opencv-python, numba, vpype, websockets, the AxiDraw API zip, and those.
Common issues
- "UploadSubmission: api_key is empty" - expected; it starts blank. You need a real key for the endpoint.
- "No files attached to UploadSubmission" - you didn't wire any
PENPLOTTER_FILEinto a file slot. At least one is required. - "HTTP 401/403" - your key is wrong for that backend. Check the key and the endpoint together.
- QR won't scan - bump
box_size, or raiseerror_correctionif the code is dense (long URLs plus H can get very busy).
The whole node is one dependency on a third-party service, so keep your expectations service-shaped: it's as good as the backend you point it at.
Inputs (15)
| Name | Type | Default | Description |
|---|---|---|---|
| api_endpoint | STRING | https://aiplotter.devine.be | — |
| project | STRING | — | |
| api_key | STRING | — | |
| box_size | INT | 101–50 | — |
| error_correction | COMBO | M | 4 options: L, M, Q, H |
| file_1opt | PENPLOTTER_FILE | — | |
| file_2opt | PENPLOTTER_FILE | — | |
| file_3opt | PENPLOTTER_FILE | — | |
| file_4opt | PENPLOTTER_FILE | — | |
| file_5opt | PENPLOTTER_FILE | — | |
| file_6opt | PENPLOTTER_FILE | — | |
| file_7opt | PENPLOTTER_FILE | — | |
| file_8opt | PENPLOTTER_FILE | — | |
| file_9opt | PENPLOTTER_FILE | — | |
| file_10opt | PENPLOTTER_FILE | — |
Outputs (3)
| Name | Type | Description |
|---|---|---|
| qr_code | IMAGE | — |
| public_url | STRING | — |
| token | STRING | — |