[{"data":1,"prerenderedAt":181},["ShallowReactive",2],{"doc:\u002Fdocs\u002Fsdks":3},{"page":4,"toc":174,"updated":180},{"path":5,"title":6,"seoTitle":7,"description":8,"blocks":9},"\u002Fdocs\u002Fsdks","Choosing an SDK","Fingerly SDKs for Web, Mobile and Server","Fingerly SDKs for the browser, six web frameworks, iOS, Android, React Native, Flutter, Lynx, and eight server languages. Which to use, and how they fit together.",[10,13,18,20,59,62,64,90,93,95,142,145,169,172],{"type":11,"text":12},"p","A Fingerly integration has two halves. A **client SDK** runs where the visitor is, collects signals and identifies them with a public key. A **server SDK** runs on your backend and reads the result with a secret key, so decisions are made on data the visitor cannot edit.",{"type":14,"level":15,"text":16,"id":17},"heading",2,"Web","web",{"type":11,"text":19},"Every web SDK is built on the JavaScript SDK. The framework bindings share one identification per page and are safe under server rendering.",{"type":21,"columns":22,"cards":23},"cards",3,[24,29,34,39,44,49,54],{"title":25,"href":26,"logo":27,"text":28},"JavaScript","\u002Fdocs\u002Fsdks\u002Fjavascript","javascript","Any site, any framework",{"title":30,"href":31,"logo":32,"text":33},"React","\u002Fdocs\u002Fsdks\u002Freact","react","Provider and hooks",{"title":35,"href":36,"logo":37,"text":38},"Next.js","\u002Fdocs\u002Fsdks\u002Fnextjs","nextjs","App Router and Server Actions",{"title":40,"href":41,"logo":42,"text":43},"Vue","\u002Fdocs\u002Fsdks\u002Fvue","vue","Plugin and composables",{"title":45,"href":46,"logo":47,"text":48},"Nuxt","\u002Fdocs\u002Fsdks\u002Fnuxt","nuxt","Module with auto-imports",{"title":50,"href":51,"logo":52,"text":53},"Svelte","\u002Fdocs\u002Fsdks\u002Fsvelte","svelte","Svelte 5 and SvelteKit",{"title":55,"href":56,"logo":57,"text":58},"Angular","\u002Fdocs\u002Fsdks\u002Fangular","angular","Providers and signals",{"type":14,"level":15,"text":60,"id":61},"Mobile","mobile",{"type":11,"text":63},"The native SDKs collect what only native code can reach. The cross-platform packages call them rather than collecting less.",{"type":21,"columns":22,"cards":65},[66,71,76,80,85],{"title":67,"href":68,"logo":69,"text":70},"iOS","\u002Fdocs\u002Fsdks\u002Fios","apple","Swift, iOS 13+",{"title":72,"href":73,"logo":74,"text":75},"Android","\u002Fdocs\u002Fsdks\u002Fandroid","android","Kotlin, API 21+",{"title":77,"href":78,"logo":32,"text":79},"React Native","\u002Fdocs\u002Fsdks\u002Freact-native","Bridge to native",{"title":81,"href":82,"logo":83,"text":84},"Flutter","\u002Fdocs\u002Fsdks\u002Fflutter","flutter","Dart plugin",{"title":86,"href":87,"logo":88,"text":89},"Lynx","\u002Fdocs\u002Fsdks\u002Flynx","lynx","Native module",{"type":14,"level":15,"text":91,"id":92},"Server","server",{"type":11,"text":94},"Server SDKs read events and verify webhooks, with the same calls in every language. Any other language can do both over [the HTTP API](\u002Freference\u002Foverview) with one request and one HMAC.",{"type":21,"columns":22,"cards":96},[97,102,107,112,117,122,127,132,137],{"title":98,"href":99,"logo":100,"text":101},"Node.js","\u002Fdocs\u002Fsdks\u002Fnode","node","Events, webhooks, proxy",{"title":103,"href":104,"logo":105,"text":106},"Python","\u002Fdocs\u002Fsdks\u002Fpython","python","Sync and asyncio",{"title":108,"href":109,"logo":110,"text":111},"Go","\u002Fdocs\u002Fsdks\u002Fgo","go","Context-aware client",{"title":113,"href":114,"logo":115,"text":116},"Java","\u002Fdocs\u002Fsdks\u002Fjava","java","Java 11+, Kotlin, Scala",{"title":118,"href":119,"logo":120,"text":121},".NET","\u002Fdocs\u002Fsdks\u002Fdotnet","dotnet","C#, async, DI",{"title":123,"href":124,"logo":125,"text":126},"PHP","\u002Fdocs\u002Fsdks\u002Fphp","php","PHP 8.1+",{"title":128,"href":129,"logo":130,"text":131},"Ruby","\u002Fdocs\u002Fsdks\u002Fruby","ruby","Ruby 3.1+, Rails",{"title":133,"href":134,"logo":135,"text":136},"Rust","\u002Fdocs\u002Fsdks\u002Frust","rust","Async, Tokio",{"title":138,"href":139,"logo":140,"text":141},"Cloudflare Worker","\u002Fdocs\u002Fsdks\u002Fcloudflare-worker","cloudflare","First-party proxy",{"type":14,"level":15,"text":143,"id":144},"What every client SDK shares","what-every-client-sdk-shares",{"type":146,"columns":147,"rows":150},"table",[148,149],"Guarantee","What it means for you",[151,154,157,160,163,166],[152,153],"No permission prompts","No dialog, picker or permission request on any platform, for any signal.",[155,156],"A strict time budget","Collection stops at its budget. A slow or failing signal is recorded as such and never holds up the answer.",[158,159],"Never crashes your app","Every signal source is isolated. One that throws cannot take the report or your app with it.",[161,162],"One response shape","Browsers, iPhones and Android phones get the same fields back: request ID, visitor ID, score, level and triggers.",[164,165],"Retries once, charged once","Network failures, `429` and `5xx` are retried with a single idempotency key.",[167,168],"Advisory local verdicts","Verdicts computed on the device help your interface. The server's score is the one to act on.",{"type":14,"level":22,"text":170,"id":171},"Versions","versions",{"type":11,"text":173},"Every SDK follows semantic versioning on its own schedule and targets version `v1` of the API. SDKs report their version with every request, and events record it as `sdk_platform` and `sdk_version`, so the dashboard shows which builds are still in use.",[175,176,177,178,179],{"id":17,"text":16,"level":15},{"id":61,"text":60,"level":15},{"id":92,"text":91,"level":15},{"id":144,"text":143,"level":15},{"id":171,"text":170,"level":22},"2026-09-17T08:28:36.000Z",1789667797778]