Object endpoints
All object operations live on a single controller, ObjectController, under:
/api/v1/genie/objectEvery endpoint is [Authorize]. An object is addressed by its name (the view name/slug). The
former separate /table and /form controllers, and the legacy GET /metadata/{name} and
POST /object/values routes, no longer exist — everything is unified here.
Schema & data
Section titled “Schema & data”| Method | Route | Returns | Purpose | Gate |
|---|---|---|---|---|
GET |
/{name}/metadata |
MetadataResult |
SQL-free schema (the ObjectView with SQL stripped). The UI decides table vs form vs view from this. Static & cacheable. |
auth only |
POST |
/{name}/table |
TableResult |
A page of grid rows + pagination + per-user permission facts. | View |
POST |
/{name}/form |
FormResult |
A record’s field values for an editable form (first row of the form SQL). | View / Update |
POST |
/{name}/view |
FormResult |
A record’s field values for a read-only view (view mode forced). | View |
POST /{name}/table accepts a TableRequest body (filters, search text, sort, page/pageSize).
POST /{name}/form and /{name}/view accept a FormRequest body (the record’s primary-key /
parent parameters). An omitted body is treated as an empty request.
The TableResult/FormResult permission facts (Permissions) carry the standard verb booleans
(Create/Update/Delete/Export/Import) plus a Capabilities list naming the caller’s
business capabilities beyond them (e.g. ["Approve"]). Rows returned by
/table and /form//view, and exports, are already row-filtered by the
caller’s List filter, and each row may carry Permit__<Capability> cells answering
per-row conditions.
Mutations
Section titled “Mutations”| Method | Route | Returns | Purpose | Gate |
|---|---|---|---|---|
POST |
/submit |
ObjectActionResult |
Create or update a record (SubmitRequest — requires FormName). |
Create / Update |
POST |
/delete-row |
ObjectActionResult |
Delete a row (DeleteRowRequest). |
Delete |
POST |
/execute-row-action |
ObjectActionResult |
Run a declared row action’s SQL (ExecuteRowActionRequest). |
per action |
Mutation results can carry dispatch envelopes (e.g. refreshTable, showAlert) that tell the
UI what to do next — see Actions & row actions.
Optimistic concurrency (409)
Section titled “Optimistic concurrency (409)”When an entity declares Concurrency="Enabled", the record’s
RowVersion stamp is loaded with the form and sent back in SubmitRequest.Parameters (and, for the
atomic authored-SQL path, DeleteRowRequest.RowVersion). If the stored stamp has moved on since the
record was loaded, the mutation is rejected with HTTP 409 Conflict (envelope
{ "success": false, "error": "This record was changed by someone else…" }) instead of silently
overwriting the other change. RowVersion is a reserved parameter — it passes the mass-assignment
sanitizer and is never written as data.
Form load time
Section titled “Form load time”FormResult (the /{name}/form and /{name}/view payload) carries FormLoadTime — the UTC instant
(ISO round-trip) at which the record was loaded, stamped server-side. Like RowVersion it is a reserved
parameter the client sends back in SubmitRequest.Parameters, and the submit binds it as
@FormLoadTime for the authored SQL (falling back to “now” when a caller supplies none). It is never
written as data. Being client-round-tripped it can be replayed — treat it as an audit/heuristic value, not
a security control. See Parameters the submit blocks always receive.
Field validation (400)
Section titled “Field validation (400)”A submit (or /import-data) that fails field validation — required, RegexValidation, a type bound, or
an author-declared <Validate> rule — is rejected with HTTP 400 whose envelope carries fieldErrors
(field name → message) alongside error, so the client can highlight and focus the offending field. Rules
declared Type="Sql" run server-side only, which is exactly why the response has to name the field. See
Validation.
Idempotency (safe retry)
Section titled “Idempotency (safe retry)”Every mutation above (plus /import-data and /upload) honours an optional Idempotency-Key
request header. Send a unique key with a write and the engine remembers the first response (scoped per
user + company, for Genie:Idempotency:Ttl, default 24 h); a repeat of the same key replays that
response instead of re-running the mutation — so a network retry or double-submit can’t create
duplicate rows. A duplicate that arrives while the first is still in flight gets a 409. Configure via
Genie:Idempotency; omit the header to opt out per request.
Export & import
Section titled “Export & import”| Method | Route | Returns | Purpose | Gate |
|---|---|---|---|---|
POST |
/export-data |
ObjectActionResult |
Generate an export file under wwwroot/Exports (ExportTableRequest). |
View / Export |
GET |
/export-file/{fileName} |
file stream | Download a previously-generated export as an authenticated attachment. Bare file name only; traversal rejected. | auth |
POST |
/import-data |
ObjectActionResult |
Bulk import (ImportTableRequest, multipart form). Body cap from Genie:Uploads:MaxImportBytes (default 1 GiB). |
Import |
GET |
/{name}/import-template?format=xlsx|csv |
ObjectActionResult |
Generate a header-only import template; download via export-file. |
Import |
Import/export column mapping and custom handlers are authored in the view — see Bulk import & handlers.
Field datasets, sequences & uploads
Section titled “Field datasets, sequences & uploads”| Method | Route | Returns | Purpose |
|---|---|---|---|
POST |
/field-dataset |
List<Dictionary<string,string>> |
Options for a dependent Select field (FieldDataSetRequest — requires FormName + FieldName). |
POST |
/sequence-number |
string |
Preview/reserve a formatted sequence number (SequenceNumberRequest). See Sequences. |
POST |
/upload |
List<FileUploadResult> |
Upload temporary attachment files (multipart: objectName, fieldName, viewId). Size limit 100 MB. |
DELETE |
/upload/{uploadKey} |
message | Remove a temporary uploaded file before submit. |
GET |
/label/{objectName} |
string |
The view’s display label. |
Related object controllers
Section titled “Related object controllers”GET/POST /api/v1/genie/object-explorer/...— the object explorer surface./api/v1/genie/rpc/...— stored-procedure / RPC calls (ProcedureCallController).
See Other endpoints for the non-object controllers.