# Ansökningar på kundens webbplats

Samla in en ansökan, genomför identitetskontroller och återuppta dokumentuppladdningar säkert.

## REST-operationer och nyckelbehörigheter

| Uppgift | Nyckelbehörigheter | Börja här |
| --- | --- | --- |
| Använd kundserverns ansökningsbudget eller den värdbaserade eID-överlämningen | `write:applications` på en separat servernyckel | `POST /api/v1/public/units/{slug}/application-eid/handoffs` |

## Bygg ett ansökningsflöde på kundens webbplats

Använd den versionerade REST-inlämningen när du erbjuder ett ansökningsformulär på din egen webbplats. Börja med den bekräftade API-adressen i anslutningsguiden. Flödet är separat från hyresvärdens ansökningsläsningar och MCP-verktyg; en företagsnyckel ersätter aldrig sökandens identitet eller samtycke.

### 1. Läs det aktuella formuläret innan en ansökan samlas in.

Läs `GET /api/v1/public/units/{slug}/application-form?language=sv` (även `en` eller `es`). Bevara returnerade `unitSlug`, `listingPeriodId` och det opaka värdet `formVersion`. Rendera publicerade `inputSchema`, villkorliga `rules`, `policies.confirmations`, dokumentkrav och `identityGate`; återskapa dem inte utifrån antaganden. Länka angivna integritets-/villkorssökvägar genom den bekräftade adressen till Homito-webbappen, inte API-adressen. Kontrollera `canApply` och `unavailableReason`; en formulärläsning skapar eller återöppnar inte en ansökningsomgång.

Använd `POST /api/v1/public/units/{slug}/application-form/validate` för återkoppling på ett utkast. Utkastsvalidering kontrollerar gemensamma fältregler, bekräftelser och deklarerad dokumentmetadata mot en skrivskyddad ögonblicksbild av formuläret. Den skapar ingen ansökan eller samtyckeslogg, kräver ingen inskickningsnyckel, verifierar inga filbytes och startar inget anrop till identitets- eller screeningleverantör. Den slutliga inlämningen valideras igen.

### 2. Håll varje nyckel och åtkomsträtt åtskild.

| Nyckel eller åtkomsträtt | Syfte | Gräns |
| --- | --- | --- |
| `X-Homito-Customer-Key` | En separat servernyckel med `write:applications` för kundens gemensamma inlämningsbudget och värdbaserade eID-överlämning | Endast på servern; samma företag som den annonserade lägenheten; ersätter inte sökandens åtkomsträtter |
| `X-Application-Submission-Key` | En UUID v4 som skapas före första inlämningen | Behåll samma nyckel och accepterade anropskropp/filer efter ett förlorat svar; den är inte en `Idempotency-Key` för hyresvärds-API:t |
| `X-Application-Receipt` | JSON med `kind: "public"`, ursprunglig lägenhetsslug som `target` och ursprunglig inskickningsnyckel som `key` | Skicka i kvittoheadern, aldrig i en URL; den visar endast om inlämningen sparats och bilagornas status |
| `X-Application-Upload-Key` | En separat åtkomsträtt skapad av 32 kryptografiskt slumpmässiga byte, kodade som 64 gemena hexadecimala tecken | Krävs för manifestets uppladdningsoperationer; ett kvitto, ansöknings-ID eller en företagsnyckel ersätter den inte |

Kundnyckeln ändrar företagets gemensamma trafikbudget; den ger inte åtkomst till ett annat företag och ersätter inte kvitto-/uppladdningsbehörigheter. En ogiltig bifogad nyckel avvisas i stället för att falla tillbaka på offentlig åtkomst. Förvara företagsnycklar på servern och håll alla åtkomsträtter utanför offentliga cacheminnen, URL:er, loggar och agentkonversationer. Bevara dem i besökarens skyddade formulärsession före första nätverksanropet.

### 3. Genomför den identitetsöverlämning som krävs och skicka sedan in en gång.

När `identityGate.required` är true använder du den publicerade värdbaserade eID-överlämningen. En administratör registrerar först kundens exakta HTTPS-callback genom det befintliga autentiserade kontrollplanet. På kundservern binder du slumpmässig `state`, en privat PKCE-verifierare och dess `S256`-utmaning till den aktuella besökarens skyddade formulärsession, aktuellt formulär/omgång och ursprunglig inskickningsnyckel. Skapa överlämningen på `POST /api/v1/public/units/{slug}/application-eid/handoffs` med samma företags servernyckel och det returnerade formulärkontraktet.

Spara överlämningens tillstånd före omdirigering till den returnerade auktoriserings-URL:en och respektera `expiresAt`. Vid den registrerade callbacken validerar du `state` mot samma besökares session; en global state-uppslagning räcker inte. Håll kod/verifierare privata, undertryck loggning av callbackens frågeparametrar och omdirigera direkt till en ren formulär-URL. En nyckel, ett konto, flaggan `hasNoPersonalNumber` eller ett klientpåstående kan inte kringgå obligatorisk eID.

Skicka `POST /api/v1/applications` som `multipart/form-data` med `X-Homito-Application-Contract: 1` och ursprunglig `X-Application-Submission-Key`. Ange korrekt `Content-Length`; saknad eller avvikande längd avvisas. Inkludera `unitSlug`, `listingPeriodId`, `formVersion` och JSON-fälten i `application`. När det krävs skickar du det separata JSON-fältet `identityHandoff` med `handoffId`, `code` och `codeVerifier`; lägg det aldrig inuti `application` och exponera inte verifieraren i webbläsarkod. För en inlämning med överlämning skickar du dessutom exakt den ursprungliga kundnyckel som skapade överlämningen; en annan nyckel för samma företag kan inte ersätta den. Äldre JSON-inlämning ger inte detta versionerade kontrakt.

Använd formulärets `documents.maxExternalBodyBytes` för hela multipart-anropet. Filer som skickas direkt använder de publicerade bilagefälten; större dokument använder `attachmentManifest` utan direkta filer och med separat uppladdningsnyckel. Följ `documents.manifestSchema`, `maxFiles`, `maxFileBytes`, `allowedMimeTypes` och `acceptedByteFormats`, inklusive kraven för huvudsökande och varje medsökande. Ett manifest deklarerar avsedda filer; det bevisar inte att filerna tagits emot.

### 4. Läs kvittot innan du väljer vad som ska försökas igen.

Läs `GET /api/v1/applications/receipt` med ursprunglig kvittoheader. `received` betyder att ansökan sparats; granska dess separata `attachments`-status i stället för att skapa en ny inlämning. En identisk upprepning av en redan sparad inlämning returnerar ursprungligt kvitto innan ett förbrukat eller utgånget engångsbevis för identitet kontrolleras igen. `unknown` kan betyda att ansökan inte skickats, fortfarande behandlas eller återställts: använd begränsad väntan mellan försök och behåll identiskt anrop och ursprunglig nyckel vid upprepning. `removed` är slutgiltigt; stoppa gamla återförsök. Kvittoläsning ger inte rätt till sökandeprofil, dokumentnedladdning, screeningresultat eller beslut. `notifications: unknown` bevisar inte e-postleverans.

### 5. Ladda upp deklarerade bytes och slutför.

Alla fyra operationer nedan kräver ursprunglig `X-Application-Upload-Key`. Bevara varje uppladdnings-ID i manifestet samt ursprungliga filbytes/hashvärden vid avbrott.

| Operation | Vad den bekräftar |
| --- | --- |
| `GET /api/v1/applications/{applicationId}/uploads` | Aktuell `finalized`-flagga och varje deklarerad fils status `pending`, `received`, `expired` eller `stale` |
| `POST /api/v1/applications/{applicationId}/uploads/{uploadId}/url` | En kortlivad PUT-URL och exakta headers, eller ett redan `received`-resultat som inte behöver PUT |
| `POST /api/v1/applications/{applicationId}/uploads/{uploadId}/complete` | Faktiska bytes, längd, SHA-256, byteformat/MIME och aktuell koppling till sökanden har kontrollerats och bilagan sparats |
| `POST /api/v1/applications/{applicationId}/finalize` | Alla deklarerade dokument har sparats i det ordinarie dokumentlagret; annars avvisas operationen |

Ladda endast upp till exakt returnerad URL med dess exakta metod, headers och bytelängd. Skicka aldrig företagsnyckeln eller sökandens åtkomsträtter till objektlagringen, följ inga omdirigeringar och logga inte den signerade URL:en. En lyckad PUT är inte i sig ett slutförande. En uppladdningsproxy på kundservern undviker antagandet att direkt CORS från webbläsare till lagring är konfigurerad.

Efter ett förlorat PUT-svar försöker du först med `complete` för samma uppladdnings-ID innan du laddar upp igen. Vid `upload_missing` hämtar du en ny URL för samma ID, laddar upp ursprungliga bytes och slutför. En ny PUT-URL förnyar inte den underliggande uppladdningsrättens giltighet. Stanna när åtkomsträtten löpt ut eller kopplingen till sökande/omgång ändrats; en ändrad fil eller person kräver det uttryckligt auktoriserade rättelse-/kompletteringsflödet, inte en ny inskickningsnyckel eller ett ändrat accepterat manifest.

### Återställ utifrån felkoden utan att skapa en andra ansökan.

| Fel | Nästa åtgärd |
| --- | --- |
| `eid_required` (403) | Genomför det godkända värdbaserade identitetsflödet; hitta inte på en genväg |
| `form_version_changed` / `application_round_changed` (409) | Läs om aktuellt kontrakt och be sökanden bekräfta ändrade uppgifter före en ny accepterad inlämning; bevara eventuellt befintligt kvitto |
| `submission_payload_changed` (409) | Stäm av ursprunglig accepterad kropp/filer; skapa inte automatiskt en ny operation |
| `upload_subject_changed` (409), inaktuell eller utgången uppladdningsåtkomst | Stoppa uppladdning/slutförande och använd auktoriserat kompletteringsflöde för aktuell sökande |
| `submission_removed` (410) | Sluta försöka skicka den borttagna inlämningen igen |
| Fil-/formatvalideringsfel (400/411/413/415/422) | Rätta det rapporterade anrops- eller dokumentfelet före ett auktoriserat nytt försök |
| 429, 503 eller förlorat svar | Respektera `Retry-After` när det anges, behåll kontrollpunkten och läs kvitto/förlopp före ett nytt försök med ursprunglig nyckel |

`application.submitted` och `application.intake_finalized` är separata webhook-händelser. Verifiera och deduplicera dem enligt webhook-guiden och använd kvitto/förlopp för aktuellt tillstånd. Varken en händelse eller slutförandet bevisar e-postleverans, hyresbeslut eller genomförd screening. Håll sökandeuppgifter och uppladdnings-/kvittoåtkomsträtter utanför offentliga annonscacheminnen.

## Håll privata uppgifter utanför offentliga cacheminnen

Håll personuppgifter, kvitton och uppladdningsåtkomsträtter utanför offentliga annonscacheminnen. Hyresgäst- och ansökningsläsningar returnerar avsiktligt begränsade operativa projektioner; dra inga slutsatser om utelämnade privata fält eller screeningbedömningar. Skilj null/okända värden från noll eller ett slutfört resultat.
