What a generated app can do: the platform capabilities behind it
An app built in the Studio is more than pages and tables. These are the capabilities the platform gives every app, what each needs from you, and how the build report tells you the truth about them.
Builds you can trust
Every build ends with a report that counts what ran: server functions that compiled (or did not, by name), planned models and fields that exist (or are listed as not built), the migration result, the seeded rows, and a browser check that opens the pages and fills the create forms. The headline says "All checks passed" only when all of that is true. A chat change is reported the same way: "checked in the browser" means a browser opened the page.
External APIs, keys and no pretending
An API that needs no key (weather, exchange rates, public holidays, geocoding) is declared in the document, registered as an integration during the build and tested with one live call. An API that needs a key is declared the same way and connected under App Hub, Integrations. A function that calls a provider that is not connected returns an error; it never invents a value, and the page shows the error as its empty state.
Bookkeeping: Accounted and Fortnox
Accounted (accounted.se) is connected with an API key and a company id under App Hub, Integrations, Accounted. The platform reads whether the key is a sandbox key (gnubok_sk_test_, every write is a dry run, nothing is booked) or a live key, and says so on the card, in the Test button and in the build report; the Test button also lists the key's scopes and whether the chosen company accepts writes. Functions create customers, invoices and journal entries with ctx.callIntegration('accounted', …) and paths such as /companies/{companyId}/invoices; the company id is filled in by the platform. Any write can be previewed with the X-Dry-Run: true header. One webhook URL per app (/webhook/accounted) answers Accounted's ownership handshake, verifies the signature of every delivery and runs your handlers for events such as invoice.paid. Fortnox is connected the same way with its own key.
AI inside the app
Server functions can call ctx.ai for one completion: classify a ticket, extract fields from a document, summarise, draft a reply, with an optional JSON schema for structured output. Pilot organisations use Nibor's key under a monthly token allowance; client organisations use their own key (Portal, AI settings). When neither is available the function reports "AI not configured" instead of guessing.
Sign-in doors
The login page offers the doors you choose under App Hub, Users, Sign-in: email and password, your organisation's Nibor accounts, Google, GitHub, and BankID. BankID matches the proven personal number to a row of a model you name (ask the chat for "BankID sign-in for customers") and needs the Idura Verify integration connected.
Payments: test first, then live
Stripe is connected with a secret key under App Hub, Integrations. The platform reads whether it is a test or a live key and says so on the card, in the Test button and in checkout responses. Connect an sk_test_ key first and pay with card 4242 4242 4242 4242 to walk the whole flow without moving money. One webhook URL is advertised; it verifies Stripe's signature and runs your app's handlers. Swish is not available yet: it needs a merchant certificate the platform cannot present, so a Swish step always returns an error and the publish scan says so.
Email from your own domain
Connect Resend under App Hub, Integrations, register your sending domain there and add the DNS records it shows, then check verification. Until the domain is verified, mail goes out from the platform address and every send says so in its result.
Search engines
A public app opts in with meta.indexable; each page can carry its own title, description and social image, and robots.txt and sitemap.xml are real files. Apps that do not opt in are kept out of search engines.
Publishing and the security scan
Publishing runs a scan first. A secret in the document, sensitive data readable by everyone, an admin route among the public routes, pages with roles but no auth, or payments without a connected key block the publish; you see the findings and can publish anyway after reading them. Custom scripts, native dialogs, unfinished placeholders and tables writable by everyone are warnings. The same scan runs from the Studio, the chat and MCP.
Versions with data
Before a chat turn changes the schema or deletes data, the version snapshot also copies the app's tables. Restoring that version brings the rows back, not only the document.
Scheduled jobs
Jobs run only after the app is published; a draft's jobs are listed as inert in the build report and in App Hub. Every run is logged under App Hub, Connections, Jobs, and the owner is emailed once when a job starts failing.