What this model file says it needs, and what is still missing
GET /assets/{id}/companion-requirements
Reads the stored model and reports the external files it
DECLARES — its glTF buffers[].uri / images[].uri, its FBX
Video/Texture filenames, its OBJ mtllib lines — then subtracts
the companions already attached (#754).
Why this exists
A multi-file model only renders if its siblings are registered
as companions. Nothing on the upload path derived that list, so
an artist who uploaded structure-wall.glb without knowing it
names Textures/planks.png got a job that SUCCEEDED and a card
and viewer that came out grey. That is the symptom chain #689
chased into the renderer before #750 traced it to missing
companion rows: the failure is silent and reads as a renderer
bug rather than a missing-input bug.
This endpoint is purely informational and purely additive. It
attaches nothing, writes nothing, and enqueues nothing — the
client decides what to do with the answer, and
POST /assets/{id}/companions remains the only way to attach.
status is three-valued on purpose
A format we cannot read must never come back as “declares nothing”, and neither must a container we failed to parse. The three are distinguished so a UI can say the true thing:
ok— the file was read anddeclaredis its reference list (possibly empty, which for a GLB is a RESULT and not an assumption: 363 of the 374 GLBs in the seed catalogue reference external textures).unsupported— no reader exists for this extension. STL, PLY and DAE land here, and so does every non-model asset. This is a gap in our parsers, NOT a claim that the file is self-contained.unreadable— the extension is one we read and the bytes did not parse.detailcarries why.
partial
True only for OBJ. An OBJ names .mtl material libraries, and
each .mtl names the textures it uses — but the second level
lives INSIDE a file that has not been uploaded yet, so only the
first level is knowable here. The seeder resolves both levels
because it has the directory on disk; content-addressed storage
has no sibling directory. A client must say so rather than
under-report silently: the deeper references become discoverable
once the .mtl is attached and this endpoint is asked again.
Authorizations
Section titled “Authorizations ”Parameters
Section titled “ Parameters ”Path Parameters
Section titled “Path Parameters ”Responses
Section titled “ Responses ”What the model declares, and what of it is still missing.
The external files a stored model declares, and which of them are still unattached (#754). Informational only — nothing here attaches, writes or enqueues anything.
object
ok — the file was read; declared is its reference list,
and an empty list means it genuinely declares none.
unsupported — no reader exists for this extension (STL,
PLY, DAE, and every non-model asset). ⚠️ NOT a claim that
the file is self-contained.
unreadable — a format we do read, whose bytes did not
parse. detail says why.
Why the file could not be read. Present only when status is unreadable.
True when the declared list is known to be incomplete — OBJ
only. An OBJ names .mtl libraries and each .mtl names
textures, but that second level lives inside a file not yet
uploaded, so only the first is knowable here. Attach the
.mtl and ask again to see the rest.
Every external file the model references, as clean relative
forward-slash paths in declaration order, de-duplicated.
Embedded data: URIs, remote URLs, absolute paths and
anything escaping the model’s directory are excluded — none
of those needs a companion.
The subset of declared with no companion attached at that
path. This is the list a create surface names to the artist
(“this model needs Textures/planks.png”). Empty means the
model has everything it asked for.
The subset of declared already satisfied by a companion
row. A companion attached at a path the model does NOT
declare appears in neither list — it is not wrong, just not
something the model asked for.
Authentication required, missing, or invalid
object
Human-readable error summary
Example
the request could not be completedExample
{ "error": "authentication required: sign in and retry with a valid session or API token"}Resource not found
object
Human-readable error summary
Example
the request could not be completedUnexpected server error
object
Human-readable error summary
Example
the request could not be completed