Skip to content

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 and declared is 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. detail carries 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.

id
required
string format: uuid

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
asset_id
required
string format: uuid
status
required

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.

string
Allowed values: ok unsupported unreadable
detail

Why the file could not be read. Present only when status is unreadable.

string
partial
required

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.

boolean
declared
required

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.

Array<string>
missing
required

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.

Array<string>
attached
required

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.

Array<string>

Authentication required, missing, or invalid

object
error
required

Human-readable error summary

string
Example
the request could not be completed
Example
{
"error": "authentication required: sign in and retry with a valid session or API token"
}

Resource not found

object
error
required

Human-readable error summary

string
Example
the request could not be completed

Unexpected server error

object
error
required

Human-readable error summary

string
Example
the request could not be completed