TulipTulip Docs
Concepts

Flux des sinistres

Les 8 statuts d'un sinistre, les transitions possibles, l'auto-soumission, le système de double identifiant, les catégories de documents, les types de règlement et les codes d'erreur.

Diagramme des statuts

┌─────────┐     ┌───────────┐     ┌───────────────┐     ┌────────┐
│  draft  │ ──► │ submitted │ ──► │  in_progress  │ ──► │ closed │
└─────────┘     └───────────┘     └───────────────┘     └────────┘
     │                               ▲    │  │
     │ (cancel)       (docs fournis) │    │  └──────────┬──────────┐
     ▼                               │    │             │          │
┌──────────┐                         │    │(docs requis)│          │
│ archived │                      ┌──┴───────────┐ ┌───────────┐ ┌──────────┐
└──────────┘                      │ pending_info │ │ abandoned │ │ rejected │
                                  └──────────────┘ └───────────┘ └──────────┘

Statuts

StatutDescriptionActions possibles
draftPré-déclaration créée, en attente de documentsModifier, uploader docs, soumettre, annuler
submittedSoumis, en attente de prise en chargeLecture seule
in_progressEn cours de traitement par TulipLecture seule
pending_infoDocuments supplémentaires demandésUploader docs
closedTraité et indemniséLecture seule
rejectedRejeté par l'assureurLecture seule
abandonedAbandonné par l'assuré ou le partenaireLecture seule
archivedPré-déclaration annulée (depuis draft uniquement)Lecture seule

Mapping des statuts internes

L'API expose des statuts publics qui sont dérivés des statuts internes. Voici le mapping complet :

Statut ExternalClaim (interne) vers statut API (public)

Statut interne ExternalClaimStatut API
unmatcheddraft
pendingdraft
matchedDépend du userClaimStage (voir ci-dessous)
abandonnedarchived

userClaimStage (interne) vers statut API (public)

Lorsque le sinistre est matched (soumis et lié à un sinistre interne), le statut API dépend du champ userClaimStage :

userClaimStageStatut API
waiting_for_tulipin_progress
document_to_sendpending_info
waiting_for_paymentin_progress
closed_paidclosed
closed_rejectedrejected
abandonedabandoned
reopenedin_progress
(autre / absent)submitted

Transitions

DeVersDéclencheur
draftsubmittedAppel POST /claims/{id}/submit ou auto-soumission
draftarchivedAppel DELETE /claims/{id}
submittedin_progressPrise en charge par Tulip
in_progresspending_infoTulip demande des documents supplémentaires
pending_infoin_progressDocuments fournis
in_progressclosedSinistre traité et indemnisé
in_progressrejectedSinistre rejeté
in_progressabandonedAbandon par l'assuré/partenaire (DELETE /claims/{id})

Double identifiant

Chaque sinistre possède deux identifiants :

ChampDisponibleExemple
idDès la créationclaim_xyz789
claimIdAprès soumissioninternal_claim_abc
  • claimId est null tant que le sinistre n'est pas soumis
  • Les deux identifiants sont acceptés pour tous les endpoints GET
  • Utilisez id si vous stockez la référence dès la création

Auto-soumission

L'auto-soumission nécessite le query parameter ?autoSubmit=true sur l'endpoint PUT /claims/{id}/documents. Sans ce paramètre, même lorsque tous les documents obligatoires sont uploadés, le sinistre reste en draft avec canSubmit: true.

Le fonctionnement est le suivant :

  1. Le partenaire uploade un document via PUT /claims/{id}/documents?autoSubmit=true
  2. Après l'upload, l'API vérifie si tous les documents mandatory sont présents
  3. Si oui et que autoSubmit=true est passé, le sinistre est automatiquement soumis
  4. La réponse contient alors autoSubmitted: true et le claimId du sinistre interne

Webhook v2.claim.draft.ready

Lorsque tous les documents obligatoires sont uploadés sans le paramètre autoSubmit=true, l'API émet le webhook v2.claim.draft.ready. Cet événement permet au partenaire de savoir que le sinistre est prêt à être soumis manuellement via POST /claims/{id}/submit.

Le champ canSubmit

Le champ booléen canSubmit indique si le sinistre peut être soumis :

  • true : Tous les documents obligatoires (category: "mandatory") sont uploadés
  • false : Il manque des documents obligatoires

Utilisez ce champ pour conditionner l'affichage du bouton de soumission dans votre interface.

Catégories de documents

Chaque type de document attendu est classé dans une catégorie qui détermine son impact sur la soumission :

CatégorieDescriptionImpact sur la soumission
mandatoryDocument obligatoireBloque la soumission tant qu'il n'est pas uploadé
expectedDocument attenduNe bloque pas la soumission mais peut retarder le traitement
optionalDocument complémentairePeut être uploadé à tout moment, aucun impact

Seuls les documents mandatory sont pris en compte pour le calcul de canSubmit. Les documents expected et optional n'affectent pas la possibilité de soumettre le sinistre.

Les catégories de documents sont déterminées par la configuration produit en fonction du subtype du sinistre et du type de produit assuré.

Types MIME autorisés et taille maximale

Les fichiers uploadés via PUT /claims/{id}/documents doivent respecter les contraintes suivantes :

ContrainteValeur
Taille maximale20 Mo (20 971 520 octets)
Types MIME autorisésapplication/pdf, image/jpeg, image/png, image/webp, image/heic, image/heif

Le type MIME est auto-détecté à partir du contenu du fichier (magic bytes). Il n'est pas nécessaire de le spécifier dans la requête. Si le type MIME détecté n'est pas dans la liste autorisée, l'upload est rejeté avec l'erreur 1003 INVALID_MIME_TYPE.

Modification d'un sinistre

Un sinistre ne peut être modifié qu'en statut draft. Seuls les champs description et location sont modifiables. La description doit contenir au minimum 50 caractères.

Les champs type, subtype, claimAt et questions sont figés dès la création et ne peuvent pas être modifiés.

Annulation

L'endpoint DELETE /claims/{id} permet d'annuler un sinistre. Le comportement varie selon le statut :

Sinistre en draft

L'annulation est simple : le sinistre passe en statut archived. Le webhook v2.claim.draft.archived est émis.

Sinistre soumis (statut submitted, in_progress, etc.)

L'annulation d'un sinistre soumis effectue les opérations suivantes :

  1. Vérification qu'il n'y a pas de paiement actif (executing, approved, pending_approval)
  2. Si un paiement est en cours, l'annulation est bloquée avec l'erreur 3007 ACTIVE_PAYMENT_BLOCKING
  3. Sinon, le sinistre interne est abandonné et le statut passe à abandoned
  4. Le webhook v2.claim.abandoned est émis

Corps de la requête

Le body est optionnel et accepte un champ reason :

{
  "reason": "Le client a retrouvé son vélo"
}

Si aucune raison n'est fournie, la raison par défaut est : "Demande d'abandon initiée par le client".

Un sinistre déjà annulé (archived ou abandoned) ne peut pas être annulé à nouveau. L'API retourne l'erreur 3003 CLAIM_STATUS_LOCKED.

Types de règlement (settlements)

Les règlements associés à un sinistre sont exposés dans le champ settlements du détail. Il existe 4 types :

TypeDescription
refundRemboursement effectué à l'assuré
chargePrélèvement ou facturation (ex : franchise)
cancelAnnulation d'un règlement précédent
returnedVirement retourné (échec du transfert, IBAN invalide, etc.)

Chaque règlement contient les champs suivants :

ChampTypeDescription
idstringIdentifiant unique du règlement
typestringType de règlement (refund, charge, cancel, returned)
amountnumberMontant en euros
paymentAtstring | nullDate de paiement effectif (ISO 8601), null si pas encore payé
createdAtstringDate de création du règlement (ISO 8601)

Filtrage dans les listes

L'endpoint GET /claims supporte le filtre status avec trois valeurs :

Valeur du filtreStatuts API retournésStatut interne correspondant
draftdraftunmatched, pending
submittedsubmitted, in_progress, pending_info, closed, rejected, abandonedmatched
cancelledarchivedabandonned

Le filtre utilise la valeur cancelled (et non archived). Ce filtre retourne les sinistres dont le statut interne est abandonned, qui sont exposés avec le statut API archived.

Codes d'erreur

L'API retourne des codes d'erreur structurés dans le champ code de la réponse d'erreur. Les codes sont organisés par plage :

Erreurs de validation (400 Bad Request)

CodeNomDescription
1000VALIDATION_ERRORErreur de validation générique
1001QUESTIONS_INCOMPLETELes réponses aux questions sont incomplètes
1002FILE_TOO_LARGELe fichier dépasse la taille maximale de 20 Mo
1003INVALID_MIME_TYPELe type MIME du fichier n'est pas autorisé
1004INVALID_SUBTYPE_FOR_PRODUCTLe sous-type n'est pas valide pour ce produit
1005INVALID_BASE64Le contenu base64 est invalide
1006UNSUPPORTED_CONTENT_TYPELe Content-Type de la requête n'est pas supporté
1007INVALID_TYPE_FOR_SUBTYPELe type n'est pas valide pour ce sous-type
1008UNSUPPORTED_PRODUCT_TYPELe type de produit n'est pas supporté

Erreurs de ressource (404 Not Found)

CodeNomDescription
2001CLAIM_NOT_FOUNDSinistre introuvable
2002CONTRACT_NOT_FOUNDContrat introuvable
2003PRODUCT_NOT_FOUNDProduit introuvable
2004DOCUMENT_NOT_FOUNDDocument introuvable

Erreurs de logique métier (409 Conflict)

CodeNomDescription
3001CLAIM_NOT_EDITABLELe sinistre ne peut pas être modifié dans son état actuel
3002CLAIM_NOT_SUBMITTABLELe sinistre ne peut pas être soumis (documents manquants ou état invalide)
3003CLAIM_STATUS_LOCKEDLe statut du sinistre ne permet pas cette opération
3004DOCUMENTS_INCOMPLETETous les documents obligatoires ne sont pas présents
3005DOCUMENT_ALREADY_VALIDATEDLe document a déjà été validé et ne peut pas être remplacé
3006INVALID_DOCUMENT_TYPELe type de document n'est pas valide
3007ACTIVE_PAYMENT_BLOCKINGUn paiement est en cours, l'opération est bloquée

Erreurs d'authentification (401 Unauthorized)

CodeNomDescription
9001MISSING_API_KEYLa clé API est manquante dans la requête
9002INVALID_API_KEYLa clé API est invalide
9003UNAUTHORIZED_USERL'utilisateur n'est pas autorisé pour cette clé API

Que pensez-vous de cette page ?

Sur cette page