curl --request GET \
--url https://client-api.salesfinity.co/v1/custom-fields \
--header 'x-api-key: <api-key>'import requests
url = "https://client-api.salesfinity.co/v1/custom-fields"
headers = {"x-api-key": "<api-key>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {'x-api-key': '<api-key>'}};
fetch('https://client-api.salesfinity.co/v1/custom-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://client-api.salesfinity.co/v1/custom-fields",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"x-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"
"net/http"
"io"
)
func main() {
url := "https://client-api.salesfinity.co/v1/custom-fields"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("x-api-key", "<api-key>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://client-api.salesfinity.co/v1/custom-fields")
.header("x-api-key", "<api-key>")
.asString();require 'uri'
require 'net/http'
url = URI("https://client-api.salesfinity.co/v1/custom-fields")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["x-api-key"] = '<api-key>'
response = http.request(request)
puts response.read_body[
{
"_id": "66e0f3a1b2c3d4e5f6a7b8c9",
"source": "hubspot",
"team": "64f1a2b3c4d5e6f7a8b9c0d1",
"user": "680edc0d1504192884a148e0",
"fields": [
{
"_id": "66e0f3a1b2c3d4e5f6a7b8ca",
"type": "enumeration",
"field_type": "select",
"internal_name": "Account tier",
"external_key": "account_tier",
"external_name": "Account Tier"
}
],
"lead_fields": [],
"createdAt": "2026-09-14T09:20:11.204Z",
"updatedAt": "2026-09-30T16:45:02.871Z"
}
]{
"message": "Forbidden resource",
"error": "Forbidden",
"statusCode": 403,
"request_id": "0f6d3c52-9f3e-4c1a-a4b8-2b1f7e5d9c10"
}{
"message": "Rate limit of 300 requests per minute exceeded. Retry in 12s.",
"error": "Too Many Requests",
"statusCode": 429,
"request_id": "0f6d3c52-9f3e-4c1a-a4b8-2b1f7e5d9c10"
}{
"message": "Internal server error",
"error": "Internal Server Error",
"statusCode": 500,
"request_id": "0f6d3c52-9f3e-4c1a-a4b8-2b1f7e5d9c10"
}List custom field mappings
Returns the team’s custom field mappings: one record for each source (a CRM, or csv for CSV uploads) whose field mapping was saved in the dashboard’s integration settings. Each entry in fields (contacts) and lead_fields (leads) ties a field in that source (external_key, external_name) to the name Salesfinity shows for it (internal_name). When contacts are imported from a CRM, each mapped field becomes a custom field on the contact whose label is the internal_name.
The custom_fields you send to POST /v1/contact-lists and POST /v1/contact-lists/{id} are free text and are not checked against these mappings. Reuse an internal_name as the label to give an API-created contact the same field a CRM-imported one has.
Not paginated. The array is empty when nothing is mapped. Records for some CRMs also carry deal_fields, account_fields, deal_field_mapping and account_field_mapping.
curl --request GET \
--url https://client-api.salesfinity.co/v1/custom-fields \
--header 'x-api-key: <api-key>'import requests
url = "https://client-api.salesfinity.co/v1/custom-fields"
headers = {"x-api-key": "<api-key>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {'x-api-key': '<api-key>'}};
fetch('https://client-api.salesfinity.co/v1/custom-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://client-api.salesfinity.co/v1/custom-fields",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"x-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"
"net/http"
"io"
)
func main() {
url := "https://client-api.salesfinity.co/v1/custom-fields"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("x-api-key", "<api-key>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://client-api.salesfinity.co/v1/custom-fields")
.header("x-api-key", "<api-key>")
.asString();require 'uri'
require 'net/http'
url = URI("https://client-api.salesfinity.co/v1/custom-fields")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["x-api-key"] = '<api-key>'
response = http.request(request)
puts response.read_body[
{
"_id": "66e0f3a1b2c3d4e5f6a7b8c9",
"source": "hubspot",
"team": "64f1a2b3c4d5e6f7a8b9c0d1",
"user": "680edc0d1504192884a148e0",
"fields": [
{
"_id": "66e0f3a1b2c3d4e5f6a7b8ca",
"type": "enumeration",
"field_type": "select",
"internal_name": "Account tier",
"external_key": "account_tier",
"external_name": "Account Tier"
}
],
"lead_fields": [],
"createdAt": "2026-09-14T09:20:11.204Z",
"updatedAt": "2026-09-30T16:45:02.871Z"
}
]{
"message": "Forbidden resource",
"error": "Forbidden",
"statusCode": 403,
"request_id": "0f6d3c52-9f3e-4c1a-a4b8-2b1f7e5d9c10"
}{
"message": "Rate limit of 300 requests per minute exceeded. Retry in 12s.",
"error": "Too Many Requests",
"statusCode": 429,
"request_id": "0f6d3c52-9f3e-4c1a-a4b8-2b1f7e5d9c10"
}{
"message": "Internal server error",
"error": "Internal Server Error",
"statusCode": 500,
"request_id": "0f6d3c52-9f3e-4c1a-a4b8-2b1f7e5d9c10"
}hubspot, salesforce or csv. The response is a plain array, not paginated, and empty when nothing is mapped.
What a mapping does
Each entry infields (contacts) or lead_fields (leads) ties a field in the source to the name Salesfinity shows for it:
| Key | Meaning | Example |
|---|---|---|
external_key | The field’s API name in the source | account_tier |
external_name | The field’s display name in the source | Account Tier |
internal_name | The name Salesfinity shows | Account tier |
type, field_type | The field’s data type and input type, as the source names them | enumeration, select |
label set to internal_name. Records for some CRMs also carry deal_fields, account_fields, deal_field_mapping and account_field_mapping, which set the deal and account fields shown for that CRM.
Using mappings with contact lists
Thecustom_fields on contacts you send to Create a contact list and Add a contact to a list are free text: nothing checks them against these mappings. To give an API-created contact the same field a CRM import creates, use the mapping’s internal_name as the label:
{ "type": "string", "label": "Account tier", "value": "Enterprise" }
Example
curl https://client-api.salesfinity.co/v1/custom-fields \
--header 'x-api-key: YOUR_API_KEY'
[
{
"_id": "66e0f3a1b2c3d4e5f6a7b8c9",
"source": "hubspot",
"team": "64f1a2b3c4d5e6f7a8b9c0d1",
"user": "680edc0d1504192884a148e0",
"fields": [
{
"_id": "66e0f3a1b2c3d4e5f6a7b8ca",
"type": "enumeration",
"field_type": "select",
"internal_name": "Account tier",
"external_key": "account_tier",
"external_name": "Account Tier"
}
],
"lead_fields": [],
"createdAt": "2026-09-14T09:20:11.204Z",
"updatedAt": "2026-09-30T16:45:02.871Z",
"__v": 0
}
]
Authorizations
Team-scoped API key generated in the Salesfinity dashboard under Settings → Connections → API & Webhooks. A missing or invalid key returns HTTP 403.
Response
Every custom field mapping record for the team.
ID of the mapping record.
The integration the mapping belongs to. csv holds the mapping used for CSV uploads.
csv, salesforce, salesforce_sandbox, salesloft, outreach, apollo, hubspot, attio, active-campaign, custom, pipe-drive, monday ID of your team.
ID of the member who first saved the mapping.
Mappings for contact fields.
Show child attributes
Show child attributes
Mappings for lead fields, for CRMs that have leads.
Show child attributes
Show child attributes
Deal fields to show, for CRMs that support them. Absent when not configured.
Show child attributes
Show child attributes
Account fields to show, for CRMs that support them. Absent when not configured.
Show child attributes
Show child attributes
Which CRM fields fill Salesfinity's standard deal fields. Absent when not configured.
Show child attributes
Show child attributes
Which CRM fields fill Salesfinity's standard account fields. Absent when not configured.
Show child attributes
Show child attributes