Create a contact
curl --request POST \
--url https://app.leonar.app/api/v1/contacts \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"first_name": "Sophie",
"last_name": "Martin",
"title": "Senior Software Engineer",
"current_company": "Doctolib",
"location": "Paris, France",
"emails": [
{
"email": "sophie@doctolib.com",
"type": "work"
}
],
"linkedin_profile": "https://www.linkedin.com/in/sophie-martin",
"skills": [
"React",
"TypeScript"
],
"custom_data": {
"industry_code": "A12",
"vip": true
},
"tags": [
"frontend"
]
}
'import requests
url = "https://app.leonar.app/api/v1/contacts"
payload = {
"first_name": "Sophie",
"last_name": "Martin",
"title": "Senior Software Engineer",
"current_company": "Doctolib",
"location": "Paris, France",
"emails": [
{
"email": "sophie@doctolib.com",
"type": "work"
}
],
"linkedin_profile": "https://www.linkedin.com/in/sophie-martin",
"skills": ["React", "TypeScript"],
"custom_data": {
"industry_code": "A12",
"vip": True
},
"tags": ["frontend"]
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
first_name: 'Sophie',
last_name: 'Martin',
title: 'Senior Software Engineer',
current_company: 'Doctolib',
location: 'Paris, France',
emails: [{email: 'sophie@doctolib.com', type: 'work'}],
linkedin_profile: 'https://www.linkedin.com/in/sophie-martin',
skills: ['React', 'TypeScript'],
custom_data: {industry_code: 'A12', vip: true},
tags: ['frontend']
})
};
fetch('https://app.leonar.app/api/v1/contacts', 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://app.leonar.app/api/v1/contacts",
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([
'first_name' => 'Sophie',
'last_name' => 'Martin',
'title' => 'Senior Software Engineer',
'current_company' => 'Doctolib',
'location' => 'Paris, France',
'emails' => [
[
'email' => 'sophie@doctolib.com',
'type' => 'work'
]
],
'linkedin_profile' => 'https://www.linkedin.com/in/sophie-martin',
'skills' => [
'React',
'TypeScript'
],
'custom_data' => [
'industry_code' => 'A12',
'vip' => true
],
'tags' => [
'frontend'
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$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://app.leonar.app/api/v1/contacts"
payload := strings.NewReader("{\n \"first_name\": \"Sophie\",\n \"last_name\": \"Martin\",\n \"title\": \"Senior Software Engineer\",\n \"current_company\": \"Doctolib\",\n \"location\": \"Paris, France\",\n \"emails\": [\n {\n \"email\": \"sophie@doctolib.com\",\n \"type\": \"work\"\n }\n ],\n \"linkedin_profile\": \"https://www.linkedin.com/in/sophie-martin\",\n \"skills\": [\n \"React\",\n \"TypeScript\"\n ],\n \"custom_data\": {\n \"industry_code\": \"A12\",\n \"vip\": true\n },\n \"tags\": [\n \"frontend\"\n ]\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
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://app.leonar.app/api/v1/contacts")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"first_name\": \"Sophie\",\n \"last_name\": \"Martin\",\n \"title\": \"Senior Software Engineer\",\n \"current_company\": \"Doctolib\",\n \"location\": \"Paris, France\",\n \"emails\": [\n {\n \"email\": \"sophie@doctolib.com\",\n \"type\": \"work\"\n }\n ],\n \"linkedin_profile\": \"https://www.linkedin.com/in/sophie-martin\",\n \"skills\": [\n \"React\",\n \"TypeScript\"\n ],\n \"custom_data\": {\n \"industry_code\": \"A12\",\n \"vip\": true\n },\n \"tags\": [\n \"frontend\"\n ]\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://app.leonar.app/api/v1/contacts")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"first_name\": \"Sophie\",\n \"last_name\": \"Martin\",\n \"title\": \"Senior Software Engineer\",\n \"current_company\": \"Doctolib\",\n \"location\": \"Paris, France\",\n \"emails\": [\n {\n \"email\": \"sophie@doctolib.com\",\n \"type\": \"work\"\n }\n ],\n \"linkedin_profile\": \"https://www.linkedin.com/in/sophie-martin\",\n \"skills\": [\n \"React\",\n \"TypeScript\"\n ],\n \"custom_data\": {\n \"industry_code\": \"A12\",\n \"vip\": true\n },\n \"tags\": [\n \"frontend\"\n ]\n}"
response = http.request(request)
puts response.read_body{
"data": {
"id": "a1b2c3d4-5678-90ab-cdef-1234567890ab",
"first_name": "Sophie",
"last_name": "Martin",
"title": "Senior Software Engineer",
"current_company": "Doctolib",
"location": "Paris, France",
"linkedin_profile": "https://www.linkedin.com/in/sophie-martin",
"emails": [
{
"email": "sophie@doctolib.com",
"type": "work"
}
],
"phones": [
{
"phone": "+33612345678",
"type": "personal"
}
],
"tags": [
"frontend",
"senior"
],
"global_status": "new",
"source": "linkedin",
"summary": null,
"skills": [
"React",
"TypeScript",
"Node.js"
],
"languages": [
"French",
"English"
],
"years_experience": 8,
"custom_data": {
"industry_code": "A12",
"vip": true
},
"do_not_contact": false,
"created_at": "2025-01-15T10:30:00Z",
"updated_at": "2025-01-20T14:00:00Z",
"last_contacted_at": null,
"archived_at": null
}
}{
"error": {
"code": "validation_error",
"message": "Invalid input"
}
}{
"error": {
"code": "invalid_api_key",
"message": "Invalid API key"
}
}{
"error": {
"code": "rate_limit_exceeded",
"message": "Rate limit exceeded. Limit: 2000 requests per hour."
}
}Contacts
Create a contact
Creates a new contact in the workspace.
POST
/
contacts
Create a contact
curl --request POST \
--url https://app.leonar.app/api/v1/contacts \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"first_name": "Sophie",
"last_name": "Martin",
"title": "Senior Software Engineer",
"current_company": "Doctolib",
"location": "Paris, France",
"emails": [
{
"email": "sophie@doctolib.com",
"type": "work"
}
],
"linkedin_profile": "https://www.linkedin.com/in/sophie-martin",
"skills": [
"React",
"TypeScript"
],
"custom_data": {
"industry_code": "A12",
"vip": true
},
"tags": [
"frontend"
]
}
'import requests
url = "https://app.leonar.app/api/v1/contacts"
payload = {
"first_name": "Sophie",
"last_name": "Martin",
"title": "Senior Software Engineer",
"current_company": "Doctolib",
"location": "Paris, France",
"emails": [
{
"email": "sophie@doctolib.com",
"type": "work"
}
],
"linkedin_profile": "https://www.linkedin.com/in/sophie-martin",
"skills": ["React", "TypeScript"],
"custom_data": {
"industry_code": "A12",
"vip": True
},
"tags": ["frontend"]
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
first_name: 'Sophie',
last_name: 'Martin',
title: 'Senior Software Engineer',
current_company: 'Doctolib',
location: 'Paris, France',
emails: [{email: 'sophie@doctolib.com', type: 'work'}],
linkedin_profile: 'https://www.linkedin.com/in/sophie-martin',
skills: ['React', 'TypeScript'],
custom_data: {industry_code: 'A12', vip: true},
tags: ['frontend']
})
};
fetch('https://app.leonar.app/api/v1/contacts', 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://app.leonar.app/api/v1/contacts",
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([
'first_name' => 'Sophie',
'last_name' => 'Martin',
'title' => 'Senior Software Engineer',
'current_company' => 'Doctolib',
'location' => 'Paris, France',
'emails' => [
[
'email' => 'sophie@doctolib.com',
'type' => 'work'
]
],
'linkedin_profile' => 'https://www.linkedin.com/in/sophie-martin',
'skills' => [
'React',
'TypeScript'
],
'custom_data' => [
'industry_code' => 'A12',
'vip' => true
],
'tags' => [
'frontend'
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$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://app.leonar.app/api/v1/contacts"
payload := strings.NewReader("{\n \"first_name\": \"Sophie\",\n \"last_name\": \"Martin\",\n \"title\": \"Senior Software Engineer\",\n \"current_company\": \"Doctolib\",\n \"location\": \"Paris, France\",\n \"emails\": [\n {\n \"email\": \"sophie@doctolib.com\",\n \"type\": \"work\"\n }\n ],\n \"linkedin_profile\": \"https://www.linkedin.com/in/sophie-martin\",\n \"skills\": [\n \"React\",\n \"TypeScript\"\n ],\n \"custom_data\": {\n \"industry_code\": \"A12\",\n \"vip\": true\n },\n \"tags\": [\n \"frontend\"\n ]\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
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://app.leonar.app/api/v1/contacts")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"first_name\": \"Sophie\",\n \"last_name\": \"Martin\",\n \"title\": \"Senior Software Engineer\",\n \"current_company\": \"Doctolib\",\n \"location\": \"Paris, France\",\n \"emails\": [\n {\n \"email\": \"sophie@doctolib.com\",\n \"type\": \"work\"\n }\n ],\n \"linkedin_profile\": \"https://www.linkedin.com/in/sophie-martin\",\n \"skills\": [\n \"React\",\n \"TypeScript\"\n ],\n \"custom_data\": {\n \"industry_code\": \"A12\",\n \"vip\": true\n },\n \"tags\": [\n \"frontend\"\n ]\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://app.leonar.app/api/v1/contacts")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"first_name\": \"Sophie\",\n \"last_name\": \"Martin\",\n \"title\": \"Senior Software Engineer\",\n \"current_company\": \"Doctolib\",\n \"location\": \"Paris, France\",\n \"emails\": [\n {\n \"email\": \"sophie@doctolib.com\",\n \"type\": \"work\"\n }\n ],\n \"linkedin_profile\": \"https://www.linkedin.com/in/sophie-martin\",\n \"skills\": [\n \"React\",\n \"TypeScript\"\n ],\n \"custom_data\": {\n \"industry_code\": \"A12\",\n \"vip\": true\n },\n \"tags\": [\n \"frontend\"\n ]\n}"
response = http.request(request)
puts response.read_body{
"data": {
"id": "a1b2c3d4-5678-90ab-cdef-1234567890ab",
"first_name": "Sophie",
"last_name": "Martin",
"title": "Senior Software Engineer",
"current_company": "Doctolib",
"location": "Paris, France",
"linkedin_profile": "https://www.linkedin.com/in/sophie-martin",
"emails": [
{
"email": "sophie@doctolib.com",
"type": "work"
}
],
"phones": [
{
"phone": "+33612345678",
"type": "personal"
}
],
"tags": [
"frontend",
"senior"
],
"global_status": "new",
"source": "linkedin",
"summary": null,
"skills": [
"React",
"TypeScript",
"Node.js"
],
"languages": [
"French",
"English"
],
"years_experience": 8,
"custom_data": {
"industry_code": "A12",
"vip": true
},
"do_not_contact": false,
"created_at": "2025-01-15T10:30:00Z",
"updated_at": "2025-01-20T14:00:00Z",
"last_contacted_at": null,
"archived_at": null
}
}{
"error": {
"code": "validation_error",
"message": "Invalid input"
}
}{
"error": {
"code": "invalid_api_key",
"message": "Invalid API key"
}
}{
"error": {
"code": "rate_limit_exceeded",
"message": "Rate limit exceeded. Limit: 2000 requests per hour."
}
}Authorizations
API key starting with leo_
Body
application/json
Maximum string length:
100Maximum string length:
100Single email (convenience field). Use emails array for multiple.
Maximum array length:
5Show child attributes
Show child attributes
Single phone (convenience field). Use phones array for multiple.
Maximum array length:
5Show child attributes
Show child attributes
Tag names to attach. Tags are created automatically if they don't exist.
Custom field values indexed by custom field key.
Values are validated against workspace custom field definitions.
Available options:
new, contacted, replied, qualified, archived Response
Contact created
Show child attributes
Show child attributes
Example:
{
"id": "a1b2c3d4-5678-90ab-cdef-1234567890ab",
"first_name": "Sophie",
"last_name": "Martin",
"title": "Senior Software Engineer",
"current_company": "Doctolib",
"location": "Paris, France",
"linkedin_profile": "https://www.linkedin.com/in/sophie-martin",
"emails": [
{
"email": "sophie@doctolib.com",
"type": "work"
}
],
"phones": [
{
"phone": "+33612345678",
"type": "personal"
}
],
"tags": ["frontend", "senior"],
"global_status": "new",
"source": "linkedin",
"summary": null,
"skills": ["React", "TypeScript", "Node.js"],
"languages": ["French", "English"],
"years_experience": 8,
"custom_data": { "industry_code": "A12", "vip": true },
"do_not_contact": false,
"created_at": "2025-01-15T10:30:00Z",
"updated_at": "2025-01-20T14:00:00Z",
"last_contacted_at": null,
"archived_at": null
}
⌘I