Record types and fields API

List and create record types and menu groups, add fields with rules, and set auto-numbering, formulas and descriptions.

Record types describe what a workspace stores (an invoice, a customer, a work order). Fields describe what each record of a type holds. These routes read and change that structure, the same things you edit in the product's record type and field settings.

Endpoints

Method Path Permission What it does
GET /orgs/{orgId}/types types:read List record types
POST /orgs/{orgId}/types types:create Create a record type
PATCH /orgs/{orgId}/types/{typeKey} types:update Change label, icon, app, layout hints or description
DELETE /orgs/{orgId}/types/{typeKey} types:delete Delete a custom record type
GET /orgs/{orgId}/modules any member List menu groups
POST /orgs/{orgId}/modules org:update Create or update a menu group
DELETE /orgs/{orgId}/modules/{slug} org:update Delete a menu group
GET /orgs/{orgId}/fields?entity_type={typeKey} fields:read List a type's fields
POST /orgs/{orgId}/fields fields:create Add a field
DELETE /orgs/{orgId}/fields/{fieldId} fields:delete Delete a custom field
PUT /orgs/{orgId}/fields/{fieldId}/autogen fields:create Turn on auto-numbering
DELETE /orgs/{orgId}/fields/{fieldId}/autogen fields:create Turn off auto-numbering
PUT /orgs/{orgId}/fields/{fieldId}/formula fields:create Make a field computed
DELETE /orgs/{orgId}/fields/{fieldId}/formula fields:create Make it an ordinary field again
PUT /orgs/{orgId}/fields/{fieldId}/description fields:create Set the field description
PUT /orgs/{orgId}/fields/{fieldId}/ref-type fields:create Point a reference field at another type

The field permissions are checked against the record type: you need fields:create on that type (resource = type key).

Record types

The type object

{
  "id": "0190f0aa-…",
  "key": "work_orders",
  "label": "Work order",
  "icon": "ledger",
  "app": "operations",
  "ui": { "lines": { "type": "work_order_lines", "ref": "work_order" } },
  "description": "Jobs raised for the workshop",
  "record_count": 128,
  "created_at": "2026-10-01T08:00:00Z"
}

Built-in types (such as invoices, payments, accounts, locations) have "system": true and no id. They cannot be deleted.

POST /orgs/{orgId}/types

Field Type Required Notes
key string Yes Lowercase letters, digits and underscores, starting with a letter, 2 to 32 characters. Cannot be changed later. Must be unused
label string Yes 1 to 100 characters
icon string No An icon name, up to 32 characters
app string No The menu group (module slug) the type is filed under
ui string No Layout hints as a JSON string, up to 2048 characters: {"child":true} for a type that only exists under another, or {"lines":{"type":"child_type_key","ref":"ref_field_key"}} for line items
curl -s -X POST https://axisiq.co/api/v1/orgs/$ORG/types \
  -H "Authorization: Bearer $AXIS_KEY" -H "Content-Type: application/json" \
  -d '{"key": "work_orders", "label": "Work order", "app": "operations"}'

Response 201 with the type object. Errors: 400 VALIDATION_ERROR (key or label rule), 409 KEY_TAKEN, 402 LIMIT_EXCEEDED.

PATCH /orgs/{orgId}/types/{typeKey}

Send only what changes: label, icon, app, ui, description. Response 200 with the type object.

DELETE /orgs/{orgId}/types/{typeKey}

Returns 204 No Content. Built-in types answer 403 FORBIDDEN.

Important: Deleting a type removes its records and fields from the workspace. This cannot be undone.

A module is a group in the main menu that record types are filed under.

{ "slug": "operations", "name": "Operations", "glyph": "ledger", "category": "Operations", "position": 10 }

POST /modules creates or updates by slug (required, up to 32 characters; name required, up to 100; glyph, category up to 32; position a number). DELETE /modules/{slug} returns 204.

Fields

The field object

{
  "id": "0190f0bb-…",
  "entity_type": "invoices",
  "key": "po_number",
  "label": "PO number",
  "type": "string",
  "required": false,
  "unique": true,
  "immutable": false,
  "autogen": "",
  "description": "Customer purchase order",
  "rules": { "max_len": 40 },
  "created_at": "2026-10-01T08:05:00Z"
}

system: true marks fields built into a built-in type. They cannot be changed or deleted.

Field types

string, text, number, bool, date, datetime, currency, select, multiselect, email, url, file, ref, refs. How each is sent and read is in Records.

POST /orgs/{orgId}/fields

Field Type Required Notes
entity_type string Yes The record type key. Must exist
key string Yes Lowercase letters, digits and underscores, starting with a letter, 2 to 64 characters. Unique within the type. Some names, such as id and created_at, are reserved
label string Yes 1 to 100 characters
type string Yes One of the types above
required boolean No The record cannot be saved or updated without it
unique boolean No No two records may hold the same value
immutable boolean No Can be set when the record is created but never changed afterwards
rules object No See below
description string No Up to 255 characters

rules

Key Applies to Meaning
min_len, max_len text fields Length bounds
pattern string A regular expression the value must match
min, max number, currency Range of the amount
options select, multiselect The allowed values. At least one is required
unit currency An ISO 4217 code that fixes the field to one currency
ref_type ref, refs The record type key the reference points at. Required
default any A value applied when a record is created without one. It must pass the field's own rules
formula any Makes the field computed. Set through the formula route instead
curl -s -X POST https://axisiq.co/api/v1/orgs/$ORG/fields \
  -H "Authorization: Bearer $AXIS_KEY" -H "Content-Type: application/json" \
  -d '{"entity_type":"invoices","key":"channel","label":"Channel","type":"select","rules":{"options":["web","store","phone"],"default":"web"}}'

Response 201 with the field object. Errors: 400 VALIDATION_ERROR, 403 FORBIDDEN, 409 KEY_TAKEN.

GET /orgs/{orgId}/fields

Pass entity_type (required; permission fields:read on that type) to list one type's fields; the response is an array of field objects, built-in fields included.

DELETE /orgs/{orgId}/fields/{fieldId}

Returns 204 No Content. A field that a computed field's formula reads is refused (400 VALIDATION_ERROR) until that formula is removed. Built-in fields answer 404 NOT_FOUND.

Important: Deleting a field discards the values stored in it for every record.

PUT /orgs/{orgId}/fields/{fieldId}/autogen

Fill a string field automatically when a record is created without a value. A value you supply always wins. Other field types and computed fields are refused with 400 VALIDATION_ERROR.

Field Type Required Notes
pattern string Yes Text with tokens. Exactly one {seq} token is required
next number No When above 0, the next number issued is at least this, for continuing an existing numbering

Tokens:

Token Meaning
{seq} Running number
{seq:4} Running number padded with zeros to 4 digits (1 to 10)
{seq:4:yearly} As above, restarting each daily, monthly or yearly period. A restarting pattern must include the period's date tokens
{yyyy} {yy} {mm} {dd} Creation date (UTC)

Example: INV/{yyyy}/{seq:4:yearly} produces INV/2026/0001. Patterns are up to 100 characters. Response 200 with the field object. DELETE on the same path turns it off (204).

PUT /orgs/{orgId}/fields/{fieldId}/formula

Make a custom field computed from other fields of the same record.

{ "formula": "price - cost" }

Fields are referenced by key. IF(status="paid", total, 0) style expressions are supported, using the same formula language as Sheets. A computed field is recomputed by the platform on every write, cannot be written to directly, and holds an empty value when the formula cannot be evaluated. Existing records are recalculated shortly after you save. DELETE on the same path makes it an ordinary field (204). Response 200 with the field object; 400 VALIDATION_ERROR for a bad formula.

PUT /orgs/{orgId}/fields/{fieldId}/description

{ "description": "Customer purchase order number" }

An empty string clears it. Maximum 255 characters. Response 200 with the field object.

PUT /orgs/{orgId}/fields/{fieldId}/ref-type

{ "ref_type": "customers" }

Re-points a ref or refs field at another existing record type. Ids already stored are not changed. Response 200 with the field object.