{"components":{"schemas":{"Error":{"properties":{"error":{"type":"string"},"ok":{"type":"boolean"}},"type":"object"}},"securitySchemes":{"key":{"description":"a key from Dev's page (sdev_…)","scheme":"bearer","type":"http"}}},"info":{"description":"Every action on a robot, with a key from Dev's page (Authorization: Bearer sdev_…). The same actions are MCP tools at /mcp. https://github.com/i41-eu/q41eu-dev","license":{"name":"Apache-2.0"},"title":"Dev: a Stackchan robot for your programs","version":"v0.9.0"},"openapi":"3.1.0","paths":{"/v1/robots":{"get":{"operationId":"listRobots","responses":{"200":{"content":{"application/json":{"schema":{"additionalProperties":true,"properties":{"ok":{"type":"boolean"}},"type":"object"}}},"description":"the robots: id, online, model, firmware, commands"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"a wrong argument"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"no key, or not a valid one"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"not this key's robot"},"429":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"too many requests: at most 10 a second per key (bursts of 30)"},"501":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"the robot does not offer it"},"503":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"the robot is offline"}},"summary":"The key's robots"}},"/v1/robots/{robot}":{"get":{"operationId":"getState","parameters":[{"description":"the robot's id, e.g. stackchan-0a1b2c3d4e50","in":"path","name":"robot","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"additionalProperties":true,"properties":{"ok":{"type":"boolean"}},"type":"object"}}},"description":"the robot's state"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"a wrong argument"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"no key, or not a valid one"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"not this key's robot"},"429":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"too many requests: at most 10 a second per key (bursts of 30)"},"501":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"the robot does not offer it"},"503":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"the robot is offline"}},"summary":"The robot's state: online, readings, last events"}},"/v1/robots/{robot}/ask":{"post":{"operationId":"ask","parameters":[{"description":"the robot's id, e.g. stackchan-0a1b2c3d4e50","in":"path","name":"robot","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"additionalProperties":false,"properties":{"answers":{"description":"2-4 short answers","items":{"type":"string"},"type":"array"},"question":{"description":"short: it is shown big","type":"string"},"timeout_s":{"description":"how long to wait (default 30, at most 120)","type":"number"}},"required":["question","answers"],"type":"object"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"additionalProperties":true,"properties":{"ok":{"type":"boolean"}},"type":"object"}}},"description":"done (ask: the answer; sound: its length)"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"a wrong argument"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"no key, or not a valid one"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"not this key's robot"},"429":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"too many requests: at most 10 a second per key (bursts of 30)"},"501":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"the robot does not offer it"},"503":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"the robot is offline"}},"summary":"Ask the person at the robot: the question and 2-4 answers as buttons on its screen; returns the answer they tap, or timed_out."}},"/v1/robots/{robot}/clickmap":{"post":{"operationId":"clickmap","parameters":[{"description":"the robot's id, e.g. stackchan-0a1b2c3d4e50","in":"path","name":"robot","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"additionalProperties":false,"properties":{"image":{"description":"a JPEG or PNG, base64, shown first (fitted to 320x240); without it the regions lie over what the screen shows now","type":"string"},"regions":{"description":"1-32 places in the screen's pixels (320x240): {\"id\", \"rect\": [x, y, w, h]}, {\"id\", \"circle\": [x, y, r]} or {\"id\", \"polygon\": [[x, y], ...]} (3-32 points); where they overlap, the first listed counts","items":{"type":"object"},"type":"array"},"timeout_s":{"description":"how long to wait (default 30, at most 120)","type":"number"}},"required":["regions"],"type":"object"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"additionalProperties":true,"properties":{"ok":{"type":"boolean"}},"type":"object"}}},"description":"done (ask: the answer; sound: its length)"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"a wrong argument"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"no key, or not a valid one"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"not this key's robot"},"429":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"too many requests: at most 10 a second per key (bursts of 30)"},"501":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"the robot does not offer it"},"503":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"the robot is offline"}},"summary":"Places to tap on the screen, over a picture or over what it shows: returns the first tap inside one (its id, x and y), or timed_out. The screen stays as it is."}},"/v1/robots/{robot}/command":{"post":{"operationId":"command","parameters":[{"description":"the robot's id, e.g. stackchan-0a1b2c3d4e50","in":"path","name":"robot","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"additionalProperties":false,"properties":{"args":{"description":"the command's arguments","type":"object"},"command":{"description":"e.g. sticker, brightness, ir_send","type":"string"}},"required":["command"],"type":"object"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"additionalProperties":true,"properties":{"ok":{"type":"boolean"}},"type":"object"}}},"description":"done (ask: the answer; sound: its length)"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"a wrong argument"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"no key, or not a valid one"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"not this key's robot"},"429":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"too many requests: at most 10 a second per key (bursts of 30)"},"501":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"the robot does not offer it"},"503":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"the robot is offline"}},"summary":"Any of the robot's own commands, as the Raw data app sends them (the q41eu-raw readme lists them), for what the other actions do not cover. Its apps and its manager's settings are not reachable here."}},"/v1/robots/{robot}/events":{"get":{"operationId":"getEvents","parameters":[{"description":"the robot's id, e.g. stackchan-0a1b2c3d4e50","in":"path","name":"robot","required":true,"schema":{"type":"string"}},{"description":"only events after this seq (0: the last ones kept)","in":"query","name":"after","schema":{"type":"integer"}},{"description":"wait this long for one","in":"query","name":"seconds","schema":{"maximum":60,"type":"integer"}},{"description":"only these events, comma-separated","in":"query","name":"names","schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"additionalProperties":true,"properties":{"ok":{"type":"boolean"}},"type":"object"}}},"description":"events and last_seq"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"a wrong argument"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"no key, or not a valid one"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"not this key's robot"},"429":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"too many requests: at most 10 a second per key (bursts of 30)"},"501":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"the robot does not offer it"},"503":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"the robot is offline"}},"summary":"What people did at the robot, after a sequence number; waits for the next one"}},"/v1/robots/{robot}/face":{"post":{"operationId":"face","parameters":[{"description":"the robot's id, e.g. stackchan-0a1b2c3d4e50","in":"path","name":"robot","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"additionalProperties":false,"properties":{"emotion":{"description":"the face's emotion","enum":["neutral","happy","angry","sad","doubt","sleepy"],"type":"string"},"view":{"description":"the robot's own screen","enum":["face","readings"],"type":"string"}},"type":"object"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"additionalProperties":true,"properties":{"ok":{"type":"boolean"}},"type":"object"}}},"description":"done (ask: the answer; sound: its length)"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"a wrong argument"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"no key, or not a valid one"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"not this key's robot"},"429":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"too many requests: at most 10 a second per key (bursts of 30)"},"501":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"the robot does not offer it"},"503":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"the robot is offline"}},"summary":"The robot's face: an emotion; or its own screen under cards: the face or its readings (its sensors live)."}},"/v1/robots/{robot}/leds":{"post":{"operationId":"leds","parameters":[{"description":"the robot's id, e.g. stackchan-0a1b2c3d4e50","in":"path","name":"robot","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"additionalProperties":false,"properties":{"bar":{"description":"0..1: light both strips from the screen end, this far","type":"number"},"color":{"description":"#rrggbb or a name; all LEDs, or the bar's / effect's colour","type":"string"},"effect":{"description":"an animation on the robot","enum":["rainbow","breathe","chase","blink","off"],"type":"string"},"off":{"description":"all off","type":"boolean"},"pixels":{"description":"12 colours: left strip 0-5 from the screen end back, right strip 6-11 from the back to the screen end","items":{"type":"string"},"type":"array"},"seconds":{"description":"the effect's length (0 = until the next leds)","type":"number"},"speed":{"description":"the effect's speed, 0.2..5 (default 1)","type":"number"}},"type":"object"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"additionalProperties":true,"properties":{"ok":{"type":"boolean"}},"type":"object"}}},"description":"done (ask: the answer; sound: its length)"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"a wrong argument"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"no key, or not a valid one"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"not this key's robot"},"429":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"too many requests: at most 10 a second per key (bursts of 30)"},"501":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"the robot does not offer it"},"503":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"the robot is offline"}},"summary":"The 12 LEDs on the head (two strips of 6): one colour, a bar from the screen end back (a level), single LEDs, an effect the robot animates, or off. Colours are corrected to look on the LEDs as on a screen."}},"/v1/robots/{robot}/menu":{"post":{"operationId":"menu","parameters":[{"description":"the robot's id, e.g. stackchan-0a1b2c3d4e50","in":"path","name":"robot","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"additionalProperties":false,"properties":{"items":{"description":"2-6 tiles: each a label (\"Apple\"), or {\"id\", \"label\", \"image\"} with a picture (JPEG or PNG, base64) above its label; the answer's item is the id, else the label","items":{"anyOf":[{"type":"string"},{"type":"object"}]},"type":"array"},"timeout_s":{"description":"how long to wait (default 30, at most 120)","type":"number"},"title":{"description":"small text at the top","type":"string"}},"required":["items"],"type":"object"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"additionalProperties":true,"properties":{"ok":{"type":"boolean"}},"type":"object"}}},"description":"done (ask: the answer; sound: its length)"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"a wrong argument"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"no key, or not a valid one"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"not this key's robot"},"429":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"too many requests: at most 10 a second per key (bursts of 30)"},"501":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"the robot does not offer it"},"503":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"the robot is offline"}},"summary":"A menu on the robot's screen: 2-6 tiles with labels, or pictures and labels, under a title; returns the tile the person taps, or timed_out."}},"/v1/robots/{robot}/move":{"post":{"operationId":"move","parameters":[{"description":"the robot's id, e.g. stackchan-0a1b2c3d4e50","in":"path","name":"robot","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"additionalProperties":false,"properties":{"gesture":{"description":"a gesture","enum":["nod","shake","home"],"type":"string"},"pitch":{"description":"degrees, 5..85, up","type":"number"},"yaw":{"description":"degrees, -128..128, + to the robot's left","type":"number"}},"type":"object"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"additionalProperties":true,"properties":{"ok":{"type":"boolean"}},"type":"object"}}},"description":"done (ask: the answer; sound: its length)"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"a wrong argument"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"no key, or not a valid one"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"not this key's robot"},"429":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"too many requests: at most 10 a second per key (bursts of 30)"},"501":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"the robot does not offer it"},"503":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"the robot is offline"}},"summary":"Move the head: a gesture (nod, shake, home = face forward), or look at an angle."}},"/v1/robots/{robot}/say":{"post":{"operationId":"say","parameters":[{"description":"the robot's id, e.g. stackchan-0a1b2c3d4e50","in":"path","name":"robot","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"additionalProperties":false,"properties":{"seconds":{"description":"how long (default 6, at most 30)","type":"number"},"text":{"description":"at most 80 characters","type":"string"}},"required":["text"],"type":"object"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"additionalProperties":true,"properties":{"ok":{"type":"boolean"}},"type":"object"}}},"description":"done (ask: the answer; sound: its length)"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"a wrong argument"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"no key, or not a valid one"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"not this key's robot"},"429":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"too many requests: at most 10 a second per key (bursts of 30)"},"501":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"the robot does not offer it"},"503":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"the robot is offline"}},"summary":"A speech bubble over the robot's face (needs the face: show clear first if a card is up)."}},"/v1/robots/{robot}/show":{"post":{"operationId":"show","parameters":[{"description":"the robot's id, e.g. stackchan-0a1b2c3d4e50","in":"path","name":"robot","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"additionalProperties":false,"properties":{"background":{"description":"the card's background: #rrggbb or a name; default dark blue","type":"string"},"clear":{"description":"take the card or picture away","type":"boolean"},"color":{"description":"the text's colour (and the title's and the bar's): #rrggbb or a name (red, orange, yellow, green, cyan, blue, purple, pink, white); default white text, a blue title","type":"string"},"image":{"description":"a JPEG or PNG, base64 (instead of a card; fitted to 320x240)","type":"string"},"note":{"description":"small text at the bottom","type":"string"},"progress":{"description":"0..1: a progress bar","type":"number"},"text":{"description":"big text in the middle","type":"string"},"title":{"description":"small text at the top, in the colour","type":"string"}},"type":"object"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"additionalProperties":true,"properties":{"ok":{"type":"boolean"}},"type":"object"}}},"description":"done (ask: the answer; sound: its length)"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"a wrong argument"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"no key, or not a valid one"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"not this key's robot"},"429":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"too many requests: at most 10 a second per key (bursts of 30)"},"501":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"the robot does not offer it"},"503":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"the robot is offline"}},"summary":"Show a card on the robot's screen (a title, big text that sizes itself, a note, a progress bar), or a picture; clear takes it away."}},"/v1/robots/{robot}/sound":{"post":{"operationId":"sound","parameters":[{"description":"the robot's id, e.g. stackchan-0a1b2c3d4e50","in":"path","name":"robot","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"additionalProperties":false,"properties":{"bell":{"description":"the notes struck like a bell","type":"boolean"},"chime":{"description":"a ready-made sound","enum":["ask","break_over","chirp","done","error","hello","lullaby","morning","munch","no","start","tada","whee","yawn","yes"],"type":"string"},"notes":{"description":"a melody: note:ms ..., up to 30 s","type":"string"},"volume":{"description":"the speaker's volume first, 0..100","type":"number"}},"type":"object"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"additionalProperties":true,"properties":{"ok":{"type":"boolean"}},"type":"object"}}},"description":"done (ask: the answer; sound: its length)"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"a wrong argument"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"no key, or not a valid one"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"not this key's robot"},"429":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"too many requests: at most 10 a second per key (bursts of 30)"},"501":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"the robot does not offer it"},"503":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"the robot is offline"}},"summary":"A sound from the speaker: a named chime, or notes like \"C5:120 E5:120 G5:300\" (note:ms, - is a rest)."}}},"security":[{"key":[]}],"servers":[{"url":"https://dev.q41.eu"}]}
