Add Table Field
curl --request POST \
--url https://tables-api.softr.io/api/v1/databases/{databaseId}/tables/{tableId}/fields \
--header 'Content-Type: application/json' \
--header 'Softr-Api-Key: <api-key>' \
--data '
{
"name": "<string>",
"type": "<string>",
"options": {}
}
'import requests
url = "https://tables-api.softr.io/api/v1/databases/{databaseId}/tables/{tableId}/fields"
payload = {
"name": "<string>",
"type": "<string>",
"options": {}
}
headers = {
"Softr-Api-Key": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'Softr-Api-Key': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({name: '<string>', type: '<string>', options: {}})
};
fetch('https://tables-api.softr.io/api/v1/databases/{databaseId}/tables/{tableId}/fields', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://tables-api.softr.io/api/v1/databases/{databaseId}/tables/{tableId}/fields",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'name' => '<string>',
'type' => '<string>',
'options' => [
]
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"Softr-Api-Key: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://tables-api.softr.io/api/v1/databases/{databaseId}/tables/{tableId}/fields"
payload := strings.NewReader("{\n \"name\": \"<string>\",\n \"type\": \"<string>\",\n \"options\": {}\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Softr-Api-Key", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://tables-api.softr.io/api/v1/databases/{databaseId}/tables/{tableId}/fields")
.header("Softr-Api-Key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"name\": \"<string>\",\n \"type\": \"<string>\",\n \"options\": {}\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://tables-api.softr.io/api/v1/databases/{databaseId}/tables/{tableId}/fields")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Softr-Api-Key"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"name\": \"<string>\",\n \"type\": \"<string>\",\n \"options\": {}\n}"
response = http.request(request)
puts response.read_body{
"data": {
"id": "<string>",
"name": "<string>",
"description": "<string>",
"options": {},
"allowMultipleEntries": true,
"readonly": true,
"required": true,
"locked": true,
"defaultValue": "<string>",
"aiOptions": {
"aiFillable": true,
"aiOnly": true,
"allowWebSearch": true,
"aiModel": "<string>",
"prompt": "<string>",
"canBeTriggeredManually": true,
"runWhenRecordIsCreated": true,
"runWhenRecordIsUpdated": true
},
"createdAt": "2023-11-07T05:31:56Z",
"updatedAt": "2023-11-07T05:31:56Z"
}
}Table Fields
Add Table Field
Add a new field to a table.
POST
/
databases
/
{databaseId}
/
tables
/
{tableId}
/
fields
Add Table Field
curl --request POST \
--url https://tables-api.softr.io/api/v1/databases/{databaseId}/tables/{tableId}/fields \
--header 'Content-Type: application/json' \
--header 'Softr-Api-Key: <api-key>' \
--data '
{
"name": "<string>",
"type": "<string>",
"options": {}
}
'import requests
url = "https://tables-api.softr.io/api/v1/databases/{databaseId}/tables/{tableId}/fields"
payload = {
"name": "<string>",
"type": "<string>",
"options": {}
}
headers = {
"Softr-Api-Key": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'Softr-Api-Key': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({name: '<string>', type: '<string>', options: {}})
};
fetch('https://tables-api.softr.io/api/v1/databases/{databaseId}/tables/{tableId}/fields', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://tables-api.softr.io/api/v1/databases/{databaseId}/tables/{tableId}/fields",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'name' => '<string>',
'type' => '<string>',
'options' => [
]
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"Softr-Api-Key: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://tables-api.softr.io/api/v1/databases/{databaseId}/tables/{tableId}/fields"
payload := strings.NewReader("{\n \"name\": \"<string>\",\n \"type\": \"<string>\",\n \"options\": {}\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Softr-Api-Key", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://tables-api.softr.io/api/v1/databases/{databaseId}/tables/{tableId}/fields")
.header("Softr-Api-Key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"name\": \"<string>\",\n \"type\": \"<string>\",\n \"options\": {}\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://tables-api.softr.io/api/v1/databases/{databaseId}/tables/{tableId}/fields")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Softr-Api-Key"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"name\": \"<string>\",\n \"type\": \"<string>\",\n \"options\": {}\n}"
response = http.request(request)
puts response.read_body{
"data": {
"id": "<string>",
"name": "<string>",
"description": "<string>",
"options": {},
"allowMultipleEntries": true,
"readonly": true,
"required": true,
"locked": true,
"defaultValue": "<string>",
"aiOptions": {
"aiFillable": true,
"aiOnly": true,
"allowWebSearch": true,
"aiModel": "<string>",
"prompt": "<string>",
"canBeTriggeredManually": true,
"runWhenRecordIsCreated": true,
"runWhenRecordIsUpdated": true
},
"createdAt": "2023-11-07T05:31:56Z",
"updatedAt": "2023-11-07T05:31:56Z"
}
}Field Types Reference
Editable Fields
| Type | Value Format | Description |
|---|---|---|
SINGLE_LINE_TEXT | string | Short text |
LONG_TEXT | string | Multi-line text |
EMAIL | string | Email address |
PHONE | string | Phone number |
URL | string | Web URL |
NUMBER | number | Numeric value |
CURRENCY | number | Monetary amount |
PERCENT | number | Percentage (0–100) |
RATING | number | Star rating |
DURATION | number | Duration |
CHECKBOX | boolean | True/false |
SELECT | string or array | Single or multi-select from predefined choices |
USER | object or array | User reference |
LINKED_RECORD | string or array | Link to record(s) in another table |
ATTACHMENT | object or array | File attachment |
DATE | string | Date (ISO 8601) |
DATETIME | string | Date and time (ISO 8601) |
Read-Only Fields
These are computed or system-managed and cannot be set when creating or updating records.| Type | Description |
|---|---|
LOOKUP | Value from a linked record’s field |
ROLLUP | Aggregation over linked records |
FORMULA | Calculated from a formula expression |
CREATED_AT | Record creation timestamp |
UPDATED_AT | Record last modified timestamp |
CREATED_BY | User who created the record |
UPDATED_BY | User who last modified the record |
AUTONUMBER | Auto-incrementing number |
RECORD_ID | System record identifier |
Field Options
Type-specific configuration passed in theoptions object when creating or updating fields.
SELECT
{
"choices": [
{ "id": "choice-1", "label": "Option A", "color": "#FF0000" },
{ "id": "choice-2", "label": "Option B", "color": "#00FF00" }
],
"allowToAddNewChoice": true,
"sorting": "CUSTOM",
"enforceOrder": false
}
sorting can be CUSTOM, ALPHA_ASC, or ALPHA_DESC.
NUMBER
{
"precision": 2,
"min": 0,
"max": 1000000,
"showThousandSeparator": true,
"thousandSeparatorLocale": "en-US",
"largeNumberAbbreviation": "NONE",
"prefix": null,
"suffix": null
}
largeNumberAbbreviation can be NONE, K, M, B, or T.
CURRENCY
{
"precision": 2,
"min": null,
"max": null,
"isoCode": "USD",
"customSymbol": null,
"showAs": "SYMBOL",
"showThousandSeparator": true,
"thousandSeparatorLocale": "en-US",
"largeNumberAbbreviation": "NONE",
"symbolOrCodePosition": "BEFORE"
}
showAs:SYMBOLorCODEsymbolOrCodePosition:BEFOREorAFTER
LINKED_RECORD
{
"linkedTableId": "table-uuid",
"inverseLinkFieldId": "field-uuid",
"viewId": null,
"sorting": [],
"filter": null,
"enforceOrder": false
}
LOOKUP
{
"linkedRecordFieldId": "field-uuid",
"lookupFieldId": "field-uuid",
"isValid": true
}
ROLLUP
{
"linkedRecordFieldId": "field-uuid",
"rollupFieldId": "field-uuid",
"function": "SUM",
"filter": null
}
SUM, MIN, MAX, COUNT, AVERAGE, ARRAYCOMPACT, ARRAYJOIN, ARRAYUNIQUE, ARRAYFLATTEN, CONCATENATE, COUNTALL, COUNTA, OR, AND.
ATTACHMENT
{
"showAs": "PREVIEW",
"inferredFileType": "OTHER",
"enableFileLinkExpiration": true,
"fileLinkExpirationValue": 2,
"fileLinkExpirationUnit": "HOURS"
}
showAs:PREVIEW,LIST, orBADGEinferredFileType:IMAGE,VIDEO,PDF,AUDIO, orOTHERfileLinkExpirationUnit:HOURSorMINUTES
FORMULA
{
"formula": "IF({Status} = 'Active', {Amount} * 1.1, {Amount})",
"isValid": true,
"referencedFieldIds": ["field-uuid-1", "field-uuid-2"]
}
AI Options
Fields can include anaiOptions object that configures AI-powered auto-fill behavior. This is returned in field definitions and can be set when creating or updating fields.
{
"aiFillable": true,
"aiOnly": false,
"allowWebSearch": true,
"aiModel": "GPT_4_1",
"prompt": "Summarize the customer's request based on {Description}",
"canBeTriggeredManually": true,
"runWhenRecordIsCreated": true,
"runWhenRecordIsUpdated": false
}
| Property | Type | Default | Description |
|---|---|---|---|
aiFillable | boolean | false | Whether AI can fill this field |
aiOnly | boolean | true | If true, only AI can write to this field |
allowWebSearch | boolean | false | Allow AI to use web search when filling |
aiModel | string | "GPT_4_1" | AI model to use |
prompt | string | "" | Prompt template (reference other fields with {FieldName}) |
canBeTriggeredManually | boolean | true | Whether users can trigger AI fill manually |
runWhenRecordIsCreated | boolean | true | Auto-run when record is created |
runWhenRecordIsUpdated | boolean | true | Auto-run when record is updated |
"aiOptions": null.Was this page helpful?
⌘I