โš™๏ธLabs API

Overview

The Programmatic File Upload API allows developers to automate file uploads to Molecule Labs datarooms without requiring browser-based user interaction. This enables integration with automated workflows, data pipelines, CI/CD systems, and external applications.

Use Cases

  • Automated Data Pipelines: Schedule regular data synchronization from research systems

  • CI/CD Integration: Automatically publish build artifacts and test results

  • External System Integration: Connect third-party tools and platforms to your Lab

  • Batch Operations: Upload multiple files programmatically

  • Monitoring & Alerting: Automated upload of logs and metrics

Ready for Production: This API is production-ready and actively used by projects for automated data management. To request API access, please join our Discord community and reach out to our team.


Authentication

The Labs API requires two authentication headers for all requests:

  1. API Key - For general API authentication

  2. Service Token - For lab-specific access control

Obtaining API Key and Service Token

To obtain access credentials:

  1. Contact the Molecule team and provide:

    • Your wallet address (will be linked to the service token)

    • Intended use case / service name

    • Which lab/dataroom you need access to

    • Desired token expiration period

  2. The team will generate and provide you with:

    • API Key - Used for all Molecule APIs

    • Service Token (JWT string) - Grants access to specific lab

    • Token ID - For management operations

Using Your Credentials

Both headers are required for all Labs API requests:

Why two tokens?

  • API Key: Authenticates you as a valid Molecule API user

  • Service Token: Identifies which specific lab/dataroom you have access to

Security Warnings:

  • Service tokens are shown only once during generation - store them securely immediately

  • Never commit tokens or API keys to version control

  • Never log credentials in application logs

  • Store in environment variables or secure secret management systems

  • Rotate tokens regularly (quarterly recommended)


API Endpoints

The Programmatic File Upload API uses a 3-step workflow:

API Base URL

Step 1: Initiate File Upload

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

GraphQL Mutation:

Parameters:

Parameter
Type
Required
Description

ipnftUid

String

Yes

IP-NFT unique identifier in format contractAddress_tokenId (e.g., 0xcaD...1_37)

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

ipnftUid

String

Yes

Same IP-NFT identifier 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

accessLevel

String

Yes

File visibility: PUBLIC, HOLDERS, or ADMIN

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:


Update File Metadata

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

GraphQL Mutation:

Parameters:

Parameter
Type
Required
Description

ipnftUid

String

Yes

IP-NFT unique identifier

ref

String

Yes

File reference (DID) from finishCreateOrUpdateFileV2 response

accessLevel

String

Yes

File visibility: PUBLIC, HOLDERS, or ADMIN

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

ipnftUid

String

Yes

IP-NFT unique identifier

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:


Create Announcement

Create project announcements to share updates with your community.

GraphQL Mutation:

Parameters:

Parameter
Type
Required
Description

ipnftUid

String

Yes

IP-NFT unique identifier

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:


Querying Projects and Files

Query operations for browsing projects, viewing files, and checking activity.

List All Projects

Get all IP-NFT projects available to you.

GraphQL Query:

Example Request:

Get Single Project with Files

Retrieve complete details for a specific project including all files.

GraphQL Query:

Example Request:

Get File by Path

Retrieve a specific file using IP-NFT UID and file path.

GraphQL Query:

Example Request:

Project Activity Feed

Get activity timeline for a specific project including file events and announcements.

GraphQL Query:

โš ๏ธ Breaking Change: Announcement attachments changed from [String!]! (array of DIDs) to [DataRoomFile!]! (array of file objects). This enables querying file metadata directly without separate API calls.

Example Request:

Performance Note: Attachment fields in projectActivityV2 are limited to essential display fields (did, path, name, contentType, accessLevel) for optimal performance. For full attachment metadata including downloadUrl and encryption details, use projectAnnouncementsV2 instead.

Project Announcements (Dedicated Endpoint)

Get announcements for a specific project with full attachment details. More efficient than projectActivityV2 when you only need announcements.

GraphQL Query:

Example Request:

Use Cases:

  • Announcement detail pages requiring full file metadata

  • Download links for announcement attachments

  • Encrypted file access with Lit Protocol

  • Projects with many announcements (efficient pagination)

All Announcements (Global Feed)

Get all announcements across all projects.

GraphQL Query:

Note: Attachment fields in activitiesV2 are limited for performance. Use projectAnnouncementsV2 for full attachment metadata including downloadUrl.


Searching Labs

Perform semantic search across all projects, files, and announcements in the Labs ecosystem.

GraphQL Query:

Parameters:

Parameter
Type
Required
Description

prompt

String

Yes

Search query text

filters

SearchLabsFilters

No

Filter criteria

page

Int

No

Page number (default: 0)

perPage

Int

No

Results per page (default: 10)

Available Filters:

Filter
Type
Description

byIpnftUids

[String!]

Filter by specific project UIDs

byTags

[String!]

Filter files by tags

byCategories

[String!]

Filter files by categories

byAccessLevels

[String!]

Filter files by access level (PUBLIC, HOLDERS, ADMIN)

byKinds

[String!]

Filter by result type

Example - Basic Search:

Example - Filtered Search:

Understanding Results:

Search results are returned as a union type. Use the __typename field to determine result type:

  • SearchLabsFileHit: File search result

    • Access via: entry.file

    • Contains: file metadata, tags, categories, download URL

  • SearchLabsAnnouncementHit: Announcement search result

    • Access via: announcement

    • Contains: headline, body, project reference, typed attachments (file objects)

JavaScript Example:


Complete Example

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

Usage:


Service Token Management

Obtaining Tokens

Service tokens must be requested from the Molecule team (see Authentication section above).

Extending Token Expiration

You can extend your service token's expiration using the extendServiceToken mutation:

Parameters:

Parameter
Type
Description

tokenId

String

Token ID provided when token was generated

expiresIn

String

New duration (e.g., "30d", "720h", "90d")

Example:

Important: Extension returns a new JWT token - update your stored token accordingly.

Revoking Tokens

Revoke a service token immediately (e.g., if compromised):

Example:


Error Handling

All API responses follow a consistent error format:

Error Response Structure

Common Error Codes

Status Code
Error
Description

401

Unauthorized

Missing or invalid service token

403

Forbidden

Service token does not have access to the specified IP-NFT

400

Bad Request

Invalid parameters (e.g., missing ipnftUid, invalid contentType)

404

Not Found

IP-NFT or dataroom not found

413

Payload Too Large

File exceeds size limits

500

Internal Server Error

Server error - check if retryable and try again

Troubleshooting

"Missing service token" error:

  • Ensure X-Service-Token header is included in requests

  • Verify token is not empty or malformed

"Service does not have access to IPNFT" error:

  • Verify your wallet address (linked to service token) has admin access to the IP-NFT/dataroom

  • Check that the ipnftUid format is correct: contractAddress_tokenId

"Token expired" error:

  • Request a new token from the Molecule team, or

  • Use extendServiceToken mutation to extend expiration

Upload to presigned URL fails:

  • Ensure binary file upload (use --data-binary in curl)

  • Verify headers match those returned in Step 1

  • Check that presigned URL hasn't expired (expires after ~15 minutes)

"File not found" error (updateFileMetadataV2, deleteDataRoomFileV2):

  • Verify the file ref (DID) or path is correct

  • Check that the file exists in the specified dataroom

  • Ensure you have access to the dataroom

"Invalid search filters" error (searchLabs):

  • Verify filter values match expected types (arrays of strings)

  • Check that access level values are: PUBLIC, HOLDERS, or ADMIN

  • Ensure ipnftUid format is correct if using byIpnftUids filter


File Requirements & Limits

Storage Limits

  • Default Limit: 5GB per lab/project

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

Supported File Types

  • All file types are supported

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

Access Levels

Level
Description

PUBLIC

Visible to anyone with access to the project

HOLDERS

Visible only to IP Token (IPT) holders

ADMIN

Visible only to project administrators

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, you can include encryption metadata using the Lit Protocol.

Encryption Metadata Parameter

Structure:

When to Use Encryption:

  • Sensitive research data requiring access control

  • Compliance requirements for data protection

  • Conditional access based on token ownership

For more information about Lit Protocol encryption, visit the Lit Protocol documentation.


Best Practices

Token Security

  • Never commit tokens to version control (add to .gitignore)

  • Use environment variables to store tokens

  • Rotate tokens regularly (quarterly recommended)

  • Use secrets management systems in production (AWS Secrets Manager, HashiCorp Vault, etc.)

  • Revoke immediately if a token is compromised

Storage Management

  • Monitor your 5GB storage limit per project

  • Organize files with meaningful names and metadata

  • Use categories and tags for easy file discovery

  • Clean up old or unnecessary files regularly

Metadata Best Practices

  • Use descriptive tags: ["experiment-1", "2024-q4", "preliminary"]

  • Organize with categories: ["raw-data", "analysis", "results"]

  • Add descriptions: Help collaborators understand file contents

  • Include searchable text (contentText): Enables full-text search via searchLabs

  • Update metadata as needed: Use updateFileMetadataV2 to refine tags and descriptions without re-uploading files

Access Control

  • Use ADMIN for sensitive internal documents

  • Use HOLDERS for IPT holder-exclusive content

  • Use PUBLIC for community-facing data

  • Review access levels regularly as your project evolves

Search and Discovery

  • Use contentText: Populate contentText field when uploading files to enable full-text search

  • Tag consistently: Use consistent tag names across files for better filtering

  • Filter strategically: Combine filters (tags + access levels) to narrow search results

  • Test search queries: Use searchLabs to verify your files are discoverable


Deprecated Operations

The following V1 operations have been replaced by improved V2 versions. V1 operations are deprecated and will be removed in a future release.

Deprecated Queries

V1 Query
V2 Replacement
Key Changes

projects

projectsV2

Added systemTime and eventTime fields

projectWithDataRoomAndFiles

projectWithDataRoomAndFilesV2

Enhanced temporal tracking

dataRoomFile(did: String!)

dataRoomFileV2(ipnftUid, path)

Query by IPNFT UID + path instead of DID

projectActivity

projectActivityV2

Improved activity feed structure

activities

activitiesV2

Enhanced announcement structure

Deprecated Mutations

V1 Mutation
V2 Replacement
Key Changes

initiateFileUpload

initiateCreateOrUpdateFileV2

Simplified parameters, no dataset alias needed

finishFileUpload

finishCreateOrUpdateFileV2

Added metadata support (tags, categories, contentText)

deleteDataRoomFile

deleteDataRoomFileV2

Streamlined parameters

createAnnouncement

createAnnouncementV2

Breaking: Removed moleculeAccessLevel parameter

Migration Guide

Breaking Change 1: createAnnouncement โ†’ createAnnouncementV2

The moleculeAccessLevel parameter has been removed in V2:

Breaking Change 2: Announcement Attachments Type Change

โš ๏ธ BREAKING CHANGE: Announcement attachments changed from string arrays to full file objects.

Previous Structure (V1):

New Structure (V2):

Migration Required: If you query announcements via projectActivityV2, activitiesV2, searchLabs, or projectAnnouncementsV2, update your code to handle attachment objects instead of strings:

Before:

After:

Benefits:

  • โœ… No additional API calls needed for file metadata

  • โœ… Better developer experience

  • โœ… Reduced API load

  • โœ… Type-safe attachment handling

Field Availability by Query:

Query
Attachment Fields Available

projectActivityV2

Minimal (did, path, name, contentType, accessLevel)

activitiesV2

Minimal (did, path, name, contentType, accessLevel)

searchLabs

Minimal (did, path, name, contentType, accessLevel)

projectAnnouncementsV2

Full (includes downloadUrl, encryptionMetadata, version, etc.)

All other V1 โ†’ V2 migrations are backward-compatible with additional optional parameters in V2.


Getting Support

If you encounter any issues or have questions about the Programmatic File Upload API:

  1. Check this documentation and troubleshooting section

  2. Review the complete example for implementation guidance

  3. Join our Discord community for support

  4. Contact the Molecule Labs development team directly


Recent Updates (January 2025)

New Features

๐Ÿ” New Query: searchLabs

Semantic search across all IP-NFT projects, files, and announcements:

  • Full-text search with relevance ranking

  • Filter by tags, categories, access levels, project UIDs

  • Returns unified results (files + announcements)

  • Paginated results with totalCount

Benefits:

  • Discover content across all Labs projects

  • Filter by multiple criteria simultaneously

  • Unified search experience

  • Support for complex queries

See Searching Labs section for complete documentation.

๐Ÿ“ New Mutation: updateFileMetadataV2

Update file metadata without creating a new version:

  • Modify description, tags, categories, contentText

  • Update access level (PUBLIC, HOLDERS, ADMIN)

  • No file re-upload required

  • Preserves version history

Benefits:

  • Refine file metadata after upload

  • Improve searchability with updated contentText

  • Reorganize files with new tags/categories

  • Adjust access control as needed

See Update File Metadata section for complete documentation.

โœจ New Query: projectAnnouncementsV2

Added dedicated announcements endpoint with full attachment metadata:

  • Fetches ONLY announcements (no file events) for better performance

  • Includes complete attachment details (downloadUrl, encryptionMetadata, etc.)

  • Efficient pagination with totalCount

  • Use this instead of projectActivityV2 when you only need announcements

Benefits over projectActivityV2:

  • Faster response times

  • Full attachment metadata available

  • Direct pagination support

  • No file events to filter through

๐Ÿ“Š Pagination Enhancement: projectActivityV2

Added pageInfo object to projectActivityV2 results:

Enables proper client-side pagination with total page count.

Breaking Changes

โš ๏ธ Announcement Attachments Type Change (IP-1025)

Affected Queries: projectActivityV2, activitiesV2, searchLabs, projectAnnouncementsV2

What Changed:

  • Attachments field type: [String!]! โ†’ [DataRoomFile!]!

  • Instead of array of DIDs, you now get full file objects

Before (Old):

After (New):

Why This Change:

  • โœ… Eliminates need for separate API calls to resolve file details

  • โœ… Improves developer experience

  • โœ… Reduces API load and complexity

  • โœ… Type-safe file handling

Migration: Update your code to access file properties directly instead of using DIDs to fetch file details:

Field Availability:

  • Activity queries (projectActivityV2, activitiesV2, searchLabs): Minimal fields (6 fields for performance)

  • Announcements query (projectAnnouncementsV2): Full fields (20+ fields including downloadUrl)

Performance Improvements

๐Ÿš€ Optimized Activity Query Performance

Reduced attachment fields in activity/search queries to prevent Lambda timeouts:

Minimal Fields (Activity Queries):

  • Essential: id, did, path, name, contentType, accessLevel

  • Removed: downloadUrl, encryptionMetadata, contentText, version, contentHash, etc.

Result: Faster response times, no timeout issues

Full Fields Available: Use projectAnnouncementsV2 when you need downloadUrl, encryptionMetadata, or other detailed fields.

Internal Improvements

๐Ÿ”ง Path Field Consistency (IP-1352)

Fixed inconsistency where the path field differed between queries:

  • Now consistently uses Kamu's native path field

  • Improved name field priority: dataset.name โ†’ description โ†’ path-derived

Impact: More consistent file paths across all queries


Last updated: January 2025

Last updated