Hver fejl, forklaret på en stabil adresse.
Denne side er en driftsreference, ikke en salgstale. Hver fejlklasse i Connect-API'et har et permanent anker her; API'ets fejlsvar vil pege på disse adresser. De får den sandsynlige årsag og løsningen — i den rækkefølge. Tilbage til udviklerdokumentationen.
Manglende, fejlformateret eller ukendt nøgle
API'et autentificerer udelukkende via headeren Authorization: Bearer vgk_… — aldrig via en sessionscookie. En tilbagekaldt nøgle bliver ukendt i samme øjeblik, den tilbagekaldes.
Den samme 401 bærer "motif": "fin_option_api", når nøglen er stoppet, fordi API'et ikke længere er en del af kontorets abonnement. Datoen for stoppet blev oplyst i en e-mail til kontorets administratorer eller, hvis der ingen er, til kontorets faktureringsadresse, og derefter annonceret i headeren Sunset på hvert svar på et accepteret kald (tidsplanen står under #cle-expiree). Uden motiv kan den også skyldes et suspenderet abonnement: suspensionen lukker nøglerne med det samme.
Løsningen. Kontrollér, at headeren faktisk afsendes (proxyer fjerner den undertiden), at nøglen begynder med vgk_, og at den ikke er blevet tilbagekaldt fra kontorets konsol. Da hemmeligheden kun vises ved oprettelsen, erstattes en mistet nøgle — den gendannes ikke. Med "motif": "fin_option_api" er hverken headeren eller nøglen årsagen: kontorets administrator skriver til os på contact@vigilae.org, så API'et kommer med i abonnementet igen, og den samme nøgle accepteres igen, så snart det er sket, indtil dens egen udløbsdato.
Udløbet nøgle
Hver nøgle udløber ét år efter oprettelsen — datoen expire_le er synlig i kontorets konsol fra dag ét. Udløbs-401'en er eksplicit: den siger, at nøglen har eksisteret og ikke længere er gyldig.
En API-nøgle kan også holde op med at blive accepteret før denne dato, når API'et ikke længere er en del af kontorets abonnement. Stoppet falder da mindst 30 dage efter en første e-mail, på den dato, som en anden e-mail oplyser, sendt mindst 7 dage i forvejen; begge sendes til kontorets administratorer eller, hvis der ingen er, til kontorets faktureringsadresse. Så snart datoen er fastsat, kan den ses i kontorets konsol (feltet coupure_le i GET /connect/cles), og hvert svar på et accepteret kald annoncerer den i headeren Sunset, indtil den indtræffer. Efter denne dato får kaldet den 401, der er beskrevet under #authentification, med "motif": "fin_option_api"; kommer API'et med i abonnementet igen, accepteres nøglen igen, indtil dens egen udløbsdato.
Løsningen. Opret en ny nøgle, flyt Deres kald over, tilbagekald den gamle. For en API-nøgle skal API'et stadig være en del af kontorets abonnement: uden det nægter konsollen at oprette en. Planlæg denne udskiftning i Deres drift i stedet for at opdage den.
Utilstrækkeligt scope
Nøgler bærer de scopes, der blev sat ved oprettelsen: de generelle lecture (læsning, standard) og ecriture (skrivning), eller finkornede pr. ressource (clients:lecture, pieces:ecriture, origine-fonds:lecture, journal:lecture…).
Nedarvningen følger endelsen, kun i én retning: lecture dækker alle *:lecture, ecriture alle *:ecriture — aldrig omvendt; et finkornet scope åbner kun sig selv.
Seks scopes falder uden for det par og nedarves fra ingen generel nøgle: alertes:qualifier, embed:emettre, adversemedia:consulter, conformite:consulter, dispositif:consulter, integrite:consulter. At kvalificere en hændelse, udstede et embed-token, læse en sags negative presseomtale eller en karakter for sagsbehandlingen følger aldrig af en generel læseret: hvert scope sættes for sig.
Løsningen. Opret en nøgle med det nødvendige scope — og kun det. Mindste privilegium er tilsigtet: en integration, der kun læser, har ingen grund til at holde en skrivenøgle, og en bred nøgle opvejer aldrig et scope, der ikke er uddelegeret udtrykkeligt.
Findes ikke — eller tilhører et andet kontor
En 404 betyder, at ressourcen ikke findes, eller at den tilhører et andet kontor. API'et skelner aldrig mellem de to tilfælde: at skelne ville afsløre, hvad der findes andetsteds. Isoleringen håndhæves på databaseniveau, ikke kun i applikationskoden.
Løsningen. Kontrollér seq mod journalen for det kontor, nøglen tilhører (GET /api/v1/evenements). Integrerer De flere kontorer, har hvert kontor sine egne nøgler: en seq rejser ikke mellem kontorer.
Denne konto findes allerede
Et POST /scim/v2/Users på et userName, der allerede er oprettet for dette kontor, svarer 409 med scimType: uniqueness. Entydigheden bæres af en databasebegrænsning, ikke af en cache: to samtidige oprettelser kan ikke give to konti.
Løsningen. Behandl 409 som en idempotent succes, ikke som en fejl: læs kontoen tilbage med ?filter=userName eq "…", og fortsæt med den returnerede identifikator. En konnektor, der prøver igen i løkke ved et 409, skaber aldrig noget mere.
Denne konto er uden for katalogets rækkevidde
Et katalog kan hverken nedgradere eller deaktivere en konto, der bærer kontorets administrationsbeføjelser: anmodningen afvises med scimType: mutability og logges. Uden den grænse ville en konnektor, der overtager den hvidvaskansvarliges adresse, lukke kontoret ude for netop den, der står til ansvar for det.
Løsningen. Fjern den person fra det synkroniserede område, eller skift rollen inde i Vigilae. Afvisningen gælder kun denne konto: resten af partiet anvendes normalt.
Rategrænse overskredet
60 forespørgsler i minuttet pr. nøgle, som standard (kan tilpasses pr. nøgle). Svaret bærer Retry-After og headerne X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset.
Løsningen. Respektér Retry-After — intet øjeblikkeligt genforsøg. At ramme grænsen under polling er næsten altid tegn på en fuld genindlæsning: depuisSeq-cursoren genlæser aldrig det, der allerede er læst.
Signaturen kan ikke verificeres hos Dem
Deres modtager skal genberegne v1 = HMAC-SHA256(secret, t + "." + body) ud fra den rå body, der er modtaget, og afvise ethvert t ældre end 5 min. De klassiske fejl: en body, der er re-serialiseret før verificeringen (omformateret JSON har ikke længere de samme bytes), et ur, der driver ud over tolerancen, og en ignoreret rotation — i 24 timer bærer headeren én v1 pr. stadig gyldig hemmelighed, og De skal acceptere, hvis blot én matcher.
Løsningen. Verificér mod de rå bytes, synkronisér Deres ur (NTP), test Deres verificering under en rotation. Node- og Python-uddragene i dokumentationen gør præcis dette — kopiér dem frem for at genskrive dem.
En hændelse ankommer to gange
Leveringen er at-least-once, i batches på højst 100, i journalens rækkefølge; cursoren rykker kun frem ved Deres 2xx, batch for batch. En fejl efter modtagelsen, men før cursoren rykker frem, udløser en genlevering — det er kontrakten, ikke en defekt.
Løsningen. seq er Deres idempotensnøgle: behandl hver sekvens præcis én gang, og svar først 2xx efter persistering. En for tidlig 2xx efterfulgt af et nedbrud er den eneste måde at miste en hændelse på.
Journalen virker ufuldstændig eller gentager sig
depuisSeq er strengt eksklusiv: kun hændelser med en højere seq returneres, sorteret stigende, højst 500 pr. side. Svaret returnerer prochainSeq, som sendes tilbage uændret. En side kortere end limite betyder journalens slutning.
Løsningen. Persistér prochainSeq mellem kørsler, og genberegn den aldrig selv. Dubletter betyder, at De er startet forfra fra en for gammel cursor; huller betyder, at De har sprunget en fejlet side over uden at genafspille den.
Parameter uden for skemaet
En ukendt status, en disposition uden for listen (planifie, traite, ecarte), en limite, der ikke er et heltal: svaret nævner det fejlbehæftede felt, og intet andet — fejlbeskeder bærer aldrig sagsindhold.
Løsningen. OpenAPI-specifikationen er kilden: de enumerationer og grænser, den erklærer, er dem, serveren håndhæver, eftersom den serveres af den.
Feltets værdi er for lang: Nationalitet
Svaret nævner det fejlbehæftede felt, og intet andet — fejlbeskeder bærer aldrig sagsindhold.
Løsningen. OpenAPI-specifikationen er kilden: de enumerationer og grænser, den erklærer, er dem, serveren håndhæver, eftersom den serveres af den.
Utilstrækkeligt scope (ressource-API)
Ressource-endpoints (/clients, /dossiers, bilag, screening, advarsler) kræver et finkornet scope: clients:*, dossiers:*, pieces:*, criblage:* eller det dedikerede scope alertes:qualifier. En ældre lecture-nøgle giver alle *:lecture-scopes og ecriture alle *:ecriture — men alertes:qualifier arves aldrig: at kvalificere en advarsel er den ansvarliges handling, delegeret ved at markere dette scope, når nøglen oprettes.
Løsningen. Opret en nøgle med præcis de scopes, Deres integration har brug for — og kun dem. Svarets detail nævner det manglende scope.
Ressource findes ikke — eller tilhører et andet kontor
Samme regel som #cloisonnement, anvendt på ressourcer: en kunde, en sag, et bilag eller en advarsel, der ikke findes, eller som tilhører et andet kontor, får den samme 404. API'et skelner aldrig mellem de to tilfælde.
Løsningen. Kontrollér identifikatoren mod listerne for det kontor, nøglen tilhører. En identifikator rejser aldrig fra ét kontor til et andet.
Headeren Idempotency-Key mangler
Enhver POST, der opretter eller udløser noget (kunde, sag, bilag, screening, reelle ejere), kræver headeren Idempotency-Key: en stabil streng på højst 200 tegn, én pr. operation. At genafspille samme nøgle med samme body returnerer det samme svar, uden effekt — Deres værn mod dubletter ved en netværkshændelse.
Løsningen. Generér nøglen før det første forsøg (én UUID pr. forretningsoperation), og genbrug den uændret ved hvert genforsøg af den samme operation.
Idempotensnøgle genbrugt med en anden body
Denne Idempotency-Key er allerede blevet brugt til en anden body inden for de seneste 24 timer. Nøglen genafspiller et svar, den overskriver aldrig et: at genbruge den til en ny operation er næsten altid tegn på en nøgle afledt af en tæller eller en afkortet dato.
Løsningen. En ny nøgle til hver ny operation. Aflæd aldrig nøglen af data, der gentager sig på tværs af operationer.
Et andet forsøg med denne nøgle kører stadig
To forespørgsler med samme Idempotency-Key ankom samtidig: den første udføres, den anden afvises før enhver virkning. Netop denne afvisning forhindrer dubletten. Det almindelige tilfælde: en proxy svarer 502 eller 504, mens serveren stadig arbejder, og Deres klient sender forespørgslen igen. Headeren Retry-After angiver, efter hvor mange sekunder den kan gentages.
Løsningen. Gentag samme forespørgsel uændret, med samme nøgle, efter den angivne ventetid: De får svaret fra det første forsøg. Lav aldrig en ny nøgle for at »frigøre« — det ville skabe netop den dublet, nøglen forhindrer.
Testmiljø: kvoten er nået
Et testmiljø har faste grænser: 200 kundekort, 50 sager og 40 bilag pr. sag. En oprettelse eller upload, der ville overskride en af dem, afvises før der skrives noget, og afvisningen oplyser, hvilken: felterne ressource, quota og courant angiver ressourcen, loftet og antallet på afvisningstidspunktet. Konkurrerer to samtidige oprettelser om den sidste plads, slipper kun den ene igennem. At ændre et eksisterende kundekort eller en eksisterende sag bruger intet af kvoten.
Løsningen. Disse kvoter kan ikke forhandles, og en gentaget forespørgsel får den samme afvisning. Nulstil testmiljøet fra Deres konto — det starter forfra med demonstrationsdataene — eller tegn et abonnement: kvoterne gælder kun for testmiljøer.
Forseglet sag: registeret er fastfrosset
Forseglingen fastfryser sagens integritetskæde — det er dens bevisværdi. En forseglet sag kan ikke længere redigeres, modtager ikke længere bilag og re-screenes ikke længere ad denne kanal. Kun kvalificering af advarsler forbliver mulig: den skrives off-chain, det forseglede hoved flytter sig aldrig.
Løsningen. Intet at »rette«: dette er tilsigtet uforanderlighed. Skal data ændres, er det en ny vigilansoperation i applikationen, ikke en mutation af den forseglede sag.
Afsluttet sag: forretningsforbindelsen er ophørt
Forbindelsen er afsluttet i applikationen: sagen modtager ikke længere skrivninger via API'et — hverken redigering, bilag, screening eller reelle ejere. Læsninger forbliver åbne: en afsluttet sag kan ses og eksporteres i hele opbevaringsperioden.
Løsningen. At genåbne forbindelsen er en menneskelig og registreret handling i applikationen; API'et gør det ikke for Dem. Er operationen ny, så opret en ny sag frem for at genoplive den gamle.
Slettet sag: data er fjernet
Opbevaringsfristen er udløbet, og sagens data er slettet. Kun revisionssporet består, som bevidner, at en sag har eksisteret, og at den blev slettet på den angivne dato; det modtager ikke længere nogen skrivning.
Løsningen. Intet at rette og intet at gentage: sletningen er endelig og tilsigtet. Et bevaret id på en slettet sag i Deres systemer er historik, aldrig et mål for skrivning.
Bilagsformat ikke accepteret
Bilag accepterer PDF, JPG, JPEG, PNG og WEBP — de samme formater som applikationen. Kontrollen sker på filendelsen i det obligatoriske filename: et bilag uden et gyldigt filnavn afvises, uanset dets indhold.
Løsningen. Konvertér før afsendelse (en TIFF- eller HEIC-scanning konverteres til PDF eller JPEG), og send indholdet som standard-base64 i contenu, med en type blandt de stabile a_doc_*-koder.
Bilag over 6 MB
Grænsen gælder den afkodede fil (6 MB), samme som i applikationen og indsamlingsportalen. Da base64 tilføjer en tredjedel i encoding-overhead, accepterer request-body'en op til 9 MB.
Løsningen. Komprimér bilaget (en farvescannet PDF i 300 dpi kommer næsten altid under grænsen i gråtoner) frem for at dele det op.
Screeningkilde utilgængelig
Ingen af sagens enheder kunne kontrolleres mod listerne: kilden (indekset over officielle lister eller leverandøren) svarede ikke. API'et nægter at konkludere — en »ren« rapport oven på en død kilde ville være det værst tænkelige falske negativ. Fejlen registreres på sagen (erreurSource). Et delvist udfald udløser ikke denne 502: 200-svaret beholder matchene for de enheder, der svarede, og nævner de fejlede i erreurSourceEntites.
Løsningen. Genafspil det samme kald senere, med den samme Idempotency-Key: kun succes-svar huskes af idempotensen — en genafspilning efter en fejl udfører en reel screening.
Indlejrede widgets ikke aktiveret på denne instans
Udstedelsen POST /api/v1/embed/jetons afhænger af de origins, der er angivet for Deres kontor — det er den liste, der styrer frame-ancestors-CSP'en for det indlejrede shell. Denne 501 siger, at den instans, De kaldte, ikke rummer den lagring: embed-fladen er inert dér i selve konstruktionen, og siger det, frem for at udstede en token, som ingen origin nogensinde ville kunne vise. Skal ikke forveksles med den 400, der returneres til et kontor, hvis origins endnu ikke er angivet.
Løsningen. Denne 501 handler om instansen, ikke om Deres forespørgsel. På vigilae.org angiver kontorets administrator selv origins, på skærmen »Integrationer og sikkerhed« (boksen i widgets-afsnittet siger hvor); genafspil derefter det samme kald. Intet at ændre i Deres kode: forespørgslen var i orden, instansen var ikke klar.
Fladen er utilgængelig på denne installation
To grundlæggende læsninger — GET /api/v1/dossiers/{id}/origine-fonds og GET /api/v1/dossiers/{id}/exigences — bygger på lagre, som ikke alle instanser bærer. Når et mangler, siger API'et det i stedet for at levere en tom liste: »intet at bemærke« og »intet blev læst« er modsatte kendsgerninger, og at forveksle dem ville få en sag, ingen har set på, til at fremstå som en sag uden forbehold. Denne 501 handler om den kaldte instans, aldrig om Deres forespørgsel eller om sagen.
Løsningen. Gentag ikke i løkke: intet ændrer sig, før instansen bærer det lager. Behandl koden som »data ikke tilgængelige her«, og tæl den frem for alt ikke som et nul i Deres dashboards — sådan bliver en manglende måling til et forkert tal. På vigilae.org betjenes begge læsninger; på en dedikeret installation er opgraderingen af lageret Deres driftsansvarliges opgave.
Denne side vil udvikle sig med API'et; de eksisterende ankre skifter dog aldrig adresse — De kan gemme dem i Deres driftslogs.