For the complete documentation index, see llms.txt. This page is also available as Markdown.

Files

Working with files in a Lab dataroom: the three-step upload flow (initiate → upload → finish), plus announcements, metadata updates, deletion, storage limits, and client-side encryption. Creating the Lab itself is covered in Lab Management.

Step 1: Initiate File Upload

Initiates the upload process and returns a presigned URL for direct file upload.

GraphQL Mutation:

mutation InitiateFileUpload(
  $oclId: String!
  $contentType: String!
  $contentLength: Int!
) {
  initiateCreateOrUpdateFile(
    oclId: $oclId
    contentType: $contentType
    contentLength: $contentLength
  ) {
    uploadToken
    uploadUrl
    uploadUrlExpiry
    method
    headers {
      key
      value
    }
    isSuccess
    error {
      message
      code
      retryable
    }
  }
}

Parameters:

Parameter
Type
Required
Description

oclId

String

Yes

Canonical 32-byte oclId of the lab (lowercase 0x-hex, e.g. 0x0101…0042)

contentType

String

Yes

MIME type of the file (e.g., application/pdf, image/png)

contentLength

Int

Yes

File size in bytes

Example Request (curl):

Success Response:

Step 2: Upload File to Storage

Upload the file directly to the presigned URL returned in Step 1.

Example Request (curl):

Example Request (JavaScript):

Step 3: Finish File Upload

Completes the upload process and registers the file in the dataroom.

GraphQL Mutation:

Parameters:

Parameter
Type
Required
Description

oclId

String

Yes

Same oclId used in Step 1

uploadToken

String

Yes

Token received from Step 1

path

String

No*

File name for NEW files (e.g., research-data.pdf)

ref

String

No*

Dataset ID for NEW VERSIONS of existing files

changeBy

String

Yes

Wallet address of user making the change

description

String

No

Optional file description

tags

[String]

No

Optional tags for categorization

categories

[String]

No

Optional categories for organization

contentText

String

No

Optional searchable text content (used for semantic search)

*Use path for new files OR ref for versions - not both

Example Request (curl):

Success Response:


Complete Example

Here's a complete Node.js example demonstrating the full 3-step workflow:

Usage:


Create Announcement

Create project announcements to share updates with your community.

GraphQL Mutation:

Parameters:

Parameter
Type
Required
Description

oclId

String

Yes

Canonical 32-byte oclId of the lab

headline

String

Yes

Announcement title/headline

body

String

Yes

Announcement body (supports Markdown)

attachments

[String]

No

Array of file DIDs to attach to the announcement

Example Request:


Update File Metadata

Update file metadata (description, tags, categories, access level) without creating a new version.

GraphQL Mutation:

Parameters:

Parameter
Type
Required
Description

oclId

String

Yes

Canonical 32-byte oclId of the lab

ref

String

Yes

File reference (DID) from finishCreateOrUpdateFile response

description

String

No

Updated file description

tags

[String]

No

Updated tags for categorization

categories

[String]

No

Updated categories for organization

contentText

String

No

Updated searchable text content

Note: The changeBy field (wallet address) is automatically derived from your authentication and does not need to be provided as a parameter.

Example Request:


Delete File

Remove a file from the dataroom permanently.

GraphQL Mutation:

Parameters:

Parameter
Type
Required
Description

oclId

String

Yes

Canonical 32-byte oclId of the lab

path

String

Yes

File path to delete

changeBy

String

Yes

Wallet address making the deletion

Warning: This is a destructive operation. The file will be permanently deleted from the dataroom and cannot be recovered.

Example Request:


Get File by Path

Retrieve a specific file using the lab's oclId and the file path.

GraphQL Query:

Example Request:


File Categories & Tags

Get File Categories and Tags

Return the valid file categories and their tags from the CMS. Use these when tagging or categorizing files. Public query — no authentication required.

Each entry in data is a FileCategory with a name and its list of allowed tags.


File Requirements & Limits

Storage Limits

  • Default Limit: 5GB per lab/project

  • Custom Limits: Can be increased upon request - contact the Molecule team

  • Note: the Labs web app additionally caps individual uploads at 100 MB per file; API uploads are not subject to that app-side cap

Supported File Types

  • All file types are supported

  • Common types: PDF, PNG, JPEG, CSV, JSON, ZIP, etc.

Optional Metadata

Enhance file discoverability with optional metadata:

  • description: Human-readable description of the file

  • tags: Array of tags for categorization (e.g., ["research", "q4-2024"])

  • categories: Array of categories for organization (e.g., ["data", "results"])

  • contentText: Searchable text content for full-text search


Advanced: Encrypted File Upload

For files requiring client-side encryption, obtain a data encryption key via the generateDataEncryptionKey mutation, encrypt locally, upload as normal, and include an encryptionMetadata object on finishCreateOrUpdateFile. The full end-to-end model — key wrapping, onchain access conditions, and condition-gated decryption — is documented on the Data Privacy & Access page.

Obtain a DEK, then encrypt locally

generateDataEncryptionKey (no arguments) returns plaintextDEK, encryptedDek, and encryptionSystem. The client uses plaintextDEK to AES-256-GCM encrypt the file locally (Web Crypto SubtleCrypto), then wipes it from memory. The upload itself uses the standard initiateCreateOrUpdateFile → PUT → finishCreateOrUpdateFile flow, with the encrypted bytes uploaded to the presigned URL.

Encryption Metadata Parameter (Onchain-Verified Envelope Encryption, current default)

encryptionSystem is backend-set — clients must echo the value returned by generateDataEncryptionKey rather than hardcode it. This keeps the roadmap rollover to BLS threshold key custody transparent to existing integrations.

accessControlConditions — gating decryption by role

accessControlConditions is a JSON-stringified array of EvmContractCondition predicates joined by BooleanCondition separators (and / or). The backend evaluates each predicate against live chain state at decrypt time via viem readContract, short-circuits booleans, and fails closed on RPC error. To gate decryption on LabNFT owner OR active Contributor OR active Viewer, OR AccessResolver.isAuthorizedSignerForTba(:userAddress, tba) against AccessResolver.hasRole(oclId, :userAddress, ROLE_VIEWER) — the role-hierarchy collapses Contributor + Viewer into one check on the canonical chain (Base).

The placeholder :userAddress in functionParams is substituted with the authenticated caller's wallet at evaluate time. The full EvmContractCondition JSON shape, the worked OR-composite example, and condition-evaluator semantics are documented on the Data Privacy & Access page.

Role Management (onchain, off this API surface)

Role grants are onchain transactions on the AccessResolver contract, not Labs API mutations. Lab owners (and active Contributors, for the Viewer slot) call grantRole(oclId, account, role, expiry, isAgent) / revokeRole(oclId, account) directly via viem / ethers / Safe. The Labs API only consumes role state at decrypt time through the accessControlConditions evaluator. See Roles & Permissions for the capability matrix, grant lifecycle (expiry, isAgent), and the AccessResolver reference for the onchain interface.

When to Use Encryption:

  • Sensitive research data requiring access control

  • Compliance requirements for data protection

  • Conditional access based on token ownership or lab role


Data Encryption Keys

Generate a Data Encryption Key

Generate a standalone data encryption key (DEK) for client-side encryption outside the file-upload flow. Returns both the plaintext DEK (used to encrypt data locally, then wiped) and the KMS-encrypted DEK (stored alongside the ciphertext). Requires authentication (Privy user or service token). See Advanced: Encrypted File Upload for the file-upload encryption path.

Field
Type
Description

plaintextDEK

String

Base64-encoded plaintext DEK (only present on success)

encryptedDek

String

Base64-encoded KMS-encrypted DEK (only present on success)

encryptionSystem

String

Encryption system used (always "kms")


Last updated