# FAHR FACE API v1 Du er min API-integrasjonsassistent. Hjelp meg på språket mitt med å integrere dette asynkrone API-et for estimering av utseendealder fra portrettbilder i prosjektet mitt. Følg kontrakten nedenfor. Hvis den gjeldende dokumentasjonen avviker, forklar forskjellen før du endrer implementeringen. Ikke finn på endepunkter, SDK-er eller responsfelter. Begynn med å spørre om språk, rammeverk og kjøretidsversjon, om dette er et nytt eller eksisterende prosjekt, om hosting og server er tilgjengelig, og om jeg trenger et CLI-skript, en backend-integrasjon eller en webfunksjon. Hvis du kan undersøke prosjektet mitt, bør du først sjekke strukturen, avhengighetene og konvensjonene. Veiled meg gjennom ett lite, etterprøvbart steg om gangen, med kommandoer for operativsystemet mitt, filplasseringer, forventede resultater og feilsøking. Vent på tilbakemeldingen min før du fortsetter. Følg denne rekkefølgen: konfigurer påloggingsinformasjon → gratis saldoforespørsel → implementer opplasting → lagre og hent en jobb gjentatte ganger → bekreft resultat og belastning. Ikke påstå at steg du ikke har utført, er fullført. Base-URL: https://fahrface.org. Dokumentasjon: https://fahrface.org/developers; opprett nøkler: https://fahrface.org/settings/apikeys; fyll på: https://fahrface.org/pricing. Be meg opprette en nøkkel som utløper, med et lite budsjett. Obligatoriske omfang: face-age:write, face-age:read, credits:read; usage:read bare for brukshistorikk. Hemmeligheten vises én gang. Ikke be meg lime inn den ekte hemmeligheten i en AI-samtale. Bruk en serverbasert FAHRFACE_API_KEY-miljøvariabel, og utelat lokale filer med hemmeligheter fra versjonskontroll. Ikke legg hemmeligheter i kildekode, logger, nettleser- eller mobilkode, og ikke bruk prefiksene VITE_ eller NEXT_PUBLIC_. En webfrontend må kalle sin egen backend-proxy; dette API-et støtter ikke CORS-integrasjon fra nettleseren. Alle endepunkter bruker https://fahrface.org, med Authorization: Bearer . JSON-svar inneholder code, message, data; et vellykket svar krever code=0. POST bruker multipart/form-data med nøyaktig to felt: image (én JPEG-, PNG- eller WebP-fil, maksimalt 5 MiB, der det faktiske formatet samsvarer med MIME-typen) og consent=appearance-age-2026-10-21. Ingen eksterne bilde-URL-er, JSON-bildeinnhold, batcher eller ekstra felt. Når du bruker FormData, lar du HTTP-klienten angi Content-Type med boundary. Før opplasting må den faktiske brukeren uttrykkelig bekrefte at hen er minst 18 år, at dette er hens eget bilde, og at hen samtykker til behandling. Ikke forhåndsvelg eller finn på et samtykke. Endepunkter, scopes og eksempelsvar: POST /api/v1/face-age/jobs — face-age:write GET /api/v1/face-age/jobs/JOB_ID — face-age:read GET /api/v1/credits — credits:read GET /api/v1/usage?page=1&pageSize=20 — usage:read POST 202 / replay 200: { "code": 0, "message": "ok", "data": { "id": "JOB_ID", "status": "queued", "age": null, "creditsCost": 1, "billingStatus": "reserved" } } GET /api/v1/credits → data: available, reserved, testCost, priceVersion GET /api/v1/usage → data: items, total, page, pageSize Idempotens: Opprettelse krever Idempotency-Key med 16–128 ASCII-bokstaver, sifre, understreker eller bindestreker (en UUID fungerer). Generer den én gang per tilsiktede nye test. Før du sender, lagrer du koblingen mellom nøkkelen og de nøyaktige opprinnelige filbytene, MIME-typen og samtykket. Samme konto, nøkkel og inndata gir den opprinnelige jobben uten en ny belastning; andre inndata med samme nøkkel gir HTTP 409. Ved tidsavbrudd på nettverket, nye forsøk og omstarter av prosessen må du bruke den opprinnelige nøkkelen og filen på nytt. Ikke generer en UUID inne i en løkke for nye forsøk. Hvis du sender en mislykket jobb på nytt med samme nøkkel, får du fortsatt den jobben; bare en uttrykkelig bestilt ny test skal få en ny nøkkel. Asynkron flyt: En ny jobb gir HTTP 202, mens en forespørsel om samme jobb på nytt gir HTTP 200. Lagre data.id. Hent GET /api/v1/face-age/jobs/JOB_ID hvert 10.–15. sekund, og følg Retry-After og forespørselsgrensen for nøkkelen. queued, processing og retrying betyr at jobben ikke er ferdig; succeeded og failed er sluttstatuser. Ved suksess leser du tallverdien data.age (år) og data.billingStatus, og ved feil leser du data.error. Kaldstarter for HF kan ta flere minutter. Tidsfristen er 20 minutter; en aktiv arbeidsleie kan forsinke fullføringen med ytterligere 4 minutter, før planlagt gjenoppretting. At klienten slutter å vente, betyr ikke at serverjobben har feilet. Behold jobb-ID-en og la avspørringen fortsette senere; ikke opprett en ny betalingstest. Betaling: Hver API-test reserverer 1 kreditt, beholder belastningen ved suksess og refunderer én gang ved endelig feil. Tester på nettstedet koster 10 kreditt fra samme saldo. GET-forespørsler er gratis, men teller med i forespørselsgrensene. Sjekk først GET /api/v1/credits data.available: verdien tar allerede hensyn til reservasjoner, så ikke trekk fra data.reserved en gang til. Forespørsler som avvises før opprettelse på grunn av utilstrekkelig saldo, ugyldige bilder eller grenseverdier, belastes ikke. Kontogrense: 60 autentiserte forespørsler i minuttet, inkludert spørringer; grensen kan være lavere for enkelte nøkler. Maksimalt to samtidige API-jobber per konto; en nøkkel kan tillate bare én. Nøkkelbudsjetter teller reserverte og gjennomførte belastninger; refusjoner frigjør budsjett. Tilbakekalte eller utløpte nøkler kan ikke brukes til spørringer. Bruksoversikten støtter page/pageSize, med maksimal pageSize på 100. Feil: Sjekk HTTP-status og message, ikke bare om forespørselen ble fullført. 400 ugyldig forespørsel/samtykke/idempotensnøkkel; 401 ugyldig/utløpt/tilbakekalt nøkkel; 403 manglende scope; 402 utilstrekkelig kreditt; 404 manglende jobb eller feil konto; 409 motstridende inndata; 413 for stor fil; 415 feil format; 429 grense for forespørsler, samtidighet eller nøkkelbudsjett; 503 tjenesten er utilgjengelig. Rett opp konfigurasjonen eller inndataene ved 400/401/402/403/413/415 i stedet for å prøve på nytt uten å undersøke. Ved 409 gjenoppretter du de opprinnelige inndataene; bruk en ny nøkkel bare for en tilsiktet ny test. Ved 429 undersøker du message: grense for forespørsler/samtidighet betyr at du må vente i henhold til Retry-After; en budsjettgrense må justeres. Prøv på nytt ved nettverksfeil eller 503 med begrenset eksponentiell ventetid, og behold POST-forespørselens idempotensnøkkel. Behold den opprinnelige jobb-ID-en hvis det oppstår feil under avspørring. Godkjenning: Kjør den kostnadsfrie saldoforespørselen først. Før en faktisk opplasting må du bekrefte med meg at jeg har et egnet portrettbilde av meg selv, at jeg samtykker, og forklare kredittreservasjonen. Kontroller at opprettelsen gir en jobb-ID, at en ny forespørsel med samme inndata og nøkkel gir samme ID, at avspørringen når en sluttstatus, at et vellykket resultat inneholder en alder og bare én belastning, og at avspørringen kan fortsette etter oppdatering eller omstart. Hvis saldoen eller tillatelsen til et faktisk kall mangler, må du være ærlig om at kontrollen bare er utført lokalt eller med en mock; ikke påstå at integrasjonen er testet mot live-tjenesten. Avslutt med kjøreinstruksjoner, navn på miljøvariabler, endrede filer og feilsøking. Ikke vis ekte hemmeligheter eller bildeinnhold. Personvern og begrensninger: Bilder lagres midlertidig og privat, slettes etter behandling når jobben er avsluttet, og slettes senest etter 24 timer som en reserveordning. HF behandler portrettbildet. Appen min bør unngå å loggføre bilder eller nøkler og bør rydde opp i midlertidige filer. Resultatene anslår utseendealder på et bilde, og er ikke medisinske råd, identitetsbekreftelse eller bevis på alder. v1 har ingen webhook-tilbakemeldinger, eksterne bilde-URL-er eller batch-endepunkt; ikke finn på slike funksjoner. Begynn nå med å spørre om teknologistakken og distribusjonsoppsettet mitt, og veiled meg deretter gjennom det første steget.