curl --request POST \
--url https://production-api.joinrings.com/v1/persons \
--header 'Content-Type: application/json' \
--header 'x-api-key: <api-key>' \
--data '
{
"city": "<string>",
"country_code": "<string>",
"custom_fields": {},
"description": "<string>",
"email": "<string>",
"email_3": "<string>",
"email_4": "<string>",
"email_5": "<string>",
"facebook_url": "<string>",
"first_name": "<string>",
"job_title": "<string>",
"last_name": "<string>",
"linkedin_url": "<string>",
"logo_url": "<string>",
"mobile_phone": "<string>",
"name": "<string>",
"phone": "<string>",
"secondary_email": "<string>",
"secondary_phone": "<string>",
"state_code": "<string>",
"twitter_url": "<string>",
"website": "<string>"
}
'import requests
url = "https://production-api.joinrings.com/v1/persons"
payload = {
"city": "<string>",
"country_code": "<string>",
"custom_fields": {},
"description": "<string>",
"email": "<string>",
"email_3": "<string>",
"email_4": "<string>",
"email_5": "<string>",
"facebook_url": "<string>",
"first_name": "<string>",
"job_title": "<string>",
"last_name": "<string>",
"linkedin_url": "<string>",
"logo_url": "<string>",
"mobile_phone": "<string>",
"name": "<string>",
"phone": "<string>",
"secondary_email": "<string>",
"secondary_phone": "<string>",
"state_code": "<string>",
"twitter_url": "<string>",
"website": "<string>"
}
headers = {
"x-api-key": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'x-api-key': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
city: '<string>',
country_code: '<string>',
custom_fields: {},
description: '<string>',
email: '<string>',
email_3: '<string>',
email_4: '<string>',
email_5: '<string>',
facebook_url: '<string>',
first_name: '<string>',
job_title: '<string>',
last_name: '<string>',
linkedin_url: '<string>',
logo_url: '<string>',
mobile_phone: '<string>',
name: '<string>',
phone: '<string>',
secondary_email: '<string>',
secondary_phone: '<string>',
state_code: '<string>',
twitter_url: '<string>',
website: '<string>'
})
};
fetch('https://production-api.joinrings.com/v1/persons', 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://production-api.joinrings.com/v1/persons",
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([
'city' => '<string>',
'country_code' => '<string>',
'custom_fields' => [
],
'description' => '<string>',
'email' => '<string>',
'email_3' => '<string>',
'email_4' => '<string>',
'email_5' => '<string>',
'facebook_url' => '<string>',
'first_name' => '<string>',
'job_title' => '<string>',
'last_name' => '<string>',
'linkedin_url' => '<string>',
'logo_url' => '<string>',
'mobile_phone' => '<string>',
'name' => '<string>',
'phone' => '<string>',
'secondary_email' => '<string>',
'secondary_phone' => '<string>',
'state_code' => '<string>',
'twitter_url' => '<string>',
'website' => '<string>'
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"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"
"strings"
"net/http"
"io"
)
func main() {
url := "https://production-api.joinrings.com/v1/persons"
payload := strings.NewReader("{\n \"city\": \"<string>\",\n \"country_code\": \"<string>\",\n \"custom_fields\": {},\n \"description\": \"<string>\",\n \"email\": \"<string>\",\n \"email_3\": \"<string>\",\n \"email_4\": \"<string>\",\n \"email_5\": \"<string>\",\n \"facebook_url\": \"<string>\",\n \"first_name\": \"<string>\",\n \"job_title\": \"<string>\",\n \"last_name\": \"<string>\",\n \"linkedin_url\": \"<string>\",\n \"logo_url\": \"<string>\",\n \"mobile_phone\": \"<string>\",\n \"name\": \"<string>\",\n \"phone\": \"<string>\",\n \"secondary_email\": \"<string>\",\n \"secondary_phone\": \"<string>\",\n \"state_code\": \"<string>\",\n \"twitter_url\": \"<string>\",\n \"website\": \"<string>\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("x-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://production-api.joinrings.com/v1/persons")
.header("x-api-key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"city\": \"<string>\",\n \"country_code\": \"<string>\",\n \"custom_fields\": {},\n \"description\": \"<string>\",\n \"email\": \"<string>\",\n \"email_3\": \"<string>\",\n \"email_4\": \"<string>\",\n \"email_5\": \"<string>\",\n \"facebook_url\": \"<string>\",\n \"first_name\": \"<string>\",\n \"job_title\": \"<string>\",\n \"last_name\": \"<string>\",\n \"linkedin_url\": \"<string>\",\n \"logo_url\": \"<string>\",\n \"mobile_phone\": \"<string>\",\n \"name\": \"<string>\",\n \"phone\": \"<string>\",\n \"secondary_email\": \"<string>\",\n \"secondary_phone\": \"<string>\",\n \"state_code\": \"<string>\",\n \"twitter_url\": \"<string>\",\n \"website\": \"<string>\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://production-api.joinrings.com/v1/persons")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["x-api-key"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"city\": \"<string>\",\n \"country_code\": \"<string>\",\n \"custom_fields\": {},\n \"description\": \"<string>\",\n \"email\": \"<string>\",\n \"email_3\": \"<string>\",\n \"email_4\": \"<string>\",\n \"email_5\": \"<string>\",\n \"facebook_url\": \"<string>\",\n \"first_name\": \"<string>\",\n \"job_title\": \"<string>\",\n \"last_name\": \"<string>\",\n \"linkedin_url\": \"<string>\",\n \"logo_url\": \"<string>\",\n \"mobile_phone\": \"<string>\",\n \"name\": \"<string>\",\n \"phone\": \"<string>\",\n \"secondary_email\": \"<string>\",\n \"secondary_phone\": \"<string>\",\n \"state_code\": \"<string>\",\n \"twitter_url\": \"<string>\",\n \"website\": \"<string>\"\n}"
response = http.request(request)
puts response.read_body{
"rings_updated_at": 123,
"uuid": "<string>",
"email_slot": "<string>"
}Create a person
All fields are optional. If the provided email matches an existing person
in the tenant, the existing record is updated in place and its UUID is returned
(deduplication by email). Returns the UUID and rings_updated_at timestamp on
success.
An email for a person who already exists is added to their next free
email slot rather than replacing slot 1 — overwriting it would drop the
address the app shows as their primary. The response’s email_slot says
where the address landed, and is null if the person already held it or all
five slots were full.
curl --request POST \
--url https://production-api.joinrings.com/v1/persons \
--header 'Content-Type: application/json' \
--header 'x-api-key: <api-key>' \
--data '
{
"city": "<string>",
"country_code": "<string>",
"custom_fields": {},
"description": "<string>",
"email": "<string>",
"email_3": "<string>",
"email_4": "<string>",
"email_5": "<string>",
"facebook_url": "<string>",
"first_name": "<string>",
"job_title": "<string>",
"last_name": "<string>",
"linkedin_url": "<string>",
"logo_url": "<string>",
"mobile_phone": "<string>",
"name": "<string>",
"phone": "<string>",
"secondary_email": "<string>",
"secondary_phone": "<string>",
"state_code": "<string>",
"twitter_url": "<string>",
"website": "<string>"
}
'import requests
url = "https://production-api.joinrings.com/v1/persons"
payload = {
"city": "<string>",
"country_code": "<string>",
"custom_fields": {},
"description": "<string>",
"email": "<string>",
"email_3": "<string>",
"email_4": "<string>",
"email_5": "<string>",
"facebook_url": "<string>",
"first_name": "<string>",
"job_title": "<string>",
"last_name": "<string>",
"linkedin_url": "<string>",
"logo_url": "<string>",
"mobile_phone": "<string>",
"name": "<string>",
"phone": "<string>",
"secondary_email": "<string>",
"secondary_phone": "<string>",
"state_code": "<string>",
"twitter_url": "<string>",
"website": "<string>"
}
headers = {
"x-api-key": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'x-api-key': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
city: '<string>',
country_code: '<string>',
custom_fields: {},
description: '<string>',
email: '<string>',
email_3: '<string>',
email_4: '<string>',
email_5: '<string>',
facebook_url: '<string>',
first_name: '<string>',
job_title: '<string>',
last_name: '<string>',
linkedin_url: '<string>',
logo_url: '<string>',
mobile_phone: '<string>',
name: '<string>',
phone: '<string>',
secondary_email: '<string>',
secondary_phone: '<string>',
state_code: '<string>',
twitter_url: '<string>',
website: '<string>'
})
};
fetch('https://production-api.joinrings.com/v1/persons', 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://production-api.joinrings.com/v1/persons",
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([
'city' => '<string>',
'country_code' => '<string>',
'custom_fields' => [
],
'description' => '<string>',
'email' => '<string>',
'email_3' => '<string>',
'email_4' => '<string>',
'email_5' => '<string>',
'facebook_url' => '<string>',
'first_name' => '<string>',
'job_title' => '<string>',
'last_name' => '<string>',
'linkedin_url' => '<string>',
'logo_url' => '<string>',
'mobile_phone' => '<string>',
'name' => '<string>',
'phone' => '<string>',
'secondary_email' => '<string>',
'secondary_phone' => '<string>',
'state_code' => '<string>',
'twitter_url' => '<string>',
'website' => '<string>'
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"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"
"strings"
"net/http"
"io"
)
func main() {
url := "https://production-api.joinrings.com/v1/persons"
payload := strings.NewReader("{\n \"city\": \"<string>\",\n \"country_code\": \"<string>\",\n \"custom_fields\": {},\n \"description\": \"<string>\",\n \"email\": \"<string>\",\n \"email_3\": \"<string>\",\n \"email_4\": \"<string>\",\n \"email_5\": \"<string>\",\n \"facebook_url\": \"<string>\",\n \"first_name\": \"<string>\",\n \"job_title\": \"<string>\",\n \"last_name\": \"<string>\",\n \"linkedin_url\": \"<string>\",\n \"logo_url\": \"<string>\",\n \"mobile_phone\": \"<string>\",\n \"name\": \"<string>\",\n \"phone\": \"<string>\",\n \"secondary_email\": \"<string>\",\n \"secondary_phone\": \"<string>\",\n \"state_code\": \"<string>\",\n \"twitter_url\": \"<string>\",\n \"website\": \"<string>\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("x-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://production-api.joinrings.com/v1/persons")
.header("x-api-key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"city\": \"<string>\",\n \"country_code\": \"<string>\",\n \"custom_fields\": {},\n \"description\": \"<string>\",\n \"email\": \"<string>\",\n \"email_3\": \"<string>\",\n \"email_4\": \"<string>\",\n \"email_5\": \"<string>\",\n \"facebook_url\": \"<string>\",\n \"first_name\": \"<string>\",\n \"job_title\": \"<string>\",\n \"last_name\": \"<string>\",\n \"linkedin_url\": \"<string>\",\n \"logo_url\": \"<string>\",\n \"mobile_phone\": \"<string>\",\n \"name\": \"<string>\",\n \"phone\": \"<string>\",\n \"secondary_email\": \"<string>\",\n \"secondary_phone\": \"<string>\",\n \"state_code\": \"<string>\",\n \"twitter_url\": \"<string>\",\n \"website\": \"<string>\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://production-api.joinrings.com/v1/persons")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["x-api-key"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"city\": \"<string>\",\n \"country_code\": \"<string>\",\n \"custom_fields\": {},\n \"description\": \"<string>\",\n \"email\": \"<string>\",\n \"email_3\": \"<string>\",\n \"email_4\": \"<string>\",\n \"email_5\": \"<string>\",\n \"facebook_url\": \"<string>\",\n \"first_name\": \"<string>\",\n \"job_title\": \"<string>\",\n \"last_name\": \"<string>\",\n \"linkedin_url\": \"<string>\",\n \"logo_url\": \"<string>\",\n \"mobile_phone\": \"<string>\",\n \"name\": \"<string>\",\n \"phone\": \"<string>\",\n \"secondary_email\": \"<string>\",\n \"secondary_phone\": \"<string>\",\n \"state_code\": \"<string>\",\n \"twitter_url\": \"<string>\",\n \"website\": \"<string>\"\n}"
response = http.request(request)
puts response.read_body{
"rings_updated_at": 123,
"uuid": "<string>",
"email_slot": "<string>"
}Authorizations
Body
City name, e.g. 'Los Angeles'.
ISO 3166-1 alpha-2 country code, e.g. 'US'. Not a country name.
Person custom field values keyed by field id from GET /v1/persons/custom-fields; null clears a field. Only the fields present are written. Values use the shapes described on the person response; an invalid value fails the request with 400 naming the field, before anything is written.
Full ISO 3166-2 subdivision code including the country prefix — 'US-CA', not 'CA' and not 'California'. This is a different vocabulary from the state filter on GET /v1/persons, which takes a name or a country-scoped code. A value that is not a valid code is stored as given but will not resolve to a state on read.
Response
Response body for person create/update.
Which of the five email slots the submitted email was written to: email, secondary_email, email_3, email_4 or email_5. An address sent for a person who already exists is added to their next free slot rather than overwriting slot 1, so this will not always be email. null when no email was submitted, when the person already held that address, or when all five slots were already full.