Core CRUD
Basic app creation, retrieval, update, and deletion operations.
GET /api/apps
Search and filter apps with pagination.
Authentication: Required
Query Parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
q | string | - | Full-text search query (searches name, slug, description) |
sort | string | name | Sort field (prefix with - for descending) |
limit | integer | 20 | Results per page |
start | integer | 0 | Pagination offset |
Response:
The response is a paginated HAL collection. App items are returned under _embedded["inf:app"], with pagination metadata and aggregations at the top level.
{
"_links": {
"self": {
"href": "/api/apps?limit=0&start=0"
}
},
"start": 0,
"count": 1,
"total": 15,
"aggs": {
"total": 15
},
"permissions": {
"create": true
},
"_embedded": {
"inf:app": [
{
"_links": {
"self": { "href": "/api/apps/analytics%3Asales-dashboard" },
"inf:owner": { "href": "/api/apps/analytics%3Asales-dashboard/owner" },
"inf:draft": { "href": "/api/apps/analytics%3Asales-dashboard/draft" },
"inf:app-shares": { "href": "/api/apps/analytics%3Asales-dashboard/shares" },
"inf:app-tags": { "href": "/api/apps/analytics%3Asales-dashboard/tags" },
"inf:favorite": { "href": "/api/apps/analytics%3Asales-dashboard/favorite" },
"inf:app-tag": {
"href": "/api/apps/analytics%3Asales-dashboard/tags/{tagId}",
"templated": true
},
"inf:export-bundle": { "href": "/api/apps/analytics%3Asales-dashboard/_export" },
"inf:cloud-publish": { "href": "/api/apps/analytics%3Asales-dashboard/_cloud-publish" },
"inf:copy": { "href": "/api/apps/analytics%3Asales-dashboard/_copy" },
"inf:print": [
{ "href": "/api/apps/analytics%3Asales-dashboard/_print" },
{ "href": "/api/apps/analytics%3Asales-dashboard/_print", "title": "Print to PDF" }
],
"inf:app-tokens": { "href": "/api/apps/analytics%3Asales-dashboard/tokens" },
"edit": { "href": "/api/apps/analytics%3Asales-dashboard/_edit" },
"inf:app-share": {
"href": "/api/apps/analytics%3Asales-dashboard/shares/{principalId}",
"templated": true
},
"share": {
"href": "/api/apps/analytics%3Asales-dashboard/view?token=%7Btoken%7D",
"title": "Share Page"
}
},
"naturalId": "analytics:sales-dashboard",
"permissions": {
"assignTags": true,
"changeOwner": true,
"copy": true,
"delete": true,
"edit": true,
"rename": true,
"run": true,
"share": true,
"write": true
},
"id": "d4f8a2b1-1234-5678-90ab-cdef12345678",
"type": "report",
"name": "Sales Dashboard",
"ownerId": "analytics",
"slug": "sales-dashboard",
"description": "Interactive sales analytics",
"createdAt": "2024-01-15T10:00:00.000Z",
"updatedAt": "2024-02-08T14:30:00.000Z"
}
]
}
}
Key Fields:
| Field | Description |
|---|---|
start | Pagination offset |
count | Number of items in this page |
total | Total matching apps |
aggs.total | Total apps accessible to the user |
permissions.create | Whether user can create apps |
Permissions Required: None (returns only apps user can read)
GET /api/apps-list
Get a complete list of all readable apps with tags, sharing info, and dataset references. This endpoint returns a plain array (not HAL-wrapped) and is used by report galleries.
Authentication: Required
Response:
[
{
"driver": "app",
"id": "d4f8a2b1-1234-5678-90ab-cdef12345678",
"slug": "sales-dashboard",
"name": "Sales Dashboard",
"description": "Interactive sales analytics",
"type": "App",
"ownerId": "analytics",
"folderId": null,
"shared": false,
"createdAt": "2024-01-15T10:00:00.000Z",
"updatedAt": "2024-02-08T14:30:00.000Z",
"favorite": true,
"naturalId": "analytics:sales-dashboard",
"listId": "app:d4f8a2b1-1234-5678-90ab-cdef12345678",
"permissions": {
"assignTags": true,
"changeOwner": true,
"copy": true,
"delete": true,
"edit": true,
"rename": true,
"run": true,
"share": true,
"write": true
},
"originalType": "report",
"image": "/images/icons/app.svg",
"rels": {
"self": "inf:app",
"owner": "inf:app-owner",
"share": "inf:app-share",
"tag": "inf:app-tag"
},
"tags": [],
"datasource": {
"ownerId": null,
"type": null,
"name": null,
"id": null,
"shares": [{ "accessLevel": 0 }]
}
}
]
Special Behaviors:
- Custom Favicon: If an app has a
favicon.svgfile in its library root, theimagefield is set to/api/apps/{naturalId}/contents/favicon.svgand the default icon is moved tofallbackImage - Translated Type: The
typefield is translated (e.g., "App"), whileoriginalTypehas the raw driver type - Datasource Stub: Apps don't have a primary datasource, so a stub object is provided for compatibility with report lists
Permissions Required: None (returns only apps user can read)
ETag Support: This endpoint supports ETags for efficient caching based on app table changes.
GET /api/apps/recent
Get recently viewed apps for the current user.
Authentication: Required
Query Parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
limit | integer | 20 | Maximum results (1-100) |
Response:
[
{
"appId": "d4f8a2b1-1234-5678-90ab-cdef12345678",
"name": "Sales Dashboard",
"naturalId": "analytics:sales-dashboard",
"type": "report",
"ownerId": "analytics",
"viewedAt": "2024-02-23T14:30:00.000Z"
}
]
Behavior:
- Queries the
audit.app_viewtable for the authenticated user - Returns distinct apps ordered by most recently viewed
- Applies read access filtering — only apps the user can still read are returned
Permissions Required: None (returns only apps user can read)
GET /api/apps/{id}
Retrieve a single app by ID or natural ID.
Authentication: Required
Path Parameters:
| Parameter | Type | Description |
|---|---|---|
id | string | App UUID or natural ID (ownerId:slug) |
Response:
{
"_links": {
"self": { "href": "/api/apps/analytics%3Asales-dashboard" },
"inf:owner": { "href": "/api/apps/analytics%3Asales-dashboard/owner" },
"inf:draft": { "href": "/api/apps/analytics%3Asales-dashboard/draft" },
"inf:app-shares": { "href": "/api/apps/analytics%3Asales-dashboard/shares" },
"inf:app-tags": { "href": "/api/apps/analytics%3Asales-dashboard/tags" },
"inf:favorite": { "href": "/api/apps/analytics%3Asales-dashboard/favorite" },
"inf:app-tag": {
"href": "/api/apps/analytics%3Asales-dashboard/tags/{tagId}",
"templated": true
},
"inf:export-bundle": { "href": "/api/apps/analytics%3Asales-dashboard/_export" },
"inf:cloud-publish": { "href": "/api/apps/analytics%3Asales-dashboard/_cloud-publish" },
"inf:copy": { "href": "/api/apps/analytics%3Asales-dashboard/_copy" },
"inf:print": [
{ "href": "/api/apps/analytics%3Asales-dashboard/_print" },
{ "href": "/api/apps/analytics%3Asales-dashboard/_print", "title": "Print to PDF" }
],
"inf:app-tokens": { "href": "/api/apps/analytics%3Asales-dashboard/tokens" },
"edit": { "href": "/api/apps/analytics%3Asales-dashboard/_edit" },
"inf:app-share": {
"href": "/api/apps/analytics%3Asales-dashboard/shares/{principalId}",
"templated": true
},
"inf:entrypoint": {
"href": "/api/apps/analytics%3Asales-dashboard/view",
"title": "index.html"
},
"inf:library": {
"href": "/api/libraries/analytics%3Asales-dashboard-files",
"title": "App Files"
},
"inf:library-contents": {
"href": "/api/libraries/analytics%3Asales-dashboard-files/contents/index.html",
"title": "Raw Contents"
},
"share": {
"href": "/api/apps/analytics%3Asales-dashboard/view?token=%7Btoken%7D",
"title": "Share Page"
}
},
"naturalId": "analytics:sales-dashboard",
"permissions": {
"assignTags": true,
"changeOwner": true,
"copy": true,
"delete": true,
"edit": true,
"rename": true,
"run": true,
"share": true,
"write": true
},
"id": "d4f8a2b1-1234-5678-90ab-cdef12345678",
"type": "report",
"name": "Sales Dashboard",
"tenant": "manager",
"ownerId": "analytics",
"slug": "sales-dashboard",
"description": "Interactive sales analytics",
"defn": {
"entryPoint": "index.html"
},
"settings": {
"sandbox": true,
"passDatasets": true
},
"source": null,
"sourceId": null,
"shared": false,
"defnUpdatedAt": "2024-02-08T14:30:00.000Z",
"libraryId": "815244b5-f257-47d1-8248-23955771ba55",
"createdAt": "2024-01-15T10:00:00.000Z",
"updatedAt": "2024-02-08T14:30:00.000Z",
"editingId": null,
"folderId": null,
"datasets": {},
"library": {
"naturalId": "analytics:sales-dashboard-files",
"connectionOwner": "analytics",
"isLocal": true,
"permissions": {
"assignTags": true,
"changeOwner": true,
"configure": true,
"connect": true,
"edit": true,
"delete": true,
"write": true,
"sync": true,
"rename": true,
"share": true,
"editConnection": true
},
"id": "815244b5-f257-47d1-8248-23955771ba55",
"type": "local",
"name": "Sales Dashboard Files",
"slug": "sales-dashboard-files",
"description": null,
"ownerId": "analytics",
"data": null,
"folderId": null,
"shared": false,
"assistantAccess": false,
"embedded": true,
"syncedAt": null,
"syncInterval": null,
"snapshotOfId": null,
"chatId": null,
"createdAt": "2024-01-15T10:00:00.000Z",
"updatedAt": "2024-01-15T10:00:00.000Z",
"tenant": "manager",
"integration": null
},
"tags": []
}
Key Fields:
| Field | Description |
|---|---|
naturalId | Computed as ownerId:slug (URL-encoded as %3A in links) |
datasets | Object keyed by alias containing AppDataset references |
library | Full embedded library object with its own permissions |
tags | Array of tag objects (empty array if none) |
editingId | If non-null, this is a draft of the app with that ID |
defn | Driver-specific definition (e.g., entryPoint for report type) |
settings | App settings (e.g., sandbox, passDatasets) |
source / sourceId | Origin tracking for imported apps |
Permissions Required: None (404 if user cannot read this app)
Error Responses:
404 Not Found- App does not exist or user lacks read access
POST /api/apps
Create a new app.
Authentication: Required
Permissions Required: Member role in at least one team
Payload:
{
"type": "report",
"name": "Sales Dashboard",
"slug": "sales-dashboard",
"ownerId": "analytics",
"description": "Interactive sales analytics",
"defn": {
"icon": "sparkles",
"entryPoint": "index.html"
},
"settings": {},
"datasets": [
{
"datasetId": "dataset-uuid-1",
"alias": "sales",
"label": "Sales Data",
"filter": null,
"chips": null
}
]
}
Required Fields:
| Field | Type | Description |
|---|---|---|
type | string | App driver type (must be valid and eligible) |
Optional Fields:
| Field | Type | Description |
|---|---|---|
name | string | Display name |
slug | string | URL-friendly identifier |
ownerId | string | Owner principal ID (defaults to current user) |
description | string | Description text |
defn | object | App definition (driver-specific) |
settings | object | App settings |
datasets | array | Dataset references to attach |
Response:
Returns the created app with a 201 Created status and a Location header pointing to the new app.
{
"id": "d4f8a2b1-1234-5678-90ab-cdef12345678",
"type": "report",
"name": "Sales Dashboard",
"slug": "sales-dashboard",
"ownerId": "analytics",
"naturalId": "analytics:sales-dashboard",
"description": "Interactive sales analytics",
"defn": {
"icon": "sparkles",
"entryPoint": "index.html"
},
"settings": {},
"shared": false,
"createdAt": "2024-02-13T10:00:00.000Z",
"updatedAt": "2024-02-13T10:00:00.000Z"
}
Error Responses:
400 Bad Request- Invalid driver type or payload403 Forbidden- User lacks permission to create apps404 Not Found- Driver type not found or not eligible
Driver Eligibility:
The type field must reference a valid app driver that passes eligibility checks. For the report driver, the user must have the ai feature enabled.
PUT /api/apps/{id}
Update an app's properties.
Authentication: Required
Permissions Required: Member+ role (write permission)
Path Parameters:
| Parameter | Type | Description |
|---|---|---|
id | string | App UUID or natural ID |
Payload:
Any subset of the app's mutable fields:
{
"name": "Updated Sales Dashboard",
"description": "New description",
"defn": {
"icon": "chart-bar"
},
"settings": {
"theme": "dark"
}
}
Response:
Returns the updated app.
Permissions Required: Member+ (write permission)
Error Responses:
404 Not Found- App does not exist or user lacks read access403 Forbidden- User lacks write permission
Important Notes:
- Updates to drafts should use
PUT /api/apps/{draftId}(not the original app's ID) - If you need to edit the published app, first create a draft via
POST /api/apps/{id}/_edit - Updating an app directly is typically only done for metadata changes (name, description)
- Content changes should go through the draft workflow
DELETE /api/apps/{id}
Delete an app and all associated resources.
Authentication: Required
Permissions Required: Member+ role (write permission)
Path Parameters:
| Parameter | Type | Description |
|---|---|---|
id | string | App UUID or natural ID |
Response:
Returns 204 No Content on success.
Cascade Behavior:
Deleting an app also removes:
- All AppDataset references
- All AppShare records
- Associated draft apps (if any)
- TagEntity associations
- The app's library (if embedded)
Error Responses:
404 Not Found- App does not exist or user lacks read access403 Forbidden- User lacks write permission
Permissions Required: Member+ (write permission)
GET /api/apps/{id}/favorite
Check if the current user has favorited an app.
Authentication: Required
Path Parameters:
| Parameter | Type | Description |
|---|---|---|
id | string | App UUID or natural ID |
Response:
Returns the favorite record if it exists, or 404 if the app is not favorited.
PUT /api/apps/{id}/favorite
Add an app to the current user's favorites.
Authentication: Required
Path Parameters:
| Parameter | Type | Description |
|---|---|---|
id | string | App UUID or natural ID |
Response:
Returns the created or existing favorite record.
DELETE /api/apps/{id}/favorite
Remove an app from the current user's favorites.
Authentication: Required
Path Parameters:
| Parameter | Type | Description |
|---|---|---|
id | string | App UUID or natural ID |
Response:
Returns 204 No Content on success.