Connect API — reference

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.

#authentification 401

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.

#cle-expiree 401

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.

#scopes 403

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.

#cloisonnement 404

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.

#unicite 409

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.

#compte-hors-portee 403

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.

#debit 429

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.

#signature webhook

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.

#idempotence webhook

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å.

#validation 400

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.

#nationalite-trop-longue 400

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.

#scope-manquant 403

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-introuvable 404

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.

#idempotency-key-requis 400

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.

#idempotency-key-reutilisee 422

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.

#idempotency-key-en-cours 409

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.

#quota-essai-atteint 409

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.

#dossier-scelle 409

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.

#dossier-clos 409

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.

#dossier-purge 409

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.

#format-piece 415

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.

#piece-trop-volumineuse 413

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.

#source-criblage 502

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.

#embed-indisponible 501

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.

#stockage-indisponible 501

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.