Assets API
Use Asset Manager for interactive work and CLI assets for file transfer. Application extensions can use the exported useUploadAssets hook inside Studio.
Upload contract
The project assets endpoint accepts a POST with the file bytes as the request body, an appropriate Content-Type, and an optional filename query parameter. It is not a multipart form upload. Use an authorized subject and the correct project endpoint or the configured Studio proxy.
The response identifies the asset with _id and includes path, url, mimeType, originalFilename, extension, size, width, height, lqip, sha256, and deduped. Metadata can be null, particularly for non-image files or unavailable image metadata.
Content deduplication may return an existing asset. Treat the returned _id as authoritative rather than assuming every upload creates another record. Uploading does not attach the asset to a business record; save the corresponding asset relationship separately.
Delivery URLs
path is the relative blob key. url is its persisted absolute delivery URL: image MIME types use https://flexkit.io/images/<path> and other types use https://flexkit.io/files/<path>. Use the returned URL directly; a missing path produces a null URL. Existing records can have null URLs until migrated.
The server maintains url; GraphQL mutation inputs do not accept it. When creating or updating asset delivery metadata through GraphQL, supply both path and mimeType together (explicit nulls are allowed). Updates to unrelated fields do not require either field. This rule also applies to nested asset mutations.
See file delivery for PDFs and other original files, and image delivery for transformations.
Errors and lifecycle
Handle authentication/authorization errors, an empty body, rate limits, identity conflicts, and storage failures. Read the response before retrying. A repeated file transfer can still make requests even when storage content is deduplicated.
Use Asset Manager to inspect the result and image delivery for presentation. Protect sensitive material according to its delivery behavior; Studio access alone does not establish that a copied URL is private.