Référence de l'API
Demandes de service
Les signalements des clients (pannes, garantie, réclamations) avec photos : les créer depuis un portail client par exemple, les attribuer et suivre leur statut. L’intervention elle-même, avec les heures et la facturation, reste le bon d’intervention. Vous liez un rendez-vous avec appointment_id ; la signature, le choix du moment lui-même et la conversion en bon d’intervention sont faits par une personne dans Klantly ou dans l’application.
Endpoints
-
GET
/servicesLister les demandes de service -
GET
/services/{service}Récupérer une demande de service -
POST
/servicesCréer une demande de service -
PATCH
/services/{service}Modifier une demande de service -
POST
/services/{service}/statusChanger le statut d’une demande de service -
DELETE
/services/{service}Supprimer une demande de service
Lister les demandes de service
/api/v1/services
Une liste des demandes, les plus récentes d’abord, avec les photos. Filtrez par statut, priorité, client, collaborateur, devis ou date de modification.
- Scope
-
services.read— Lire les demandes de service, avec le nom, l'adresse et les coordonnées du client - Fonctionnalité requise
work_orders
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 | Le champ sur lequel trier ; un signe moins devant signifie décroissant. Les champs que vous pouvez choisir et la valeur par défaut sont indiqués avec ce paramètre. l'une des valeurs : -created_at, created_at, -updated_at, updated_at · par défaut : -created_at |
filter[status]
|
string | Uniquement les demandes ayant ce statut. l'une des valeurs : draft, planned, in_progress, completed, cancelled |
filter[priority]
|
string | Uniquement les demandes ayant cette priorité. l'une des valeurs : low, normal, high, urgent |
filter[customer_id]
|
string (uuid) | Uniquement ce qui appartient à ce client. |
filter[assigned_user_id]
|
string | Uniquement ce qui est assigné à cet utilisateur (l’id de Lister les utilisateurs). |
filter[quote_id]
|
string (uuid) | Uniquement ce qui appartient à ce devis. |
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. Prévoyez un chevauchement de quelques minutes avec votre moment précédent, car l'horloge de votre système et celle de Klantly ne sont pas exactement synchronisées, et car une modification juste après votre moment précédent tomberait sinon de justesse en dehors. La limite est inclusive : un élément modifié exactement à cet instant est inclus. |
Exemple de requête
curl "https://app.klantly.com/api/v1/services?filter[status]=planned&sort=-updated_at" \
-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', 'services', [
'query' => [
'filter[status]' => 'planned',
'sort' => '-updated_at',
],
]);
$data = json_decode((string) $response->getBody(), true)['data'];const response = await fetch('https://app.klantly.com/api/v1/services?filter[status]=planned&sort=-updated_at', {
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/services",
headers={
"Authorization": f"Bearer {os.environ['KLANTLY_API_KEY']}",
},
params={
"filter[status]": "planned",
"sort": "-updated_at"
},
)
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": "service",
"id": "9d3f8339-9ed1-4f6e-8dbc-c1dfe0f1a2bb",
"number": "SV-2026-00042",
"status": "planned",
"priority": "high",
"category": "malfunction",
"title": "Lekkage bij de dakgoot",
"location": null,
"description": "Water loopt langs de gevel na regen.",
"resolution": null,
"customer_notes": null,
"customer_id": "9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70",
"customer": {
"type": "business",
"name": "De Vries Bouw",
"email": "jan@example.com",
"phone": "+31 6 12345678",
"address": "Dorpsstraat 1",
"postal_code": "3511 AB",
"city": "Utrecht",
"country": "NL"
},
"quote_id": null,
"appointment_id": null,
"work_order_id": null,
"assigned_user_id": "usr_0k3j9x21m4zq8p",
"language": "nl",
"reported_at": null,
"scheduled_at": "2026-10-01T08:00:00Z",
"started_at": null,
"completed_at": null,
"signature": {
"is_signed": false,
"signed_by_name": null,
"signed_at": null
},
"photos": [],
"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 une demande de service
/api/v1/services/{service}
Une demande par id, avec ses photos (et un lien de téléchargement) et l’état de la signature.
- Scope
-
services.read— Lire les demandes de service, avec le nom, l'adresse et les coordonnées du client - Fonctionnalité requise
work_orders
Paramètres de chemin
| Nom | Type | Description |
|---|---|---|
service obligatoire |
string (uuid) | L’id (UUID) de la demande de service. |
Exemple de requête
curl "https://app.klantly.com/api/v1/services/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', 'services/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70');
$data = json_decode((string) $response->getBody(), true)['data'];const response = await fetch('https://app.klantly.com/api/v1/services/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/services/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70",
headers={
"Authorization": f"Bearer {os.environ['KLANTLY_API_KEY']}",
},
)
data = response.json()["data"]Réponse 200
{
"data": {
"object": "service",
"id": "9d3f8339-9ed1-4f6e-8dbc-c1dfe0f1a2bb",
"number": "SV-2026-00042",
"status": "planned",
"priority": "high",
"category": "malfunction",
"title": "Lekkage bij de dakgoot",
"location": null,
"description": "Water loopt langs de gevel na regen.",
"resolution": null,
"customer_notes": null,
"customer_id": "9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70",
"customer": {
"type": "business",
"name": "De Vries Bouw",
"email": "jan@example.com",
"phone": "+31 6 12345678",
"address": "Dorpsstraat 1",
"postal_code": "3511 AB",
"city": "Utrecht",
"country": "NL"
},
"quote_id": null,
"appointment_id": null,
"work_order_id": null,
"assigned_user_id": "usr_0k3j9x21m4zq8p",
"language": "nl",
"reported_at": null,
"scheduled_at": "2026-10-01T08:00:00Z",
"started_at": null,
"completed_at": null,
"signature": {
"is_signed": false,
"signed_by_name": null,
"signed_at": null
},
"photos": [],
"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 une demande de service
/api/v1/services
Crée une demande pour un client, en brouillon ou planifiée. Klantly lui attribue un numéro d’une série propre (SV-année-numéro par défaut) ; le nom, l’adresse et les coordonnées proviennent du client. Sans reported_at, c’est le moment de la création.
- Scope
-
services.write— Créer et modifier des demandes de service, changer leur statut et ajouter des photos - Fonctionnalité requise
work_orders
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. Obligatoire à la création ; le nom, l’adresse et les coordonnées proviennent du client. |
title
obligatoire
|
string | Objet de la demande. Obligatoire à la création. au maximum 255 caractères |
status
facultatif
|
string | draft (brouillon), planned (planifiée), in_progress (en cours), completed (clôturée) ou cancelled (annulée). À la création : draft ou planned. l'une des valeurs : draft, planned |
category
facultatif
|
string | Type de demande, par exemple malfunction (panne), warranty (garantie), maintenance (entretien), complaint (réclamation), question ou other. Texte libre : une entreprise peut utiliser ses propres types. peut être vide (null) · au maximum 64 caractères |
priority
facultatif
|
string | low, normal, high ou urgent. Par défaut normal. l'une des valeurs : low, normal, high, urgent |
location
facultatif
|
string | Où se situe le problème, si ce n’est pas l’adresse du client. peut être vide (null) · au maximum 255 caractères |
description
facultatif
|
string | Le problème tel que le client le signale. peut être vide (null) · au maximum 20000 caractères |
resolution
facultatif
|
string | Ce qui a été fait pour le résoudre. peut être vide (null) · au maximum 20000 caractères |
customer_notes
facultatif
|
string | Remarques destinées au client. peut être vide (null) · au maximum 20000 caractères |
reported_at
facultatif
|
string (date-time) | Quand la demande est arrivée (UTC). Vide à la création signifie le moment de la création. En entrée : ISO 8601 avec fuseau horaire. peut être vide (null) |
scheduled_at
facultatif
|
string (date-time) | Quand la visite de service est planifiée (UTC). En entrée : ISO 8601 avec fuseau horaire. peut être vide (null) |
assigned_user_id
facultatif
|
string | Le collaborateur qui prend en charge la demande, ou null. peut être vide (null) |
appointment_id
facultatif
|
string (uuid) | Le rendez-vous pour la visite de service, ou null. peut être vide (null) |
quote_id
facultatif
|
string (uuid) | Le devis auquel la demande est liée, ou null. peut être vide (null) |
language
facultatif
|
string | Langue de la demande : nl, en, de ou fr. l'une des valeurs : nl, en, de, fr |
Exemple de requête
curl -X POST "https://app.klantly.com/api/v1/services" \
-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": "Lekkage bij de dakgoot",
"category": "malfunction",
"priority": "high",
"description": "Water loopt langs de gevel na regen."
}'$client = new \GuzzleHttp\Client([
'base_uri' => 'https://app.klantly.com/api/v1/',
'headers' => ['Authorization' => 'Bearer ' . getenv('KLANTLY_API_KEY')],
]);
$response = $client->request('POST', 'services', [
'headers' => [
'Idempotency-Key' => '6f1c2d3e-4a5b-4c6d-8e7f-9a0b1c2d3e4f',
],
'json' => [
'customer_id' => '9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70',
'title' => 'Lekkage bij de dakgoot',
'category' => 'malfunction',
'priority' => 'high',
'description' => 'Water loopt langs de gevel na regen.',
],
]);
$data = json_decode((string) $response->getBody(), true)['data'];const response = await fetch('https://app.klantly.com/api/v1/services', {
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": "Lekkage bij de dakgoot",
"category": "malfunction",
"priority": "high",
"description": "Water loopt langs de gevel na regen."
}),
});
const { data } = await response.json();import os
import requests
response = requests.post(
"https://app.klantly.com/api/v1/services",
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": "Lekkage bij de dakgoot",
"category": "malfunction",
"priority": "high",
"description": "Water loopt langs de gevel na regen."
},
)
data = response.json()["data"]Réponse 201
{
"data": {
"object": "service",
"id": "9d3f8339-9ed1-4f6e-8dbc-c1dfe0f1a2bb",
"number": "SV-2026-00042",
"status": "planned",
"priority": "high",
"category": "malfunction",
"title": "Lekkage bij de dakgoot",
"location": null,
"description": "Water loopt langs de gevel na regen.",
"resolution": null,
"customer_notes": null,
"customer_id": "9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70",
"customer": {
"type": "business",
"name": "De Vries Bouw",
"email": "jan@example.com",
"phone": "+31 6 12345678",
"address": "Dorpsstraat 1",
"postal_code": "3511 AB",
"city": "Utrecht",
"country": "NL"
},
"quote_id": null,
"appointment_id": null,
"work_order_id": null,
"assigned_user_id": "usr_0k3j9x21m4zq8p",
"language": "nl",
"reported_at": null,
"scheduled_at": "2026-10-01T08:00:00Z",
"started_at": null,
"completed_at": null,
"signature": {
"is_signed": false,
"signed_by_name": null,
"signed_at": null
},
"photos": [],
"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. -
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 une demande de service
/api/v1/services/{service}
Ne modifie que les champs que vous envoyez. Vous ne définissez pas vous-même le lien avec le bon d’intervention : il apparaît lorsque vous convertissez la demande dans Klantly.
- Scope
-
services.write— Créer et modifier des demandes de service, changer leur statut et ajouter des photos - Fonctionnalité requise
work_orders
Envoyez l'ETag dans If-Match : vous n'écraserez jamais par erreur une version plus récente.
Paramètres de chemin
| Nom | Type | Description |
|---|---|---|
service obligatoire |
string (uuid) | L’id (UUID) de la demande de service. |
Corps (JSON)
| Champ | Type | Description |
|---|---|---|
title
facultatif
|
string | Objet de la demande. Obligatoire à la création. au maximum 255 caractères |
category
facultatif
|
string | Type de demande, par exemple malfunction (panne), warranty (garantie), maintenance (entretien), complaint (réclamation), question ou other. Texte libre : une entreprise peut utiliser ses propres types. peut être vide (null) · au maximum 64 caractères |
priority
facultatif
|
string | low, normal, high ou urgent. Par défaut normal. l'une des valeurs : low, normal, high, urgent |
location
facultatif
|
string | Où se situe le problème, si ce n’est pas l’adresse du client. peut être vide (null) · au maximum 255 caractères |
description
facultatif
|
string | Le problème tel que le client le signale. peut être vide (null) · au maximum 20000 caractères |
resolution
facultatif
|
string | Ce qui a été fait pour le résoudre. peut être vide (null) · au maximum 20000 caractères |
customer_notes
facultatif
|
string | Remarques destinées au client. peut être vide (null) · au maximum 20000 caractères |
reported_at
facultatif
|
string (date-time) | Quand la demande est arrivée (UTC). Vide à la création signifie le moment de la création. En entrée : ISO 8601 avec fuseau horaire. peut être vide (null) |
scheduled_at
facultatif
|
string (date-time) | Quand la visite de service est planifiée (UTC). En entrée : ISO 8601 avec fuseau horaire. peut être vide (null) |
assigned_user_id
facultatif
|
string | Le collaborateur qui prend en charge la demande, ou null. peut être vide (null) |
appointment_id
facultatif
|
string (uuid) | Le rendez-vous pour la visite de service, ou null. peut être vide (null) |
quote_id
facultatif
|
string (uuid) | Le devis auquel la demande est liée, ou null. peut être vide (null) |
language
facultatif
|
string | Langue de la demande : nl, en, de ou fr. l'une des valeurs : nl, en, de, fr |
Exemple de requête
curl -X PATCH "https://app.klantly.com/api/v1/services/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70" \
-H "Authorization: Bearer $KLANTLY_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"resolution": "Goot opnieuw afgekit en getest."
}'$client = new \GuzzleHttp\Client([
'base_uri' => 'https://app.klantly.com/api/v1/',
'headers' => ['Authorization' => 'Bearer ' . getenv('KLANTLY_API_KEY')],
]);
$response = $client->request('PATCH', 'services/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70', [
'json' => [
'resolution' => 'Goot opnieuw afgekit en getest.',
],
]);
$data = json_decode((string) $response->getBody(), true)['data'];const response = await fetch('https://app.klantly.com/api/v1/services/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70', {
method: 'PATCH',
headers: {
Authorization: `Bearer ${process.env.KLANTLY_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
"resolution": "Goot opnieuw afgekit en getest."
}),
});
const { data } = await response.json();import os
import requests
response = requests.patch(
"https://app.klantly.com/api/v1/services/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70",
headers={
"Authorization": f"Bearer {os.environ['KLANTLY_API_KEY']}",
},
json={
"resolution": "Goot opnieuw afgekit en getest."
},
)
data = response.json()["data"]Réponse 200
{
"data": {
"object": "service",
"id": "9d3f8339-9ed1-4f6e-8dbc-c1dfe0f1a2bb",
"number": "SV-2026-00042",
"status": "planned",
"priority": "high",
"category": "malfunction",
"title": "Lekkage bij de dakgoot",
"location": null,
"description": "Water loopt langs de gevel na regen.",
"resolution": null,
"customer_notes": null,
"customer_id": "9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70",
"customer": {
"type": "business",
"name": "De Vries Bouw",
"email": "jan@example.com",
"phone": "+31 6 12345678",
"address": "Dorpsstraat 1",
"postal_code": "3511 AB",
"city": "Utrecht",
"country": "NL"
},
"quote_id": null,
"appointment_id": null,
"work_order_id": null,
"assigned_user_id": "usr_0k3j9x21m4zq8p",
"language": "nl",
"reported_at": null,
"scheduled_at": "2026-10-01T08:00:00Z",
"started_at": null,
"completed_at": null,
"signature": {
"is_signed": false,
"signed_by_name": null,
"signed_at": null
},
"photos": [],
"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.
Changer le statut d’une demande de service
/api/v1/services/{service}/status
Met la demande en brouillon, planifiée, en cours, clôturée ou annulée. Pour en cours et clôturée, started_at et completed_at sont enregistrés. Si « signature obligatoire pour le service » est activé dans les paramètres des bons de travail, une demande non signée ne peut pas être clôturée (invalid_state_transition).
- Scope
-
services.write— Créer et modifier des demandes de service, changer leur statut et ajouter des photos - Fonctionnalité requise
work_orders
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 |
|---|---|---|
service obligatoire |
string (uuid) | L’id (UUID) de la demande de service. |
Corps (JSON)
| Champ | Type | Description |
|---|---|---|
status
obligatoire
|
string | draft (brouillon), planned (planifiée), in_progress (en cours), completed (clôturée) ou cancelled (annulée). À la création : draft ou planned. l'une des valeurs : draft, planned, in_progress, completed, cancelled |
Exemple de requête
curl -X POST "https://app.klantly.com/api/v1/services/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70/status" \
-H "Authorization: Bearer $KLANTLY_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: 6f1c2d3e-4a5b-4c6d-8e7f-9a0b1c2d3e4f" \
-d '{
"status": "completed"
}'$client = new \GuzzleHttp\Client([
'base_uri' => 'https://app.klantly.com/api/v1/',
'headers' => ['Authorization' => 'Bearer ' . getenv('KLANTLY_API_KEY')],
]);
$response = $client->request('POST', 'services/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70/status', [
'headers' => [
'Idempotency-Key' => '6f1c2d3e-4a5b-4c6d-8e7f-9a0b1c2d3e4f',
],
'json' => [
'status' => 'completed',
],
]);
$data = json_decode((string) $response->getBody(), true)['data'];const response = await fetch('https://app.klantly.com/api/v1/services/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70/status', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.KLANTLY_API_KEY}`,
'Content-Type': 'application/json',
'Idempotency-Key': '6f1c2d3e-4a5b-4c6d-8e7f-9a0b1c2d3e4f',
},
body: JSON.stringify({
"status": "completed"
}),
});
const { data } = await response.json();import os
import requests
response = requests.post(
"https://app.klantly.com/api/v1/services/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70/status",
headers={
"Authorization": f"Bearer {os.environ['KLANTLY_API_KEY']}",
"Idempotency-Key": "6f1c2d3e-4a5b-4c6d-8e7f-9a0b1c2d3e4f",
},
json={
"status": "completed"
},
)
data = response.json()["data"]Réponse 200
{
"data": {
"object": "service",
"id": "9d3f8339-9ed1-4f6e-8dbc-c1dfe0f1a2bb",
"number": "SV-2026-00042",
"status": "planned",
"priority": "high",
"category": "malfunction",
"title": "Lekkage bij de dakgoot",
"location": null,
"description": "Water loopt langs de gevel na regen.",
"resolution": null,
"customer_notes": null,
"customer_id": "9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70",
"customer": {
"type": "business",
"name": "De Vries Bouw",
"email": "jan@example.com",
"phone": "+31 6 12345678",
"address": "Dorpsstraat 1",
"postal_code": "3511 AB",
"city": "Utrecht",
"country": "NL"
},
"quote_id": null,
"appointment_id": null,
"work_order_id": null,
"assigned_user_id": "usr_0k3j9x21m4zq8p",
"language": "nl",
"reported_at": null,
"scheduled_at": "2026-10-01T08:00:00Z",
"started_at": null,
"completed_at": null,
"signature": {
"is_signed": false,
"signed_by_name": null,
"signed_at": null
},
"photos": [],
"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.
Supprimer une demande de service
/api/v1/services/{service}
Supprime la demande, y compris ses photos.
- Scope
-
services.delete— Supprimer des demandes de service - Fonctionnalité requise
work_orders
Paramètres de chemin
| Nom | Type | Description |
|---|---|---|
service obligatoire |
string (uuid) | L’id (UUID) de la demande de service. |
Exemple de requête
curl -X DELETE "https://app.klantly.com/api/v1/services/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('DELETE', 'services/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70');
$data = json_decode((string) $response->getBody(), true)['data'];const response = await fetch('https://app.klantly.com/api/v1/services/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70', {
method: 'DELETE',
headers: {
Authorization: `Bearer ${process.env.KLANTLY_API_KEY}`,
},
});
const { data } = await response.json();import os
import requests
response = requests.delete(
"https://app.klantly.com/api/v1/services/9d3f6c1e-4b2a-4c8e-9f1a-2b3c4d5e6f70",
headers={
"Authorization": f"Bearer {os.environ['KLANTLY_API_KEY']}",
},
)
data = response.json()["data"]Réponse 200
{
"data": {
"object": "note",
"id": "9d3f7b41-2d6f-4e8c-9b3a-4f5d6e7a8b92",
"deleted": true
}
}Erreurs possibles
-
403
insufficient_scope— Cette clé API n'a pas accès à cette action. -
404
not_found— Introuvable.
L'objet
Tous les champs sont toujours présents ; un champ sans valeur vaut null.
| Champ | Type | Description |
|---|---|---|
object |
string | Toujours "service". |
id |
string (uuid) | Id unique (UUID). |
number |
string | Numéro de la demande, par exemple SV-2026-00042 ; Klantly l’attribue depuis une série propre, distincte des bons d’intervention. |
status |
string | draft (brouillon), planned (planifiée), in_progress (en cours), completed (clôturée) ou cancelled (annulée). À la création : draft ou planned. l'une des valeurs : draft, planned, in_progress, completed, cancelled |
priority |
string | low, normal, high ou urgent. Par défaut normal. l'une des valeurs : low, normal, high, urgent |
category |
string | Type de demande, par exemple malfunction (panne), warranty (garantie), maintenance (entretien), complaint (réclamation), question ou other. Texte libre : une entreprise peut utiliser ses propres types. peut être vide (null) |
title |
string | Objet de la demande. Obligatoire à la création. |
location |
string | Où se situe le problème, si ce n’est pas l’adresse du client. peut être vide (null) |
description |
string | Le problème tel que le client le signale. peut être vide (null) |
resolution |
string | Ce qui a été fait pour le résoudre. peut être vide (null) |
customer_notes |
string | Remarques destinées au client. peut être vide (null) |
customer_id |
string (uuid) | Le client. Obligatoire à la création ; le nom, l’adresse et les coordonnées proviennent du client. peut être vide (null) |
customer |
object | Les coordonnées du client sur la demande, telles qu’elles étaient à la création. |
customer.type |
string | individual (particulier) ou business (entreprise). peut être vide (null) |
customer.name |
string | Nom ; pour une entreprise, la raison sociale. peut être vide (null) |
customer.email |
string | Adresse e-mail. peut être vide (null) |
customer.phone |
string | Numéro de téléphone. peut être vide (null) |
customer.address |
string | Rue et numéro. peut être vide (null) |
customer.postal_code |
string | Code postal. peut être vide (null) |
customer.city |
string | Ville. peut être vide (null) |
customer.country |
string | Pays. peut être vide (null) |
quote_id |
string (uuid) | Le devis auquel la demande est liée, ou null. peut être vide (null) |
appointment_id |
string (uuid) | Le rendez-vous pour la visite de service, ou null. peut être vide (null) |
work_order_id |
string (uuid) | Le bon d’intervention issu de cette demande, ou null. Vous ne le définissez pas vous-même : il apparaît lorsque la demande est convertie dans Klantly. peut être vide (null) |
assigned_user_id |
string | Le collaborateur qui prend en charge la demande, ou null. peut être vide (null) |
language |
string | Langue de la demande : nl, en, de ou fr. l'une des valeurs : nl, en, de, fr |
reported_at |
string (date-time) | Quand la demande est arrivée (UTC). Vide à la création signifie le moment de la création. En entrée : ISO 8601 avec fuseau horaire. peut être vide (null) |
scheduled_at |
string (date-time) | Quand la visite de service est planifiée (UTC). En entrée : ISO 8601 avec fuseau horaire. peut être vide (null) |
started_at |
string (date-time) | Quand l’intervention a commencé. peut être vide (null) |
completed_at |
string (date-time) | Quand la demande a été clôturée. peut être vide (null) |
signature |
object | La signature du client à la réception (uniquement les données, pas d’image). |
signature.is_signed |
boolean | La demande est-elle signée. |
signature.signed_by_name |
string | Nom du signataire. peut être vide (null) |
signature.signed_at |
string (date-time) | Quand la signature a eu lieu. peut être vide (null) |
photos |
array<object> | Les photos de la demande. Le téléversement passe par POST /services/{id}/photos. |
photos.object |
string | Toujours "service_photo". |
photos.id |
string (uuid) | Id de la photo. |
photos.kind |
string | issue (le signalement), progress, completion (la réception) ou other. peut être vide (null) · l'une des valeurs : issue, progress, completion, other |
photos.caption |
string | Légende de la photo. peut être vide (null) |
photos.download_url |
string (uri) | Un lien signé vers la photo, valable un quart d’heure et accessible sans clé API. |
photos.created_at |
string (date-time) | Quand la photo a été ajoutée (UTC). |
created_at |
string (date-time) | Quand la demande a été créée (UTC). |
updated_at |
string (date-time) | Quand la demande a changé pour la dernière fois (UTC). |