Référence API
Connectez votre site web ou des outils externes à Check-in ARTISAN
Présentation
L'API Check-in ARTISAN vous permet d'intégrer votre entreprise de terrain à votre propre site web ou à des applications externes. Que vous souhaitiez afficher votre profil entreprise, synchroniser vos données clients et chantiers, ou exporter vos factures vers votre logiciel de comptabilité, l'API vous donne un accès programmatique complet à vos données.
Principaux cas d'usage :
- Afficher les informations de votre entreprise sur votre propre site web.
- Créer un portail client personnalisé.
- Exporter les données de visites terrain et de facturation vers votre logiciel de comptabilité.
- Automatiser des flux de travail avec d'autres outils métiers.
URL de base
Toutes les requêtes API sont adressées à :
https://checkinartisan.app/api/v1/
Toutes les réponses sont au format JSON. Les dates et horodatages utilisent le format ISO 8601.
Authentification
La plupart des endpoints de l'API nécessitent une authentification via un jeton Bearer. Vous générez ces jetons depuis le panneau d'administration, sous Compte Check-in ARTISAN > Jetons API.
Incluez le jeton dans l'en-tête Authorization de chaque requête authentifiée :
Authorization: Bearer votre-jeton-api-ici
Chaque jeton est rattaché à une seule entreprise. Vous pouvez créer plusieurs jetons pour la même entreprise (par exemple, un par intégration).
Bonnes pratiques de sécurité :
- Traitez les jetons API comme des mots de passe. Ne les incluez jamais dans le code source.
- Utilisez un jeton par intégration pour pouvoir révoquer individuellement les accès.
- Révoquez les jetons inutilisés immédiatement.
Endpoints publics
Ces endpoints ne nécessitent aucune authentification. Ils sont conçus pour une intégration sur des sites publics.
GET /api/v1/companies/{slug}
Retourne le profil public d'une entreprise.
Paramètres : {slug} est l'identifiant unique de votre entreprise (visible dans l'URL de votre espace d'administration).
Réponse :
{
"data": {
"slug": "swift-plumbing",
"name": "Swift Plumbing & Co.",
"description": "Plomberie professionnelle pour particuliers et professionnels.",
"phone": "+33 1 23 45 67 89",
"mobile": null,
"email": "contact@swiftplumbing.fr",
"website": "https://swiftplumbing.fr",
"address": "12 Rue des Artisans",
"address2": null,
"zip_code": "75001",
"city": "Paris",
"country": "FR",
"opening_hours": { "monday": "8:00-18:00" },
"social": {
"facebook": null,
"instagram": "https://instagram.com/swiftplumbing",
"twitter": null,
"youtube": null
},
"locale": "fr",
"currency": "EUR",
"timezone": "Europe/Paris"
}
}
Endpoints authentifiés
Tous les endpoints ci-dessous nécessitent un jeton Bearer valide dans l'en-tête Authorization.
GET /api/v1/company
Retourne le profil complet de l'entreprise associée au jeton API, y compris le plan d'abonnement actif.
Réponse : identique à l'endpoint public, avec en plus un champ "plan" ("free", "solo" ou "pro").
Clients
GET /api/v1/customers
Liste tous les clients de votre entreprise.
Paramètres de requête :
| Paramètre | Type | Description |
|---|---|---|
search |
string | Filtrer par nom, e-mail ou téléphone. |
per_page |
integer | Résultats par page (défaut : 25, max : 100). |
page |
integer | Numéro de page (défaut : 1). |
Réponse :
{
"data": [
{
"id": 1,
"first_name": "Marie",
"last_name": "Dupont",
"full_name": "Marie Dupont",
"email": "marie@exemple.fr",
"phone": "+33 6 12 34 56 78",
"mobile": null,
"address": "12 Rue des Artisans",
"address2": null,
"zip_code": "75001",
"city": "Paris",
"country": "FR",
"notes": null,
"send_sms": true,
"is_walk_in": false,
"created_at": "2026-01-15T10:30:00+01:00",
"updated_at": "2026-01-15T10:30:00+01:00"
}
],
"meta": {
"current_page": 1,
"last_page": 3,
"per_page": 25,
"total": 72
}
}
POST /api/v1/customers
Crée un nouveau client.
Corps de la requête :
{
"first_name": "Marie",
"last_name": "Dupont",
"email": "marie@exemple.fr",
"phone": "+33 6 12 34 56 78",
"mobile": "+33 7 98 76 54 32",
"address": "12 Rue des Artisans",
"address2": "Apt 3B",
"zip_code": "75001",
"city": "Paris",
"country": "FR",
"notes": "Préfère les rendez-vous le matin.",
"send_sms": true
}
| Champ | Type | Obligatoire | Description |
|---|---|---|---|
first_name |
string | Oui | Prénom (max 255). |
last_name |
string | Oui | Nom (max 255). |
email |
string | Non | Adresse e-mail. |
phone |
string | Non | Numéro de téléphone (max 50). |
mobile |
string | Non | Numéro de portable (max 50). |
address |
string | Non | Adresse, ligne 1 (max 255). |
address2 |
string | Non | Adresse, ligne 2 (max 255). |
zip_code |
string | Non | Code postal (max 20). |
city |
string | Non | Ville (max 255). |
country |
string | Non | Code pays ISO 3166-1 alpha-2 (ex. "FR"). |
notes |
string | Non | Notes internes (max 5000 caractères). |
send_sms |
boolean | Non | Inclure ce client dans les rappels SMS. |
Réponse (201) : le client créé (mêmes champs que la liste).
GET /api/v1/customers/{id}
Récupère un client avec ses chantiers.
Réponse : mêmes champs que la liste, avec en plus un tableau jobs :
{
"data": {
"id": 1,
"first_name": "Marie",
"last_name": "Dupont",
"full_name": "Marie Dupont",
"email": "marie@exemple.fr",
"phone": "+33 6 12 34 56 78",
"mobile": null,
"address": "12 Rue des Artisans",
"address2": null,
"zip_code": "75001",
"city": "Paris",
"country": "FR",
"notes": null,
"send_sms": true,
"is_walk_in": false,
"created_at": "2026-01-15T10:30:00+01:00",
"updated_at": "2026-01-15T10:30:00+01:00",
"jobs": [
{ "id": 12, "title": "Réparation plomberie salle de bain" }
]
}
}
PUT /api/v1/customers/{id}
Met à jour un client. Envoyez uniquement les champs à modifier. Accepte les mêmes champs que POST /api/v1/customers, tous optionnels.
DELETE /api/v1/customers/{id}
Supprime un client. Retourne 204 No Content.
Chantiers
GET /api/v1/jobs
Liste tous les chantiers de votre entreprise.
Paramètres de requête :
| Paramètre | Type | Description |
|---|---|---|
customer_id |
integer | Filtrer par client. |
status |
string | Filtrer par statut (draft, open, in_progress, completed, cancelled). |
per_page |
integer | Résultats par page (défaut : 25, max : 100). |
page |
integer | Numéro de page (défaut : 1). |
Réponse :
{
"data": [
{
"id": 12,
"customer_id": 1,
"job_type_id": 3,
"title": "Réparation plomberie salle de bain",
"description": "Remplacement mitigeur et rejointement baignoire.",
"address": "12 Rue des Artisans, Paris",
"status": "in_progress",
"created_at": "2026-02-01T09:00:00+01:00",
"updated_at": "2026-02-10T14:30:00+01:00"
}
],
"meta": {
"current_page": 1,
"last_page": 2,
"per_page": 25,
"total": 47
}
}
POST /api/v1/jobs
Crée un nouveau chantier.
| Champ | Type | Obligatoire | Description |
|---|---|---|---|
customer_id |
integer | Oui | Identifiant du client associé au chantier. |
title |
string | Oui | Intitulé du chantier (max 255). |
job_type_id |
integer | Non | Identifiant du type de travaux. |
description |
string | Non | Description du chantier (max 5000). |
address |
string | Non | Adresse du chantier (max 255). |
status |
string | Non | Statut initial : draft, open, in_progress, completed ou cancelled. |
Réponse (201) : le chantier créé.
GET /api/v1/jobs/{id}
Récupère un chantier avec le client, le type de travaux et le nombre de visites terrain.
Réponse :
{
"data": {
"id": 12,
"customer_id": 1,
"job_type_id": 3,
"title": "Réparation plomberie salle de bain",
"description": "Remplacement mitigeur et rejointement baignoire.",
"address": "12 Rue des Artisans, Paris",
"status": "in_progress",
"created_at": "2026-02-01T09:00:00+01:00",
"updated_at": "2026-02-10T14:30:00+01:00",
"customer": {
"id": 1,
"full_name": "Marie Dupont"
},
"job_type": {
"id": 3,
"name": "Plomberie"
},
"site_visits_count": 2
}
}
Le champ job_type.name est retourné dans la langue de l'entreprise (fr ou en).
PUT /api/v1/jobs/{id}
Met à jour un chantier. Envoyez uniquement les champs à modifier. Accepte job_type_id, title, description, address et status.
DELETE /api/v1/jobs/{id}
Supprime un chantier. Retourne 204 No Content.
Visites terrain
GET /api/v1/site-visits
Liste les visites terrain de votre entreprise.
Paramètres de requête :
| Paramètre | Type | Description |
|---|---|---|
from |
string | Date de début du filtre (YYYY-MM-DD). |
to |
string | Date de fin du filtre (YYYY-MM-DD). |
customer_id |
integer | Filtrer par client. |
job_id |
integer | Filtrer par chantier. |
status |
string | Filtrer par statut (scheduled, completed, cancelled). |
per_page |
integer | Résultats par page (défaut : 25, max : 100). |
page |
integer | Numéro de page. |
Réponse :
{
"data": [
{
"id": 7,
"job_id": 12,
"customer_id": 1,
"team_member_id": 2,
"scheduled_at": "2026-03-20T09:00:00+01:00",
"duration_minutes": 120,
"status": "scheduled",
"notes": "Le client sera présent dès 9h.",
"created_at": "2026-03-01T11:00:00+01:00",
"updated_at": "2026-03-01T11:00:00+01:00"
}
],
"meta": {
"current_page": 1,
"last_page": 1,
"per_page": 25,
"total": 5
}
}
POST /api/v1/site-visits
Crée une nouvelle visite terrain.
| Champ | Type | Obligatoire | Description |
|---|---|---|---|
job_id |
integer | Oui | Identifiant du chantier associé à cette visite. |
scheduled_at |
string | Oui | Date et heure planifiées (ISO 8601, ex. "2026-03-20T09:00:00"). |
customer_id |
integer | Non | Identifiant du client (par défaut, le client du chantier). |
duration_minutes |
integer | Non | Durée estimée en minutes (min : 1). |
notes |
string | Non | Notes internes pour la visite (max 2000). |
status |
string | Non | Statut initial : scheduled, completed ou cancelled. |
team_member_id |
integer | Non | Identifiant du technicien assigné à la visite. |
Réponse (201) : la visite terrain créée.
GET /api/v1/site-visits/{id}
Récupère une visite terrain avec les détails du chantier, du client et du technicien.
Réponse :
{
"data": {
"id": 7,
"job_id": 12,
"customer_id": 1,
"team_member_id": 2,
"scheduled_at": "2026-03-20T09:00:00+01:00",
"duration_minutes": 120,
"status": "scheduled",
"notes": "Le client sera présent dès 9h.",
"created_at": "2026-03-01T11:00:00+01:00",
"updated_at": "2026-03-01T11:00:00+01:00",
"job": {
"id": 12,
"title": "Réparation plomberie salle de bain"
},
"customer": {
"id": 1,
"full_name": "Marie Dupont"
},
"team_member": {
"id": 2,
"name": "Jean Martin"
}
}
}
PUT /api/v1/site-visits/{id}
Met à jour une visite terrain. Envoyez uniquement les champs à modifier. Accepte scheduled_at, duration_minutes, notes, status et team_member_id.
DELETE /api/v1/site-visits/{id}
Supprime une visite terrain. Retourne 204 No Content.
Factures
Les factures utilisent un système de numérotation séquentielle immuable. Pour garantir l'intégrité de l'audit, les factures ne peuvent pas être modifiées ni supprimées via l'API.
GET /api/v1/invoices
Liste les factures de votre entreprise.
Paramètres de requête :
| Paramètre | Type | Description |
|---|---|---|
from |
string | Date de création de début (YYYY-MM-DD). |
to |
string | Date de création de fin (YYYY-MM-DD). |
customer_id |
integer | Filtrer par client. |
paid |
boolean | Filtrer par statut de paiement. |
per_page |
integer | Résultats par page (défaut : 25, max : 100). |
page |
integer | Numéro de page. |
Réponse :
{
"data": [
{
"id": 42,
"invoice_number": "FA260200042",
"customer_id": 1,
"paid": true,
"total_with_tax": 180.00,
"notes": "Merci pour votre confiance !",
"created_at": "2026-02-15T10:00:00+01:00",
"updated_at": "2026-02-15T10:00:00+01:00"
}
],
"meta": {
"current_page": 1,
"last_page": 2,
"per_page": 25,
"total": 38
}
}
GET /api/v1/invoices/{id}
Récupère une facture avec ses lignes et les coordonnées du client.
Réponse :
{
"data": {
"id": 42,
"invoice_number": "FA260200042",
"customer_id": 1,
"paid": true,
"total_with_tax": 180.00,
"notes": "Merci pour votre confiance !",
"created_at": "2026-02-15T10:00:00+01:00",
"updated_at": "2026-02-15T10:00:00+01:00",
"customer": {
"id": 1,
"full_name": "Marie Dupont",
"email": "marie@exemple.fr"
},
"lines": [
{
"id": 101,
"item_id": 5,
"description": "Réparation plomberie - salle de bain",
"quantity": 1,
"unit_price_with_tax": 180.00,
"discount_percent": 0,
"line_total_with_tax": 180.00
}
]
}
}
POST /api/v1/invoices
Crée une nouvelle facture. Le numéro de facture est attribué automatiquement.
Corps de la requête :
{
"customer_id": 1,
"paid": false,
"notes": "Merci pour votre confiance !",
"lines": [
{
"item_id": 5,
"description": "Réparation plomberie - salle de bain",
"quantity": 1,
"price_with_tax": 180.00,
"discount": 0
}
]
}
| Champ | Type | Obligatoire | Description |
|---|---|---|---|
customer_id |
integer | Oui | Identifiant du client. |
paid |
boolean | Non | Facture déjà réglée (défaut : false). |
notes |
string | Non | Notes imprimées sur la facture (max 5000). |
lines |
array | Non | Tableau des lignes de facturation. |
lines[].item_id |
integer | Non | Identifiant de l'article du catalogue. |
lines[].description |
string | Non | Description de la ligne (max 1000). |
lines[].quantity |
number | Oui* | Quantité (obligatoire si lines est présent, min : 0.01). |
lines[].price_with_tax |
number | Oui* | Prix unitaire TTC (obligatoire si lines est présent, min : 0). |
lines[].discount |
number | Non | Remise en pourcentage sur cette ligne (0-50). |
*Obligatoire uniquement lorsque le tableau lines est présent.
Réponse (201) : la facture créée au même format que GET /api/v1/invoices/{id}.
Réponses d'erreur
L'API retourne des codes HTTP standards. Les réponses d'erreur incluent un corps JSON avec un champ error et, pour les erreurs de validation, un champ messages.
| Code | Signification |
|---|---|
| 401 | Non authentifié. Le jeton est absent ou invalide. |
| 403 | Accès refusé. Vous n'avez pas accès à cette ressource. |
| 404 | Ressource introuvable. |
| 422 | Erreur de validation. Consultez le champ messages. |
| 429 | Trop de requêtes. Limite de 60 requêtes par minute. |
| 500 | Erreur interne du serveur. |
Exemple d'erreur de validation :
{
"error": "Validation failed.",
"messages": {
"first_name": ["The first name field is required."],
"email": ["The email must be a valid email address."]
}
}
Pagination
Tous les endpoints de liste retournent des résultats paginés avec un objet meta :
{
"meta": {
"current_page": 1,
"last_page": 5,
"per_page": 25,
"total": 118
}
}
Utilisez les paramètres page et per_page pour naviguer dans les résultats.
Premiers pas
- Connectez-vous à votre espace d'administration Check-in ARTISAN.
- Allez dans Compte Check-in ARTISAN > Jetons API.
- Cliquez sur Générer un jeton, donnez-lui un nom et copiez le jeton affiché.
- Utilisez ce jeton dans l'en-tête
Authorization: Bearerde toutes vos requêtes authentifiées. - Testez avec une requête simple vers
/api/v1/companypour vérifier que votre jeton fonctionne.
Support
Pour toute question sur l'intégration de l'API, contactez-nous via la page Contact ou consultez la documentation complète.