Create Transaction Custom Field
Creates a team-level custom field for transactions and returns it, id included, so the id can be used straight away when populating LeadTransaction.customFields.
Place the field in at least one group. A field belonging to no field group is invisible - it will not show on the transaction detail page, as a list column, or in filters. Pass formIds from GET /v1.0/transaction/forms, or place it from the CRM UI afterwards.
Differences from the lead custom field API worth knowing: anniversary_date does not exist on transactions, html is not offered, and the option list for select types is a bare JSON array, though the lead API’s shape, that same array wrapped in an object under an option key, is accepted here too and normalised.
Scope: the caller’s team.
curl --request POST \
--url https://api.lofty.com/v1.0/transaction/customfields \
--header 'Authorization: <authorization>' \
--header 'Content-Type: <content-type>' \
--data '
{
"attributeName": "Mailer Sent",
"attributeType": "date",
"params": "[\"Pending\",\"Closed\"]",
"formIds": [
301
]
}
'import requests
url = "https://api.lofty.com/v1.0/transaction/customfields"
payload = {
"attributeName": "Mailer Sent",
"attributeType": "date",
"params": "[\"Pending\",\"Closed\"]",
"formIds": [301]
}
headers = {
"Authorization": "<authorization>",
"Content-Type": "<content-type>"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: '<authorization>', 'Content-Type': '<content-type>'},
body: JSON.stringify({
attributeName: 'Mailer Sent',
attributeType: 'date',
params: '["Pending","Closed"]',
formIds: [301]
})
};
fetch('https://api.lofty.com/v1.0/transaction/customfields', 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://api.lofty.com/v1.0/transaction/customfields",
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([
'attributeName' => 'Mailer Sent',
'attributeType' => 'date',
'params' => '["Pending","Closed"]',
'formIds' => [
301
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: <authorization>",
"Content-Type: <content-type>"
],
]);
$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://api.lofty.com/v1.0/transaction/customfields"
payload := strings.NewReader("{\n \"attributeName\": \"Mailer Sent\",\n \"attributeType\": \"date\",\n \"params\": \"[\\\"Pending\\\",\\\"Closed\\\"]\",\n \"formIds\": [\n 301\n ]\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "<authorization>")
req.Header.Add("Content-Type", "<content-type>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.lofty.com/v1.0/transaction/customfields")
.header("Authorization", "<authorization>")
.header("Content-Type", "<content-type>")
.body("{\n \"attributeName\": \"Mailer Sent\",\n \"attributeType\": \"date\",\n \"params\": \"[\\\"Pending\\\",\\\"Closed\\\"]\",\n \"formIds\": [\n 301\n ]\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.lofty.com/v1.0/transaction/customfields")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = '<authorization>'
request["Content-Type"] = '<content-type>'
request.body = "{\n \"attributeName\": \"Mailer Sent\",\n \"attributeType\": \"date\",\n \"params\": \"[\\\"Pending\\\",\\\"Closed\\\"]\",\n \"formIds\": [\n 301\n ]\n}"
response = http.request(request)
puts response.read_body{
"id": 1001,
"name": "Closing Agent",
"type": "Single-Select",
"params": "[{\"label\":\"Option A\",\"value\":\"1\"},{\"label\":\"Option B\",\"value\":\"2\"}]"
}"<string>""<string>""<string>"Body
Custom field definition.
Display name for the new field. Trimmed before use, and checked for collisions against both existing custom fields and the built-in transaction fields.
"Mailer Sent"
Field data type.
Note two differences from the lead custom field API: anniversary_date does not exist on transactions and is rejected, and html is not offered here.
text, number, date, percentage, currency, single_select, multi_select "date"
Option list, required for single_select and multi_select and ignored otherwise.
Both shapes are accepted and normalised: a bare JSON array ["Pending","Closed"], or the lead API's wrapper {"option":["Pending","Closed"]}. Sending an empty list for a select type is rejected.
"[\"Pending\",\"Closed\"]"
Field groups to place the new field in, from GET /v1.0/transaction/forms.
A field in no group is invisible - it will not appear on the transaction detail page, as a list column, or in filters. Omit this only if you intend to place the field from the CRM UI afterwards.
Every id is validated before the field is created, so a bad id fails the whole request rather than leaving an orphaned field behind. A group already at its 50-field limit is rejected the same way.
Field groups to place the new field in, from GET /v1.0/transaction/forms.
A field in no group is invisible - it will not appear on the transaction detail page, as a list column, or in filters. Omit this only if you intend to place the field from the CRM UI afterwards.
Every id is validated before the field is created, so a bad id fails the whole request rather than leaving an orphaned field behind. A group already at its 50-field limit is rejected the same way.
[301]
Response
The field that was created, id included.
Custom field id.
1001
Custom field display name.
"Closing Agent"
Custom field data type. Note the mixed casing: Single-Select and Multi-Select are emitted with hyphens and mixed case, while the other values are the upper-case enum names.
DATE, TEXT, NUMBER, PERCENTAGE, Single-Select, Multi-Select, CURRENCY, HTML "Single-Select"
For Single-Select and Multi-Select types, a JSON string encoding the option list, e.g. "[{"label":"Option A","value":"1"},{"label":"Option B","value":"2"}]". Empty or null for non-select types.
"[{\"label\":\"Option A\",\"value\":\"1\"},{\"label\":\"Option B\",\"value\":\"2\"}]"
curl --request POST \
--url https://api.lofty.com/v1.0/transaction/customfields \
--header 'Authorization: <authorization>' \
--header 'Content-Type: <content-type>' \
--data '
{
"attributeName": "Mailer Sent",
"attributeType": "date",
"params": "[\"Pending\",\"Closed\"]",
"formIds": [
301
]
}
'import requests
url = "https://api.lofty.com/v1.0/transaction/customfields"
payload = {
"attributeName": "Mailer Sent",
"attributeType": "date",
"params": "[\"Pending\",\"Closed\"]",
"formIds": [301]
}
headers = {
"Authorization": "<authorization>",
"Content-Type": "<content-type>"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: '<authorization>', 'Content-Type': '<content-type>'},
body: JSON.stringify({
attributeName: 'Mailer Sent',
attributeType: 'date',
params: '["Pending","Closed"]',
formIds: [301]
})
};
fetch('https://api.lofty.com/v1.0/transaction/customfields', 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://api.lofty.com/v1.0/transaction/customfields",
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([
'attributeName' => 'Mailer Sent',
'attributeType' => 'date',
'params' => '["Pending","Closed"]',
'formIds' => [
301
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: <authorization>",
"Content-Type: <content-type>"
],
]);
$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://api.lofty.com/v1.0/transaction/customfields"
payload := strings.NewReader("{\n \"attributeName\": \"Mailer Sent\",\n \"attributeType\": \"date\",\n \"params\": \"[\\\"Pending\\\",\\\"Closed\\\"]\",\n \"formIds\": [\n 301\n ]\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "<authorization>")
req.Header.Add("Content-Type", "<content-type>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.lofty.com/v1.0/transaction/customfields")
.header("Authorization", "<authorization>")
.header("Content-Type", "<content-type>")
.body("{\n \"attributeName\": \"Mailer Sent\",\n \"attributeType\": \"date\",\n \"params\": \"[\\\"Pending\\\",\\\"Closed\\\"]\",\n \"formIds\": [\n 301\n ]\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.lofty.com/v1.0/transaction/customfields")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = '<authorization>'
request["Content-Type"] = '<content-type>'
request.body = "{\n \"attributeName\": \"Mailer Sent\",\n \"attributeType\": \"date\",\n \"params\": \"[\\\"Pending\\\",\\\"Closed\\\"]\",\n \"formIds\": [\n 301\n ]\n}"
response = http.request(request)
puts response.read_body{
"id": 1001,
"name": "Closing Agent",
"type": "Single-Select",
"params": "[{\"label\":\"Option A\",\"value\":\"1\"},{\"label\":\"Option B\",\"value\":\"2\"}]"
}"<string>""<string>""<string>"