Référence de l'API
Deals
Les cartes de votre tableau de pipeline : créer, modifier, déplacer vers une autre étape, gagner, perdre et archiver.
Endpoints
-
GET
/dealsLister les deals -
GET
/deals/{deal}Récupérer un deal -
POST
/dealsCréer un deal -
PATCH
/deals/{deal}Modifier un deal -
POST
/deals/{deal}/moveDéplacer un deal -
POST
/deals/{deal}/winGagner un deal -
POST
/deals/{deal}/losePerdre un deal -
POST
/deals/{deal}/archiveArchiver un deal -
POST
/deals/{deal}/unarchiveRestaurer un deal
Lister les deals
/api/v1/deals
Une liste de deals, le plus récent en premier. Les deals archivés sont exclus par défaut ; utilisez filter[archived] pour les inclure. Filtrez par statut, étape, client, responsable ou date de modification.
- Scope
-
deals.read— Lire les affaires et les étapes du pipeline - Fonctionnalité requise
pipeline
Paramètres de requête
| Nom | Type | Description |
|---|---|---|
limit |
integer | Nombre de résultats par page. de 1 à 100 · par défaut : 50 |
cursor |
string | Le next_cursor ou prev_cursor de meta dans la réponse précédente. |
sort |
string | Tri par created_at, updated_at ou stage_changed_at ; un signe moins devant signifie décroissant. l'une des valeurs : -created_at, created_at, -updated_at, updated_at, -stage_changed_at, stage_changed_at · par défaut : -created_at |
filter[status] |
string | Uniquement les deals ouverts, gagnés ou perdus. l'une des valeurs : open, won, lost |
filter[stage_id] |
integer | Uniquement les deals de cette étape (l'id vient de Lister les étapes du pipeline). |
filter[customer_id] |
string (uuid) | Uniquement les deals de ce client. |
filter[assigned_user_id] |
integer | Uniquement les deals de cet utilisateur. |
filter[archived] |
string | false (par défaut) affiche uniquement les deals du tableau, true uniquement les deals archivés, all les deux. l'une des valeurs : false, true, all · par défaut : false |
filter[updated_since] |
string (date-time) | Uniquement ce qui a changé depuis ce moment : ISO 8601 avec fuseau horaire, par exemple 2026-09-14T10:15:00Z. Pratique pour synchroniser. |
Exemple de requête
curl "https://app.klantly.com/api/v1/deals?filter[status]=open" \
-H "Authorization: Bearer $KLANTLY_API_KEY"$client = new \GuzzleHttp\Client([
'base_uri' => 'https://app.klantly.com/api/v1/',
'headers' => ['Authorization' => 'Bearer ' . getenv('KLANTLY_API_KEY')],
]);
$response = $client->request('GET', 'deals', [
'query' => [
'filter[status]' => 'open',
],
]);
$data = json_decode((string) $response->getBody(), true)['data'];const response = await fetch('https://app.klantly.com/api/v1/deals?filter[status]=open', {
headers: {
Authorization: `Bearer ${process.env.KLANTLY_API_KEY}`,
},
});
const { data } = await response.json();import os
import requests
response = requests.get(
"https://app.klantly.com/api/v1/deals",
headers={
"Authorization": f"Bearer {os.environ['KLANTLY_API_KEY']}",
},
params={
"filter[status]": "open"
},
)
data = response.json()["data"]Réponse 200
La réponse est une liste avec pagination par curseur : data contient les objets, meta la pagination.
{
"data": [
{
"object": "deal",
"id": "9d3f7a20-1c5e-4d7b-8a2f-3e4c5d6f7a81",
"title": "Veranda 5x3 m",
"description": null,
"status": "open",
"value": "8450.00",
"currency": "EUR",
"value_source": "manual",
"stage": {
"object": "pipeline_stage",
"id": "3"
},
"customer_id": "9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70",
"assigned_user_id": "7",
"source": "api",
"lost_reason": null,
"is_archived": false,
"stage_changed_at": "2026-09-14T10:15:00Z",
"won_at": null,
"lost_at": null,
"archived_at": null,
"created_at": "2026-09-14T10:15:00Z",
"updated_at": "2026-09-14T10:15:00Z"
}
],
"meta": {
"limit": 50,
"next_cursor": "eyJpZCI6IjlkM2Y2YzFlIn0",
"prev_cursor": null
}
}Erreurs possibles
-
403
insufficient_scope— Cette clé API n'a pas accès à cette action. -
422
validation_failed— Les données saisies ne sont pas valides.
Récupérer un deal
/api/v1/deals/{deal}
Un deal par id. La réponse contient un ETag que vous pouvez envoyer dans If-Match lors d'une modification.
- Scope
-
deals.read— Lire les affaires et les étapes du pipeline - Fonctionnalité requise
pipeline
Paramètres de chemin
| Nom | Type | Description |
|---|---|---|
deal obligatoire |
string (uuid) | L'id (UUID) du deal. |
Exemple de requête
curl "https://app.klantly.com/api/v1/deals/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70" \
-H "Authorization: Bearer $KLANTLY_API_KEY"$client = new \GuzzleHttp\Client([
'base_uri' => 'https://app.klantly.com/api/v1/',
'headers' => ['Authorization' => 'Bearer ' . getenv('KLANTLY_API_KEY')],
]);
$response = $client->request('GET', 'deals/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70');
$data = json_decode((string) $response->getBody(), true)['data'];const response = await fetch('https://app.klantly.com/api/v1/deals/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70', {
headers: {
Authorization: `Bearer ${process.env.KLANTLY_API_KEY}`,
},
});
const { data } = await response.json();import os
import requests
response = requests.get(
"https://app.klantly.com/api/v1/deals/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70",
headers={
"Authorization": f"Bearer {os.environ['KLANTLY_API_KEY']}",
},
)
data = response.json()["data"]Réponse 200
{
"data": {
"object": "deal",
"id": "9d3f7a20-1c5e-4d7b-8a2f-3e4c5d6f7a81",
"title": "Veranda 5x3 m",
"description": null,
"status": "open",
"value": "8450.00",
"currency": "EUR",
"value_source": "manual",
"stage": {
"object": "pipeline_stage",
"id": "3"
},
"customer_id": "9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70",
"assigned_user_id": "7",
"source": "api",
"lost_reason": null,
"is_archived": false,
"stage_changed_at": "2026-09-14T10:15:00Z",
"won_at": null,
"lost_at": null,
"archived_at": null,
"created_at": "2026-09-14T10:15:00Z",
"updated_at": "2026-09-14T10:15:00Z"
}
}Erreurs possibles
-
403
insufficient_scope— Cette clé API n'a pas accès à cette action. -
404
not_found— Introuvable.
Créer un deal
/api/v1/deals
Place un client sur le tableau de pipeline. Un client ne peut avoir qu'un seul deal ouvert à la fois : s'il en a déjà un, vous recevez 409 avec son id dans deal_id. Sans stage_id, le deal arrive dans l'étape par défaut. Si vous envoyez value, Klantly conserve ce montant au lieu de le calculer à partir des devis.
- Scope
-
deals.write— Créer, modifier, déplacer et archiver les affaires - Fonctionnalité requise
pipeline
Envoyez une Idempotency-Key : une nouvelle tentative après un délai d'attente ne crée alors jamais de doublon.
Corps (JSON)
| Champ | Type | Description |
|---|---|---|
customer_id
obligatoire
|
string (uuid) | Le client du deal. |
title
facultatif
|
string | Titre du deal. peut être vide (null) · au maximum 255 caractères |
description
facultatif
|
string | Description. peut être vide (null) · au maximum 10000 caractères |
value
facultatif
|
number | Valeur sous forme de texte à deux décimales, par exemple « 8450.00 ». À la création et à la modification, vous pouvez aussi envoyer un nombre. peut être vide (null) · de 0 à 99999999 |
stage_id
facultatif
|
integer | L'étape dans laquelle le deal arrive. Sans stage_id : l'étape par défaut. peut être vide (null) |
assigned_user_id
facultatif
|
integer | L'utilisateur qui gère le deal, ou null. peut être vide (null) |
Exemple de requête
curl -X POST "https://app.klantly.com/api/v1/deals" \
-H "Authorization: Bearer $KLANTLY_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: 6f1c2d3e-4a5b-4c6d-8e7f-9a0b1c2d3e4f" \
-d '{
"customer_id": "9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70",
"title": "Veranda 5x3 m",
"value": "8450.00"
}'$client = new \GuzzleHttp\Client([
'base_uri' => 'https://app.klantly.com/api/v1/',
'headers' => ['Authorization' => 'Bearer ' . getenv('KLANTLY_API_KEY')],
]);
$response = $client->request('POST', 'deals', [
'headers' => [
'Idempotency-Key' => '6f1c2d3e-4a5b-4c6d-8e7f-9a0b1c2d3e4f',
],
'json' => [
'customer_id' => '9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70',
'title' => 'Veranda 5x3 m',
'value' => '8450.00',
],
]);
$data = json_decode((string) $response->getBody(), true)['data'];const response = await fetch('https://app.klantly.com/api/v1/deals', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.KLANTLY_API_KEY}`,
'Content-Type': 'application/json',
'Idempotency-Key': '6f1c2d3e-4a5b-4c6d-8e7f-9a0b1c2d3e4f',
},
body: JSON.stringify({
"customer_id": "9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70",
"title": "Veranda 5x3 m",
"value": "8450.00"
}),
});
const { data } = await response.json();import os
import requests
response = requests.post(
"https://app.klantly.com/api/v1/deals",
headers={
"Authorization": f"Bearer {os.environ['KLANTLY_API_KEY']}",
"Idempotency-Key": "6f1c2d3e-4a5b-4c6d-8e7f-9a0b1c2d3e4f",
},
json={
"customer_id": "9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70",
"title": "Veranda 5x3 m",
"value": "8450.00"
},
)
data = response.json()["data"]Réponse 201
{
"data": {
"object": "deal",
"id": "9d3f7a20-1c5e-4d7b-8a2f-3e4c5d6f7a81",
"title": "Veranda 5x3 m",
"description": null,
"status": "open",
"value": "8450.00",
"currency": "EUR",
"value_source": "manual",
"stage": {
"object": "pipeline_stage",
"id": "3"
},
"customer_id": "9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70",
"assigned_user_id": "7",
"source": "api",
"lost_reason": null,
"is_archived": false,
"stage_changed_at": "2026-09-14T10:15:00Z",
"won_at": null,
"lost_at": null,
"archived_at": null,
"created_at": "2026-09-14T10:15:00Z",
"updated_at": "2026-09-14T10:15:00Z"
}
}Erreurs possibles
-
403
insufficient_scope— Cette clé API n'a pas accès à cette action. -
422
validation_failed— Les données saisies ne sont pas valides. -
422
unknown_field— Les données contiennent un champ inconnu. -
415
unsupported_media_type— Ce format n'est pas pris en charge. -
413
payload_too_large— Le corps de la requête est trop volumineux. -
409
conflict— Ceci est en conflit avec l'état actuel. -
422
idempotency_key_reused— Cette Idempotency-Key a déjà été utilisée pour une autre requête. -
409
idempotency_in_progress— Une requête avec cette Idempotency-Key est encore en cours.
Modifier un deal
/api/v1/deals/{deal}
Modifie uniquement les champs que vous envoyez. Pour changer d'étape, utilisez déplacer, gagner ou perdre. Envoyer value met value_source sur manual.
- Scope
-
deals.write— Créer, modifier, déplacer et archiver les affaires - Fonctionnalité requise
pipeline
Envoyez l'ETag dans If-Match : vous n'écraserez jamais par erreur une version plus récente.
Paramètres de chemin
| Nom | Type | Description |
|---|---|---|
deal obligatoire |
string (uuid) | L'id (UUID) du deal. |
Corps (JSON)
| Champ | Type | Description |
|---|---|---|
title
facultatif
|
string | Titre du deal. au maximum 255 caractères |
description
facultatif
|
string | Description. peut être vide (null) · au maximum 10000 caractères |
value
facultatif
|
number | Valeur sous forme de texte à deux décimales, par exemple « 8450.00 ». À la création et à la modification, vous pouvez aussi envoyer un nombre. de 0 à 99999999 |
assigned_user_id
facultatif
|
integer | L'utilisateur qui gère le deal, ou null. peut être vide (null) |
Exemple de requête
curl -X PATCH "https://app.klantly.com/api/v1/deals/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70" \
-H "Authorization: Bearer $KLANTLY_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"value": "9100.00",
"assigned_user_id": 7
}'$client = new \GuzzleHttp\Client([
'base_uri' => 'https://app.klantly.com/api/v1/',
'headers' => ['Authorization' => 'Bearer ' . getenv('KLANTLY_API_KEY')],
]);
$response = $client->request('PATCH', 'deals/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70', [
'json' => [
'value' => '9100.00',
'assigned_user_id' => 7,
],
]);
$data = json_decode((string) $response->getBody(), true)['data'];const response = await fetch('https://app.klantly.com/api/v1/deals/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70', {
method: 'PATCH',
headers: {
Authorization: `Bearer ${process.env.KLANTLY_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
"value": "9100.00",
"assigned_user_id": 7
}),
});
const { data } = await response.json();import os
import requests
response = requests.patch(
"https://app.klantly.com/api/v1/deals/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70",
headers={
"Authorization": f"Bearer {os.environ['KLANTLY_API_KEY']}",
},
json={
"value": "9100.00",
"assigned_user_id": 7
},
)
data = response.json()["data"]Réponse 200
{
"data": {
"object": "deal",
"id": "9d3f7a20-1c5e-4d7b-8a2f-3e4c5d6f7a81",
"title": "Veranda 5x3 m",
"description": null,
"status": "open",
"value": "8450.00",
"currency": "EUR",
"value_source": "manual",
"stage": {
"object": "pipeline_stage",
"id": "3"
},
"customer_id": "9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70",
"assigned_user_id": "7",
"source": "api",
"lost_reason": null,
"is_archived": false,
"stage_changed_at": "2026-09-14T10:15:00Z",
"won_at": null,
"lost_at": null,
"archived_at": null,
"created_at": "2026-09-14T10:15:00Z",
"updated_at": "2026-09-14T10:15:00Z"
}
}Erreurs possibles
-
403
insufficient_scope— Cette clé API n'a pas accès à cette action. -
422
validation_failed— Les données saisies ne sont pas valides. -
422
unknown_field— Les données contiennent un champ inconnu. -
415
unsupported_media_type— Ce format n'est pas pris en charge. -
413
payload_too_large— Le corps de la requête est trop volumineux. -
404
not_found— Introuvable. -
412
precondition_failed— L'enregistrement a été modifié entre-temps.
Déplacer un deal
/api/v1/deals/{deal}/move
Déplace le deal vers une autre étape, exactement comme un glisser-déposer sur le tableau. S'il s'agit d'une étape gagnée ou perdue, le deal est lui aussi gagné ou perdu.
- Scope
-
deals.write— Créer, modifier, déplacer et archiver les affaires - Fonctionnalité requise
pipeline
Envoyez une Idempotency-Key : une nouvelle tentative après un délai d'attente ne crée alors jamais de doublon.
Paramètres de chemin
| Nom | Type | Description |
|---|---|---|
deal obligatoire |
string (uuid) | L'id (UUID) du deal. |
Corps (JSON)
| Champ | Type | Description |
|---|---|---|
stage_id
obligatoire
|
integer | L'id de l'étape vers laquelle le deal est déplacé (voir Lister les étapes du pipeline). |
notes
facultatif
|
string | Remarque facultative ; conservée avec le changement d'étape dans l'historique du deal. peut être vide (null) · au maximum 500 caractères |
Exemple de requête
curl -X POST "https://app.klantly.com/api/v1/deals/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70/move" \
-H "Authorization: Bearer $KLANTLY_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: 6f1c2d3e-4a5b-4c6d-8e7f-9a0b1c2d3e4f" \
-d '{
"stage_id": 3
}'$client = new \GuzzleHttp\Client([
'base_uri' => 'https://app.klantly.com/api/v1/',
'headers' => ['Authorization' => 'Bearer ' . getenv('KLANTLY_API_KEY')],
]);
$response = $client->request('POST', 'deals/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70/move', [
'headers' => [
'Idempotency-Key' => '6f1c2d3e-4a5b-4c6d-8e7f-9a0b1c2d3e4f',
],
'json' => [
'stage_id' => 3,
],
]);
$data = json_decode((string) $response->getBody(), true)['data'];const response = await fetch('https://app.klantly.com/api/v1/deals/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70/move', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.KLANTLY_API_KEY}`,
'Content-Type': 'application/json',
'Idempotency-Key': '6f1c2d3e-4a5b-4c6d-8e7f-9a0b1c2d3e4f',
},
body: JSON.stringify({
"stage_id": 3
}),
});
const { data } = await response.json();import os
import requests
response = requests.post(
"https://app.klantly.com/api/v1/deals/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70/move",
headers={
"Authorization": f"Bearer {os.environ['KLANTLY_API_KEY']}",
"Idempotency-Key": "6f1c2d3e-4a5b-4c6d-8e7f-9a0b1c2d3e4f",
},
json={
"stage_id": 3
},
)
data = response.json()["data"]Réponse 200
{
"data": {
"object": "deal",
"id": "9d3f7a20-1c5e-4d7b-8a2f-3e4c5d6f7a81",
"title": "Veranda 5x3 m",
"description": null,
"status": "open",
"value": "8450.00",
"currency": "EUR",
"value_source": "manual",
"stage": {
"object": "pipeline_stage",
"id": "3"
},
"customer_id": "9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70",
"assigned_user_id": "7",
"source": "api",
"lost_reason": null,
"is_archived": false,
"stage_changed_at": "2026-09-14T10:15:00Z",
"won_at": null,
"lost_at": null,
"archived_at": null,
"created_at": "2026-09-14T10:15:00Z",
"updated_at": "2026-09-14T10:15:00Z"
}
}Erreurs possibles
-
403
insufficient_scope— Cette clé API n'a pas accès à cette action. -
422
validation_failed— Les données saisies ne sont pas valides. -
422
unknown_field— Les données contiennent un champ inconnu. -
415
unsupported_media_type— Ce format n'est pas pris en charge. -
413
payload_too_large— Le corps de la requête est trop volumineux. -
404
not_found— Introuvable. -
422
idempotency_key_reused— Cette Idempotency-Key a déjà été utilisée pour une autre requête. -
409
idempotency_in_progress— Une requête avec cette Idempotency-Key est encore en cours.
Gagner un deal
/api/v1/deals/{deal}/win
Déplace le deal vers l'étape que votre entreprise a définie comme gagnée. S'il est déjà gagné, rien ne change.
- Scope
-
deals.write— Créer, modifier, déplacer et archiver les affaires - Fonctionnalité requise
pipeline
Envoyez une Idempotency-Key : une nouvelle tentative après un délai d'attente ne crée alors jamais de doublon.
Paramètres de chemin
| Nom | Type | Description |
|---|---|---|
deal obligatoire |
string (uuid) | L'id (UUID) du deal. |
Exemple de requête
curl -X POST "https://app.klantly.com/api/v1/deals/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70/win" \
-H "Authorization: Bearer $KLANTLY_API_KEY" \
-H "Idempotency-Key: 6f1c2d3e-4a5b-4c6d-8e7f-9a0b1c2d3e4f"$client = new \GuzzleHttp\Client([
'base_uri' => 'https://app.klantly.com/api/v1/',
'headers' => ['Authorization' => 'Bearer ' . getenv('KLANTLY_API_KEY')],
]);
$response = $client->request('POST', 'deals/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70/win', [
'headers' => [
'Idempotency-Key' => '6f1c2d3e-4a5b-4c6d-8e7f-9a0b1c2d3e4f',
],
]);
$data = json_decode((string) $response->getBody(), true)['data'];const response = await fetch('https://app.klantly.com/api/v1/deals/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70/win', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.KLANTLY_API_KEY}`,
'Idempotency-Key': '6f1c2d3e-4a5b-4c6d-8e7f-9a0b1c2d3e4f',
},
});
const { data } = await response.json();import os
import requests
response = requests.post(
"https://app.klantly.com/api/v1/deals/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70/win",
headers={
"Authorization": f"Bearer {os.environ['KLANTLY_API_KEY']}",
"Idempotency-Key": "6f1c2d3e-4a5b-4c6d-8e7f-9a0b1c2d3e4f",
},
)
data = response.json()["data"]Réponse 200
{
"data": {
"object": "deal",
"id": "9d3f7a20-1c5e-4d7b-8a2f-3e4c5d6f7a81",
"title": "Veranda 5x3 m",
"description": null,
"status": "open",
"value": "8450.00",
"currency": "EUR",
"value_source": "manual",
"stage": {
"object": "pipeline_stage",
"id": "3"
},
"customer_id": "9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70",
"assigned_user_id": "7",
"source": "api",
"lost_reason": null,
"is_archived": false,
"stage_changed_at": "2026-09-14T10:15:00Z",
"won_at": null,
"lost_at": null,
"archived_at": null,
"created_at": "2026-09-14T10:15:00Z",
"updated_at": "2026-09-14T10:15:00Z"
}
}Erreurs possibles
-
403
insufficient_scope— Cette clé API n'a pas accès à cette action. -
404
not_found— Introuvable. -
409
invalid_state_transition— Cette action n'est pas possible dans le statut actuel. -
422
idempotency_key_reused— Cette Idempotency-Key a déjà été utilisée pour une autre requête. -
409
idempotency_in_progress— Une requête avec cette Idempotency-Key est encore en cours.
Perdre un deal
/api/v1/deals/{deal}/lose
Déplace le deal vers l'étape que votre entreprise a définie comme perdue, avec une raison facultative.
- Scope
-
deals.write— Créer, modifier, déplacer et archiver les affaires - Fonctionnalité requise
pipeline
Envoyez une Idempotency-Key : une nouvelle tentative après un délai d'attente ne crée alors jamais de doublon.
Paramètres de chemin
| Nom | Type | Description |
|---|---|---|
deal obligatoire |
string (uuid) | L'id (UUID) du deal. |
Corps (JSON)
| Champ | Type | Description |
|---|---|---|
lost_reason
facultatif
|
string | Pourquoi le deal a été perdu, ou null. peut être vide (null) · au maximum 255 caractères |
Exemple de requête
curl -X POST "https://app.klantly.com/api/v1/deals/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70/lose" \
-H "Authorization: Bearer $KLANTLY_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: 6f1c2d3e-4a5b-4c6d-8e7f-9a0b1c2d3e4f" \
-d '{
"lost_reason": "Te duur"
}'$client = new \GuzzleHttp\Client([
'base_uri' => 'https://app.klantly.com/api/v1/',
'headers' => ['Authorization' => 'Bearer ' . getenv('KLANTLY_API_KEY')],
]);
$response = $client->request('POST', 'deals/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70/lose', [
'headers' => [
'Idempotency-Key' => '6f1c2d3e-4a5b-4c6d-8e7f-9a0b1c2d3e4f',
],
'json' => [
'lost_reason' => 'Te duur',
],
]);
$data = json_decode((string) $response->getBody(), true)['data'];const response = await fetch('https://app.klantly.com/api/v1/deals/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70/lose', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.KLANTLY_API_KEY}`,
'Content-Type': 'application/json',
'Idempotency-Key': '6f1c2d3e-4a5b-4c6d-8e7f-9a0b1c2d3e4f',
},
body: JSON.stringify({
"lost_reason": "Te duur"
}),
});
const { data } = await response.json();import os
import requests
response = requests.post(
"https://app.klantly.com/api/v1/deals/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70/lose",
headers={
"Authorization": f"Bearer {os.environ['KLANTLY_API_KEY']}",
"Idempotency-Key": "6f1c2d3e-4a5b-4c6d-8e7f-9a0b1c2d3e4f",
},
json={
"lost_reason": "Te duur"
},
)
data = response.json()["data"]Réponse 200
{
"data": {
"object": "deal",
"id": "9d3f7a20-1c5e-4d7b-8a2f-3e4c5d6f7a81",
"title": "Veranda 5x3 m",
"description": null,
"status": "open",
"value": "8450.00",
"currency": "EUR",
"value_source": "manual",
"stage": {
"object": "pipeline_stage",
"id": "3"
},
"customer_id": "9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70",
"assigned_user_id": "7",
"source": "api",
"lost_reason": null,
"is_archived": false,
"stage_changed_at": "2026-09-14T10:15:00Z",
"won_at": null,
"lost_at": null,
"archived_at": null,
"created_at": "2026-09-14T10:15:00Z",
"updated_at": "2026-09-14T10:15:00Z"
}
}Erreurs possibles
-
403
insufficient_scope— Cette clé API n'a pas accès à cette action. -
422
validation_failed— Les données saisies ne sont pas valides. -
422
unknown_field— Les données contiennent un champ inconnu. -
415
unsupported_media_type— Ce format n'est pas pris en charge. -
413
payload_too_large— Le corps de la requête est trop volumineux. -
404
not_found— Introuvable. -
409
invalid_state_transition— Cette action n'est pas possible dans le statut actuel. -
422
idempotency_key_reused— Cette Idempotency-Key a déjà été utilisée pour une autre requête. -
409
idempotency_in_progress— Une requête avec cette Idempotency-Key est encore en cours.
Archiver un deal
/api/v1/deals/{deal}/archive
Retire le deal du tableau sans le supprimer. Les deals ne peuvent pas être supprimés via l'API.
- Scope
-
deals.write— Créer, modifier, déplacer et archiver les affaires - Fonctionnalité requise
pipeline
Envoyez une Idempotency-Key : une nouvelle tentative après un délai d'attente ne crée alors jamais de doublon.
Paramètres de chemin
| Nom | Type | Description |
|---|---|---|
deal obligatoire |
string (uuid) | L'id (UUID) du deal. |
Exemple de requête
curl -X POST "https://app.klantly.com/api/v1/deals/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70/archive" \
-H "Authorization: Bearer $KLANTLY_API_KEY" \
-H "Idempotency-Key: 6f1c2d3e-4a5b-4c6d-8e7f-9a0b1c2d3e4f"$client = new \GuzzleHttp\Client([
'base_uri' => 'https://app.klantly.com/api/v1/',
'headers' => ['Authorization' => 'Bearer ' . getenv('KLANTLY_API_KEY')],
]);
$response = $client->request('POST', 'deals/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70/archive', [
'headers' => [
'Idempotency-Key' => '6f1c2d3e-4a5b-4c6d-8e7f-9a0b1c2d3e4f',
],
]);
$data = json_decode((string) $response->getBody(), true)['data'];const response = await fetch('https://app.klantly.com/api/v1/deals/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70/archive', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.KLANTLY_API_KEY}`,
'Idempotency-Key': '6f1c2d3e-4a5b-4c6d-8e7f-9a0b1c2d3e4f',
},
});
const { data } = await response.json();import os
import requests
response = requests.post(
"https://app.klantly.com/api/v1/deals/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70/archive",
headers={
"Authorization": f"Bearer {os.environ['KLANTLY_API_KEY']}",
"Idempotency-Key": "6f1c2d3e-4a5b-4c6d-8e7f-9a0b1c2d3e4f",
},
)
data = response.json()["data"]Réponse 200
{
"data": {
"object": "deal",
"id": "9d3f7a20-1c5e-4d7b-8a2f-3e4c5d6f7a81",
"title": "Veranda 5x3 m",
"description": null,
"status": "open",
"value": "8450.00",
"currency": "EUR",
"value_source": "manual",
"stage": {
"object": "pipeline_stage",
"id": "3"
},
"customer_id": "9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70",
"assigned_user_id": "7",
"source": "api",
"lost_reason": null,
"is_archived": false,
"stage_changed_at": "2026-09-14T10:15:00Z",
"won_at": null,
"lost_at": null,
"archived_at": null,
"created_at": "2026-09-14T10:15:00Z",
"updated_at": "2026-09-14T10:15:00Z"
}
}Erreurs possibles
-
403
insufficient_scope— Cette clé API n'a pas accès à cette action. -
404
not_found— Introuvable. -
422
idempotency_key_reused— Cette Idempotency-Key a déjà été utilisée pour une autre requête. -
409
idempotency_in_progress— Une requête avec cette Idempotency-Key est encore en cours.
Restaurer un deal
/api/v1/deals/{deal}/unarchive
Remet un deal archivé sur le tableau.
- Scope
-
deals.write— Créer, modifier, déplacer et archiver les affaires - Fonctionnalité requise
pipeline
Envoyez une Idempotency-Key : une nouvelle tentative après un délai d'attente ne crée alors jamais de doublon.
Paramètres de chemin
| Nom | Type | Description |
|---|---|---|
deal obligatoire |
string (uuid) | L'id (UUID) du deal. |
Exemple de requête
curl -X POST "https://app.klantly.com/api/v1/deals/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70/unarchive" \
-H "Authorization: Bearer $KLANTLY_API_KEY" \
-H "Idempotency-Key: 6f1c2d3e-4a5b-4c6d-8e7f-9a0b1c2d3e4f"$client = new \GuzzleHttp\Client([
'base_uri' => 'https://app.klantly.com/api/v1/',
'headers' => ['Authorization' => 'Bearer ' . getenv('KLANTLY_API_KEY')],
]);
$response = $client->request('POST', 'deals/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70/unarchive', [
'headers' => [
'Idempotency-Key' => '6f1c2d3e-4a5b-4c6d-8e7f-9a0b1c2d3e4f',
],
]);
$data = json_decode((string) $response->getBody(), true)['data'];const response = await fetch('https://app.klantly.com/api/v1/deals/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70/unarchive', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.KLANTLY_API_KEY}`,
'Idempotency-Key': '6f1c2d3e-4a5b-4c6d-8e7f-9a0b1c2d3e4f',
},
});
const { data } = await response.json();import os
import requests
response = requests.post(
"https://app.klantly.com/api/v1/deals/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70/unarchive",
headers={
"Authorization": f"Bearer {os.environ['KLANTLY_API_KEY']}",
"Idempotency-Key": "6f1c2d3e-4a5b-4c6d-8e7f-9a0b1c2d3e4f",
},
)
data = response.json()["data"]Réponse 200
{
"data": {
"object": "deal",
"id": "9d3f7a20-1c5e-4d7b-8a2f-3e4c5d6f7a81",
"title": "Veranda 5x3 m",
"description": null,
"status": "open",
"value": "8450.00",
"currency": "EUR",
"value_source": "manual",
"stage": {
"object": "pipeline_stage",
"id": "3"
},
"customer_id": "9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70",
"assigned_user_id": "7",
"source": "api",
"lost_reason": null,
"is_archived": false,
"stage_changed_at": "2026-09-14T10:15:00Z",
"won_at": null,
"lost_at": null,
"archived_at": null,
"created_at": "2026-09-14T10:15:00Z",
"updated_at": "2026-09-14T10:15:00Z"
}
}Erreurs possibles
-
403
insufficient_scope— Cette clé API n'a pas accès à cette action. -
404
not_found— Introuvable. -
422
idempotency_key_reused— Cette Idempotency-Key a déjà été utilisée pour une autre requête. -
409
idempotency_in_progress— Une requête avec cette Idempotency-Key est encore en cours.
L'objet
Tous les champs sont toujours présents ; un champ sans valeur vaut null.
| Champ | Type | Description |
|---|---|---|
object |
string | Toujours « deal ». |
id |
string (uuid) | Id unique (UUID). |
title |
string | Titre du deal. |
description |
string | Description. peut être vide (null) |
status |
string | open (ouvert), won (gagné) ou lost (perdu) ; découle de l'étape. l'une des valeurs : open, won, lost |
value |
string | Valeur sous forme de texte à deux décimales, par exemple « 8450.00 ». À la création et à la modification, vous pouvez aussi envoyer un nombre. |
currency |
string | Toujours « EUR ». |
value_source |
string | quotes : la valeur découle des devis liés ; manual : définie à la main. l'une des valeurs : quotes, manual |
stage |
object | L'étape dans laquelle se trouve le deal ; les noms figurent dans Lister les étapes du pipeline. peut être vide (null) |
stage.object |
string | Toujours « pipeline_stage ». |
stage.id |
string | Id de l'étape. |
customer_id |
string (uuid) | Le client du deal. peut être vide (null) |
assigned_user_id |
string | L'utilisateur qui gère le deal, ou null. peut être vide (null) |
source |
string | D'où vient le deal ; via l'API, c'est api. peut être vide (null) |
lost_reason |
string | Pourquoi le deal a été perdu, ou null. peut être vide (null) |
is_archived |
boolean | Archivé : n'est plus sur le tableau. |
stage_changed_at |
string (date-time) | Quand le deal a changé d'étape pour la dernière fois. peut être vide (null) |
won_at |
string (date-time) | Quand le deal a été gagné. peut être vide (null) |
lost_at |
string (date-time) | Quand le deal a été perdu. peut être vide (null) |
archived_at |
string (date-time) | Quand le deal a été archivé. peut être vide (null) |
created_at |
string (date-time) | Créé le (UTC). |
updated_at |
string (date-time) | Dernière modification le (UTC). |