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
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