diff --git a/pages/api-reference/crud/delete/index.mdx b/pages/api-reference/crud/delete/index.mdx
new file mode 100644
index 0000000..26cdc89
--- /dev/null
+++ b/pages/api-reference/crud/delete/index.mdx
@@ -0,0 +1,93 @@
+---
+title: API CRUD DELETE | Datasquirel docs
+description: Delete a record from a Datasquirel table via the API
+page_title: DELETE
+page_description: Delete one or more records from a table using the Datasquirel REST API or npm package.
+---
+
+## Overview
+
+Use the DELETE endpoint to remove records from a table. You can delete by a specific record ID or by matching field values.
+
+## npm Package
+
+### Delete by ID
+
+```javascript
+import datasquirel from "@moduletrace/datasquirel";
+
+const result = await datasquirel.crud.delete({
+ dbName: "my_database",
+ tableName: "users",
+ targetID: 42,
+ apiKey: process.env.DATASQUIREL_API_KEY,
+});
+```
+
+### Delete by Field Value
+
+```javascript
+const result = await datasquirel.crud.delete({
+ dbName: "my_database",
+ tableName: "sessions",
+ deleteSpec: {
+ deleteKeyValues: [
+ { key: "user_id", value: 42, operator: "=" },
+ ],
+ },
+ apiKey: process.env.DATASQUIREL_API_KEY,
+});
+```
+
+## Parameters
+
+| Parameter | Type | Required | Description |
+|-----------|------|----------|-------------|
+| `dbName` | `string` | Yes | The database slug |
+| `tableName` | `string` | Yes | The table to delete from |
+| `targetID` | `string \| number` | No | The `id` of the record to delete. Either `targetID` or `deleteSpec` is required |
+| `deleteSpec` | `object` | No | Field-value conditions for deletion (see below) |
+| `apiKey` | `string` | No | API key. Falls back to `DATASQUIREL_API_KEY` environment variable |
+
+### deleteSpec.deleteKeyValues
+
+An array of conditions. Each condition has:
+
+| Field | Type | Description |
+|-------|------|-------------|
+| `key` | `string` | The field name to match |
+| `value` | `string \| number \| null` | The value to match against |
+| `operator` | `string` | Comparison operator — `"="`, `"!="`, `">"`, `"<"`, etc. Defaults to `"="` |
+
+## REST API
+
+```
+DELETE /api/v1/crud/{dbName}/{tableName}/{id}
+DELETE /api/v1/crud/{dbName}/{tableName}
+```
+
+**Headers:**
+```
+Authorization: Bearer YOUR_API_KEY
+Content-Type: application/json
+```
+
+**Body (when deleting by field value):**
+```json
+{
+ "deleteKeyValues": [
+ { "key": "user_id", "value": 42, "operator": "=" }
+ ]
+}
+```
+
+## Response
+
+```json
+{
+ "success": true,
+ "payload": 1
+}
+```
+
+A successful response returns `success: true` and `payload` with the number of deleted rows.
diff --git a/pages/api-reference/crud/get/index.mdx b/pages/api-reference/crud/get/index.mdx
new file mode 100644
index 0000000..29e332b
--- /dev/null
+++ b/pages/api-reference/crud/get/index.mdx
@@ -0,0 +1,104 @@
+---
+title: API CRUD GET | Datasquirel docs
+description: Fetch records from a Datasquirel table via the API
+page_title: GET
+page_description: Read one or more records from a table using the Datasquirel REST API or npm package.
+---
+
+## Overview
+
+Use the GET endpoint to fetch records from any table in your database. You can retrieve all records, a single record by ID, or a filtered and paginated subset.
+
+## npm Package
+
+```javascript
+import datasquirel from "@moduletrace/datasquirel";
+
+const result = await datasquirel.crud.get({
+ dbName: "my_database",
+ tableName: "users",
+ apiKey: process.env.DATASQUIREL_API_KEY,
+});
+
+// result.payload contains the array of records
+console.log(result.payload);
+```
+
+### Get a Single Record by ID
+
+```javascript
+const result = await datasquirel.crud.get({
+ dbName: "my_database",
+ tableName: "users",
+ targetId: 42,
+ apiKey: process.env.DATASQUIREL_API_KEY,
+});
+```
+
+### Filtered and Paginated Query
+
+```javascript
+const result = await datasquirel.crud.get({
+ dbName: "my_database",
+ tableName: "posts",
+ apiKey: process.env.DATASQUIREL_API_KEY,
+ query: {
+ limit: 10,
+ page: 1,
+ order: { field: "created_at", strategy: "DESC" },
+ query: {
+ is_published: { value: 1, equality: "=" },
+ },
+ },
+});
+```
+
+## Parameters
+
+| Parameter | Type | Required | Description |
+|-----------|------|----------|-------------|
+| `dbName` | `string` | Yes | The database slug to query |
+| `tableName` | `string` | Yes | The table to read from |
+| `apiKey` | `string` | No | API key. Falls back to the `DATASQUIREL_API_KEY` environment variable |
+| `targetId` | `string \| number` | No | Fetch a single record by its `id` |
+| `query` | `object` | No | Filter, pagination, and ordering options (see below) |
+
+### Query Options
+
+| Option | Type | Description |
+|--------|------|-------------|
+| `limit` | `number` | Maximum number of records to return |
+| `page` | `number` | Page number for pagination (1-based) |
+| `offset` | `number` | Number of records to skip |
+| `order` | `{ field, strategy }` | Sort by a field — `strategy` is `"ASC"` or `"DESC"` |
+| `selectFields` | `string[]` | Only return these fields |
+| `omitFields` | `string[]` | Exclude these fields from the result |
+| `query` | `object` | Field-level filters — each key is a field name with a `value` and `equality` |
+| `fullTextSearch` | `object` | Full-text search across specified fields |
+| `join` | `array` | JOIN conditions against other tables |
+
+## REST API
+
+```
+GET /api/v1/crud/{dbName}/{tableName}
+GET /api/v1/crud/{dbName}/{tableName}/{id}
+```
+
+**Headers:**
+```
+Authorization: Bearer YOUR_API_KEY
+```
+
+## Response
+
+```json
+{
+ "success": true,
+ "payload": [
+ { "id": 1, "name": "Alice", "email": "alice@example.com" },
+ { "id": 2, "name": "Bob", "email": "bob@example.com" }
+ ]
+}
+```
+
+A successful response has `success: true` and a `payload` array. A single-record fetch (by `targetId`) returns `payload` as an object.
diff --git a/pages/api-reference/crud/options/index.mdx b/pages/api-reference/crud/options/index.mdx
new file mode 100644
index 0000000..2bf955e
--- /dev/null
+++ b/pages/api-reference/crud/options/index.mdx
@@ -0,0 +1,46 @@
+---
+title: API CRUD OPTIONS | Datasquirel docs
+description: Inspect available CRUD operations for a table
+page_title: OPTIONS
+page_description: Retrieve metadata about the CRUD operations available for a table.
+---
+
+## Overview
+
+The OPTIONS endpoint returns metadata about the available operations for a given table — useful for dynamically discovering what fields and actions are supported.
+
+## REST API
+
+```
+OPTIONS /api/v1/crud/{dbName}/{tableName}
+```
+
+**Headers:**
+```
+Authorization: Bearer YOUR_API_KEY
+```
+
+## Response
+
+The response includes information about the table schema and the HTTP methods supported for that table.
+
+```json
+{
+ "success": true,
+ "payload": {
+ "methods": ["GET", "POST", "PUT", "DELETE"],
+ "schema": [
+ { "name": "id", "type": "int", "required": true },
+ { "name": "name", "type": "varchar(255)", "required": true },
+ { "name": "email", "type": "varchar(255)", "required": false }
+ ]
+ }
+}
+```
+
+## Related
+
+- [GET](/docs/api-reference/crud/get) — read records
+- [POST](/docs/api-reference/crud/post) — create records
+- [PUT](/docs/api-reference/crud/put) — update records
+- [DELETE](/docs/api-reference/crud/delete) — delete records
diff --git a/pages/api-reference/crud/post/index.mdx b/pages/api-reference/crud/post/index.mdx
new file mode 100644
index 0000000..7dd5385
--- /dev/null
+++ b/pages/api-reference/crud/post/index.mdx
@@ -0,0 +1,88 @@
+---
+title: API CRUD POST | Datasquirel docs
+description: Create a new record in a Datasquirel table via the API
+page_title: POST
+page_description: Insert a new record into a table using the Datasquirel REST API or npm package.
+---
+
+## Overview
+
+Use the POST endpoint to insert a new record into a table. Provide the data as a plain object — the keys must match your table's field names.
+
+## npm Package
+
+```javascript
+import datasquirel from "@moduletrace/datasquirel";
+
+const result = await datasquirel.crud.insert({
+ dbName: "my_database",
+ tableName: "users",
+ body: {
+ name: "Alice",
+ email: "alice@example.com",
+ is_active: 1,
+ },
+ apiKey: process.env.DATASQUIREL_API_KEY,
+});
+
+// result.payload is the inserted record's ID
+console.log(result.payload);
+```
+
+### Insert Multiple Records (Batch)
+
+You can insert multiple records in a single request by passing an array in a `batchData` field:
+
+```javascript
+const result = await datasquirel.crud.insert({
+ dbName: "my_database",
+ tableName: "tags",
+ body: { batchData: [
+ { name: "javascript" },
+ { name: "typescript" },
+ { name: "sql" },
+ ]},
+ apiKey: process.env.DATASQUIREL_API_KEY,
+});
+```
+
+## Parameters
+
+| Parameter | Type | Required | Description |
+|-----------|------|----------|-------------|
+| `dbName` | `string` | Yes | The database slug |
+| `tableName` | `string` | Yes | The table to insert into |
+| `body` | `object` | Yes | The record to insert. Keys must match field names |
+| `apiKey` | `string` | No | API key. Falls back to `DATASQUIREL_API_KEY` environment variable |
+
+## REST API
+
+```
+POST /api/v1/crud/{dbName}/{tableName}
+```
+
+**Headers:**
+```
+Authorization: Bearer YOUR_API_KEY
+Content-Type: application/json
+```
+
+**Body:**
+```json
+{
+ "name": "Alice",
+ "email": "alice@example.com",
+ "is_active": 1
+}
+```
+
+## Response
+
+```json
+{
+ "success": true,
+ "payload": 7
+}
+```
+
+A successful response returns `success: true` and `payload` containing the `insertId` (the auto-incremented `id` of the new record).
diff --git a/pages/api-reference/crud/put/index.mdx b/pages/api-reference/crud/put/index.mdx
new file mode 100644
index 0000000..a680dc8
--- /dev/null
+++ b/pages/api-reference/crud/put/index.mdx
@@ -0,0 +1,68 @@
+---
+title: API CRUD PUT | Datasquirel docs
+description: Update an existing record in a Datasquirel table via the API
+page_title: PUT
+page_description: Update an existing record in a table using the Datasquirel REST API or npm package.
+---
+
+## Overview
+
+Use the PUT endpoint to update an existing record. You must provide the `id` of the record you want to update, along with the fields you want to change. Only the fields you include in the body are updated — other fields are left unchanged.
+
+## npm Package
+
+```javascript
+import datasquirel from "@moduletrace/datasquirel";
+
+const result = await datasquirel.crud.update({
+ dbName: "my_database",
+ tableName: "users",
+ targetID: 42,
+ body: {
+ name: "Alice Updated",
+ is_active: 0,
+ },
+ apiKey: process.env.DATASQUIREL_API_KEY,
+});
+```
+
+## Parameters
+
+| Parameter | Type | Required | Description |
+|-----------|------|----------|-------------|
+| `dbName` | `string` | Yes | The database slug |
+| `tableName` | `string` | Yes | The table to update |
+| `targetID` | `string \| number` | Yes | The `id` of the record to update |
+| `body` | `object` | Yes | Fields to update. Keys must match field names |
+| `apiKey` | `string` | No | API key. Falls back to `DATASQUIREL_API_KEY` environment variable |
+
+## REST API
+
+```
+PUT /api/v1/crud/{dbName}/{tableName}/{id}
+```
+
+**Headers:**
+```
+Authorization: Bearer YOUR_API_KEY
+Content-Type: application/json
+```
+
+**Body:**
+```json
+{
+ "name": "Alice Updated",
+ "is_active": 0
+}
+```
+
+## Response
+
+```json
+{
+ "success": true,
+ "payload": 1
+}
+```
+
+A successful response returns `success: true` and `payload` with the number of affected rows (typically `1`).
diff --git a/pages/api-reference/media/delete/index.mdx b/pages/api-reference/media/delete/index.mdx
new file mode 100644
index 0000000..7f85f23
--- /dev/null
+++ b/pages/api-reference/media/delete/index.mdx
@@ -0,0 +1,56 @@
+---
+title: API Media DELETE | Datasquirel docs
+description: Delete a media file via the Datasquirel API
+page_title: Media DELETE
+page_description: Delete a media file from your Datasquirel media storage using the API.
+---
+
+## Overview
+
+Use the Media DELETE endpoint to permanently remove a file from your media storage. Provide the file's database ID to identify which file to delete.
+
+## npm Package
+
+```javascript
+import datasquirel from "@moduletrace/datasquirel";
+
+const result = await datasquirel.media.delete({
+ mediaID: 23,
+ apiKey: process.env.DATASQUIREL_API_KEY,
+});
+
+console.log(result.success); // true
+```
+
+## Parameters
+
+| Parameter | Type | Required | Description |
+|-----------|------|----------|-------------|
+| `mediaID` | `string \| number` | Yes | The database ID of the file to delete |
+| `apiKey` | `string` | No | API key. Falls back to `DATASQUIREL_API_KEY` |
+
+## REST API
+
+```
+DELETE /api/v1/media/{id}
+```
+
+**Headers:**
+```
+Authorization: Bearer YOUR_API_KEY
+```
+
+## Response
+
+```json
+{
+ "success": true,
+ "payload": { "id": 23 }
+}
+```
+
+## Notes
+
+- A **Full Access** API key is required. Read-only keys cannot delete files.
+- Deletion is permanent. The file and its thumbnail are both removed from storage.
+- Use the [Media GET](/docs/api-reference/media/get) endpoint to look up a file's ID before deleting.
diff --git a/pages/api-reference/media/get/index.mdx b/pages/api-reference/media/get/index.mdx
new file mode 100644
index 0000000..1ed97a3
--- /dev/null
+++ b/pages/api-reference/media/get/index.mdx
@@ -0,0 +1,91 @@
+---
+title: API Media GET | Datasquirel docs
+description: Retrieve media file metadata via the Datasquirel API
+page_title: Media GET
+page_description: Retrieve a media file or a list of media files using the Datasquirel API.
+---
+
+## Overview
+
+Use the Media GET endpoint to retrieve metadata for one or more media files. You can look up a file by its database ID, by name, or list all files in a folder.
+
+## npm Package
+
+### Get All Media Files
+
+```javascript
+import datasquirel from "@moduletrace/datasquirel";
+
+const result = await datasquirel.media.get({
+ apiKey: process.env.DATASQUIREL_API_KEY,
+});
+
+console.log(result.payload); // Array of media objects
+```
+
+### Get a Single File by ID
+
+```javascript
+const result = await datasquirel.media.get({
+ mediaID: 15,
+ apiKey: process.env.DATASQUIREL_API_KEY,
+});
+```
+
+### Get Files in a Specific Folder
+
+```javascript
+const result = await datasquirel.media.get({
+ folder: "profile-images",
+ apiKey: process.env.DATASQUIREL_API_KEY,
+});
+```
+
+### Get a File by Name
+
+```javascript
+const result = await datasquirel.media.get({
+ mediaName: "avatar.jpg",
+ apiKey: process.env.DATASQUIREL_API_KEY,
+});
+```
+
+## Parameters
+
+| Parameter | Type | Required | Description |
+|-----------|------|----------|-------------|
+| `mediaID` | `string \| number` | No | The database ID of the media file |
+| `mediaName` | `string` | No | The file name to look up |
+| `folder` | `string` | No | Folder name to filter results |
+| `thumbnail` | `"true" \| "false"` | No | Return thumbnail URL instead of original |
+| `skipBase64` | `"true" \| "false"` | No | Skip base64 encoding in the response |
+| `apiKey` | `string` | No | API key. Falls back to `DATASQUIREL_API_KEY` |
+
+## REST API
+
+```
+GET /api/v1/media
+GET /api/v1/media/{id}
+```
+
+**Headers:**
+```
+Authorization: Bearer YOUR_API_KEY
+```
+
+## Response
+
+```json
+{
+ "success": true,
+ "payload": {
+ "id": 15,
+ "name": "avatar.jpg",
+ "folder": "profile-images",
+ "url": "https://your-instance.com/media/profile-images/avatar.jpg",
+ "thumbnail_url": "https://your-instance.com/media/profile-images/thumbs/avatar.jpg",
+ "size": 24576,
+ "mime_type": "image/jpeg"
+ }
+}
+```
diff --git a/pages/api-reference/media/index.mdx b/pages/api-reference/media/index.mdx
new file mode 100644
index 0000000..7b75b22
--- /dev/null
+++ b/pages/api-reference/media/index.mdx
@@ -0,0 +1,44 @@
+---
+title: API Media Reference | Datasquirel docs
+description: Manage media files via the Datasquirel API
+page_title: Media API
+page_description: Upload, retrieve, and delete media files programmatically using the Datasquirel API.
+---
+
+## Overview
+
+The Media API lets you manage files stored in your Datasquirel media storage. Use it to upload files from your application, retrieve file metadata, and delete files that are no longer needed.
+
+```bash
+npm install @moduletrace/datasquirel
+```
+
+
+
+
+
+
+
+## Authentication
+
+All media API requests require a **Full Access** API key. Read-only keys cannot upload or delete media.
+
+Include your key in the `Authorization` header:
+
+```
+Authorization: Bearer YOUR_API_KEY
+```
+
+Or pass it as `apiKey` in the npm package function call.
diff --git a/pages/api-reference/media/post/index.mdx b/pages/api-reference/media/post/index.mdx
new file mode 100644
index 0000000..69212b8
--- /dev/null
+++ b/pages/api-reference/media/post/index.mdx
@@ -0,0 +1,99 @@
+---
+title: API Media POST | Datasquirel docs
+description: Upload a media file via the Datasquirel API
+page_title: Media POST
+page_description: Upload images and files to your Datasquirel media storage programmatically.
+---
+
+## Overview
+
+Use the Media POST endpoint to upload one or more files to your media storage. Files are stored in the folder you specify, and image thumbnails are generated automatically.
+
+## npm Package
+
+```javascript
+import datasquirel from "@moduletrace/datasquirel";
+import fs from "fs";
+
+// Read the file and convert to base64
+const fileBuffer = fs.readFileSync("./photo.jpg");
+const base64 = fileBuffer.toString("base64");
+
+const result = await datasquirel.media.add({
+ media: [
+ {
+ name: "photo.jpg",
+ base64: `data:image/jpeg;base64,${base64}`,
+ },
+ ],
+ folder: "profile-images",
+ type: "image",
+ apiKey: process.env.DATASQUIREL_API_KEY,
+});
+
+console.log(result.payload); // Uploaded media object(s)
+```
+
+## Parameters
+
+| Parameter | Type | Required | Description |
+|-----------|------|----------|-------------|
+| `media` | `array` | Yes | Array of files to upload. Each item has a `name` and `base64` string |
+| `folder` | `string` | No | Destination folder name. Created automatically if it does not exist |
+| `type` | `string` | Yes | File type — `"image"`, `"video"`, `"audio"`, or `"file"` |
+| `apiKey` | `string` | No | API key. Falls back to `DATASQUIREL_API_KEY` |
+
+### media Array Items
+
+| Field | Type | Description |
+|-------|------|-------------|
+| `name` | `string` | The file name including extension (e.g. `"photo.jpg"`) |
+| `base64` | `string` | Base64-encoded file data. Must include the data URL prefix (e.g. `data:image/jpeg;base64,...`) |
+
+## REST API
+
+```
+POST /api/v1/media
+```
+
+**Headers:**
+```
+Authorization: Bearer YOUR_API_KEY
+Content-Type: application/json
+```
+
+**Body:**
+```json
+{
+ "media": [
+ {
+ "name": "photo.jpg",
+ "base64": "data:image/jpeg;base64,/9j/4AAQSkZJRgABAQ..."
+ }
+ ],
+ "folder": "profile-images",
+ "type": "image"
+}
+```
+
+## Response
+
+```json
+{
+ "success": true,
+ "payload": [
+ {
+ "id": 23,
+ "name": "photo.jpg",
+ "folder": "profile-images",
+ "url": "https://your-instance.com/media/profile-images/photo.jpg"
+ }
+ ]
+}
+```
+
+## Notes
+
+- A **Full Access** API key is required. Read-only keys cannot upload files.
+- Image thumbnails are generated automatically and stored alongside the original.
+- Uploading a file with the same name as an existing file in the same folder will overwrite it if `update: true` is passed.
diff --git a/pages/api-reference/sql/index.mdx b/pages/api-reference/sql/index.mdx
new file mode 100644
index 0000000..49ae79f
--- /dev/null
+++ b/pages/api-reference/sql/index.mdx
@@ -0,0 +1,37 @@
+---
+title: API SQL Reference | Datasquirel docs
+description: Execute raw SQL queries via the Datasquirel API
+page_title: SQL API
+page_description: Run raw MariaDB SQL queries against your databases using the Datasquirel API.
+---
+
+## Overview
+
+The SQL API lets you execute any valid MariaDB SQL statement directly against your database and receive the result set as JSON. Use it when the standard CRUD endpoints don't cover your use case — complex JOINs, aggregations, subqueries, or DDL operations.
+
+
+
+
+
+## Quick Example
+
+```javascript
+import datasquirel from "@moduletrace/datasquirel";
+
+const result = await datasquirel.api.sql({
+ key: process.env.DATASQUIREL_API_KEY,
+ params: {
+ query: "SELECT * FROM users WHERE is_active = 1 ORDER BY created_at DESC LIMIT 10",
+ },
+});
+
+console.log(result.payload);
+```
+
+## Authentication
+
+A **Full Access** API key is required to run raw SQL queries. Read-only keys cannot use the SQL endpoint.
diff --git a/pages/api-reference/sql/options/index.mdx b/pages/api-reference/sql/options/index.mdx
new file mode 100644
index 0000000..6546930
--- /dev/null
+++ b/pages/api-reference/sql/options/index.mdx
@@ -0,0 +1,81 @@
+---
+title: API SQL OPTIONS | Datasquirel docs
+description: Execute a raw SQL query via the Datasquirel API
+page_title: SQL OPTIONS
+page_description: Execute any valid MariaDB SQL statement and receive results as JSON.
+---
+
+## Overview
+
+The SQL OPTIONS endpoint accepts any valid MariaDB SQL string and executes it against your database. Results are returned as a JSON array.
+
+## npm Package
+
+```javascript
+import datasquirel from "@moduletrace/datasquirel";
+
+const result = await datasquirel.api.sql({
+ key: process.env.DATASQUIREL_API_KEY,
+ params: {
+ query: "SELECT posts.id, posts.title, users.name AS author FROM posts JOIN users ON posts.user_id = users.id WHERE posts.is_published = 1 ORDER BY posts.created_at DESC LIMIT 20",
+ },
+});
+
+console.log(result.payload);
+```
+
+### Aggregation Query
+
+```javascript
+const result = await datasquirel.api.sql({
+ key: process.env.DATASQUIREL_API_KEY,
+ params: {
+ query: "SELECT category, COUNT(*) AS total FROM posts GROUP BY category ORDER BY total DESC",
+ },
+});
+```
+
+## Parameters
+
+| Parameter | Type | Required | Description |
+|-----------|------|----------|-------------|
+| `key` | `string` | Yes | Full Access API key |
+| `params.query` | `string` | Yes | The raw MariaDB SQL string to execute |
+
+## REST API
+
+```
+POST /api/v1/sql
+```
+
+**Headers:**
+```
+Authorization: Bearer YOUR_API_KEY
+Content-Type: application/json
+```
+
+**Body:**
+```json
+{
+ "query": "SELECT * FROM users WHERE is_active = 1 LIMIT 10"
+}
+```
+
+## Response
+
+```json
+{
+ "success": true,
+ "payload": [
+ { "id": 1, "name": "Alice", "email": "alice@example.com" },
+ { "id": 2, "name": "Bob", "email": "bob@example.com" }
+ ]
+}
+```
+
+## Notes
+
+- A **Full Access** API key is required.
+- All valid MariaDB statements are supported: SELECT, INSERT, UPDATE, DELETE, ALTER, CREATE, DROP, and more.
+- Be careful with DDL statements (ALTER, DROP) — they modify the table structure and cannot be undone.
+- Parameterized queries are not supported through this endpoint — sanitize user input before embedding it in a SQL string.
diff --git a/pages/database-reference/data-types/index.mdx b/pages/database-reference/data-types/index.mdx
new file mode 100644
index 0000000..6df81d3
--- /dev/null
+++ b/pages/database-reference/data-types/index.mdx
@@ -0,0 +1,65 @@
+---
+title: Data Types | Datasquirel docs
+description: SQL data types supported by Datasquirel
+page_title: Data Types
+page_description: All SQL data types available for table fields in Datasquirel.
+---
+
+## Overview
+
+Every field in a Datasquirel table has a **data type** that defines what kind of values the column can store. Datasquirel is built on MariaDB, so all standard MariaDB column types are supported.
+
+Choosing the right data type matters for:
+- **Storage efficiency** — smaller types use less disk space
+- **Query performance** — properly typed columns are faster to index and compare
+- **Data integrity** — the database enforces type constraints automatically
+
+## Text Types
+
+| Type | Description |
+|------|-------------|
+| `VARCHAR(n)` | Variable-length string up to `n` characters. Use for short text like names, slugs, email addresses. Maximum `n` is 65,535. |
+| `TEXT` | Unlimited-length text. Use for longer content like descriptions or comments. |
+| `LONGTEXT` | Very large text (up to 4 GB). Use for HTML, Markdown, or JSON stored as a string. |
+| `CHAR(n)` | Fixed-length string of exactly `n` characters. Padded with spaces if shorter. |
+| `ENUM(...)` | A value from a predefined list (e.g. `ENUM('draft', 'published', 'archived')`). |
+
+## Numeric Types
+
+| Type | Description |
+|------|-------------|
+| `INT` | 32-bit signed integer. Range: –2,147,483,648 to 2,147,483,647. |
+| `BIGINT` | 64-bit signed integer. Use for IDs that may exceed 2 billion or for large counts. |
+| `TINYINT` | 8-bit integer. Range: –128 to 127. Commonly used for boolean-like flags. |
+| `SMALLINT` | 16-bit integer. Range: –32,768 to 32,767. |
+| `FLOAT` | Single-precision floating-point number. |
+| `DOUBLE` | Double-precision floating-point number. |
+| `DECIMAL(p, s)` | Exact decimal with `p` total digits and `s` decimal places. Use for money values. |
+
+## Date and Time Types
+
+| Type | Description |
+|------|-------------|
+| `DATETIME` | A date and time value (e.g. `2024-03-15 14:30:00`). |
+| `DATE` | A date without time (e.g. `2024-03-15`). |
+| `TIME` | A time without date (e.g. `14:30:00`). |
+| `TIMESTAMP` | A Unix timestamp. Automatically updates to the current time on row modification when configured. |
+
+## Boolean
+
+MariaDB does not have a native BOOLEAN type. Datasquirel uses `TINYINT(1)` for boolean fields — `1` for true, `0` for false.
+
+## Structured Data
+
+| Type | Description |
+|------|-------------|
+| `JSON` | Native JSON column. MariaDB validates and stores the value as structured JSON. |
+| `LONGTEXT` | Store JSON, Markdown, or HTML as plain text when native JSON validation is not needed. |
+
+
+
+
diff --git a/pages/database-reference/data-types/varchar/index.mdx b/pages/database-reference/data-types/varchar/index.mdx
new file mode 100644
index 0000000..0e14f18
--- /dev/null
+++ b/pages/database-reference/data-types/varchar/index.mdx
@@ -0,0 +1,50 @@
+---
+title: VARCHAR | Datasquirel docs
+description: Learn about the VARCHAR data type in Datasquirel
+page_title: VARCHAR
+page_description: Store variable-length text strings with VARCHAR columns in Datasquirel.
+---
+
+## Overview
+
+`VARCHAR(n)` stores variable-length strings up to `n` characters. It is the most commonly used text type for short strings like names, email addresses, slugs, and status values.
+
+## Syntax
+
+```sql
+VARCHAR(255)
+```
+
+The number in parentheses is the maximum length in characters. Common values are:
+- `VARCHAR(100)` — short names, slugs, categories
+- `VARCHAR(255)` — email addresses, URLs, titles
+- `VARCHAR(1000)` — longer descriptions (though TEXT is often more appropriate)
+
+The maximum allowed length is **65,535** characters, though in practice anything over a few hundred characters is better stored as `TEXT`.
+
+## When to Use VARCHAR
+
+Use `VARCHAR` when:
+- The value is a short string with a predictable maximum length
+- You plan to index the column (VARCHAR columns are faster to index than TEXT)
+- The value is used in `WHERE` clauses, `ORDER BY`, or `JOIN` conditions
+
+Use `TEXT` instead when:
+- The value can be arbitrarily long (descriptions, comments, content)
+- You do not need to index the full value
+
+## In Datasquirel
+
+When adding a field to a table, select **VARCHAR** as the data type and enter the maximum length. If no length is specified, Datasquirel defaults to `VARCHAR(255)`.
+
+
+
+## Notes
+
+- VARCHAR is case-insensitive in comparisons by default (controlled by the column collation).
+- Leading and trailing spaces are preserved in VARCHAR values.
+- An empty string `""` is a valid VARCHAR value and is distinct from NULL.
diff --git a/pages/database-reference/querying-data/delete/index.mdx b/pages/database-reference/querying-data/delete/index.mdx
new file mode 100644
index 0000000..50c93a1
--- /dev/null
+++ b/pages/database-reference/querying-data/delete/index.mdx
@@ -0,0 +1,87 @@
+---
+title: DELETE | Datasquirel docs
+description: Remove rows from a table using DELETE statements in Datasquirel
+page_title: DELETE
+page_description: Remove rows from your tables using SQL DELETE statements.
+---
+
+## Overview
+
+`DELETE FROM` removes rows from a table. Always include a `WHERE` clause to target specific rows — a DELETE without a WHERE clause removes **every row** in the table.
+
+## Basic Syntax
+
+```sql
+DELETE FROM table_name WHERE condition;
+```
+
+## Examples
+
+### Delete a Single Row by ID
+
+```sql
+DELETE FROM users WHERE id = 42;
+```
+
+### Delete Multiple Rows by Condition
+
+```sql
+DELETE FROM sessions WHERE expires_at < NOW();
+```
+
+### Delete All Rows Matching a Value
+
+```sql
+DELETE FROM notifications WHERE user_id = 5 AND is_read = 1;
+```
+
+### Delete with LIMIT
+
+MariaDB supports `LIMIT` on DELETE to cap how many rows can be removed in one statement:
+
+```sql
+DELETE FROM logs WHERE created_at < '2024-01-01' ORDER BY created_at ASC LIMIT 1000;
+```
+
+This is useful for batched cleanup of large tables.
+
+## Safety Note
+
+A `DELETE` without a `WHERE` clause removes **every row** from the table. This cannot be undone.
+
+```sql
+-- This deletes ALL rows in the table:
+DELETE FROM users;
+
+-- This deletes only the intended row:
+DELETE FROM users WHERE id = 42;
+```
+
+If you need to remove all rows from a large table efficiently, use `TRUNCATE TABLE` instead — it is faster and resets the AUTO_INCREMENT counter.
+
+## Using DELETE via the API
+
+The [CRUD DELETE endpoint](/docs/api-reference/crud/delete) handles row removal by ID or by field value:
+
+```javascript
+// Delete by ID
+const result = await datasquirel.crud.delete({
+ dbName: "my_database",
+ tableName: "sessions",
+ targetID: 99,
+ apiKey: process.env.DATASQUIREL_API_KEY,
+});
+
+// Delete by field value
+const result = await datasquirel.crud.delete({
+ dbName: "my_database",
+ tableName: "notifications",
+ deleteSpec: {
+ deleteKeyValues: [
+ { key: "user_id", value: 5, operator: "=" },
+ { key: "is_read", value: 1, operator: "=" },
+ ],
+ },
+ apiKey: process.env.DATASQUIREL_API_KEY,
+});
+```
diff --git a/pages/database-reference/querying-data/index.mdx b/pages/database-reference/querying-data/index.mdx
new file mode 100644
index 0000000..95bdda1
--- /dev/null
+++ b/pages/database-reference/querying-data/index.mdx
@@ -0,0 +1,41 @@
+---
+title: Querying Data | Datasquirel docs
+description: Learn how to query data in Datasquirel using SQL
+page_title: Querying Data
+page_description: Use SQL to read, insert, update, and delete data in your Datasquirel databases.
+---
+
+## Overview
+
+Datasquirel is built on MariaDB, so all standard SQL query syntax works as expected. You can run queries directly from the [admin panel SQL shell](/docs/gui-reference) or through the [REST API](/docs/api-reference/sql).
+
+
+
+
+
+
+
+
+## Running Queries
+
+You have two options for executing SQL queries:
+
+**Admin Panel SQL Shell** — navigate to any database in the admin panel and open the SQL shell. Type your query and run it. Results appear in a table below the editor.
+
+**REST API** — POST any SQL string to the `/api/v1/sql` endpoint and receive results as JSON. See [API Reference → SQL](/docs/api-reference/sql).
diff --git a/pages/database-reference/querying-data/insert/index.mdx b/pages/database-reference/querying-data/insert/index.mdx
new file mode 100644
index 0000000..c227fe2
--- /dev/null
+++ b/pages/database-reference/querying-data/insert/index.mdx
@@ -0,0 +1,82 @@
+---
+title: INSERT | Datasquirel docs
+description: Add new rows to a table using INSERT statements in Datasquirel
+page_title: INSERT
+page_description: Add new rows to your tables using SQL INSERT statements.
+---
+
+## Overview
+
+`INSERT INTO` adds one or more new rows to a table. Each row must provide values for all `NOT NULL` columns that do not have a default value.
+
+## Basic Syntax
+
+```sql
+INSERT INTO table_name (column1, column2, column3)
+VALUES (value1, value2, value3);
+```
+
+## Examples
+
+### Insert a Single Row
+
+```sql
+INSERT INTO users (name, email, is_active)
+VALUES ('Alice', 'alice@example.com', 1);
+```
+
+### Insert Multiple Rows
+
+```sql
+INSERT INTO tags (name)
+VALUES ('javascript'), ('typescript'), ('sql');
+```
+
+### Insert with Default Values
+
+If a column has a DEFAULT value defined, you can omit it:
+
+```sql
+INSERT INTO posts (title, content)
+VALUES ('My First Post', 'Hello world!');
+-- created_at and updated_at will use their DEFAULT values
+```
+
+## AUTO_INCREMENT
+
+Every Datasquirel table has an `id` column with `AUTO_INCREMENT`. You never need to provide the `id` value on insert — the database assigns the next available integer automatically.
+
+After an INSERT, the new row's `id` is returned as the `insertId` in the API response.
+
+## Using INSERT via the API
+
+The [CRUD POST endpoint](/docs/api-reference/crud/post) handles inserts through a simple object:
+
+```javascript
+const result = await datasquirel.crud.insert({
+ dbName: "my_database",
+ tableName: "users",
+ body: {
+ name: "Alice",
+ email: "alice@example.com",
+ is_active: 1,
+ },
+ apiKey: process.env.DATASQUIREL_API_KEY,
+});
+
+console.log(result.payload); // The new row's id
+```
+
+For batch inserts via the API, include a `batchData` array:
+
+```javascript
+const result = await datasquirel.crud.insert({
+ dbName: "my_database",
+ tableName: "tags",
+ body: { batchData: [
+ { name: "javascript" },
+ { name: "typescript" },
+ ]},
+ apiKey: process.env.DATASQUIREL_API_KEY,
+});
+```
diff --git a/pages/database-reference/querying-data/select/index.mdx b/pages/database-reference/querying-data/select/index.mdx
new file mode 100644
index 0000000..527e40a
--- /dev/null
+++ b/pages/database-reference/querying-data/select/index.mdx
@@ -0,0 +1,90 @@
+---
+title: SELECT | Datasquirel docs
+description: Read data from a table using SELECT queries in Datasquirel
+page_title: SELECT
+page_description: Retrieve rows from your tables using SQL SELECT statements.
+---
+
+## Overview
+
+`SELECT` retrieves rows from one or more tables. It is the most frequently used SQL statement.
+
+## Basic Syntax
+
+```sql
+SELECT column1, column2 FROM table_name WHERE condition ORDER BY column1 ASC LIMIT 10;
+```
+
+## Examples
+
+### Get All Rows
+
+```sql
+SELECT * FROM users;
+```
+
+### Select Specific Columns
+
+```sql
+SELECT id, name, email FROM users;
+```
+
+### Filter with WHERE
+
+```sql
+SELECT * FROM posts WHERE is_published = 1;
+```
+
+### Multiple Conditions
+
+```sql
+SELECT * FROM posts WHERE is_published = 1 AND category = 'technology';
+```
+
+### Sorting
+
+```sql
+SELECT * FROM posts ORDER BY created_at DESC;
+```
+
+### Pagination
+
+```sql
+SELECT * FROM posts ORDER BY created_at DESC LIMIT 10 OFFSET 20;
+```
+
+`LIMIT` caps the number of rows returned. `OFFSET` skips the first N rows — useful for pagination (page 3 with 10 items per page = `LIMIT 10 OFFSET 20`).
+
+### JOIN
+
+```sql
+SELECT posts.id, posts.title, users.name AS author
+FROM posts
+JOIN users ON posts.user_id = users.id
+WHERE posts.is_published = 1
+ORDER BY posts.created_at DESC;
+```
+
+### Aggregation
+
+```sql
+SELECT category, COUNT(*) AS total
+FROM posts
+GROUP BY category
+ORDER BY total DESC;
+```
+
+## Using SELECT via the API
+
+For simple reads, use the [CRUD GET endpoint](/docs/api-reference/crud/get) — it handles filtering, sorting, and pagination through query parameters without writing raw SQL.
+
+For complex queries (JOINs, aggregations, subqueries), use the [SQL API](/docs/api-reference/sql/options):
+
+```javascript
+const result = await datasquirel.api.sql({
+ key: process.env.DATASQUIREL_API_KEY,
+ params: {
+ query: "SELECT posts.id, posts.title, users.name AS author FROM posts JOIN users ON posts.user_id = users.id WHERE posts.is_published = 1 ORDER BY posts.created_at DESC LIMIT 20",
+ },
+});
+```
diff --git a/pages/database-reference/querying-data/update/index.mdx b/pages/database-reference/querying-data/update/index.mdx
new file mode 100644
index 0000000..38d5258
--- /dev/null
+++ b/pages/database-reference/querying-data/update/index.mdx
@@ -0,0 +1,75 @@
+---
+title: UPDATE | Datasquirel docs
+description: Modify existing rows using UPDATE statements in Datasquirel
+page_title: UPDATE
+page_description: Modify existing rows in your tables using SQL UPDATE statements.
+---
+
+## Overview
+
+`UPDATE` modifies existing rows in a table. Always include a `WHERE` clause to target specific rows — an UPDATE without a WHERE clause updates every row in the table.
+
+## Basic Syntax
+
+```sql
+UPDATE table_name SET column1 = value1, column2 = value2 WHERE condition;
+```
+
+## Examples
+
+### Update a Single Row by ID
+
+```sql
+UPDATE users SET name = 'Alice Smith', email = 'alice.smith@example.com' WHERE id = 42;
+```
+
+### Update Multiple Rows
+
+```sql
+UPDATE posts SET is_published = 1 WHERE category = 'announcements';
+```
+
+### Update with a Calculated Value
+
+```sql
+UPDATE products SET price = price * 1.10 WHERE category = 'electronics';
+```
+
+### Update with LIMIT
+
+MariaDB supports `LIMIT` on UPDATE to cap how many rows can be modified in one statement:
+
+```sql
+UPDATE notifications SET is_read = 1 WHERE user_id = 5 ORDER BY created_at ASC LIMIT 50;
+```
+
+## Safety Note
+
+An `UPDATE` without a `WHERE` clause will update **every row** in the table. Always double-check your `WHERE` clause before running an update, especially in production.
+
+```sql
+-- This updates ALL rows in the table:
+UPDATE users SET is_active = 0;
+
+-- This updates only the intended row:
+UPDATE users SET is_active = 0 WHERE id = 42;
+```
+
+## Using UPDATE via the API
+
+The [CRUD PUT endpoint](/docs/api-reference/crud/put) handles updates with a target ID:
+
+```javascript
+const result = await datasquirel.crud.update({
+ dbName: "my_database",
+ tableName: "users",
+ targetID: 42,
+ body: {
+ name: "Alice Smith",
+ email: "alice.smith@example.com",
+ },
+ apiKey: process.env.DATASQUIREL_API_KEY,
+});
+```
+
+Only the fields you include in `body` are changed — other columns retain their current values.
diff --git a/pages/getting-started/index.mdx b/pages/getting-started/index.mdx
new file mode 100644
index 0000000..aa9f671
--- /dev/null
+++ b/pages/getting-started/index.mdx
@@ -0,0 +1,51 @@
+---
+title: Getting Started | Datasquirel docs
+description: Get up and running with Datasquirel quickly
+page_title: Getting Started
+page_description: Everything you need to start managing your data with Datasquirel.
+---
+
+## Welcome to Datasquirel
+
+Datasquirel is a cloud-based SQL data management platform built on MariaDB. It gives you a web GUI for managing databases, tables, and entries, a REST API for programmatic access, and a TypeScript npm package that wraps the API with full type safety.
+
+## Where to Start
+
+If you want to be up and running as quickly as possible, follow the [Quick Start](/docs/quick-start) guide — it walks you through creating an account, adding a database and table, and making your first API call in minutes.
+
+
+
+
+
+
+
+
+## Datasquirel or Self Hosted?
+
+**Datasquirel.com** — create a free account at [datasquirel.com/signup](/signup) and start managing data immediately. No infrastructure to set up.
+
+**Self Hosted** — download the Datasquirel Docker stack and run it on your own server or cloud VM. You own the data and the infrastructure. See the [Self Hosting](/docs/self-hosting) guide to get started.
+
+## Core Concepts
+
+- **Database** — a named collection of tables. Each user account can have multiple databases.
+- **Table** — a set of rows that share the same column structure (schema).
+- **Field** — a column in a table. Each field has a name, a SQL data type, and optional constraints.
+- **Entry** — a single row in a table.
+- **API Key** — a credential used to authenticate REST API requests. Read-only keys can only fetch data; full-access keys can read, write, update, and delete.
diff --git a/pages/gui-reference/databases/add-entry/index.mdx b/pages/gui-reference/databases/add-entry/index.mdx
new file mode 100644
index 0000000..9db6fab
--- /dev/null
+++ b/pages/gui-reference/databases/add-entry/index.mdx
@@ -0,0 +1,55 @@
+---
+title: Add an Entry | Datasquirel docs
+description: Insert a new row into a Datasquirel table
+page_title: Add an Entry
+page_description: Insert a new row into a table using the web admin panel.
+---
+
+## Overview
+
+An **entry** is a single row in a table. Once you have a table with fields defined, you can start inserting entries through the admin panel or via the API.
+
+## Steps
+
+### 1. Open the Table
+
+Navigate to your database and click on the table you want to add an entry to.
+
+
+
+### 2. Click Add New Table Entry
+
+Click the **Add New Table Entry** button at the top of the table page.
+
+### 3. Fill in the Fields
+
+A form will appear with an input for each field in your table. Fill in the values:
+
+- Fields marked **Required** must have a value — the form will not submit without them.
+- Fields with a **Default Value** are pre-filled — you can leave them or override the default.
+- **Rich fields** (HTML, Markdown, JSON, code) open in their dedicated editors.
+
+### 4. Save the Entry
+
+Click **Add Entry**. The new row is inserted into the table and will appear in the table view immediately.
+
+## Editing an Entry
+
+To edit an existing entry, click on the row in the table view to open the edit form. Change the values and click **Update Entry**.
+
+## Deleting an Entry
+
+To delete an entry, open the edit form and click **Delete Entry**, or use the delete action in the table row controls. Deleted entries are permanently removed from the database.
+
+## Adding Entries via the API
+
+Entries can also be inserted programmatically using the REST API or the npm package. See [API Reference → POST](/docs/api-reference/crud/post) for details.
+
+## What's Next
+
+- [API Reference → CRUD](/docs/api-reference/crud) — manage entries programmatically
+- [Media](/docs/gui-reference/media) — upload and attach files to your entries
diff --git a/pages/gui-reference/databases/create-database/index.mdx b/pages/gui-reference/databases/create-database/index.mdx
new file mode 100644
index 0000000..472086b
--- /dev/null
+++ b/pages/gui-reference/databases/create-database/index.mdx
@@ -0,0 +1,43 @@
+---
+title: Create a Database | Datasquirel docs
+description: Create a new database from the Datasquirel web GUI
+page_title: Create a Database
+page_description: Add a new database to your Datasquirel account using the web admin panel.
+---
+
+## Overview
+
+A **database** is a named container that holds one or more tables. Each Datasquirel account can have multiple databases, and each database is isolated from the others — API keys can be scoped to specific databases.
+
+## Steps
+
+### 1. Open the Databases Page
+
+Log in to your admin panel and navigate to **Databases** in the sidebar, or go to [/admin/databases](/admin/databases).
+
+### 2. Click Add Database
+
+Click the **Add Database** button at the top of the databases list.
+
+
+
+### 3. Fill in the Database Details
+
+A form will appear. Fill in the required fields:
+
+- **Database Name** — a unique name for the database. Use lowercase letters, numbers, and underscores (e.g. `social_network`).
+- **Description** *(optional)* — a short description of the database.
+- **Image** *(optional)* — an image to display on the database card.
+
+### 4. Create the Database
+
+Click **Create Database**. You will be taken to the new database page where you can start creating tables or import an existing database from an SQL file.
+
+## What's Next
+
+- [Create a Table](/docs/gui-reference/databases/create-table) — add your first table to the database
+- [Create Table Fields](/docs/gui-reference/databases/create-table-fields) — define the columns for your table
diff --git a/pages/gui-reference/databases/create-table-fields/index.mdx b/pages/gui-reference/databases/create-table-fields/index.mdx
index ad65e83..13dd357 100644
--- a/pages/gui-reference/databases/create-table-fields/index.mdx
+++ b/pages/gui-reference/databases/create-table-fields/index.mdx
@@ -2,9 +2,65 @@
title: Create Database Table Fields
description: Learn how to create fields/columns in your tables
page_title: Create Table Fields
-page_description: Learn how to create fields/columns in your tables
+page_description: Define the columns and data types for your Datasquirel tables.
---
-## Create Database Table Fields
+## Overview
-Fields (or Columns) define the structure of your SQL tables. Datasquirel Helps you define these structures and even extend them.
+**Fields** (also called columns) define the structure of a SQL table. Every row in the table must conform to the field definitions. Datasquirel provides a visual field editor that maps directly to MariaDB column definitions — what you define is what gets created in the database.
+
+## Adding a Field
+
+Open a table in your admin panel and click **Add Field** (or access the field editor during table creation). For each field you need to provide:
+
+### Field Name
+
+The name of the column. Use lowercase letters, numbers, and underscores. This name is used in API responses and SQL queries (e.g. `first_name`, `created_at`).
+
+### Data Type
+
+The SQL data type for the column. Common types include:
+
+| Type | Description |
+|------|-------------|
+| `VARCHAR` | Variable-length text, up to a defined maximum length (e.g. `VARCHAR(255)`) |
+| `INT` | 32-bit integer |
+| `BIGINT` | 64-bit integer — use for IDs that may exceed 2 billion |
+| `TEXT` | Unlimited-length text |
+| `LONGTEXT` | Very large text content (e.g. HTML, Markdown, JSON) |
+| `DATETIME` | Date and time value |
+| `DATE` | Date only |
+| `BOOLEAN` | True/false stored as `TINYINT(1)` |
+| `FLOAT` | Floating-point number |
+| `JSON` | Structured JSON data |
+| `ENUM` | A value from a predefined list |
+
+See the full list in the [Database Reference → Data Types](/docs/database-reference/data-types).
+
+### Required
+
+Check this option to add a `NOT NULL` constraint — the field must have a value on every insert. Leave it unchecked to allow `NULL`.
+
+### Default Value
+
+A value to use when no value is provided on insert. For example:
+- `0` for numeric fields
+- `""` for empty text
+- `CURRENT_TIMESTAMP` for datetime fields that should auto-populate
+
+### More Options
+
+Click **More** on any field to access additional options:
+
+- **Unique** — adds a UNIQUE constraint so no two rows can have the same value for this field.
+- **Encryption** — encrypts the value before storing it. Useful for sensitive data like tokens.
+- **Foreign Key** — links this field to a column in another table, enforcing referential integrity.
+
+## Editing and Removing Fields
+
+To edit an existing field, open the table schema editor and click on the field. To remove a field, click the delete icon next to it. Removing a field drops the column from the underlying MariaDB table — all data in that column will be lost.
+
+## What's Next
+
+- [Create Table Indexes](/docs/gui-reference/databases/create-table-indexes) — add indexes to speed up queries on specific fields
+- [Add an Entry](/docs/gui-reference/databases/add-entry) — start inserting rows
diff --git a/pages/gui-reference/databases/create-table-indexes/index.mdx b/pages/gui-reference/databases/create-table-indexes/index.mdx
new file mode 100644
index 0000000..bf313eb
--- /dev/null
+++ b/pages/gui-reference/databases/create-table-indexes/index.mdx
@@ -0,0 +1,56 @@
+---
+title: Create Table Indexes | Datasquirel docs
+description: Add indexes to your database tables to improve query performance
+page_title: Create Table Indexes
+page_description: Add indexes to your tables to speed up queries on frequently searched fields.
+---
+
+## Overview
+
+An **index** is a data structure that MariaDB maintains alongside your table to make certain queries faster. Without an index, a query that filters by a column must scan every row in the table. With an index on that column, MariaDB can jump directly to the matching rows.
+
+Adding indexes is especially important on:
+- Fields used in `WHERE` clauses (e.g. `WHERE slug = ?`)
+- Fields used in `ORDER BY` or `GROUP BY`
+- Foreign key fields
+
+## Index Types
+
+Datasquirel supports the following MariaDB index types:
+
+| Type | Description |
+|------|-------------|
+| **INDEX** | A standard non-unique index. Use this to speed up queries on any column that is not required to be unique. |
+| **UNIQUE** | Like INDEX, but also enforces that no two rows can have the same value for the indexed column. |
+| **FULLTEXT** | A full-text index used for text search with `MATCH ... AGAINST`. Applies to `TEXT` and `VARCHAR` columns. |
+
+## Adding an Index
+
+### From the Field Settings
+
+The simplest way to index a field is directly in the field editor. When creating or editing a field, click **More** and enable the **Unique** option — this creates a UNIQUE index on the field.
+
+### From the Table Schema Editor
+
+1. Open the table in your admin panel.
+2. Navigate to the **Schema** or **Indexes** tab.
+3. Click **Add Index**.
+4. Select the index type and choose the field(s) to include.
+5. Save the index.
+
+
+
+## Notes
+
+- Every table automatically has a PRIMARY KEY on the `id` column. This index is created by Datasquirel and cannot be removed.
+- Adding an index on a large table may take a moment as MariaDB rebuilds the index structure.
+- Indexes speed up reads but add a small overhead to writes (INSERT, UPDATE, DELETE). Only index fields you actually query on.
+
+## What's Next
+
+- [Create Table Fields](/docs/gui-reference/databases/create-table-fields) — understand field types and constraints
+- [API Reference → GET](/docs/api-reference/crud/get) — use query parameters to filter and sort data
diff --git a/pages/gui-reference/databases/create-table/index.mdx b/pages/gui-reference/databases/create-table/index.mdx
new file mode 100644
index 0000000..4618f7b
--- /dev/null
+++ b/pages/gui-reference/databases/create-table/index.mdx
@@ -0,0 +1,52 @@
+---
+title: Create a Table | Datasquirel docs
+description: Create a new table inside a Datasquirel database
+page_title: Create a Table
+page_description: Add a new table to an existing database using the web admin panel.
+---
+
+## Overview
+
+A **table** is a structured set of rows, where every row has the same columns (fields). Before you can add data, you need to create at least one table in your database and define its fields.
+
+## Steps
+
+### 1. Open a Database
+
+Navigate to the database you want to add a table to. Click on the database from the [Databases](/admin/databases) list.
+
+### 2. Click Add Table
+
+On the database page, click the **Add Table** button.
+
+
+
+### 3. Name the Table
+
+Enter a name for the table. Table names should use lowercase letters, numbers, and underscores (e.g. `blog_posts`).
+
+### 4. Add Fields
+
+The table creation form includes a field editor. Add at least one field to define the structure of the table. For each field, provide:
+
+- **Field Name** — the column name (e.g. `title`, `created_at`).
+- **Data Type** — the SQL data type for the column. See [Data Types](/docs/database-reference/data-types) for the full list.
+- **Required** — whether the field must have a value (NOT NULL constraint).
+- **Default Value** — a default value used when no value is provided.
+- **More** — additional options including encryption and foreign key relationships.
+
+See [Create Table Fields](/docs/gui-reference/databases/create-table-fields) for a detailed breakdown of each field option.
+
+### 5. Save the Table
+
+Click **Add Table** to create the table. It will appear in the table list for the database.
+
+## What's Next
+
+- [Create Table Fields](/docs/gui-reference/databases/create-table-fields) — learn more about field types and options
+- [Add an Entry](/docs/gui-reference/databases/add-entry) — insert your first row
+- [Create Table Indexes](/docs/gui-reference/databases/create-table-indexes) — add indexes to improve query speed
diff --git a/pages/gui-reference/databases/index.mdx b/pages/gui-reference/databases/index.mdx
index a151dd9..95f5470 100644
--- a/pages/gui-reference/databases/index.mdx
+++ b/pages/gui-reference/databases/index.mdx
@@ -7,22 +7,30 @@ page_description: Create and manage databases via the web GUI
## Quick Links
-
-
-
-
-
-
-
+
+
+
+
+
+
+
diff --git a/pages/gui-reference/getting-started/create-an-account/index.mdx b/pages/gui-reference/getting-started/create-an-account/index.mdx
new file mode 100644
index 0000000..6e1281e
--- /dev/null
+++ b/pages/gui-reference/getting-started/create-an-account/index.mdx
@@ -0,0 +1,40 @@
+---
+title: Create an account | Datasquirel docs
+description: Create an Account with Datasquirel
+page_title: Create an Account
+page_description: Get started with a new Datasquirel account.
+---
+
+## Datasquirel.com
+
+Creating an account on datasquirel.com is simple. Just navigate to the [signup page](/signup) and log in with Google or enter your account details to create an account.
+
+
+
+## Self Hosted
+
+Creating an account for self-hosted instances can only be done by the `super admin` user. This user is created during the initial setup of the instance. Every other user is created by the `super admin` user.
+
+### Creating The Super Admin User
+
+When a self-hosted instance is first started, you are directed to the `super admin` user creation page. Fill in the required fields to create the `super admin` user. This user has all privileges and can create other users. This user is created only once and cannot be deleted.
+
+
+
+### Creating Other Users
+
+To create other users, navigate to the Super Admin [users page](/admin/su/users) and click the `Add User` button. Fill in the required fields to create the user.
+
+
diff --git a/pages/gui-reference/getting-started/index.mdx b/pages/gui-reference/getting-started/index.mdx
index 2fbc329..7f10278 100644
--- a/pages/gui-reference/getting-started/index.mdx
+++ b/pages/gui-reference/getting-started/index.mdx
@@ -1,8 +1,8 @@
---
-title: Getting Started | Datasquirel docs
-description: Get started with Datasquirel
-page_title: Create Table Fields
-page_description: Jump in and start up your project
+title: GUI Getting Started | Datasquirel docs
+description: Get started with the Datasquirel web admin panel
+page_title: Getting Started
+page_description: Jump in and start managing your data using the Datasquirel GUI.
---
## Get Started With Datasquirel
@@ -10,7 +10,7 @@ page_description: Jump in and start up your project
diff --git a/pages/gui-reference/media/index.mdx b/pages/gui-reference/media/index.mdx
new file mode 100644
index 0000000..b9758a9
--- /dev/null
+++ b/pages/gui-reference/media/index.mdx
@@ -0,0 +1,40 @@
+---
+title: Media GUI Reference | Datasquirel docs
+description: Upload and manage media files using the Datasquirel web GUI
+page_title: Media
+page_description: Upload, organize, and manage media files from the Datasquirel admin panel.
+---
+
+## Overview
+
+Datasquirel includes a built-in media storage system. Files are organized into folders, served by a dedicated static file server, and can be made public or private per folder.
+
+
+
+
+
+## Navigating to Media
+
+In the admin panel sidebar, click **Media** to open the media management page. From here you can:
+
+- Browse your media folders and files
+- Create new folders
+- Toggle a folder between **public** and **private** mode
+- Upload new files
+- Delete existing files
+
+
+
+## Public vs Private Folders
+
+**Public folders** — files are accessible to anyone with the direct URL. Use this for profile images, product photos, and other assets that should be freely accessible.
+
+**Private folders** — files require a valid, time-limited access key to download. Use this for documents, premium content, or any file that should only be accessible to specific users. See [Private Media](/features/private-media) for details.
diff --git a/pages/gui-reference/media/upload-media/index.mdx b/pages/gui-reference/media/upload-media/index.mdx
new file mode 100644
index 0000000..f798e5f
--- /dev/null
+++ b/pages/gui-reference/media/upload-media/index.mdx
@@ -0,0 +1,51 @@
+---
+title: Upload Media | Datasquirel docs
+description: Upload images and files to Datasquirel media storage
+page_title: Upload Media
+page_description: Upload images and other files to your Datasquirel media storage folders.
+---
+
+## Overview
+
+You can upload any file type to Datasquirel media storage through the admin panel. Uploaded images are automatically given a thumbnail. All uploaded files are served by a dedicated static file server.
+
+## Steps
+
+### 1. Open the Media Page
+
+Click **Media** in the admin panel sidebar to open the media management page.
+
+### 2. Select or Create a Folder
+
+Choose an existing folder from the list or create a new one by clicking **Add Folder**. Folders keep your files organized and control public/private access at the folder level.
+
+### 3. Open a Folder
+
+Click on a folder to open it and see its files.
+
+
+
+### 4. Upload a File
+
+Click **Upload** (or drag and drop a file into the folder view). You can upload multiple files at once.
+
+Supported file types include images (JPEG, PNG, WebP, GIF, SVG), documents (PDF), and any other file type.
+
+### 5. Copy the File URL
+
+Once uploaded, the file appears in the folder. Click on a file to copy its URL. For public folders, this URL can be used directly in your application.
+
+## Uploading via the API
+
+You can also upload files programmatically using the media API. See [API Reference → Media → POST](/docs/api-reference/media/post) for details.
+
+## Notes
+
+- Image thumbnails are generated automatically on upload.
+- File names are stored as uploaded. Avoid special characters in file names.
+- To move a file to a different folder, delete it and re-upload it to the target folder.
+- Deleting a folder deletes all files inside it permanently.
diff --git a/pages/self-hosting/windows/index.mdx b/pages/self-hosting/windows/index.mdx
new file mode 100644
index 0000000..3da4d03
--- /dev/null
+++ b/pages/self-hosting/windows/index.mdx
@@ -0,0 +1,62 @@
+---
+title: Windows Self Hosting | Datasquirel docs
+description: Host Datasquirel on a Windows machine
+page_title: Self Hosting on Windows
+page_description: Deploy Datasquirel on a Windows machine using Docker Desktop.
+---
+
+## Prerequisites
+
+Before installing Datasquirel on Windows you need:
+
+- [Docker Desktop for Windows](https://www.docker.com/products/docker-desktop/) — installed and running
+- [WSL 2](https://learn.microsoft.com/en-us/windows/wsl/install) (Windows Subsystem for Linux) — required by Docker Desktop
+- A terminal application (Windows Terminal, PowerShell, or Git Bash)
+
+## Installation
+
+### 1. Enable WSL 2 and Docker Desktop
+
+Make sure Docker Desktop is running and WSL 2 integration is enabled in Docker Desktop settings under **Resources → WSL Integration**.
+
+### 2. Open a WSL Terminal
+
+Open Windows Terminal and launch a WSL shell (Ubuntu or another distribution):
+
+```bash
+wsl
+```
+
+### 3. Run the Installer
+
+From inside your WSL shell, run the Datasquirel install script:
+
+```bash
+curl https://datasquirel.com/install | bash
+```
+
+Follow the prompts to complete the installation. The script will download the Docker Compose stack, configure the environment, and start all services.
+
+### 4. Access the Admin Panel
+
+Once the installation finishes, open your browser and navigate to:
+
+```
+http://localhost:7070
+```
+
+You will be redirected to the super admin setup page on first launch.
+
+## Updating
+
+To update Datasquirel to a newer version, re-run the install script and follow the prompts:
+
+```bash
+curl https://datasquirel.com/install | bash
+```
+
+## Notes
+
+- All data is stored in Docker volumes on your Windows machine.
+- Stopping Docker Desktop will stop Datasquirel. Start Docker Desktop again and the containers will resume automatically.
+- For production use on Windows Server, WSL 2 with Ubuntu is the recommended environment.