scribbles and placements
drawing reads and writes use the same chat scope as messages. ownership is checked per stroke or placement, never inferred from group ownership.
stroke representation
Scribble contains id, chat_id, actor, installation_id for bot-owned work, anchor_sequence, canvas_width, tool, color, size, points, draw_order, erasures, created_at and revision. tool is pen, pencil or highlighter. points are finite [x,y] coordinates normalized by canvas width; x is 0–1, y is the vertical distance divided by canvas width. anchor_sequence identifies an eligible visible ordinary message or the chat’s zero anchor. use existing drawing bounds, brushes and validators; arbitrary paths or CSS are rejected.
{
"actor": "bot",
"anchor_sequence": "0",
"canvas_width": 800,
"tool": "pen",
"color": "#3e5bb0",
"size": 3,
"points": [
[
0.1,
0.1
],
[
0.2,
0.2
]
],
"draw_order": 1
}drawing routes
GET requires scribbles.read. creation and replacement use 30/51. erase uses 31/52 and checks every referenced stroke before applying anything. updates preserve the author and target chat. batch erasure is atomic and rejects mixed ownership without partial changes. a bot cannot erase another application’s or human’s artwork.
scroll the table horizontally to see all columns.
| method and path | request | result |
|---|---|---|
| GET /chats/{chat}/scribbles | cursor, limit | Scribble list |
| POST /chats/{chat}/scribbles | actor + stroke fields | 201 Scribble |
| PATCH /chats/{chat}/scribbles/{id} | actor, points?, color?, size?; If-Match | changed fields, id and revision; same owner |
| POST /chats/{chat}/scribbles/erase | actor, removed_ids[], cuts:[{stroke_id,size,points}], revisions | {removed_ids,cuts,revision} |
| POST /chats/{chat}/scribbles/preview | actor, preview_id, stroke, revision | 204; transient preview, five-second expiry |
| GET /chats/{chat}/placements | cursor, limit | Placement list; permission 6 or readable parent |
| PATCH /chats/{chat}/placements/{id} | actor, anchor_sequence?,canvas_width?,x?,y?,width?,height?,rotation?,order?; If-Match | Placement; permission 34/55 |
| DELETE /chats/{chat}/placements/{id} | actor in JSON; If-Match | 204; permission 34/55 |
drawing limits
at most 1,200 points per stroke, 100 strokes/cuts per erasure request and 256 KiB JSON per drawing request. GET /limits exposes the brush, coordinate and color constraints. previews are limited to 10 per second per installation/chat and never persisted. deleting a message anchor uses the app’s normal relocation behavior. erasure returns an opaque batch revision; each affected stroke retains its own numeric revision for subsequent edits.
placement representation
Placement has id, chat_id, message_id, kind, actor_id, anchor_sequence, canvas_width, x, y, width, height, rotation, order and revision. kind is sticker or gif. coordinates and dimensions are normalized by canvas width; width and height must also fit the 16–1,440 pixel bounds. rotation is degrees modulo 360. sending a sticker/GIF creates its placement through the normal app layout. dragging changes geometry; removal deletes the owned placed message. profile and nameplate artwork use profile endpoints.