Introduction
Lisez et écrivez vos données CRM par programmation. Utilisez cette API pour synchroniser vos fiches avec des outils externes, automatiser des traitements ou alimenter des intégrations avec des plateformes ERP, e-commerce et analytiques.
Authentification
Chaque requête doit inclure un jeton d'accès personnel (PAT).
- Ouvrez votre CRM Initiative
- Allez dans Mes préférences → Jetons d'API
- Créez un jeton. Il ressemble à
itv_YXBpdG9rZW4_a1b2c3d4... - Envoyez-le comme jeton
Bearerdans chaque requête :
curl https://app.initiative-crm.com/api/v1/me \
-H "Authorization: Bearer itv_YXBpdG9rZW4_a1b2c3d4..."URL de base
L'URL de base de l'API dépend de l'environnement :
| Environnement | URL de base |
|---|---|
| Production | https://app.initiative-crm.com/api/v1 |
| Pré-production | https://test.initiative.solutions/api/v1 |
Vous n'avez pas besoin de préciser à quelle instance vous appartenez dans l'URL — votre instance est encodée dans le jeton d'API et résolue côté serveur.
Démarrage rapide — créez votre premier contact
curl -X POST https://app.initiative-crm.com/api/v1/contacts \
-H "Authorization: Bearer itv_YXBpdG9rZW4_a1b2c3d4..." \
-H "Content-Type: application/json" \
-d '{
"data": {
"attributes": {
"firstname": "Jean",
"lastname": "Dupont",
"email": "[email protected]"
}
}
}'Une réponse réussie renvoie 201 Created avec le nouveau contact :
{
"data": {
"id": "65",
"type": "contacts",
"attributes": {
"firstname": "Jean",
"lastname": "Dupont",
"email": "[email protected]",
"assigned_user_id": { "id": "1", "label": "Admin User" },
"createdtime": "2026-05-15T10:00:00Z",
"modifiedtime": "2026-05-15T10:00:00Z"
}
},
"meta": { "request_id": "550e8400-e29b-41d4-a716-446655440000" }
}Le même schéma fonctionne pour n'importe quel module — remplacez /contacts par /leads, /accounts, /invoices, etc. Les champs obligatoires de chaque module sont indiqués dans son schéma, dans la barre latérale.
Concepts
Modules
Les fiches sont organisées en modules. Chaque module représente un type d'objet métier — Contacts, Accounts, Invoices, etc. Parcourez les modules dans la barre latérale, à gauche. La liste complète est également disponible via GET /modules.
Champs de référence
Les champs de référence (comme account_id sur un contact) renvoient toujours un objet contenant à la fois l'identifiant et un libellé lisible, ce qui vous évite une requête de recherche séparée :
"account_id": { "id": "49", "label": "ACME France" }Identifiants
Tous les identifiants sont renvoyés sous forme de chaînes d'entiers ("49"), jamais de nombres. C'est uniforme dans toute l'API.
Horodatages
Les horodatages utilisent le format ISO 8601 en UTC : 2026-04-30T10:00:00Z.
Champs nuls
Les champs nuls sont omis des réponses par défaut afin d'alléger les charges utiles. Ajoutez ?include_nulls=true à n'importe quel GET pour les inclure explicitement.
Propriété des fiches
Chaque fiche a un propriétaire — l'utilisateur auquel elle est attribuée. Lors de la création ou de la mise à jour d'une fiche, vous pouvez définir le propriétaire explicitement en envoyant assigned_user_id dans le corps de la requête :
{ "data": { "attributes": { "firstname": "Jean", "lastname": "Dupont", "assigned_user_id": "7206" } } }Si vous omettez assigned_user_id, la fiche est attribuée à l'utilisateur propriétaire du jeton d'API — c'est-à-dire vous. La plupart des intégrations n'ont pas besoin de renseigner ce champ.
Pagination
Les endpoints de liste renvoient une enveloppe paginée :
{
"data": [ ... ],
"meta": {
"total": 240,
"page": 1,
"per_page": 20,
"pages": 12,
"request_id": "550e8400-e29b-41d4-a716-446655440000"
}
}Contrôlez la pagination avec ?page=N&per_page=M. La taille de page par défaut est de 20, le maximum de 100.
Limitation du débit
Chaque jeton d'API dispose d'un quota de requêtes géré par un seau à jetons. La limite par défaut est configurée au niveau d'utilisateur.
Chaque réponse inclut trois en-têtes pour suivre votre quota restant :
| En-tête | Type | Description |
|---|---|---|
X-RateLimit-Limit | entier | Nombre maximum de requêtes autorisées dans la fenêtre courante. |
X-RateLimit-Remaining | entier | Requêtes restantes dans la fenêtre courante. |
X-RateLimit-Reset | timestamp Unix | Moment où le seau se remplit complètement. |
Lorsque la limite est atteinte, l'API répond avec 429 Too Many Requests et ajoute un en-tête Retry-After (en secondes) :
HTTP/1.1 429 Too Many Requests
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1748340000
Retry-After: 42{
"error": {
"code": "RATE_LIMIT_EXCEEDED",
"message": "Rate limit exceeded.",
"request_id": "1f3c8e2a-..."
}
}Attendez le nombre de secondes indiqué dans Retry-After avant de renvoyer la requête. Ne réessayez pas immédiatement — le seau sera toujours vide.
Erreurs
Chaque réponse d'erreur utilise une enveloppe unique :
{
"error": {
"code": "NOT_FOUND",
"message": "Record not found.",
"request_id": "1f3c8e2a-..."
}
}request_id est unique pour chaque requête — mentionnez-le lorsque vous contactez le support.
Erreurs de premier niveau
| Statut HTTP | Code(s) | Signification |
|---|---|---|
| 400 | INVALID_FILTER | Le filtre de la requête n'a pas pu être interprété. |
| 401 | UNAUTHORIZED | Jeton d'accès manquant, mal formé ou expiré. |
| 403 | FORBIDDEN, ADMIN_REQUIRED | Vous n'êtes pas autorisé à effectuer cette action / l'endpoint nécessite un administrateur. |
| 404 | NOT_FOUND | La fiche, le module ou la ressource n'existe pas. |
| 405 | METHOD_NOT_ALLOWED | L'opération n'est pas autorisée sur cette ressource. |
| 429 | RATE_LIMIT_EXCEEDED | Vous avez envoyé trop de requêtes. Attendez le délai indiqué dans Retry-After avant de réessayer. |
| 422 | VALIDATION_ERROR | Le corps de la requête a échoué à la validation (voir les codes par champ ci-dessous). |
| 500 | INTERNAL_ERROR, ERROR | Un problème inattendu de notre côté. |
Erreurs de validation (422)
Une VALIDATION_ERROR répertorie tous les champs en échec d'un coup dans details[], chacun avec son propre code :
{
"error": {
"code": "VALIDATION_ERROR",
"message": "The request body contains invalid data.",
"request_id": "1f3c8e2a-...",
"details": [
{ "field": "lastname", "code": "REQUIRED", "message": "This field is required." },
{ "field": "email", "code": "INVALID_FORMAT", "message": "Must be a valid email address." }
]
}
}| Code | Signification |
|---|---|
REQUIRED | Un champ obligatoire était manquant ou vide. |
INVALID_OPTION | La valeur ne fait pas partie des options autorisées du champ. |
MAX_LENGTH | La valeur dépasse la longueur autorisée pour le champ. |
INVALID_TYPE | La valeur est du mauvais type (par ex. du texte là où un nombre est attendu). |
INVALID_FORMAT | La valeur est du bon type mais mal formée (par ex. un e-mail ou une URL incorrects). |
REFERENCE_NOT_FOUND | Une fiche référencée (par id) n'existe pas. |
NOT_SUPPORTED | La relation ne porte aucun attribut, ou un attribut de relation inconnu a été envoyé. |
Ces codes peuvent apparaître sur n'importe quelle création ou mise à jour. Certains endpoints définissent des codes de validation supplémentaires, spécifiques à l'endpoint (par exemple les abonnements aux webhooks, la conversion de prospects, l'envoi de documents, les commentaires et les catalogues de prix) — ils sont documentés sur les opérations qui les renvoient.
Consultez les schémas Error et ValidationError dans la section Components pour la structure exacte.
Versions
Ceci est la v1. Les changements incompatibles seront livrés sous une nouvelle version majeure (v2) ; la v1 restera disponible.