๐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 has different authentication requirements depending on the operation type:
Simple Rule: All queries are public (API Key only). All mutations are protected (API Key + Service Token).
Public Queries (Read-Only)
All queries are public and only require an API Key:
projectsV2- List all projects with paginationprojectWithDataRoomAndFilesV2- Get project details and filesprojectActivityV2- Get activity feed for a projectprojectAnnouncementsV2- Get announcements for a projectactivitiesV2- Get global activity feeddataRoomFileV2- Get file by pathsearchLabs- Search across projects, files, and announcements
Protected Mutations (Write Operations)
All mutations require authentication with two headers:
API Key - For general API authentication
Service Token - For lab-specific write access control
Protected mutations include:
createProject- Create a new project/data room for an IP-NFTinitiateCreateOrUpdateFileV2- Initiate file uploadfinishCreateOrUpdateFileV2- Complete file uploadupdateFileMetadataV2- Update file metadatadeleteDataRoomFileV2- Delete a filecreateAnnouncementV2- Create an announcementdataRoomPassphrase- Get Telegram bot passphrase for a dataroomextendServiceToken- Extend service token expirationrevokeServiceToken- Revoke a service token
Obtaining API Key and Service Token
To obtain access credentials:
Join our Discord community
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
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
For all queries (read-only operations):
For all mutations (write operations):
Why two tokens for mutations?
API Key: Authenticates you as a valid Molecule API user
Service Token: Identifies which specific lab/dataroom you have write 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:
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:
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:
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
changeByfield (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:
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:
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:
Create Project
Create a new project/data room for an IP-NFT you own or have authorized access to.
Admin Authorization Required: This mutation requires either a service token (JWT) from the Molecule team OR a valid Privy authentication token. Users can only create projects for IP-NFTs they own or are authorized signers for.
GraphQL Mutation:
Parameters:
ipnftSymbol
String
Yes
IP-NFT ticker/symbol (e.g., "APOB", "RARE")
ipnftTokenId
String
Yes
Token ID as string representation of U256 (e.g., "37", "12345")
Prerequisites:
IP-NFT Ownership: You must own the IP-NFT or be an authorized signer for it
For individual wallets: You must be the owner
For multisig/Safe wallets: You must be one of the Safe owners
For ERC-4337 accounts: You must be an authorized account owner
Authentication: One of the following:
Service Token (recommended for automation): Obtain from Molecule team via Discord
Privy Token (for user-initiated requests): Use your authenticated Privy session
IP-NFT Must Be Minted: The IP-NFT must already exist on-chain before creating a project
Authentication Options:
Option 1: Service Token (Recommended for Automation)
Option 2: Privy Token (User-Initiated)
Example Request (Service Token):
Success Response:
Error Responses:
Not Authorized (No Token):
Not IP-NFT Owner:
Project Already Exists:
How It Works:
Authentication Check: Validates service token or Privy token
On-Chain Verification: Verifies you own or are authorized for the IP-NFT
Project Creation: Creates project in Kamu with IP-NFT metadata
Whitelist Update: Automatically adds your wallet address to the project whitelist
Returns Result: Project details if successful, error details if failed
Use Cases:
Automate Project Creation: Create projects programmatically after minting IP-NFTs
CI/CD Integration: Automatically set up data rooms for new research projects
Batch Operations: Create multiple projects for a portfolio of IP-NFTs
User Self-Service: Allow users to create their own project data rooms
Getting Service Token Access:
To obtain a service token for automated project creation:
Join our Discord community
Contact the Molecule team
Provide:
Your wallet address
Use case description
Intended automation workflow
You'll receive:
API Key (for all APIs)
Service Token (JWT for project creation)
Token expiration date
Querying Projects and Files
Query operations for browsing projects, viewing files, and checking activity.
List All Projects
Get all IP-NFT projects. This is a public endpoint - no authentication required.
๐ Public Endpoint: The
projectsV2query does not require authentication. You only need thex-api-keyheader - no Service Token is needed.
GraphQL Query:
Parameters:
walletAddress
String
No
Filter projects by admin wallet address
page
Int
No
Page number (0-indexed, default: 0)
perPage
Int
No
Results per page (default: 20, max: 100)
Example Request:
Get Single Project with Files
Retrieve complete details for a specific project including all files. This is a public endpoint - no authentication required.
๐ Public Endpoint: The
projectWithDataRoomAndFilesV2query does not require authentication. You only need thex-api-keyheader - no Service Token is needed. File-level access control is handled via encryption rather than query-level authentication.
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. This is a public endpoint - no authentication required.
๐ Public Endpoint: The
projectActivityV2query does not require authentication. You only need thex-api-keyheader - no Service Token is needed.
GraphQL Query:
โ ๏ธ Breaking Change: Announcement
attachmentschanged 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. This is a public endpoint - no authentication required.
๐ Public Endpoint: The
projectAnnouncementsV2query does not require authentication. You only need thex-api-keyheader - no Service Token is needed.
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. This is a public endpoint - no authentication required.
๐ Public Endpoint: The
activitiesV2query does not require authentication. You only need thex-api-keyheader - no Service Token is needed.
GraphQL Query:
Note: Attachment fields in
activitiesV2are limited for performance. UseprojectAnnouncementsV2for full attachment metadata including downloadUrl.
Searching Labs
Perform semantic search across all projects, files, and announcements in the Labs ecosystem.
GraphQL Query:
Parameters:
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:
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.fileContains: file metadata, tags, categories, download URL
SearchLabsAnnouncementHit: Announcement search result
Access via:
announcementContains: 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:
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:
Dataroom Utilities
Get Dataroom Passphrase
Retrieve the Telegram bot passphrase for connecting to a dataroom's notification channel. This passphrase is used to authenticate with the Molecule Telegram bot for receiving real-time updates about dataroom activity.
GraphQL Mutation:
Parameters:
ipnftUid
String
Yes
IP-NFT unique identifier
Example Request:
Success Response:
Use Case:
Connect the Molecule Telegram bot to receive notifications about file uploads, announcements, and other dataroom activity
The passphrase is a 3-word phrase separated by dashes
Note: This is a mutation (not a query) because it may have side effects related to notification channel setup. Requires admin access to the specified IP-NFT.
Error Handling
All API responses follow a consistent error format:
Error Response Structure
Common Error Codes
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-Tokenheader is included in requestsVerify 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
extendServiceTokenmutation to extend expiration
Upload to presigned URL fails:
Ensure binary file upload (use
--data-binaryin 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) orpathis correctCheck 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
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 viasearchLabsUpdate metadata as needed: Use
updateFileMetadataV2to refine tags and descriptions without re-uploading files
Access Control
Use
ADMINfor sensitive internal documentsUse
HOLDERSfor IPT holder-exclusive contentUse
PUBLICfor community-facing dataReview access levels regularly as your project evolves
Search and Discovery
Use contentText: Populate
contentTextfield when uploading files to enable full-text searchTag 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
searchLabsto 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
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
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:
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:
Check this documentation and troubleshooting section
Review the complete example for implementation guidance
Join our Discord community for support
Contact the Molecule Labs development team directly
Recent Updates (January 2025)
Authentication Changes
๐ Simplified Authentication Model
All queries are now public (API Key only) and all mutations remain protected (API Key + Service Token).
All Queries
API Key only
No Service Token needed for read operations
All Mutations
API Key + Service Token
Write operations require full authentication
๐ Public Query Endpoints
The following queries are now publicly accessible and no longer require Service Token authentication:
projectsV2
Service Token OR User Auth
API Key only
Now supports pagination parameters
projectWithDataRoomAndFilesV2
Service Token + Admin Auth
API Key only
File access controlled via encryption
projectActivityV2
Service Token OR User Auth
API Key only
Activity feed for a project
projectAnnouncementsV2
Service Token OR User Auth
API Key only
Announcements for a project
activitiesV2
Service Token OR User Auth
API Key only
Global activity feed
dataRoomFileV2
Service Token OR User Auth
API Key only
Get file by path
searchLabs
Service Token OR User Auth
API Key only
Search across all content
๐ dataRoomPassphrase Converted to Mutation
The dataRoomPassphrase operation has been converted from a Query to a Mutation to maintain the pattern that all queries are public:
Migration Required: Update your GraphQL operations from query to mutation for dataRoomPassphrase.
What This Means:
Simplified Integration: Query projects and files with just an API key
Reduced Complexity: No need to manage Service Tokens for read-only operations
File Security Maintained: Encrypted files remain protected via Lit Protocol - access control moved from query-level to file-level
Migration Required: If you're currently including X-Service-Token headers for these queries, you can safely remove them. The queries will work with just x-api-key.
๐ New Pagination for projectsV2
projectsV2The projectsV2 query now supports pagination and wallet filtering:
New Parameters:
walletAddress
String
null
Filter projects by admin wallet address
page
Int
0
Page number (0-indexed)
perPage
Int
20
Results per page (max: 100)
Note: Invalid pagination values are automatically sanitized (negative page โ 0, perPage > 100 โ 20).
New Features
๐ New Query: searchLabs
searchLabsSemantic 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
updateFileMetadataV2Update 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
projectAnnouncementsV2Added 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
projectActivityV2Added pageInfo object to projectActivityV2 results:
Enables proper client-side pagination with total page count.
๐๏ธ New Mutation: createProject (IP-1359)
createProject (IP-1359)Added project creation endpoint with on-chain ownership verification:
Create projects/data rooms for IP-NFTs you own
Requires admin authorization (service token or Privy token)
On-chain verification via AccessResolver contract
Automatic whitelist management
Support for multisig and ERC-4337 accounts
Prerequisites:
IP-NFT must be minted on-chain first
User must own IP-NFT or be an authorized signer
Service token required (obtain from Molecule team)
Benefits:
โ Automate project creation workflows
โ Secure on-chain ownership verification
โ Eliminate manual whitelist management
โ Support for complex ownership structures (Safe, ERC-4337)
See Create Project section for complete documentation.
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,accessLevelRemoved:
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
pathfieldImproved
namefield priority:dataset.nameโdescriptionโpath-derived
Impact: More consistent file paths across all queries
Last updated: January 2026
Last updated