Retrouver un contact sans se tromper d'homonyme
Chercher un contact par votre propre référence, son email, son mobile ou son nom, et choisir la bonne fiche quand plusieurs se ressemblent.
Avant d'écrire sur une personne — compléter sa fiche, l'inviter dans un parcours, lui ouvrir un portail —, retrouvez sa fiche : jamais la première venue. Une organisation peut compter deux « Camille Martin », ou deux fiches qui partagent une adresse. Chaque recherche est une lecture de la liste des contacts — voir Lire des listes.
1Par votre propre référence
Le plus sûr : gardez l'identifiant de la personne dans votre outil sur sa fiche, dans ExternalId (128 caractères au plus), à sa
création ou par un PUT. Elle se retrouve ensuite sans ambiguïté :
QUERY https://staging-api.docage.com/Contacts
Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9…
Content-Type: application/json
{
"Filter": { "PropertyName": "ExternalId", "Comparison": "=", "Value": "CRM-CLIENT-881" },
"Take": 10,
"EntityProperties": ["Id", "FirstName", "LastName", "Email", "Mobile", "Company", "City", "ExternalId"]
}curl -X QUERY "https://staging-api.docage.com/Contacts" \
-H "Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9…" \
-H "Content-Type: application/json" \
-d '{
"Filter": {"PropertyName": "ExternalId", "Comparison": "=", "Value": "CRM-CLIENT-881"},
"Take": 10,
"EntityProperties": ["Id", "FirstName", "LastName", "Email", "Mobile", "Company", "City", "ExternalId"]
}'using HttpClient client = new();
using HttpRequestMessage request = new(new HttpMethod("QUERY"), "https://staging-api.docage.com/Contacts");
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", token);
request.Content = new StringContent("""
{
"Filter": {
"PropertyName": "ExternalId",
"Comparison": "=",
"Value": "CRM-CLIENT-881"
},
"Take": 10,
"EntityProperties": [
"Id",
"FirstName",
"LastName",
"Email",
"Mobile",
"Company",
"City",
"ExternalId"
]
}
""", Encoding.UTF8, "application/json");
using HttpResponseMessage response = await client.SendAsync(request);
string result = await response.Content.ReadAsStringAsync();
if (!response.IsSuccessStatusCode)
throw new HttpRequestException(result);const response = await fetch("https://staging-api.docage.com/Contacts", {
method: "QUERY",
headers: {
Authorization: `Bearer ${token}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
"Filter": {"PropertyName": "ExternalId", "Comparison": "=", "Value": "CRM-CLIENT-881"},
"Take": 10,
"EntityProperties": ["Id", "FirstName", "LastName", "Email", "Mobile", "Company", "City", "ExternalId"]
})
});
const text = await response.text();
if (!response.ok) throw new Error(text);
const result = text ? JSON.parse(text) : null;ExternalId n'est pas tenu d'être unique : comptez les fiches rendues, comme ci-dessous.
2Par son email
QUERY https://staging-api.docage.com/Contacts
Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9…
Content-Type: application/json
{
"Filter": { "PropertyName": "Email", "Comparison": "=", "Value": "camille.martin@example.com" },
"SortOrder": "LastModificationDate_Desc",
"Take": 10,
"EntityProperties": ["Id", "FirstName", "LastName", "Email", "Mobile", "Company", "City", "CreationDate", "LastModificationDate"]
}curl -X QUERY "https://staging-api.docage.com/Contacts" \
-H "Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9…" \
-H "Content-Type: application/json" \
-d '{
"Filter": {"PropertyName": "Email", "Comparison": "=", "Value": "camille.martin@example.com"},
"SortOrder": "LastModificationDate_Desc",
"Take": 10,
"EntityProperties": ["Id", "FirstName", "LastName", "Email", "Mobile", "Company", "City", "CreationDate", "LastModificationDate"]
}'using HttpClient client = new();
using HttpRequestMessage request = new(new HttpMethod("QUERY"), "https://staging-api.docage.com/Contacts");
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", token);
request.Content = new StringContent("""
{
"Filter": {
"PropertyName": "Email",
"Comparison": "=",
"Value": "camille.martin@example.com"
},
"SortOrder": "LastModificationDate_Desc",
"Take": 10,
"EntityProperties": [
"Id",
"FirstName",
"LastName",
"Email",
"Mobile",
"Company",
"City",
"CreationDate",
"LastModificationDate"
]
}
""", Encoding.UTF8, "application/json");
using HttpResponseMessage response = await client.SendAsync(request);
string result = await response.Content.ReadAsStringAsync();
if (!response.IsSuccessStatusCode)
throw new HttpRequestException(result);const response = await fetch("https://staging-api.docage.com/Contacts", {
method: "QUERY",
headers: {
Authorization: `Bearer ${token}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
"Filter": {"PropertyName": "Email", "Comparison": "=", "Value": "camille.martin@example.com"},
"SortOrder": "LastModificationDate_Desc",
"Take": 10,
"EntityProperties": ["Id", "FirstName", "LastName", "Email", "Mobile", "Company", "City", "CreationDate", "LastModificationDate"]
})
});
const text = await response.text();
if (!response.ok) throw new Error(text);
const result = text ? JSON.parse(text) : null;Plusieurs fiches peuvent partager une adresse : l'en-tête Docage-TotalItems de la réponse dit combien le filtre en retient.
Attention
GET https://staging-api.docage.com/Contacts/ByEmail/{email} rend une seule fiche quand plusieurs partagent l'adresse, sans dire laquelle ni combien il y
en a. Préférez la liste filtrée, qui les rend toutes.
3Par son mobile
Un numéro reconnu est enregistré au format international E.164 (+33612345678), quelle que soit la façon dont il a été saisi. Pour
retrouver un numéro tapé autrement (« 06 12 34 56 78 »), comparez ses derniers chiffres, dans le mobile et le téléphone :
{
"Filter": {
"OperatorType": "Or",
"Operands": [
{ "PropertyName": "Mobile", "Comparison": "contains", "Value": "612345678" },
{ "PropertyName": "Phone", "Comparison": "contains", "Value": "612345678" }
]
},
"Take": 10
}Un numéro que le serveur n'a pas reconnu est gardé tel qu'il a été saisi, espaces compris : celui-là ne se retrouve que tel quel.
4Par son nom
Cherchez dans FirstName et LastName, pas dans Name : le nom complet d'un contact est calculé, et sa colonne peut être vide.
{
"Filter": {
"OperatorType": "And",
"Operands": [
{ "PropertyName": "FirstName", "Comparison": "contains", "Value": "Camille" },
{ "PropertyName": "LastName", "Comparison": "contains", "Value": "Martin" }
]
},
"Take": 10
}Pour un texte libre saisi par un utilisateur, exigez chaque mot dans l'un des champs qui identifient une personne : un And de
mots, chacun un Or sur FirstName, LastName, Email, Company et City.
5Choisir entre homonymes
Plusieurs fiches répondent : ne prenez pas la première. Comparez ce qui les distingue — l'email, le mobile, la société (Company,
le nom de la société rattachée), la ville, la date de création — et faites choisir la personne qui sait. Aucune fiche : la personne
n'existe pas, ou l'utilisateur ne la voit pas ; une liste ne rend que ce qu'il a le droit de voir.
Une fois la fiche choisie, lisez-la entière par GET https://staging-api.docage.com/Contacts/{id} : coordonnées, société (ParentCompanyId), classeurs
(BoxIds) et champs personnalisés.
6Les contacts d'une société
CompanyId restreint la liste aux contacts rattachés à une société :
QUERY https://staging-api.docage.com/Contacts
Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9…
Content-Type: application/json
{
"CompanyId": "00000000-0000-4000-8000-000000000101",
"SortOrder": "LastName",
"Take": 50
}curl -X QUERY "https://staging-api.docage.com/Contacts" \
-H "Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9…" \
-H "Content-Type: application/json" \
-d '{
"CompanyId": "00000000-0000-4000-8000-000000000101",
"SortOrder": "LastName",
"Take": 50
}'using HttpClient client = new();
using HttpRequestMessage request = new(new HttpMethod("QUERY"), "https://staging-api.docage.com/Contacts");
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", token);
request.Content = new StringContent("""
{
"CompanyId": "00000000-0000-4000-8000-000000000101",
"SortOrder": "LastName",
"Take": 50
}
""", Encoding.UTF8, "application/json");
using HttpResponseMessage response = await client.SendAsync(request);
string result = await response.Content.ReadAsStringAsync();
if (!response.IsSuccessStatusCode)
throw new HttpRequestException(result);const response = await fetch("https://staging-api.docage.com/Contacts", {
method: "QUERY",
headers: {
Authorization: `Bearer ${token}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
"CompanyId": "00000000-0000-4000-8000-000000000101",
"SortOrder": "LastName",
"Take": 50
})
});
const text = await response.text();
if (!response.ok) throw new Error(text);
const result = text ? JSON.parse(text) : null;La société elle-même se cherche de la même façon dans QUERY https://staging-api.docage.com/Companies : par son nom (Name), sa ville, son téléphone ou
votre référence (ExternalId).
7Un collègue n'est pas un contact
Un collègue est un utilisateur de l'organisation : il se cherche de la même façon dans QUERY https://staging-api.docage.com/DocageUsers. Une même
personne peut avoir les deux fiches.
Les pièges
- Un filtre ne s'élargit jamais : une propriété mal écrite ne retient aucune fiche. Une liste vide inattendue se relit critère par critère.
- La liste ne rend que les fiches actives : un contact mis à la corbeille, ou absorbé par une fusion de doublons, n'y figure plus — voir Mettre un contact à la corbeille et le restaurer et Traiter les doublons de contacts.
- Pour ne pas créer de doublon en écrivant, voir Créer un contact, une société et une carte.