Some responses that the Oda web app receives carry bytes rather than JSON alone: a file's contents coming down to the page, an image, any result that is binary. Such a response arrives as a multipart response, with one part carrying the JSON envelope and further parts carrying the bytes, which are put back into the result at the places the envelope marks. This page is the reference for that framing: the parts, the rules a valid response obeys, and how a malformed or interrupted response fails. For files going the other way, from the page to Oda, see File uploads in the web app.
multipart/ form-data) instead of a single JSON body. A response with no bytes stays plain JSON, and a failure stays JSON too.metadata holds the envelope, the same JSON a response without bytes carries, plus the attachment table: the list of where the bytes belong and which part carries them.bytes-N, one part for each attached value.Each entry of the attachment table names three things:
| Field | What it names |
|---|---|
path | Where the bytes belong in the result. |
codec | How the bytes are coded; the value for these attachments is bytes. |
part | The part that carries this entry's bytes. |
path names a place inside the result: a property name in an object, an index in an array, and any nesting of the two.metadata part carries, each attachment's place is marked with null, and the bytes fill those places. A placeholder that already holds a value is refused, so the fill never replaces data that is already there.Uint8Array of bytes, backed by an ArrayBuffer. Nothing is turned into text on the way.invalid binary response message that names what was wrong. No result from that response is delivered.metadata part that cannot be read as the envelope and its table, or an attachment entry that is not valid; a placeholder that already holds a value; and paths that repeat or sit inside one another.rpcId mismatch for <endpoint>: sent <id>, got <id>.invalid binary response?The multipart response was malformed for one of the reasons in When a binary response fails: a missing, repeated or unclaimed part; metadata or an entry that could not be read; an occupied placeholder; or repeated or overlapping paths. No result was delivered. Ask again, and keep the message for your administrator if it returns.
The route to a place inside the result: property names, array indices, and any nesting of the two. An empty path means the whole result is the bytes. The attachment table rides beside the result, so no field name is reserved; a path simply points at where the bytes sit.
null?The bytes are put into the result at the places the table names, and each of those places must be marked with null first. A place that already holds a value is refused instead of overwritten, so the bytes never quietly replace data that was already there.
Yes. Each attachment gets its own entry and its own part, named in sequence under bytes-N. The paths must stay unique and must not overlap, so every part lands in its own place.
No. Every byte place ends up holding a Uint8Array of raw bytes, backed by an ArrayBuffer. Nothing is turned into text on the way, and the JSON values around the bytes are unchanged.
rpcId mismatch?The response carried a different call id than the request sent, so it was not delivered. Every request carries a call id, and its response must echo the same one. Ask again; if the message returns, keep it for your administrator.
The call fails, and no short answer is delivered: the response must arrive whole. Bytes that keep arriving after the caller has cancelled fail the call in the same way.
No. The same byte parts are restored whether or not a response is compressed; gzip does not alter the bytes.
Anywhere a value can: a top-level field, a field nested in others, an item of an array, or the whole result under an empty path. The framing reserves no field names, so the result keeps its own shape.
codec field say?Each entry declares how its bytes are coded, and the codec for these attachments is bytes: the part carries the raw bytes themselves. An entry that does not declare a valid codec makes the response invalid.