The schema-driven model

Every application in dbo.io is defined by metadata records stored in a database. From this metadata, dbo derives a complete REST API with predictable endpoint patterns, security enforcement at every layer of every query, content rendering for any output format, background messaging with template rendering, and a full revision history for every change.

When you add a column to an entity, the API surface updates immediately — no code change, no restart, no regeneration cycle. The metadata is the only source of truth.

App ├── Data Sources (MySQL, SQL Server, ODBC) │ └── Entities (tables / views) │ └── Entity Columns (fields, types, validation) ├── Outputs (named queries) │ ├── Output Values (SELECT definitions) │ └── Output Value Filters (WHERE / HAVING) ├── Content (templates — pages, layouts, snippets) ├── Sites (domains and URL routing) ├── Security (access grants) │ └── Security Columns (field-level restrictions) ├── Media (files — images, fonts, binaries) ├── Automation (schedulers) ├── Messaging (email, SMS, chatbot) └── Revisions (full change history)

The request pipeline

Every API request — whether from a browser, mobile app, or AI agent — travels the same path. There is no controller code in this path.

Request arrives → Session resolved (cookie, Authorization header, inline credentials) → Route matched (output UID / entity UID / content path / media path) → Security evaluated (grants checked, row filters applied, columns projected) → Query constructed (dynamic SQL from output config or custom SQL body) → Template rendered (tokens substituted, embeds resolved) → Response dispatched (JSON, HTML, CSV, XML, binary — caller's choice)

The framework reads metadata, constructs the query, enforces security, and renders the response — all at runtime. There is no generated code. There is no compilation step when you change your schema.

The API surface

All endpoints follow consistent patterns and return a standard JSON envelope.

{
  "Successful": true,
  "Messages": [],
  "Payload": { ... }
}

Input — Universal Write

POST /api/input/submit

The single endpoint for all creates, updates, and deletes across any entity. One request can add a parent record and its children across multiple tables in a single transaction.

Dry-run default
Omit _confirm=true to validate without writing. Every write is a two-step confirm.
Batch operations
Add, edit, and delete across multiple entities in one call.
FK resolution
String UIDs auto-resolve to numeric PKs; parent IDs available to child rows in the same request.
Special values
_{unique} generates a UID, _{now} inserts current datetime, _{session@UserID} injects session context.
Optimistic locking
_protect_after=[datetime] prevents overwriting concurrent updates.

Output — Query and Introspect

GET /api/o/{uid}                      # Execute a named query
GET /api/o/e/{entityUid}              # Ad-hoc query against any entity
GET /api/o/e/{entityUid}/{rowId}      # Single-record fetch by ID or UID
GET /api/output/meta/entity/{uid}     # Schema introspection: entity structure
GET /api/output/meta/column/{uid}     # Schema introspection: column detail

Named outputs are pre-configured query definitions stored as data records. Every output has a UID, making it directly addressable as an API endpoint or as a tool definition for an AI agent.

Query parameters:

_filter@Col=val
Filter results (comma-separated = OR)
_sort=Col:DESC
Sort ascending or descending
_limit / _page
Pagination
_search@Col1,Col2=term
Full-text search across columns
_template=csv
Response format: json_indented, json_raw, html, csv, xml, txt

Content — Render

GET /api/c/{uid}
GET /app/{appName}/{site}/{*path}

Server-side template rendering with a composable token and embed system. Used for HTML pages, API response templates, email/SMS bodies, and any text output.

Token syntax

#{type@reference$target!default:modifier}
  • #{session@UserID} — session context
  • #{request@paramName} — URL parameter or form field
  • #{value@ColumnName} — current row value (in render context)
  • #{payload$EmbedName} — rendered output of a named embed

Authentication

GET/POST /api/authenticate

Username/password, email/password, phone/passkey, inline credentials, HTTP header SSO, SAML 2.0 SP-initiated. Network restriction: optional IP/domain validation per user.

Security architecture

Declarative security configured as data records and enforced at query construction time, before any SQL executes.

Entity level

Seven operations per rule: View, Add, Edit, Delete for CRUD; Execute for rendering outputs, content, and media; Associate for FK relationship access; and Impersonate for delegated account support — all configured per user or group.

Row level

Restrict access to specific rows via static ID list, dynamic query output, or single UID. Injected as WHERE clause at construction time.

Column level

Hide or make read-only specific fields per user or group. Unauthorized data is never fetched — not just hidden.

For AI agents

Agents authenticate as distinct identities and receive exactly the same security treatment as human users. An agent that only needs to read invoice records gets View on the invoice entity and nothing else. The constraint is enforced at the data layer, not in application code. Every agent operation is logged with attribution.

Session-delegated security

A complementary pattern for user-facing APIs. Mark an output or content record as Public — which bypasses the grant check for the endpoint itself — and apply a CurrentUser filter preset inside the output. The preset resolves to the authenticated session's UserID at request time, so each caller automatically sees only their own rows. The endpoint is accessible without an explicit security grant, but the data is always scoped to the session. Ideal for user account patterns where every authenticated user should see their own records without requiring per-user row grant configuration.

App packaging and portability

Every dbo application is a self-contained unit that can be exported as a .model archive — a zip file containing schema definitions, query configurations, security rules, content records, and media.

  • Environment promotion — export from dev, import to staging, promote to production. No manual environment sync.
  • Client deployment — ship a complete application to a client's VPC as a single import operation.
  • Versioning — named app_version records track exactly which assets changed in each release.

App discovery for agents

The /api/app/object/{appName} endpoint returns the complete application definition as structured JSON. Combined with the index_search stored procedure — which performs weighted semantic search across all asset UIDs, names, display titles, and descriptions — dbo applications are fully discoverable by tooling and AI agents without requiring access to source code.

Local development and the CLI

Clone

Pull to local filesystem

Pull the app to a local filesystem as ordinary files in a structured directory. Each asset has a .metadata.json companion storing its server identity.

Edit

Work in any editor

Modify content, query definitions, templates, and security records in any editor — including AI-assisted environments like Claude Code.

Push

Sync back to server

Sync changes back to the server; triggers postpush hooks for builds and cache invalidation. The local directory is a git repository; app changes are tracked alongside source code.

Claude Code integration

Install the CLI plugin and any Claude Code session gains /dbo-push, /dbo-pull, and /dbo-clone skills. AI-assisted dbo development is a first-class workflow, not an afterthought.

dbo install plugins --global

AI agent integration

dbo.io is a natural environment for AI agents because the entire application surface is structured, queryable, and schema-driven.

Discovery

Call /api/app/object/{appName} to receive the complete application definition as structured JSON. Semantic search via index_search for locating specific resources.

Operation

Agents use the same REST API as human users. Authenticate with a session, and all security enforcement applies automatically. No special agent API.

Writing safely

Every write through /api/input/submit is dry-run by default. Add _confirm=true to commit. Two-step pattern enables human-in-the-loop review.

Function calling

The chatbot integration maps function names to platform operations by convention. A function named output_invoices resolves to /api/o/invoices. No custom routing code.

Infrastructure

Runtime
.NET Core (Linux-native)
Primary DBs
MySQL / MariaDB, SQL Server
External DB sync
MySQL, SQL Server, ODBC
Cache
In-process (single instance) / Redis (multi-instance)
Storage
Local filesystem / AWS S3
Cloud
AWS ECS / Fargate / ALB
Config
AWS Secrets Manager
AI
OpenAI, Anthropic, Google Gemini, xAI Grok
SMS
Twilio
Email
SMTP (outbound) / IMAP (inbound)

Deployment model

Each client runs dbo in their own VPC. No shared infrastructure between clients. Source provided under client agreement for operational continuity and trust.

Multi-tenancy

Account (organization) → Instance (application environment). Physical database isolation per instance. Tenant-aware caching with strict partition isolation.

Ready to stop writing the middle tier?

dbo.io is invite-only. We work with a small number of early partners to make sure the integration is set up right. Tell us about what you're building.