What is MongoDB Data API
An open-source API to read, write, and aggregate data in MongoDB. The application can be deployed to Modelence Cloud or to any other cloud provider.
CRUD Operations : Insert, find, update, and delete documents
Advanced Querying : Aggregation pipelines and complex queries
Database Management : Collection and index management
Authentication : API key-based security
MongoDB Operations : Direct access to MongoDB features
Sandbox
Try the Data API live at data-api-demo.modelence.app to explore all endpoints and test operations without setup.
Project Setup
1. Create a new application
npx create-modelence-app@latest data-api --template data-api
2. Connect to Modelenece Cloud
Open cloud.modelence.com create
Create a new application and a local environment
Click on Setting → Set up
Follow the steps described in the modal
3. Start the Development Server
Your Data API will be available at http://localhost:3000
4. Deploy to Modelence Cloud
To deploy your Data API to cloud:
Create a Cloud Environment : In your Modelence Cloud dashboard, navigate to your application and create a new environment, selecting cloud as the environment type.
Get the Deployment Command : Go to your cloud environment’s settings page and copy the deployment command:
npx modelence@latest deploy --app < app-nam e > --env < env-nam e >
Deploy : Run the deployment command in your project directory. The deployment process will:
Build your application
Upload it to Modelence Cloud
Provision resources including MongoDB database and server infrastructure
Launch your application
Once deployment completes, your environment status will become active and you’ll receive a URL to access your deployed Data API.
Core Components
DB Access
The MongoDB URL for Data API can be configured via the dataApi.mongodbUri setting in Application → Configuration at https://cloud.modelence.com/ .
The Modelence framework uses the _system.mongodbUri configuration to connect to MongoDB. You can configure two different MongoDB instances to separate Modelence-specific collections from those accessible via Data API.
Authentication
The Data API supports two authentication methods:
1. Direct API Key Authentication
Set the api key as the value of ‘dataApi.apiKey’ in Modelence Cloud from the Application page. (Alternatively you can use DATA_API_KEY environment variable).
Use the apiKey header in your requests:
apiKey: your-secure-api-key-here
2. Bearer Token Authentication
Alternatively, you can use Bearer token authentication by first obtaining an access token from the login endpoint:
Login Endpoint : POST /auth/providers/api-key/login
Request :
{
"key" : "your-api-key"
}
Response :
{
"access_token" : "eyJhbGc..." ,
"refresh_token" : "eyJhbGc..." ,
"token_type" : "Bearer" ,
"expires_in" : 1800
}
Then use the access token in the Authorization header:
Authorization: Bearer eyJhbGc...
Access tokens expire after 30 minutes. Use the refresh token to obtain a new access token without re-authenticating.
Available Endpoints
The API provides comprehensive MongoDB operations with full request/response specifications:
API Operations Reference
1. Find One Document (POST /data/v1/action/findOne)
Purpose : Retrieve a single document from a collection
Request Fields :
{
"collection" : "string" , // Required: Collection name
"database" : "string" , // Optional: Database name (uses default if not specified)
"filter" : {}, // Optional: Query filter object
"projection" : {} // Optional: Fields to include/exclude
}
Example Request :
{
"collection" : "users" ,
"filter" : { "email" : "user@example.com" },
"projection" : { "name" : 1 , "email" : 1 , "_id" : 0 }
}
Response :
{
"document" : {
"name" : "John Doe" ,
"email" : "user@example.com"
}
}
2. Find Multiple Documents (POST /data/v1/action/find)
Purpose : Retrieve multiple documents from a collection
Request Fields :
{
"collection" : "string" , // Required: Collection name
"database" : "string" , // Optional: Database name
"filter" : {}, // Optional: Query filter object
"projection" : {}, // Optional: Fields to include/exclude
"sort" : {}, // Optional: Sort specification
"limit" : 0 , // Optional: Maximum number of documents
"skip" : 0 // Optional: Number of documents to skip
}
Example Request :
{
"collection" : "products" ,
"filter" : { "category" : "electronics" , "price" : { "$lt" : 500 } },
"projection" : { "name" : 1 , "price" : 1 , "category" : 1 },
"sort" : { "price" : 1 },
"limit" : 10 ,
"skip" : 0
}
Response :
{
"documents" : [
{
"name" : "Wireless Mouse" ,
"price" : 29.99 ,
"category" : "electronics"
},
{
"name" : "USB Cable" ,
"price" : 9.99 ,
"category" : "electronics"
}
]
}
3. Insert One Document (POST /data/v1/action/insertOne)
Purpose : Insert a single document into a collection
Request Fields :
{
"collection" : "string" , // Required: Collection name
"database" : "string" , // Optional: Database name
"document" : {} // Required: Document to insert
}
Example Request :
{
"collection" : "users" ,
"document" : {
"name" : "John Doe" ,
"email" : "john@example.com" ,
"age" : 30 ,
"createdAt" : "2024-01-01T00:00:00Z"
}
}
Response :
{
"insertedId" : "507f1f77bcf86cd799439011"
}
4. Insert Multiple Documents (POST /data/v1/action/insertMany)
Purpose : Insert multiple documents into a collection
Request Fields :
{
"collection" : "string" , // Required: Collection name
"database" : "string" , // Optional: Database name
"documents" : [] // Required: Array of documents to insert
}
Example Request :
{
"collection" : "orders" ,
"documents" : [
{
"orderId" : "ORD001" ,
"customerId" : "CUST123" ,
"total" : 99.99 ,
"status" : "pending"
},
{
"orderId" : "ORD002" ,
"customerId" : "CUST456" ,
"total" : 149.99 ,
"status" : "completed"
}
]
}
Response :
{
"insertedIds" : [
"507f1f77bcf86cd799439011" ,
"507f1f77bcf86cd799439012"
]
}
5. Update One Document (POST /data/v1/action/updateOne)
Purpose : Update a single document in a collection
Request Fields :
{
"collection" : "string" , // Required: Collection name
"database" : "string" , // Optional: Database name
"filter" : {}, // Required: Query filter to match document
"update" : {}, // Required: Update operations
"upsert" : false // Optional: Create document if not found
}
Example Request :
{
"collection" : "users" ,
"filter" : { "email" : "john@example.com" },
"update" : {
"$set" : { "lastLogin" : "2024-01-15T10:30:00Z" },
"$inc" : { "loginCount" : 1 }
},
"upsert" : false
}
Response :
{
"matchedCount" : 1 ,
"modifiedCount" : 1
}
6. Update Multiple Documents (POST /data/v1/action/updateMany)
Purpose : Update multiple documents in a collection
Request Fields :
{
"collection" : "string" , // Required: Collection name
"database" : "string" , // Optional: Database name
"filter" : {}, // Required: Query filter to match documents
"update" : {}, // Required: Update operations
"upsert" : false // Optional: Create documents if not found
}
Example Request :
{
"collection" : "products" ,
"filter" : { "category" : "electronics" },
"update" : {
"$mul" : { "price" : 0.9 }
},
"upsert" : false
}
Response :
{
"matchedCount" : 25 ,
"modifiedCount" : 25
}
7. Replace One Document (POST /data/v1/action/replaceOne)
Purpose : Replace an entire document in a collection
Request Fields :
{
"collection" : "string" , // Required: Collection name
"database" : "string" , // Optional: Database name
"filter" : {}, // Required: Query filter to match document
"replacement" : {}, // Required: New document to replace with
"upsert" : false // Optional: Create document if not found
}
Example Request :
{
"collection" : "users" ,
"filter" : { "_id" : { "$oid" : "507f1f77bcf86cd799439011" } },
"replacement" : {
"name" : "Jane Smith" ,
"email" : "jane@example.com" ,
"age" : 25 ,
"department" : "Engineering"
},
"upsert" : false
}
Response :
{
"matchedCount" : 1 ,
"modifiedCount" : 1
}
8. Delete One Document (POST /data/v1/action/deleteOne)
Purpose : Delete a single document from a collection
Request Fields :
{
"collection" : "string" , // Required: Collection name
"database" : "string" , // Optional: Database name
"filter" : {} // Required: Query filter to match document
}
Example Request :
{
"collection" : "users" ,
"filter" : { "email" : "inactive@example.com" }
}
Response :
9. Delete Multiple Documents (POST /data/v1/action/deleteMany)
Purpose : Delete multiple documents from a collection
Request Fields :
{
"collection" : "string" , // Required: Collection name
"database" : "string" , // Optional: Database name
"filter" : {} // Required: Query filter to match documents
}
Example Request :
{
"collection" : "logs" ,
"filter" : {
"timestamp" : {
"$lt" : "2024-01-01T00:00:00Z"
}
}
}
Response :
10. Aggregate (POST /data/v1/action/aggregate)
Purpose : Perform aggregation operations on a collection
Request Fields :
{
"collection" : "string" , // Required: Collection name
"database" : "string" , // Optional: Database name
"pipeline" : [] // Required: Aggregation pipeline stages
}
Example Request :
{
"collection" : "orders" ,
"pipeline" : [
{
"$match" : { "status" : "completed" }
},
{
"$group" : {
"_id" : "$customerId" ,
"totalSpent" : { "$sum" : "$total" },
"orderCount" : { "$sum" : 1 }
}
},
{
"$sort" : { "totalSpent" : -1 }
},
{
"$limit" : 10
}
]
}
Response :
{
"documents" : [
{
"_id" : "CUST123" ,
"totalSpent" : 1299.97 ,
"orderCount" : 13
},
{
"_id" : "CUST456" ,
"totalSpent" : 899.95 ,
"orderCount" : 6
}
]
}
11. Count Documents (POST /data/v1/action/countDocuments)
Purpose : Count the number of documents matching a filter
Request Fields :
{
"dataSource" : "string" , // Required: Data source identifier
"collection" : "string" , // Required: Collection name
"database" : "string" , // Required: Database name
"filter" : {} // Optional: Query filter object
}
Example Request :
{
"dataSource" : "main" ,
"database" : "mydb" ,
"collection" : "users" ,
"filter" : { "status" : "active" }
}
Response :
12. Estimated Document Count (POST /data/v1/action/estimatedDocumentCount)
Purpose : Get an estimated count of all documents in a collection (faster but less accurate than countDocuments)
Request Fields :
{
"dataSource" : "string" , // Required: Data source identifier
"collection" : "string" , // Required: Collection name
"database" : "string" // Required: Database name
}
Example Request :
{
"dataSource" : "main" ,
"database" : "mydb" ,
"collection" : "users"
}
Response :
13. Distinct (POST /data/v1/action/distinct)
Purpose : Get distinct values for a specific field across documents
Request Fields :
{
"dataSource" : "string" , // Required: Data source identifier
"collection" : "string" , // Required: Collection name
"database" : "string" , // Required: Database name
"key" : "string" , // Required: Field name to get distinct values for
"filter" : {} // Optional: Query filter object
}
Example Request :
{
"dataSource" : "main" ,
"database" : "mydb" ,
"collection" : "orders" ,
"key" : "status" ,
"filter" : { "year" : 2024 }
}
Response :
{
"values" : [ "pending" , "completed" , "cancelled" , "refunded" ]
}
14. Find One and Update (POST /data/v1/action/findOneAndUpdate)
Purpose : Find a single document and update it atomically, returning either the original or updated document
Request Fields :
{
"dataSource" : "string" , // Required: Data source identifier
"collection" : "string" , // Required: Collection name
"database" : "string" , // Required: Database name
"filter" : {}, // Required: Query filter to match document
"update" : {}, // Required: Update operations (must contain update operators)
"projection" : {}, // Optional: Fields to include/exclude in returned document
"sort" : {}, // Optional: Sort specification if multiple documents match
"upsert" : false , // Optional: Create document if not found
"returnNewDocument" : true // Optional: Return updated document (true) or original (false)
}
Example Request :
{
"dataSource" : "main" ,
"database" : "mydb" ,
"collection" : "inventory" ,
"filter" : { "sku" : "ABC123" },
"update" : {
"$inc" : { "quantity" : -1 },
"$set" : { "lastModified" : "2024-01-15T10:30:00Z" }
},
"returnNewDocument" : true
}
Response :
{
"document" : {
"_id" : "507f1f77bcf86cd799439011" ,
"sku" : "ABC123" ,
"quantity" : 49 ,
"lastModified" : "2024-01-15T10:30:00Z"
}
}
15. Find One and Replace (POST /data/v1/action/findOneAndReplace)
Purpose : Find a single document and replace it entirely, returning either the original or replacement document
Request Fields :
{
"dataSource" : "string" , // Required: Data source identifier
"collection" : "string" , // Required: Collection name
"database" : "string" , // Required: Database name
"filter" : {}, // Required: Query filter to match document
"replacement" : {}, // Required: New document (cannot contain update operators)
"projection" : {}, // Optional: Fields to include/exclude in returned document
"sort" : {}, // Optional: Sort specification if multiple documents match
"upsert" : false , // Optional: Create document if not found
"returnNewDocument" : true // Optional: Return replacement document (true) or original (false)
}
Example Request :
{
"dataSource" : "main" ,
"database" : "mydb" ,
"collection" : "profiles" ,
"filter" : { "userId" : "user123" },
"replacement" : {
"userId" : "user123" ,
"name" : "Jane Doe" ,
"email" : "jane.doe@example.com" ,
"preferences" : {
"theme" : "dark" ,
"notifications" : true
}
},
"returnNewDocument" : true
}
Response :
{
"document" : {
"_id" : "507f1f77bcf86cd799439011" ,
"userId" : "user123" ,
"name" : "Jane Doe" ,
"email" : "jane.doe@example.com" ,
"preferences" : {
"theme" : "dark" ,
"notifications" : true
}
}
}
16. Find One and Delete (POST /data/v1/action/findOneAndDelete)
Purpose : Find a single document and delete it atomically, returning the deleted document
Request Fields :
{
"dataSource" : "string" , // Required: Data source identifier
"collection" : "string" , // Required: Collection name
"database" : "string" , // Required: Database name
"filter" : {}, // Required: Query filter to match document
"projection" : {}, // Optional: Fields to include/exclude in returned document
"sort" : {} // Optional: Sort specification if multiple documents match
}
Example Request :
{
"dataSource" : "main" ,
"database" : "mydb" ,
"collection" : "sessions" ,
"filter" : { "sessionId" : "sess_abc123" },
"projection" : { "userId" : 1 , "expiredAt" : 1 }
}
Response :
{
"document" : {
"_id" : "507f1f77bcf86cd799439011" ,
"userId" : "user456" ,
"expiredAt" : "2024-01-15T10:30:00Z"
}
}
17. Bulk Write (POST /data/v1/action/bulkWrite)
Purpose : Perform multiple write operations (insert, update, replace, delete) in a single request
Request Fields :
{
"dataSource" : "string" , // Required: Data source identifier
"collection" : "string" , // Required: Collection name
"database" : "string" , // Required: Database name
"operations" : [], // Required: Array of write operations
"ordered" : true // Optional: Execute operations in order (default true)
}
Operation Types :
insertOne: { "insertOne": { "document": {...} } }
updateOne: { "updateOne": { "filter": {...}, "update": {...}, "upsert": false } }
updateMany: { "updateMany": { "filter": {...}, "update": {...}, "upsert": false } }
replaceOne: { "replaceOne": { "filter": {...}, "replacement": {...}, "upsert": false } }
deleteOne: { "deleteOne": { "filter": {...} } }
deleteMany: { "deleteMany": { "filter": {...} } }
Example Request :
{
"dataSource" : "main" ,
"database" : "mydb" ,
"collection" : "products" ,
"operations" : [
{
"insertOne" : {
"document" : { "name" : "New Product" , "price" : 99.99 }
}
},
{
"updateMany" : {
"filter" : { "category" : "electronics" },
"update" : { "$mul" : { "price" : 0.9 } }
}
},
{
"deleteOne" : {
"filter" : { "discontinued" : true }
}
}
],
"ordered" : true
}
Response :
{
"insertedCount" : 1 ,
"matchedCount" : 15 ,
"modifiedCount" : 15 ,
"deletedCount" : 1 ,
"upsertedCount" : 0 ,
"upsertedIds" : {}
}
18. Create Index (POST /data/v1/action/createIndex)
Purpose : Create an index on a collection to improve query performance
Request Fields :
{
"dataSource" : "string" , // Required: Data source identifier
"collection" : "string" , // Required: Collection name
"database" : "string" , // Required: Database name
"keys" : {}, // Required: Index specification (field: 1 or -1)
"options" : {} // Optional: Index options (name, unique, sparse, etc.)
}
Example Request :
{
"dataSource" : "main" ,
"database" : "mydb" ,
"collection" : "users" ,
"keys" : { "email" : 1 },
"options" : {
"name" : "email_index" ,
"unique" : true ,
"sparse" : false
}
}
Response :
{
"createdCollectionAutomatically" : false ,
"numIndexesBefore" : 1 ,
"numIndexesAfter" : 2 ,
"ok" : 1
}
19. Drop Index (POST /data/v1/action/dropIndex)
Purpose : Remove an index from a collection
Request Fields :
{
"dataSource" : "string" , // Required: Data source identifier
"collection" : "string" , // Required: Collection name
"database" : "string" , // Required: Database name
"name" : "string" // Required: Index name to drop
}
Example Request :
{
"dataSource" : "main" ,
"database" : "mydb" ,
"collection" : "users" ,
"name" : "email_index"
}
Response :
{
"nIndexesWas" : 2 ,
"ok" : 1
}
20. List Indexes (POST /data/v1/action/listIndexes)
Purpose : List all indexes on a collection
Request Fields :
{
"dataSource" : "string" , // Required: Data source identifier
"collection" : "string" , // Required: Collection name
"database" : "string" // Required: Database name
}
Example Request :
{
"dataSource" : "main" ,
"database" : "mydb" ,
"collection" : "users"
}
Response :
{
"indexes" : [
{
"v" : 2 ,
"key" : { "_id" : 1 },
"name" : "_id_"
},
{
"v" : 2 ,
"key" : { "email" : 1 },
"name" : "email_index" ,
"unique" : true
}
]
}
21. List Collections (POST /data/v1/action/listCollections)
Purpose : List all collections in a database
Request Fields :
{
"dataSource" : "string" , // Required: Data source identifier
"database" : "string" // Required: Database name
}
Example Request :
{
"dataSource" : "main" ,
"database" : "mydb"
}
Response :
{
"collections" : [
{ "name" : "users" , "type" : "collection" },
{ "name" : "products" , "type" : "collection" },
{ "name" : "orders" , "type" : "collection" }
]
}
22. Create Collection (POST /data/v1/action/createCollection)
Purpose : Create a new collection in a database
Request Fields :
{
"dataSource" : "string" , // Required: Data source identifier
"database" : "string" , // Required: Database name
"collection" : "string" // Required: Collection name to create
}
Example Request :
{
"dataSource" : "main" ,
"database" : "mydb" ,
"collection" : "analytics"
}
Response :
23. Drop Collection (POST /data/v1/action/dropCollection)
Purpose : Delete a collection and all its documents
Request Fields :
{
"dataSource" : "string" , // Required: Data source identifier
"database" : "string" , // Required: Database name
"collection" : "string" // Required: Collection name to drop
}
Example Request :
{
"dataSource" : "main" ,
"database" : "mydb" ,
"collection" : "temp_data"
}
Response :
24. List Databases (POST /data/v1/action/listDatabases)
Purpose : List all available databases
Request Fields :
{
"dataSource" : "string" // Required: Data source identifier
}
Example Request :
Response :
{
"databases" : [
{ "name" : "admin" , "sizeOnDisk" : 32768 , "empty" : false },
{ "name" : "mydb" , "sizeOnDisk" : 8192000 , "empty" : false },
{ "name" : "test" , "sizeOnDisk" : 32768 , "empty" : true }
],
"totalSize" : 8256736 ,
"ok" : 1
}
25. Run Command (POST /data/v1/action/runCommand)
Purpose : Execute arbitrary database commands
Request Fields :
{
"dataSource" : "string" , // Required: Data source identifier
"database" : "string" , // Required: Database name
"command" : {} // Required: Command object
}
Example Request :
{
"dataSource" : "main" ,
"database" : "mydb" ,
"command" : {
"dbStats" : 1 ,
"scale" : 1024
}
}
Response :
{
"result" : {
"db" : "mydb" ,
"collections" : 5 ,
"views" : 0 ,
"objects" : 1523 ,
"avgObjSize" : 512 ,
"dataSize" : 780288 ,
"storageSize" : 1024000 ,
"ok" : 1
}
}
Quick cURL Examples
# Insert a document
curl -X POST http://localhost:3000/data/v1/action/insertOne \
-H "Content-Type: application/json" \
-H "apiKey: your-api-key" \
-d '{"dataSource": "main", "database": "mydb", "collection": "users", "document": {"name": "John Doe"}}'
# Find documents
curl -X POST http://localhost:3000/data/v1/action/find \
-H "Content-Type: application/json" \
-H "apiKey: your-api-key" \
-d '{"dataSource": "main", "database": "mydb", "collection": "users", "filter": {"name": "John Doe"}}'
# Update a document
curl -X POST http://localhost:3000/data/v1/action/updateOne \
-H "Content-Type: application/json" \
-H "apiKey: your-api-key" \
-d '{"dataSource": "main", "database": "mydb", "collection": "users", "filter": {"name": "John Doe"}, "update": {"$set": {"active": true}}}'
# Count documents
curl -X POST http://localhost:3000/data/v1/action/countDocuments \
-H "Content-Type: application/json" \
-H "apiKey: your-api-key" \
-d '{"dataSource": "main", "database": "mydb", "collection": "users", "filter": {"status": "active"}}'
# Aggregate data
curl -X POST http://localhost:3000/data/v1/action/aggregate \
-H "Content-Type: application/json" \
-H "apiKey: your-api-key" \
-d '{"dataSource": "main", "database": "mydb", "collection": "orders", "pipeline": [{"$match": {"status": "completed"}}, {"$group": {"_id": "$customerId", "total": {"$sum": "$amount"}}}]}'
Security Considerations
API Key Authentication : All endpoints require a valid API key
Input Validation : Requests are validated before processing
Error Handling : Proper error responses without exposing sensitive information
Rate Limiting : Consider implementing rate limiting for production use
Use Cases
The Data API is ideal for:
Admin Dashboards : Building administrative interfaces for data management
Data Integration : Connecting external systems to your MongoDB database
Rapid Prototyping : Quickly testing database operations and queries
Analytics Tools : Building custom analytics and reporting tools
Mobile Apps : Providing backend API for mobile applications
Complete Example
Want to see the full working code? Check it out on GitHub:
Complete Data API Example See the complete source code for this example on GitHub, including all endpoints and configuration.
Next Steps