Put it in front of someone
Turn the staffing outlook into a shareable grid app, six cafés by seven days with the short-handed cells in red, described to Kai in one prompt and published from the builder.
A chat answer reaches the person who asked. The manager of the Brno café does not want to ask; she
wants to glance at next week on Monday morning and see which day is red. This step turns
staffing_outlook into a published grid app: six cafés down, seven days across, a number in every
cell and a red cell where it will hurt.
Where you are: staffing_outlook exists in Storage. When you finish: the grid, running as
an app you can open and refine. Publishing it to production gives it a URL and a password, and that
last step did not succeed in our project: see step 5.
Three ways to do this, one page. They are alternatives, not steps. Prompt is what you paste into Kai; UI is the same task click by click, for when you want to see where each setting lives; CLI / API is the same task from a terminal, with the raw request beside it. Pick one tab and carry on; your choice follows you to the next page.
There is no click-by-click equivalent for building this: by hand it is a development workflow with its own section, and the UI tab says where to go for it.
Kai asks before it changes anything: expect one approval dialog per object it creates, showing the exact configuration it is about to write. Questions that only read do not ask. If confirming each one gets tiring, pre-approve tools in tool permissions. The chat's plan mode button is a different thing: Kai writes the steps down and asks you to approve the plan before it starts, and then still asks for each change. Use it when you want to read the plan first, not to save clicks.
One thing stays yours either way: deciding who gets the URL and the password.
If a step builds something other than what this page describes, say so in the same chat; it edits what it made. Nothing here is one-way.
Before you start
You need
- A Keboola project. No project yet? Get a project.
Apps in the project’s navigation. No Apps there? Skip this page; the flow on the next page then runs without the app.
A table to build from:
staffing_outlookfrom Transform data, or any table of yours with a few numeric columns. The note below says what to adapt.
Depending on the tab you use
- Prompt tab:
Kai, from Apps → Create App, on supported stacks. The first time, an organization admin switches it on; see Get started with Kai.
- UI tab:
a Git repository and your own Streamlit or Python/JS code. The UI tab points to where that is covered.
- CLI / API tab:
kbagent, connected with write access, and the app you built on the Prompt tab.
Arriving here from the Apps announcement rather than from the previous page? The prompt below names this guide’s table and its columns, so with a table of your own you adapt both, and the checks further down describe our data rather than yours. If you would rather start from nothing, Build your first app with Kai does that without a tutorial dataset.
What a data app is
Section titled “What a data app is”A data app is a small web application that runs inside Keboola and reads your Storage tables (a grid, a dashboard, an explorer) with its own URL you can send to anyone you choose. Like everything else in this guide it is a component: it can sit in a flow, and the Apps section covers it in full.
Set it up
Section titled “Set it up”Describing an app is a one-paragraph job, and the Apps section has Kai wired in as the primary way to build one (Build your first app with Kai).
-
Open Apps in the navigation and click Create App. You land on the Build web apps from your Keboola data screen: a prompt field that says Describe what you want to build…, and below it, under or create manually, the Streamlit and Python/JS routes of the other tab.
-
Describe the app and send it:
Prompt Build a data app from the table out.c-Boolabean-staffing-outlook.staffing_outlook. Show onegrid: a row per café (store_name and city) and a column per forecast date, in date order.Each cell shows expected_units_per_person as the big number, with the weekday,forecast_temp_c and forecast_rain_mm in small text underneath. Colour a cell red whenshort_handed is true and leave the other cells neutral. Above the grid, one caption line:how many café-days in the table are short-handed. No filters, no other charts, no sidebar.Saying what not to build is half the prompt. Left to itself Kai adds filters and a second chart, and the grid stops being the thing you glance at. Kai also names the app itself; ours came out as Staffing Outlook Grid, and the flow on the next page refers to it by that name. Use whatever yours is called.
-
Kai creates the app’s configuration, then a draft pinned to its own branch, and asks before it writes code: one Confirmation required card with Approve, Decline and Always allow. Approve, and the builder splits into Preview and Code, with a line above them that says it plainly: This is a private draft that updates live as Kai builds. Expect five to six minutes from the prompt to a grid you can look at; most of that is the draft’s container installing and starting.
-
Read the preview. Six rows, seven columns, one big number per cell, red where
short_handedis true, and the caption’s count matching the number of red cells. If it is not that, say so in the same chat; the draft updates in place. This is what ours looked like, on a week with two red days:
-
When the draft is right, click Publish to production. No confirmation dialog appears, which is normal. What tells you it worked is the app itself: it is now listed under Apps with a page of its own. (In our project the click also started no deploy job, which is the platform failure this page documents, not something you did.)
Open that page. Its status reads Not Deployed, with a Deploy App button, so publishing and starting are two separate steps: click Deploy App. A deploy builds and starts a container, which takes a few minutes. When it succeeds the status turns Active, Open App appears, and the app asks for the password from its Authentication setting, Basic by default, so the grid is not public until you decide who gets the link and the password.
It has not succeeded in our project yet, and the reasons are worth knowing before you try: see the failure list at the foot of this page. The draft preview is the part that has worked every time, and it is enough to finish this guide.
Check: the draft preview (or Open App, if the deploy succeeded for you) shows the grid,
and its caption’s count equals both the number of red cells and the number of rows where
short_handed is true in Storage. That count moves with the forecast: the capture above was a
week with two, an earlier week had four. A deploy that ends in Failed with nothing in
Terminal Logs is not your grid’s fault; see below.
Building an app by hand means a Git repository and your own Streamlit or Python/JS code, a real development workflow rather than a form. It has its own pages: create an app manually for the UI flow, and Build locally for the repo-based workflow. Finish the guide with the Prompt tab first; come back when the app you want is one the description field cannot hold.
The app itself is written by Kai in the builder. No command turns a paragraph into a grid.
What kbagent does is the part you repeat: listing apps, deploying the version Storage
holds, waking one that has gone to sleep, and reading its log when it will not start.
kbagent data-app list --project docs-demoThat prints each app with its numeric app ID, its state and its URL. kbagent data-app detail --project docs-demo --app-id <app-id> adds the Storage configuration ID, a different
identifier, and the one the flow on the next page needs for its third phase.
With the app ID, a deploy of the latest saved configuration is one command:
kbagent data-app deploy --project docs-demo --app-id <app-id> --wait--wait blocks until the container is running or the deploy fails. This is the same call the
flow’s third phase makes on the next page, which is why a broken app turns a scheduled run red.
Four more worth knowing:
kbagent data-app start --project docs-demo --app-id <app-id>kbagent data-app logs --project docs-demo --app-id <app-id>kbagent data-app runs --project docs-demo --app-id <app-id>kbagent data-app password --project docs-demo --app-id <app-id>start wakes an app that auto-suspended, logs is the app’s own output, runs lists each
start with the container’s startup log, which is where a failed deploy actually explains itself,
and password prints the Basic-auth password for the URL, the one thing to keep out of a
screenshot or a chat.
If it goes wrong
Section titled “If it goes wrong”-
The grid is empty, or shows another table. The app is reading the wrong table. Give Kai the full table ID,
out.c-Boolabean-staffing-outlook.staffing_outlook, in the same chat and let the draft update. -
The red cells do not match the caption. Kai coloured on a threshold of its own instead of the
short_handedcolumn. Tell it to use the column; the transformation already decided what red means, and the app should not decide again. -
The deploy of the production app fails, and Terminal Logs says the app is not running. The draft ran, so the code works; the production container did not come up. The job’s own error is usually just Internal Server Error occurred, which says nothing. The reason is in the container’s startup log, and the fastest way to read it is
kbagent data-app runs --project <alias> --app-id <app-id>. Two causes have shown up in this project, and neither is your grid:App must have keboola-config/nginx/ directory: the repository Kai wrote has no nginx configuration, which a Python/JS app needs in production. The draft does not, because it runs in dev mode.Authentication failed for https://git.<stack>/keboola/app-<id>.gitwith Credentials are incorrect or have expired: the app’s managed Git credentials have expired, so the container cannot clone its own code.
After several failures the platform disables the app: a banner says it failed to start automatically multiple times, and the button becomes Start App. Either message is one for Support, with the run ID from the command above. The rest of the pipeline is unaffected: the table is rebuilt every morning whether or not the app is up, and the draft preview still shows it.
-
Nothing happens for a minute after you open the app. It went to sleep. Apps stop after a while without visitors (Auto Sleep on the app’s page; ours was set to fifteen minutes) and wake on the next request, which is the wait you are seeing.
Going further
Section titled “Going further”- Publish and share: authentication options beyond the default password, and who can reach the URL.
- Authentication: the Authentication setting decides who can open
the app. Basic (Password) is the default and the shared password above. Every other gate,
whether OIDC with Auth0, Google Cloud, Microsoft Entra ID or Okta, or the GitHub, GitLab and
JumpCloud options, needs a client you register in that provider’s own console. That part is always
yours: neither Kai nor
kbagentperforms it, andkbagent data-app create --authoffers onlypasswordorpublic. - Build locally: the Git-based workflow once an app outgrows its first description.