PromptRails

Apps

Turn a PromptRails workflow into a hosted app, presentation, form, portal, or review queue without building a separate frontend.

Apps let you turn agents, prompts, data sources, and records into hosted web surfaces without building a separate frontend.

Use Apps for internal tools, demos, review queues, customer-facing forms, and lightweight portals where the UI needs to run a PromptRails resource and show the result.

The Apps list shows each hosted surface, its slug, status, access mode, and quick actions for opening, previewing, editing, or deleting.

Overview

An app is built on a visual canvas. You place widgets, bind them to queries, and wire up interactions without writing frontend code. Widgets cover inputs, buttons, charts, tables, forms, markdown, images, embedded agent chat, prompt runs, and data source runs. Queries fetch or write data, while page parameters and app records keep state.

Builders get an editor with undo/redo, multi-select, guided data binding, version history, and an assistant that can place widgets. End users get a focused app instead of direct access to the full PromptRails workspace. Apps can render as scrolling web pages or full-screen presentation decks, with optional export controls for PDF and PowerPoint deliverables.

Technical detailsApp data model

App Structure

App  (slug, access control, version history)
├── Page 1 ("Customer Lookup")
│   ├── Widgets        — text inputs, table, agent chat, ... on the canvas
│   ├── Queries        — record_list, agent_run, ... data fetchers
│   └── Parameters     — shared page inputs ({{params.name}})
├── Page 2 ("Content Generator")
│   └── ...
└── Records            — app-scoped JSONB documents, grouped by collection
  • Pages define the navigation structure; each owns its own canvas, queries, and parameters.
  • Widgets are placed freely on the canvas and can be nested inside Container / Card widgets.
  • Queries are page-scoped data fetchers referenced by widgets via {{queryName.data}}.
  • Records are app-scoped documents (the persistence target for Form / Table widgets).
  • Versions are immutable snapshots of the whole app, restorable from the editor.

The Canvas Editor

The editor lives at /apps/:id/edit and is organized around a left icon rail and contextual panels:

  • Components — the widget toolbox; drag a widget onto the canvas.
  • Pages — list / add / rename / delete pages, plus per-page Parameters.
  • Queries — create and run data fetchers (bottom strip).
  • History — save and restore version snapshots.
  • Settings — app name, slug, display mode, access control, theme, and export controls.
  • Inspector (right) — edits the selected widget's configuration.

Widgets use free placement: drop them where they should appear and adjust the layout visually. The editor also supports zoom, undo/redo, duplicate, copy/paste, delete, multi-select, and a context menu.

Widget Library

Widgets are organized into five categories. Each is configured from the Inspector and can bind its properties to query output or page parameters.

CategoryWidgets
Common / Presentationtext, markdown, button, link, alert, tag, code_block, divider, image, statistic
Inputstext_input, number_input, select, checkbox, switch, radio_group, date_input, date_range_input, form
Layoutcontainer, card, tabs, modal, spacer
Datatable, list, chart, rest_endpoint
Agentagent_chat, prompt_run, data_source

Highlights:

  • Chart — bar, line, area, pie, donut, scatter, and number visualizations with guided query binding, column pickers, and configurable series.
  • Markdown — renders Markdown + GFM, ideal for agent / prompt output.
  • List — repeats a row template for any bound array, with dotted-path field access (row.user.email).
  • Table — renders arrays of objects with a sticky header; bind to a page query, connect a data source directly, or use static/custom data.
  • Form — collects inputs and runs a query on submit (typically record_create).
  • Container / Card — group child widgets; nesting survives reload via parent_id.
  • Tabs — exposes activeIndex / activeLabel so other widgets can react to the current pane.
  • Agent chat — embeds a conversational agent surface directly on the page.
  • Prompt run / Data source — run a prompt or connected data source from the page and expose its output to other widgets.

Guided Data Binding

Tables and charts can be connected without writing raw {{ ... }} bindings:

  • Pick an existing Page query from the widget Inspector.
  • Use Connect data source from the same picker to create a page-load data_source query and bind the widget to {{queryName.data}} automatically.
  • Switch to Advanced binding only when you need a custom expression or transformed rows.

For charts, PromptRails reads the latest query result and offers field pickers for the X/category field and value series. If the query has not run yet, you can still type field names and run the query once to load real columns.

Technical detailsCanvas data and query details

Widget Bindings

Widgets read dynamic data through {{ ... }} bindings, resolved against page state at runtime:

{{ orders.data }}          # output of the "orders" query
{{ params.customer_email }}# value of the page parameter "customer_email"
{{ row.user.email }}       # dotted-path field inside a List/Table row

Reactive widgets (those with {{...}} bindings) are flagged in the editor so you can see at a glance what's data-driven.

Queries

Queries are page-scoped data fetchers. Each has a name, a type, type-specific config, and a trigger.

TypePurpose
record_listRead documents from the app record store
record_createWrite a document to the app record store
agent_runExecute an agent
prompt_runRender and execute a prompt template
data_sourceRun a connected data source
transformerDerive a value from other query outputs
jsSandboxed JavaScript evaluation against page state

Triggers control when a query runs:

TriggerBehavior
manualRuns only when explicitly triggered
page_loadRuns automatically when the page loads
on_changeRe-runs when an upstream input changes

Create queries from the dialog; source pickers list your agents, prompts, and data sources. Run a query from the detail panel and the result renders as a table, scalar card, or JSON depending on its shape. Query runs are persisted so page state can be replayed on refresh and public traffic can be audited.

App Records

Records give an app its own document store without a separate database. Each record belongs to a collection (think of it as a table within the app) and holds an arbitrary JSON data payload.

  • record_create queries write records (e.g. a Form submission).
  • record_list queries read them back (e.g. into a Table), with GIN-indexed filtering.
  • Public widget writes are attributed to the visitor's session; dashboard writes to the user.

Page Parameters

Pages can define parameters that users fill in, then reference anywhere via {{params.name}}.

FieldDescription
nameReference name (used in {{params.*}})
labelDisplay label
param_typeInput type (text, number, select, etc.)
default_valueDefault value
optionsOptions for select-type parameters
requiredWhether the parameter is required
sort_orderDisplay order

Add parameters through a guided dialog (Label → Reference name → Type → Options → Default → Required) — no JSON authoring.

Version History

Every save can be snapshotted. The History panel lists versions with a human-readable summary, lets you Save version on demand, and Restore any prior snapshot. Restoring auto-checkpoints the current state first, then atomically rewrites pages, widgets, parameters, and queries inside a transaction — so a restore is fully reversible and Container nesting survives the round-trip.

Presentation Mode and Export

Apps support two display modes:

ModeBest for
Web pageA scrolling app or portal with page tabs
PresentationA full-screen slide deck with one app page per slide
Web page mode renders a clean hosted app with page tabs, export controls, and dashboard content in a scrolling page layout.

Presentation mode is designed for customer demos and reports: app chrome is hidden, slides are preloaded for smooth navigation, and controls stay out of the content area. Web page mode keeps the same clean runtime surface while preserving page navigation.

When export controls are enabled in App Settings, public runtimes can export the current app as:

  • PDF — browser print export with app chrome hidden.
  • PPTX — PowerPoint export with each app page or slide captured as a deck slide.

Export controls are enabled by default and can be hidden from both web and presentation views.

Locked and Frozen Apps

Locking an app freezes editing for the builder and preserves runtime data for customer-facing presentations. Prompt and data-source widgets serve their frozen result while locked, so published demos do not shift because of fresh LLM or data-source runs. Unlock the app when you want to edit layout, change queries, or refresh frozen outputs.

Access Control

Each app has a single auth_method that gates the public URL:

auth_methodBehavior
noneFully public — anyone with the link can use the app
pinRequires a shared PIN. The PIN is hashed before storage
promptrails_loginRequires a Promptrails account with access to the owning workspace

For promptrails_login, visitors sign in through an inline login flow on the hosted-app domain. The app verifies that the account belongs to the owning workspace before rendering the app.

AI Assistant

The built-in assistant can build the canvas for you. It exposes tools to list, add, update, and delete widgets, and to list and add queries on the current page (list_canvas_widgets, add_canvas_widget, update_canvas_widget, delete_canvas_widget, list_canvas_queries, add_canvas_query). All are gated by a page-ownership check, so the assistant can only edit apps in workspaces you have access to.

Public URLs

Each app has a unique slug that forms its public URL, such as https://your-app-domain.com/internal-tools.

Slugs must be unique across all apps. Depending on the access method, the first visit may show the PIN prompt or the inline login form before the app renders.

Creating an App

Create apps from the PromptRails dashboard:

  1. Open Apps in your workspace and create a new app — set its name and slug.
  2. Add one or more pages to define the navigation structure.
  3. On each page, drag widgets from the Components panel onto the canvas (or start from a template: Dashboard / Form + Table / Agent chat / Single input).
  4. Add Queries to fetch or write data, and bind widget properties to them with {{queryName.data}}.
  5. Add Parameters for shared inputs and reference them via {{params.name}}.
  6. Configure Access Control under Settings (none / pin / promptrails_login).
  7. Save a version and share the public URL.

Analytics

Apps track execution logs including:

  • Which widgets / queries were executed
  • Input payloads and output summaries
  • Status (success / failure)
  • Session tracking
  • Error messages

Query runs are persisted separately with per-run duration, input snapshot, and output. Review these from the app detail view to understand how end users are interacting with each page.

Technical detailsApp field reference

App Fields

FieldTypeDescription
idKSUIDUnique app identifier
workspace_idKSUIDWorkspace scope
namestringDisplay name
descriptionstringOptional description
slugstringURL slug (unique)
statusstringactive or inactive
auth_methodstringnone, pin, or promptrails_login
modestringweb_page or presentation
export_enabledbooleanShows PDF/PPTX export controls
grid_columnsintegerLegacy grid column count (default: 12)
last_published_attimestampLast publish time
created_attimestampCreation time
updated_attimestampLast update time
  • Agents -- Agents used in app widgets and queries
  • Prompts -- Prompts used in app widgets and queries
  • Data Sources -- Data sources used in app widgets and queries