Records API

Create, read, search, filter, sort, update and delete records, import and export CSV, and read the change history.

Records are the rows of your workspace: invoices, customers, products, or any record type you create. This API creates, reads, searches, updates and deletes them, imports and exports CSV, and reads their change history.

Every record type works the same way, so one set of routes covers all of them. {typeKey} is the key of the record type, such as invoices. List your types with GET /types.

Endpoints

Method Path Permission What it does
POST /orgs/{orgId}/records/{typeKey} records:create Create a record
GET /orgs/{orgId}/records/{typeKey} records:read List records, or search, filter and sort them
GET /orgs/{orgId}/records/{typeKey}/{recordId} records:read Get one record
PUT /orgs/{orgId}/records/{typeKey}/{recordId}/values records:update Change field values
GET /orgs/{orgId}/records/{typeKey}/{recordId}/values records:read Read just the values
DELETE /orgs/{orgId}/records/{typeKey}/{recordId} records:delete Delete a record
GET /orgs/{orgId}/records/{typeKey}/export records:export Download CSV
POST /orgs/{orgId}/records/{typeKey}/import records:import Create records from CSV
GET /orgs/{orgId}/audit audit:read Change history

Permissions can be limited to a record type (the resource is the type key) and can carry conditions such as "only records you own". A record that fails the condition reads as not found. See Policy format.

The record object

{
  "id": "0190f0aa-7c1e-7a3b-9d52-4f0e6c1b2a10",
  "object_type": "invoices",
  "created_by": "0190f0a0-3b44-7d10-8a21-90c4e7f01d55",
  "created_at": "2026-10-04T09:30:00Z",
  "updated_at": "2026-10-04T09:30:00Z",
  "values": {
    "number": "INV-1001",
    "status": "open",
    "issue_date": "2026-10-04",
    "amount": { "amount": 12500, "code": "INR" }
  }
}

values is keyed by field key. Fields your role may not read are left out.

Value formats

Field type Send Read back
string, text, email, url string. Email must be a valid address; URL must be absolute http or https string
number number or numeric string, up to 14 digits before and 6 after the decimal point number
currency {"amount": 12500, "code": "INR"}, or a bare number {"amount": …, "code": "INR"}
bool true or false (the strings "true"/"false" are accepted) boolean
date "2026-10-04" string
datetime RFC 3339, such as "2026-10-04T09:30:00Z" RFC 3339 in UTC
select one of the field's options string
multiselect array of options, no duplicates, at most 100 array
ref the UUID of another record string
refs array of record UUIDs, at most 100 array
file a Drive key (text) string

Text limits: string up to 500 characters, text up to 100,000. Sending null clears a field unless it is required. Computed fields (formula fields) are read-only: any value you send for them is ignored.

POST /orgs/{orgId}/records/{typeKey}

Create a record. Permission: records:create.

Request

Field Type Required Notes
values object No Field values by key. Required fields must be present unless they have a default or an auto-numbering pattern. An empty body creates an empty record if no field is required
curl -s -X POST https://axisiq.co/api/v1/orgs/$ORG/records/invoices \
  -H "Authorization: Bearer $AXIS_KEY" -H "Content-Type: application/json" \
  -d '{"values": {"number": "INV-1002", "status": "open", "amount": {"amount": "980.50", "code": "INR"}}}'

Response 201 with the record object.

Errors

Status Code When
400 VALIDATION_ERROR A value breaks its field's type or rules, or a required field is missing
403 FORBIDDEN The role lacks records:create for this type, or a condition fails on the new values
404 NOT_FOUND No such record type
402 LIMIT_EXCEEDED A free-plan cap was reached
409 DUPLICATE_VALUE A unique field already holds the value

GET /orgs/{orgId}/records/{typeKey}

List records. Newest first. Permission: records:read.

There are two modes. The mode is chosen by the parameters you send.

Plain listing (cursor paging)

Parameter Notes
limit 1 to 200, default 50
cursor The next_cursor from the previous page
ref_field and ref_id Together: only records whose reference field ref_field points at the record ref_id. For example the lines of one order
{
  "data": {
    "records": [ { "id": "0190f0aa-…", "object_type": "invoices", "values": { "…": "…" } } ],
    "next_cursor": "0190f0a9-…"
  }
}

When there are no more pages next_cursor is absent. Records your role may not read are skipped, so a page can hold fewer than limit items even when more exist; keep following next_cursor until it is absent.

Search mode (offset paging)

Use any of q, filter, sort, page or offset to search.

Parameter Notes
q Text to find. Matches any text field (string or text type) that contains it
filter A JSON array of conditions, URL-encoded. All conditions must match
sort A field key, or created_at. Default is newest first
dir asc or desc. Default desc
limit 1 to 200, default 50
page 1-based page number
offset Start position, instead of page
{ "data": { "records": [ … ], "total": 137 } }

total counts only the records you may read.

Filter syntax

[
  { "field": "status", "op": "eq", "value": "open" },
  { "field": "amount", "op": "gte", "value": "10000" },
  { "field": "issue_date", "op": "lt", "value": "2026-10-01" }
]

value is always a string. The operators you can use depend on the field type:

Field type Operators
string, text, select, email, url eq, ne, contains (the default when op is omitted)
number, currency eq (default), ne, gt, gte, lt, lte. The value must be a number. Currency compares the amount
date, datetime eq (default), ne, gt, gte, lt, lte. The value is YYYY-MM-DD or RFC 3339
bool eq, with "true" or "false"
ref eq, with a record id
refs, multiselect Not filterable or sortable

Fields your role cannot read cannot be filtered on, sorted by, or matched by q. Doing so is a 400 VALIDATION_ERROR.

curl -s -G https://axisiq.co/api/v1/orgs/$ORG/records/invoices \
  -H "Authorization: Bearer $AXIS_KEY" \
  --data-urlencode 'q=acme' \
  --data-urlencode 'filter=[{"field":"status","op":"eq","value":"open"}]' \
  --data-urlencode 'sort=due_date' --data-urlencode 'dir=asc' \
  --data-urlencode 'limit=100'

Errors: 400 VALIDATION_ERROR (bad limit, page, offset, or a filter that is not a JSON array of {field, op, value}), 403 FORBIDDEN (no way to read this type), 404 NOT_FOUND (no such type).

GET /orgs/{orgId}/records/{typeKey}/{recordId}

Get one record. Permission: records:read. Returns the record object. A record you may not read answers 404 NOT_FOUND.

PUT /orgs/{orgId}/records/{typeKey}/{recordId}/values

Change values on a record. Fields you do not send are left alone. Permission: records:update.

Request

{ "values": { "status": "paid", "amount": { "amount": "980.50", "code": "INR" } } }
Field Type Required Notes
values object Yes Field values by key. null clears a field

Response 204 No Content.

Fields marked write-once (immutable) cannot be changed after creation. A required field cannot be cleared.

Errors

Status Code When
400 VALIDATION_ERROR Body is not {"values": {...}}, or a value breaks its rules
403 FORBIDDEN The role lacks records:update for this record
404 NOT_FOUND No such record, or you may not read it
409 DUPLICATE_VALUE A unique field already holds the value

GET /orgs/{orgId}/records/{typeKey}/{recordId}/values

Returns {"data": {"values": { … }}} with the readable values.

DELETE /orgs/{orgId}/records/{typeKey}/{recordId}

Delete a record. Permission: records:delete. Returns 204 No Content.

Important: Deleting a record cannot be undone through the API. Other records that reference it keep the id and will show a missing reference.

GET /orgs/{orgId}/records/{typeKey}/export

Download the records of a type as CSV. Permission: records:export (and read access to the type).

  • The first row is id, created_at, then every field key.
  • Only records and fields your role may read are included.
  • At most 10,000 records. If there were more, the response header X-Export-Truncated: true is set.
  • A cell that a spreadsheet could read as a formula (starting with =, +, -, @) gets a leading '. Plain numbers and phone numbers are left as they are. Import removes the same '.
  • Currency cells read 12500 INR. List cells (refs, multiselect) are JSON arrays.
curl -s https://axisiq.co/api/v1/orgs/$ORG/records/invoices/export \
  -H "Authorization: Bearer $AXIS_KEY" -o invoices.csv

POST /orgs/{orgId}/records/{typeKey}/import

Create records from a CSV. Permission: records:import.

Send either a multipart upload with a file field, or the CSV as the raw body with Content-Type: text/csv.

curl -s -X POST https://axisiq.co/api/v1/orgs/$ORG/records/invoices/import \
  -H "Authorization: Bearer $AXIS_KEY" -H "Content-Type: text/csv" \
  --data-binary @invoices.csv
  • The first row is a header. Each column name must be a field key; other columns (including id and created_at) are ignored.
  • Up to 500 data rows per request. More is a 400 VALIDATION_ERROR: split the file.
  • Empty cells are left unset, so defaults and auto-numbering still apply.
  • Cell formats: booleans true/false; refs and multiselect as a JSON array or values separated by |; currency as 12500 INR or a bare amount.
  • Rows are independent. A bad row is reported and skipped and the others are still created.

Response

{
  "data": {
    "created": 48,
    "failed": 2,
    "errors": [
      { "row": 7, "message": "amount: expected a number" },
      { "row": 19, "message": "a unique field already holds this value" }
    ]
  }
}

row counts data rows starting at 1, not counting the header.

GET /orgs/{orgId}/audit

The change history of records. Permission: audit:read.

Parameter Notes
object_type Record type key
record_id One record
actor A person's or service account's id
action record.created, record.updated or record.deleted
from, to RFC 3339 range
limit Default 50, maximum 200
offset Start position
{
  "data": {
    "entries": [
      {
        "id": "0190f0ab-…",
        "actor_id": "0190f0a0-…",
        "actor_type": "service",
        "action": "record.updated",
        "object_type": "invoices",
        "record_id": "0190f0aa-…",
        "before": { "status": "open" },
        "after": { "status": "paid" },
        "request_id": "9f2c41a0b7d3e655",
        "created_at": "2026-10-04T10:02:11Z"
      }
    ],
    "total": 1
  }
}

actor_type is user, service (an access key) or system (a change made by the platform itself with no signed-in caller).