Actions
Action endpoints perform specific operations on apps like copying, printing, and more.
POST /api/apps/{id}/_copy
Create a copy of an app, including its library and all associated resources.
Authentication: Required
Permissions Required:
- Member+ role (copy permission) on the source app
- Member role (create permission) for apps
Path Parameters:
| Parameter | Type | Description |
|---|---|---|
id | string | App UUID or natural ID |
Payload:
{
"name": "Sales Dashboard (Copy)",
"progress": "optional-progress-callback-id"
}
Payload Fields:
| Field | Type | Required | Description |
|---|---|---|---|
name | string | No | Name for the copy (default: original name) |
progress | string | No | Progress callback ID for tracking |
Response:
Returns the copied app with status 201 Created and a Location header pointing to the new app.
{
"_links": {
"self": { "href": "/api/apps/john.doe:sales-dashboard-copy" }
},
"id": "new-uuid-5678",
"type": "report",
"name": "Sales Dashboard (Copy)",
"slug": "sales-dashboard-copy",
"ownerId": "john.doe",
"naturalId": "john.doe:sales-dashboard-copy",
"description": "Interactive sales analytics",
"defn": {
"icon": "sparkles"
},
"settings": {},
"libraryId": "new-lib-uuid-9012",
"shared": false,
"createdAt": "2024-02-13T10:30:00.000Z",
"updatedAt": "2024-02-13T10:30:00.000Z",
"datasets": {
"sales": {
"id": "new-rd-uuid-3456",
"appId": "new-uuid-5678",
"datasetId": "dataset-uuid-1",
"alias": "sales",
"label": "Sales Data"
}
}
}
Copy Behavior:
The copy operation duplicates:
- All app metadata (name, description, defn, settings)
- The embedded library (if present) with all files
- All resource junction rows (AppDataset, AppQuery, AppDatasource, AppIntegration, AppToolkit)
- The copy is owned by the current user
- The copy is not shared by default
- The copy gets a new UUID and slug
Not Copied:
- Shares (AppShare records)
- Tags (TagEntity records)
- Agents (AppAgent records — re-created on next deploy)
- Favorite status
- Edit history
- Tokens
Library Copy:
If the app has an embedded library (libraryId):
- A new library is created with the name
"{original name} (Copy)" - All files from the original library are copied to the new library
- The new app references the new library
- The copy is fully independent (editing one doesn't affect the other)
Error Responses:
400 Bad Request- Invalid payload or copy operation failed404 Not Found- App doesn't exist or user lacks access403 Forbidden- User lacks copy or create permission
Transaction Safety:
The entire copy operation runs in a database transaction. If any step fails, the entire operation is rolled back.
POST /api/apps/{id}/_print
Export an app as a PDF.
Authentication: Required
Permissions Required: Member role (run permission)
Path Parameters:
| Parameter | Type | Description |
|---|---|---|
id | string | App UUID or natural ID |
Payload:
Print configuration depends on the app driver. For report apps:
{
"format": "letter",
"orientation": "portrait",
"margins": {
"top": 0.5,
"right": 0.5,
"bottom": 0.5,
"left": 0.5
},
"headerTemplate": "<div>...</div>",
"footerTemplate": "<div>...</div>",
"displayHeaderFooter": true,
"printBackground": true
}
Common Payload Fields:
| Field | Type | Default | Description |
|---|---|---|---|
format | string | "letter" | Paper format (letter, legal, a4, etc.) |
orientation | string | "portrait" | Page orientation (portrait, landscape) |
margins | object | {} | Page margins in inches |
printBackground | boolean | true | Include background graphics |
Response:
Returns a PDF file as a binary stream.
HTTP/1.1 200 OK
Content-Type: application/pdf
Content-Disposition: attachment; filename="Sales Dashboard.pdf"
[PDF binary data]
Use Cases:
- Export dashboards for offline viewing
- Generate reports for email distribution
- Archive app snapshots
- Print physical copies
Implementation Notes:
- Uses headless Chrome/Puppeteer for rendering
- Captures the current state of the app
- Respects app's CSS print styles
- May timeout for very complex apps
Error Responses:
404 Not Found- App doesn't exist or user lacks access403 Forbidden- User lacks run permission500 Internal Server Error- PDF generation failed
Other Actions
Export Bundle
Apps can be exported as bundles (not yet documented in routes).
Route: GET /api/apps/{id}/_export
Use Case: Export app and its library as a portable bundle for backup or transfer.
Cloud Publish
Apps can be published to cloud services (not yet documented in routes).
Route: POST /api/apps/{id}/_cloud-publish
Use Case: Publish app to external hosting or app marketplaces.
Common Action Patterns
Copy and Modify
// 1. Copy the app
const copy = await POST('/api/apps/analytics:sales-dashboard/_copy', {
name: 'Sales Dashboard - Modified'
});
// 2. Edit the copy
await POST(`/api/apps/${copy.id}/_edit`);
// 3. Modify files in the draft
await PUT(`/api/apps/${draftId}/contents/index.html`, {
content: modifiedHTML
});
// 4. Commit changes
await POST(`/api/apps/${copy.id}/draft/_commit`);
Create PDF Archive
// Generate PDF of current state
const pdf = await POST('/api/apps/analytics:sales-dashboard/_print', {
format: 'letter',
orientation: 'landscape',
printBackground: true
});
// Save to file or send via email
await fs.writeFile('dashboard-archive.pdf', pdf);
Copy to Different Owner
// 1. Copy the app (owned by current user)
const copy = await POST('/api/apps/analytics:sales-dashboard/_copy', {
name: 'Sales Dashboard - Marketing Copy'
});
// 2. Transfer ownership to Marketing team
await PUT(`/api/apps/${copy.id}/owner`, {
teamId: 'marketing'
});
Batch Copy
// Copy multiple apps
const sourceApps = [
'analytics:sales-dashboard',
'analytics:customer-report',
'analytics:inventory-tracker'
];
const copies = [];
for (const appId of sourceApps) {
const copy = await POST(`/api/apps/${appId}/_copy`, {
name: `${appId} (Backup ${new Date().toISOString()})`
});
copies.push(copy);
}
console.log(`Created ${copies.length} backups`);
Permissions Summary
| Action | Required Permission | Description |
|---|---|---|
| Copy | Member+ (copy) + Member (create) | Copy source app and create new app |
| Member (run) | Generate PDF from app | |
| Export Bundle | Member+ (write) | Export app as bundle |
| Cloud Publish | Publisher (share) | Publish to external services |