[{"data":1,"prerenderedAt":1596},["ShallowReactive",2],{"docsv3-nav":3,"\u002Fdocs\u002Fv3\u002Fquick-start":198},[4],{"title":5,"path":6,"stem":7,"children":8,"page":188},"V3","\u002Fdocs\u002Fv3","1.docs\u002Fv3",[9,13,17,21,38,87,189],{"title":10,"path":11,"stem":12},"Introduction","\u002Fdocs\u002Fv3\u002Fintroduction","1.docs\u002Fv3\u002F1.Introduction",{"title":14,"path":15,"stem":16},"Quick start","\u002Fdocs\u002Fv3\u002Fquick-start","1.docs\u002Fv3\u002F2.Quick start",{"title":18,"path":19,"stem":20},"Challenge flow","\u002Fdocs\u002Fv3\u002Fchallenge-flow","1.docs\u002Fv3\u002F3.Challenge flow",{"title":22,"path":23,"stem":24,"children":25},"Fundamentals","\u002Fdocs\u002Fv3\u002Ffundamentals","1.docs\u002Fv3\u002F4.fundamentals",[26,30,34],{"title":27,"path":28,"stem":29},"Signup protection","\u002Fdocs\u002Fv3\u002Ffundamentals\u002Fsignup-protection","1.docs\u002Fv3\u002F4.fundamentals\u002F00.Signup protection",{"title":31,"path":32,"stem":33},"Login protection","\u002Fdocs\u002Fv3\u002Ffundamentals\u002Flogin-protection","1.docs\u002Fv3\u002F4.fundamentals\u002F01.Login protection",{"title":35,"path":36,"stem":37},"Access protection","\u002Fdocs\u002Fv3\u002Ffundamentals\u002Faccess-protection","1.docs\u002Fv3\u002F4.fundamentals\u002F02.Access protection",{"title":39,"path":40,"stem":41,"children":42},"Guides","\u002Fdocs\u002Fv3\u002Fguides","1.docs\u002Fv3\u002F5.guides",[43,47,51,55,59,63,67,71,75,79,83],{"title":44,"path":45,"stem":46},"Account sharing prevention","\u002Fdocs\u002Fv3\u002Fguides\u002Faccount-sharing-prevention","1.docs\u002Fv3\u002F5.guides\u002F1.Account sharing prevention",{"title":48,"path":49,"stem":50},"Web scraping prevention","\u002Fdocs\u002Fv3\u002Fguides\u002Fweb-scraping-prevention","1.docs\u002Fv3\u002F5.guides\u002F13.Web scraping prevention",{"title":52,"path":53,"stem":54},"Ban enforcement","\u002Fdocs\u002Fv3\u002Fguides\u002Fban-enforcement","1.docs\u002Fv3\u002F5.guides\u002F14.Ban enforcement",{"title":56,"path":57,"stem":58},"Chargeback dispute","\u002Fdocs\u002Fv3\u002Fguides\u002Fchargeback-dispute","1.docs\u002Fv3\u002F5.guides\u002F15.Chargeback dispute",{"title":60,"path":61,"stem":62},"Multi-accounting prevention","\u002Fdocs\u002Fv3\u002Fguides\u002Fmulti-accounting-prevention","1.docs\u002Fv3\u002F5.guides\u002F16.Multi-accounting prevention",{"title":64,"path":65,"stem":66},"Account takeover prevention","\u002Fdocs\u002Fv3\u002Fguides\u002Faccount-takeover-prevention","1.docs\u002Fv3\u002F5.guides\u002F2.Account takeover prevention",{"title":68,"path":69,"stem":70},"Risky transaction prevention","\u002Fdocs\u002Fv3\u002Fguides\u002Frisky-transaction-prevention","1.docs\u002Fv3\u002F5.guides\u002F20.Risky transaction prevention",{"title":72,"path":73,"stem":74},"Fake account detection","\u002Fdocs\u002Fv3\u002Fguides\u002Ffake-account-detection","1.docs\u002Fv3\u002F5.guides\u002F3.Fake account detection",{"title":76,"path":77,"stem":78},"Bot detection","\u002Fdocs\u002Fv3\u002Fguides\u002Fbot-detection","1.docs\u002Fv3\u002F5.guides\u002F4.Bot detection",{"title":80,"path":81,"stem":82},"Card testing prevention","\u002Fdocs\u002Fv3\u002Fguides\u002Fcard-testing-prevention","1.docs\u002Fv3\u002F5.guides\u002F5.Card testing prevention",{"title":84,"path":85,"stem":86},"Incentive abuse prevention","\u002Fdocs\u002Fv3\u002Fguides\u002Fincentive-abuse-prevention","1.docs\u002Fv3\u002F5.guides\u002F9.Incentive abuse prevention",{"title":88,"path":89,"stem":90,"children":91,"page":188},"Concepts","\u002Fdocs\u002Fv3\u002Fconcepts","1.docs\u002Fv3\u002F6.concepts",[92,96,100,104,108,112,116,120,124,128,132,136,140,144,148,152,156,160,164,168,172,176,180,184],{"title":93,"path":94,"stem":95},"Evaluations","\u002Fdocs\u002Fv3\u002Fconcepts\u002Fevaluations","1.docs\u002Fv3\u002F6.concepts\u002F01.evaluations",{"title":97,"path":98,"stem":99},"Actions","\u002Fdocs\u002Fv3\u002Fconcepts\u002Factions","1.docs\u002Fv3\u002F6.concepts\u002F02.actions",{"title":101,"path":102,"stem":103},"Signals","\u002Fdocs\u002Fv3\u002Fconcepts\u002Fsignals","1.docs\u002Fv3\u002F6.concepts\u002F03.signals",{"title":105,"path":106,"stem":107},"Checks","\u002Fdocs\u002Fv3\u002Fconcepts\u002Fchecks","1.docs\u002Fv3\u002F6.concepts\u002F04.checks",{"title":109,"path":110,"stem":111},"Risks","\u002Fdocs\u002Fv3\u002Fconcepts\u002Frisks","1.docs\u002Fv3\u002F6.concepts\u002F05.risks",{"title":113,"path":114,"stem":115},"Verdicts","\u002Fdocs\u002Fv3\u002Fconcepts\u002Fverdicts","1.docs\u002Fv3\u002F6.concepts\u002F06.verdicts",{"title":117,"path":118,"stem":119},"Policies","\u002Fdocs\u002Fv3\u002Fconcepts\u002Fpolicies","1.docs\u002Fv3\u002F6.concepts\u002F07.policies",{"title":121,"path":122,"stem":123},"Challenges","\u002Fdocs\u002Fv3\u002Fconcepts\u002Fchallenges","1.docs\u002Fv3\u002F6.concepts\u002F08.challenges",{"title":125,"path":126,"stem":127},"Concurrency","\u002Fdocs\u002Fv3\u002Fconcepts\u002Fconcurrency","1.docs\u002Fv3\u002F6.concepts\u002F09.concurrency",{"title":129,"path":130,"stem":131},"Impossible travel","\u002Fdocs\u002Fv3\u002Fconcepts\u002Fimpossible-travel","1.docs\u002Fv3\u002F6.concepts\u002F10.impossible-travel",{"title":133,"path":134,"stem":135},"Bots","\u002Fdocs\u002Fv3\u002Fconcepts\u002Fbots","1.docs\u002Fv3\u002F6.concepts\u002F11.bots",{"title":137,"path":138,"stem":139},"Devices","\u002Fdocs\u002Fv3\u002Fconcepts\u002Fdevices","1.docs\u002Fv3\u002F6.concepts\u002F12.devices",{"title":141,"path":142,"stem":143},"Fingerprints","\u002Fdocs\u002Fv3\u002Fconcepts\u002Ffingerprints","1.docs\u002Fv3\u002F6.concepts\u002F13.fingerprints",{"title":145,"path":146,"stem":147},"People","\u002Fdocs\u002Fv3\u002Fconcepts\u002Fpeople","1.docs\u002Fv3\u002F6.concepts\u002F14.people",{"title":149,"path":150,"stem":151},"Lists","\u002Fdocs\u002Fv3\u002Fconcepts\u002Flists","1.docs\u002Fv3\u002F6.concepts\u002F15.lists",{"title":153,"path":154,"stem":155},"Account takeover","\u002Fdocs\u002Fv3\u002Fconcepts\u002Faccount-takeover","1.docs\u002Fv3\u002F6.concepts\u002F16.account-takeover",{"title":157,"path":158,"stem":159},"Account sharing","\u002Fdocs\u002Fv3\u002Fconcepts\u002Faccount-sharing","1.docs\u002Fv3\u002F6.concepts\u002F17.account-sharing",{"title":161,"path":162,"stem":163},"Fake account","\u002Fdocs\u002Fv3\u002Fconcepts\u002Ffake-account","1.docs\u002Fv3\u002F6.concepts\u002F18.fake-account",{"title":165,"path":166,"stem":167},"Scraping","\u002Fdocs\u002Fv3\u002Fconcepts\u002Fscraping","1.docs\u002Fv3\u002F6.concepts\u002F19.scraping",{"title":169,"path":170,"stem":171},"Linked accounts","\u002Fdocs\u002Fv3\u002Fconcepts\u002Flinked-accounts","1.docs\u002Fv3\u002F6.concepts\u002F20.linked-accounts",{"title":173,"path":174,"stem":175},"New IP","\u002Fdocs\u002Fv3\u002Fconcepts\u002Fip","1.docs\u002Fv3\u002F6.concepts\u002F21.ip",{"title":177,"path":178,"stem":179},"Anonymizing network","\u002Fdocs\u002Fv3\u002Fconcepts\u002Fanonymizing-network","1.docs\u002Fv3\u002F6.concepts\u002F22.anonymizing-network",{"title":181,"path":182,"stem":183},"Email quality","\u002Fdocs\u002Fv3\u002Fconcepts\u002Femail","1.docs\u002Fv3\u002F6.concepts\u002F23.email",{"title":185,"path":186,"stem":187},"Velocity","\u002Fdocs\u002Fv3\u002Fconcepts\u002Fvelocity","1.docs\u002Fv3\u002F6.concepts\u002F24.velocity",false,{"title":190,"path":191,"stem":192,"children":193,"page":188},"Advanced","\u002Fdocs\u002Fv3\u002Fadvanced","1.docs\u002Fv3\u002F7.Advanced",[194],{"title":195,"path":196,"stem":197},"Proxy setup","\u002Fdocs\u002Fv3\u002Fadvanced\u002Fproxy-setup","1.docs\u002Fv3\u002F7.Advanced\u002F1.Proxy-setup",{"id":199,"title":14,"body":200,"description":1590,"extension":1591,"meta":1592,"navigation":458,"path":15,"rawbody":1593,"seo":1594,"stem":16,"__hash__":1595},"docsv3\u002F1.docs\u002Fv3\u002F2.Quick start.md",{"type":201,"value":202,"toc":1583},"minimark",[203,207,216,220,228,233,407,411,418,949,956,960,966,1057,1079,1507,1513,1517,1527,1536,1539,1555,1558,1562,1579],[204,205,14],"h1",{"id":206},"quick-start",[208,209,210,211,215],"p",{},"Rupt works the same on every platform: run an ",[212,213,214],"a",{"href":94},"evaluation"," when the user takes an action, then confirm it on your server before you honor it. Here's the flow:",[217,218],"mermaid-diagram",{"code":219},"sequenceDiagram\n  actor U as User\n  participant C as Client app\n  participant S as Your server\n  participant R as Rupt\n  U->>C: Takes action (login \u002F signup \u002F access)\n  C->>R: evaluate(action, user?, email?, phone?, metadata?)\n  R-->>C: evaluation_id\n  C->>S: Forward evaluation_id with the action request\n  S->>R: GET \u002Fv3\u002Fevaluations\u002F{evaluation_id}\n  R-->>S: Evaluation (verdict, user, challenge, …)\n  Note over S: Integrity check\n  S-->>U: Honor or block the action\n",[208,221,222,223,227],{},"The ",[224,225,226],"strong",{},"integrity check"," is where your server confirms the evaluation matches what your client app sent and hasn't been tampered with.",[229,230,232],"h2",{"id":231},"_1-install-the-rupt-sdk","1. Install the Rupt SDK",[234,235,236,346,378],"client-platform",{},[237,238,240],"template",{"v-slot:web":239},"",[241,242,243,270,287,303],"code-tabs",{},[237,244,245],{"v-slot:npm":239},[246,247,251],"pre",{"className":248,"code":249,"language":250,"meta":239,"style":239},"language-sh shiki shiki-themes material-theme-lighter one-dark-pro monokai","npm install @ruptjs\u002Fclient\n","sh",[252,253,254],"code",{"__ignoreMap":239},[255,256,259,263,267],"span",{"class":257,"line":258},"line",1,[255,260,262],{"class":261},"sHrIR","npm",[255,264,266],{"class":265},"siibJ"," install",[255,268,269],{"class":265}," @ruptjs\u002Fclient\n",[237,271,272],{"v-slot:yarn":239},[246,273,275],{"className":248,"code":274,"language":250,"meta":239,"style":239},"yarn add @ruptjs\u002Fclient\n",[252,276,277],{"__ignoreMap":239},[255,278,279,282,285],{"class":257,"line":258},[255,280,281],{"class":261},"yarn",[255,283,284],{"class":265}," add",[255,286,269],{"class":265},[237,288,289],{"v-slot:bun":239},[246,290,292],{"className":248,"code":291,"language":250,"meta":239,"style":239},"bun add @ruptjs\u002Fclient\n",[252,293,294],{"__ignoreMap":239},[255,295,296,299,301],{"class":257,"line":258},[255,297,298],{"class":261},"bun",[255,300,284],{"class":265},[255,302,269],{"class":265},[237,304,305],{"v-slot:CDN":239},[246,306,310],{"className":307,"code":308,"language":309,"meta":239,"style":239},"language-html shiki shiki-themes material-theme-lighter one-dark-pro monokai","\u003Cscript src=\"https:\u002F\u002Fcdn.rupt.dev\u002Fjs\u002Fv3\u002Frupt.js\">\u003C\u002Fscript>\n","html",[252,311,312],{"__ignoreMap":239},[255,313,314,318,322,326,329,333,336,338,341,343],{"class":257,"line":258},[255,315,317],{"class":316},"shEKG","\u003C",[255,319,321],{"class":320},"slwgX","script",[255,323,325],{"class":324},"sXIpk"," src",[255,327,328],{"class":316},"=",[255,330,332],{"class":331},"s9QZx","\"",[255,334,335],{"class":265},"https:\u002F\u002Fcdn.rupt.dev\u002Fjs\u002Fv3\u002Frupt.js",[255,337,332],{"class":331},[255,339,340],{"class":316},">\u003C\u002F",[255,342,321],{"class":320},[255,344,345],{"class":316},">\n",[237,347,348],{"v-slot:ios":239},[349,350,351,361,368],"ol",{},[352,353,354,355,360],"li",{},"Download the SDK binary from ",[212,356,359],{"href":357,"target":358},"\u002Fios\u002Fsdk\u002FRuptClient.xcframework.zip","_blank","RuptClient.xcframework.zip",".",[352,362,363,364,367],{},"Unzip and drag ",[252,365,366],{},"RuptClient.xcframework"," into your Xcode project.",[352,369,370,371,374,375,360],{},"Select ",[224,372,373],{},"Copy items if needed"," and click ",[224,376,377],{},"Finish",[237,379,380],{"v-slot:android":239},[381,382,383,401],"ul",{},[352,384,385,386,389,390,393,394,397,398,360],{},"Make sure ",[252,387,388],{},"mavenCentral()"," and ",[252,391,392],{},"jitpack"," are listed under ",[252,395,396],{},"dependencyResolutionManagement"," in ",[252,399,400],{},"settings.gradle",[352,402,403,404,360],{},"Add Rupt to your dependencies: ",[252,405,406],{},"implementation(\"dev.rupt.android:rupt-android:4.0.0\")",[229,408,410],{"id":409},"_2-run-an-evaluation-client-side","2. Run an evaluation (client-side)",[208,412,413,414,417],{},"Call ",[252,415,416],{},"evaluate()"," at the moment the user takes the action (e.g. right after they submit the login, sign up, or checkout).",[234,419,420,641,811],{},[237,421,422],{"v-slot:web":239},[246,423,427],{"className":424,"code":425,"language":426,"meta":239,"style":239},"language-js shiki shiki-themes material-theme-lighter one-dark-pro monokai","import Rupt from \"@ruptjs\u002Fclient\";\n\nconst rupt = new Rupt({ clientId: \"your_client_id\" });\n\n\u002F\u002F Call rupt.evaluate.login \u002F .signup \u002F .access for the action you're protecting.\nconst response = await rupt.evaluate.login({\n  user: \"USER_ID\",\n  email: \"EMAIL\",\n  phone: \"PHONE\",\n  metadata: { key: \"value\" },\n});\n","js",[252,428,429,453,460,511,516,523,553,571,588,605,631],{"__ignoreMap":239},[255,430,431,435,439,442,445,448,450],{"class":257,"line":258},[255,432,434],{"class":433},"sAPXc","import",[255,436,438],{"class":437},"seeE2"," Rupt",[255,440,441],{"class":433}," from",[255,443,444],{"class":331}," \"",[255,446,447],{"class":265},"@ruptjs\u002Fclient",[255,449,332],{"class":331},[255,451,452],{"class":316},";\n",[255,454,456],{"class":257,"line":455},2,[255,457,459],{"emptyLinePlaceholder":458},true,"\n",[255,461,463,467,471,475,479,482,486,489,493,496,498,501,503,506,509],{"class":257,"line":462},3,[255,464,466],{"class":465},"sHm3x","const",[255,468,470],{"class":469},"sZ9uN"," rupt",[255,472,474],{"class":473},"sut_7"," =",[255,476,478],{"class":477},"srTuz"," new",[255,480,438],{"class":481},"sjp9t",[255,483,485],{"class":484},"sJCYa","(",[255,487,488],{"class":316},"{",[255,490,492],{"class":491},"sUwfj"," clientId",[255,494,495],{"class":316},":",[255,497,444],{"class":331},[255,499,500],{"class":265},"your_client_id",[255,502,332],{"class":331},[255,504,505],{"class":316}," }",[255,507,508],{"class":484},")",[255,510,452],{"class":316},[255,512,514],{"class":257,"line":513},4,[255,515,459],{"emptyLinePlaceholder":458},[255,517,519],{"class":257,"line":518},5,[255,520,522],{"class":521},"s42Qa","\u002F\u002F Call rupt.evaluate.login \u002F .signup \u002F .access for the action you're protecting.\n",[255,524,526,528,531,533,536,538,540,543,545,548,550],{"class":257,"line":525},6,[255,527,466],{"class":465},[255,529,530],{"class":469}," response",[255,532,474],{"class":473},[255,534,535],{"class":433}," await",[255,537,470],{"class":469},[255,539,360],{"class":316},[255,541,542],{"class":469},"evaluate",[255,544,360],{"class":316},[255,546,547],{"class":481},"login",[255,549,485],{"class":484},[255,551,552],{"class":316},"{\n",[255,554,556,559,561,563,566,568],{"class":257,"line":555},7,[255,557,558],{"class":491},"  user",[255,560,495],{"class":316},[255,562,444],{"class":331},[255,564,565],{"class":265},"USER_ID",[255,567,332],{"class":331},[255,569,570],{"class":316},",\n",[255,572,574,577,579,581,584,586],{"class":257,"line":573},8,[255,575,576],{"class":491},"  email",[255,578,495],{"class":316},[255,580,444],{"class":331},[255,582,583],{"class":265},"EMAIL",[255,585,332],{"class":331},[255,587,570],{"class":316},[255,589,591,594,596,598,601,603],{"class":257,"line":590},9,[255,592,593],{"class":491},"  phone",[255,595,495],{"class":316},[255,597,444],{"class":331},[255,599,600],{"class":265},"PHONE",[255,602,332],{"class":331},[255,604,570],{"class":316},[255,606,608,611,613,616,619,621,623,626,628],{"class":257,"line":607},10,[255,609,610],{"class":491},"  metadata",[255,612,495],{"class":316},[255,614,615],{"class":316}," {",[255,617,618],{"class":491}," key",[255,620,495],{"class":316},[255,622,444],{"class":331},[255,624,625],{"class":265},"value",[255,627,332],{"class":331},[255,629,630],{"class":316}," },\n",[255,632,634,637,639],{"class":257,"line":633},11,[255,635,636],{"class":316},"}",[255,638,508],{"class":484},[255,640,452],{"class":316},[237,642,643],{"v-slot:ios":239},[246,644,648],{"className":645,"code":646,"language":647,"meta":239,"style":239},"language-swift shiki shiki-themes material-theme-lighter one-dark-pro monokai","import Rupt\n\nlet rupt = Rupt(clientID: \"your_client_id\")\n\nlet response = try await rupt.evaluate(\n  action: \"login\", \u002F\u002F \"login\", \"signup\", or \"access\" (you can add more later)\n  user: \"USER_ID\",\n  email: \"EMAIL\",\n  phone: \"PHONE\",\n  metadata: [\"key\": \"value\"]\n)\n","swift",[252,649,650,658,662,693,697,719,738,752,766,780,807],{"__ignoreMap":239},[255,651,652,654],{"class":257,"line":258},[255,653,434],{"class":433},[255,655,657],{"class":656},"sX0Ul"," Rupt\n",[255,659,660],{"class":257,"line":455},[255,661,459],{"emptyLinePlaceholder":458},[255,663,664,668,671,674,677,679,682,684,686,688,690],{"class":257,"line":462},[255,665,667],{"class":666},"s2NTT","let",[255,669,670],{"class":484}," rupt ",[255,672,328],{"class":673},"sKfv_",[255,675,438],{"class":676},"sh6BQ",[255,678,485],{"class":316},[255,680,681],{"class":676},"clientID",[255,683,495],{"class":316},[255,685,444],{"class":331},[255,687,500],{"class":265},[255,689,332],{"class":331},[255,691,692],{"class":316},")\n",[255,694,695],{"class":257,"line":513},[255,696,459],{"emptyLinePlaceholder":458},[255,698,699,701,704,706,709,711,714,716],{"class":257,"line":518},[255,700,667],{"class":666},[255,702,703],{"class":484}," response ",[255,705,328],{"class":673},[255,707,708],{"class":433}," try",[255,710,535],{"class":433},[255,712,713],{"class":484}," rupt.",[255,715,542],{"class":676},[255,717,718],{"class":316},"(\n",[255,720,721,724,726,728,730,732,735],{"class":257,"line":525},[255,722,723],{"class":676},"  action",[255,725,495],{"class":316},[255,727,444],{"class":331},[255,729,547],{"class":265},[255,731,332],{"class":331},[255,733,734],{"class":484},", ",[255,736,737],{"class":521},"\u002F\u002F \"login\", \"signup\", or \"access\" (you can add more later)\n",[255,739,740,742,744,746,748,750],{"class":257,"line":555},[255,741,558],{"class":676},[255,743,495],{"class":316},[255,745,444],{"class":331},[255,747,565],{"class":265},[255,749,332],{"class":331},[255,751,570],{"class":484},[255,753,754,756,758,760,762,764],{"class":257,"line":573},[255,755,576],{"class":676},[255,757,495],{"class":316},[255,759,444],{"class":331},[255,761,583],{"class":265},[255,763,332],{"class":331},[255,765,570],{"class":484},[255,767,768,770,772,774,776,778],{"class":257,"line":590},[255,769,593],{"class":676},[255,771,495],{"class":316},[255,773,444],{"class":331},[255,775,600],{"class":265},[255,777,332],{"class":331},[255,779,570],{"class":484},[255,781,782,784,786,789,791,794,796,798,800,802,804],{"class":257,"line":607},[255,783,610],{"class":676},[255,785,495],{"class":316},[255,787,788],{"class":484}," [",[255,790,332],{"class":331},[255,792,793],{"class":265},"key",[255,795,332],{"class":331},[255,797,495],{"class":477},[255,799,444],{"class":331},[255,801,625],{"class":265},[255,803,332],{"class":331},[255,805,806],{"class":484},"]\n",[255,808,809],{"class":257,"line":633},[255,810,692],{"class":316},[237,812,813],{"v-slot:android":239},[246,814,818],{"className":815,"code":816,"language":817,"meta":239,"style":239},"language-kotlin shiki shiki-themes material-theme-lighter one-dark-pro monokai","import dev.rupt.Rupt\n\nval rupt = Rupt(context, clientId = \"your_client_id\")\n\nval response = rupt.evaluate(\n  action = \"login\", \u002F\u002F \"login\", \"signup\", or \"access\" (you can add more later)\n  user = \"USER_ID\",\n  email = \"EMAIL\",\n  phone = \"PHONE\",\n  metadata = mapOf(\"key\" to \"value\"),\n)\n","kotlin",[252,819,820,828,832,853,857,871,885,897,909,921,945],{"__ignoreMap":239},[255,821,822,824],{"class":257,"line":258},[255,823,434],{"class":477},[255,825,827],{"class":826},"s3gOb"," dev.rupt.Rupt\n",[255,829,830],{"class":257,"line":455},[255,831,459],{"emptyLinePlaceholder":458},[255,833,834,837,839,841,843,846,848,851],{"class":257,"line":462},[255,835,836],{"class":477},"val",[255,838,670],{"class":484},[255,840,328],{"class":473},[255,842,438],{"class":481},[255,844,845],{"class":484},"(context, clientId ",[255,847,328],{"class":473},[255,849,850],{"class":265}," \"your_client_id\"",[255,852,692],{"class":484},[255,854,855],{"class":257,"line":513},[255,856,459],{"emptyLinePlaceholder":458},[255,858,859,861,863,865,867,869],{"class":257,"line":518},[255,860,836],{"class":477},[255,862,703],{"class":484},[255,864,328],{"class":473},[255,866,713],{"class":484},[255,868,542],{"class":481},[255,870,718],{"class":484},[255,872,873,876,878,881,883],{"class":257,"line":525},[255,874,875],{"class":484},"  action ",[255,877,328],{"class":473},[255,879,880],{"class":265}," \"login\"",[255,882,734],{"class":484},[255,884,737],{"class":521},[255,886,887,890,892,895],{"class":257,"line":555},[255,888,889],{"class":484},"  user ",[255,891,328],{"class":473},[255,893,894],{"class":265}," \"USER_ID\"",[255,896,570],{"class":484},[255,898,899,902,904,907],{"class":257,"line":573},[255,900,901],{"class":484},"  email ",[255,903,328],{"class":473},[255,905,906],{"class":265}," \"EMAIL\"",[255,908,570],{"class":484},[255,910,911,914,916,919],{"class":257,"line":590},[255,912,913],{"class":484},"  phone ",[255,915,328],{"class":473},[255,917,918],{"class":265}," \"PHONE\"",[255,920,570],{"class":484},[255,922,923,926,928,931,933,936,939,942],{"class":257,"line":607},[255,924,925],{"class":484},"  metadata ",[255,927,328],{"class":473},[255,929,930],{"class":481}," mapOf",[255,932,485],{"class":484},[255,934,935],{"class":265},"\"key\"",[255,937,938],{"class":484}," to ",[255,940,941],{"class":265},"\"value\"",[255,943,944],{"class":484},"),\n",[255,946,947],{"class":257,"line":633},[255,948,692],{"class":484},[208,950,951,952,955],{},"The response includes the ",[252,953,954],{},"evaluation_id"," that you need to send to your server in step 3.",[229,957,959],{"id":958},"_3-confirm-the-evaluation-server-side","3. Confirm the evaluation (server-side)",[208,961,962,963,965],{},"This step takes place on your server. Your server should take the ",[252,964,954],{}," from the client and get that evaluation details from Rupt.",[246,967,969],{"className":424,"code":968,"language":426,"meta":239,"style":239},"import RuptAPI from \"@rupt\u002Fapi\";\n\nconst rupt = new RuptAPI(\"API_SECRET\");\nconst evaluation = await rupt.evaluation.get(evaluation_id);\n\n\u002F** Alternatively: curl https:\u002F\u002Fapi.rupt.dev\u002Fv3\u002Fevaluations\u002F$EVALUATION_ID \\ -H \"Authorization: Bearer $API_SECRET\" **\u002F\n",[252,970,971,989,993,1018,1048,1052],{"__ignoreMap":239},[255,972,973,975,978,980,982,985,987],{"class":257,"line":258},[255,974,434],{"class":433},[255,976,977],{"class":437}," RuptAPI",[255,979,441],{"class":433},[255,981,444],{"class":331},[255,983,984],{"class":265},"@rupt\u002Fapi",[255,986,332],{"class":331},[255,988,452],{"class":316},[255,990,991],{"class":257,"line":455},[255,992,459],{"emptyLinePlaceholder":458},[255,994,995,997,999,1001,1003,1005,1007,1009,1012,1014,1016],{"class":257,"line":462},[255,996,466],{"class":465},[255,998,470],{"class":469},[255,1000,474],{"class":473},[255,1002,478],{"class":477},[255,1004,977],{"class":481},[255,1006,485],{"class":484},[255,1008,332],{"class":331},[255,1010,1011],{"class":265},"API_SECRET",[255,1013,332],{"class":331},[255,1015,508],{"class":484},[255,1017,452],{"class":316},[255,1019,1020,1022,1025,1027,1029,1031,1033,1035,1037,1040,1042,1044,1046],{"class":257,"line":513},[255,1021,466],{"class":465},[255,1023,1024],{"class":469}," evaluation",[255,1026,474],{"class":473},[255,1028,535],{"class":433},[255,1030,470],{"class":469},[255,1032,360],{"class":316},[255,1034,214],{"class":469},[255,1036,360],{"class":316},[255,1038,1039],{"class":481},"get",[255,1041,485],{"class":484},[255,1043,954],{"class":437},[255,1045,508],{"class":484},[255,1047,452],{"class":316},[255,1049,1050],{"class":257,"line":518},[255,1051,459],{"emptyLinePlaceholder":458},[255,1053,1054],{"class":257,"line":525},[255,1055,1056],{"class":521},"\u002F** Alternatively: curl https:\u002F\u002Fapi.rupt.dev\u002Fv3\u002Fevaluations\u002F$EVALUATION_ID \\ -H \"Authorization: Bearer $API_SECRET\" **\u002F\n",[208,1058,951,1059,1062,1063,1066,1067,1070,1071,1074,1075,1078],{},[212,1060,1061],{"href":114},"verdict",", the ",[212,1064,1065],{"href":98},"action",", the user details Rupt received, the ",[212,1068,1069],{"href":118},"policy"," that matched, the ",[212,1072,1073],{"href":110},"risks"," detected, and the ",[212,1076,1077],{"href":122},"challenge"," if one was issued, and more:",[246,1080,1084],{"className":1081,"code":1082,"language":1083,"meta":239,"style":239},"language-json shiki shiki-themes material-theme-lighter one-dark-pro monokai","{\n  \"id\": \"...\",\n  \"action\": \"login\",\n  \"verdict\": \"allow\",\n  \"user\": {\n    \"rupt_id\": \"...\",\n    \"id\": \"USER_ID\", \u002F\u002F The user ID you provided to Rupt\n    \"email\": \"EMAIL\", \u002F\u002F The email you provided to Rupt\n    \"phone\": \"PHONE\" \u002F\u002F The phone you provided to Rupt\n  },\n  \"metadata\": { \"key\": \"value\" }, \u002F\u002F The metadata you provided to Rupt\n  \"policy\": { \"id\": \"...\", \"name\": \"...\", \"action\": { \"type\": \"allow\" } }, \u002F\u002F The policy that matched\n  \"challenge\": null, \u002F\u002F The challenge details if one was issued\n  \"redirect\": null, \u002F\u002F The redirect URL if one was issued\n  \"risk_summary\": [{ \"category\": \"ato\", \"severity\": \"low\" }], \u002F\u002F The risks detected\n  \"createdAt\": \"...\",\n  \"updatedAt\": \"...\"\n}\n","json",[252,1085,1086,1090,1115,1133,1152,1166,1187,1209,1231,1251,1256,1289,1368,1388,1407,1462,1482,1501],{"__ignoreMap":239},[255,1087,1088],{"class":257,"line":258},[255,1089,552],{"class":316},[255,1091,1092,1096,1100,1102,1104,1107,1111,1113],{"class":257,"line":455},[255,1093,1095],{"class":1094},"s32IW","  \"",[255,1097,1099],{"class":1098},"s49Q_","id",[255,1101,332],{"class":1094},[255,1103,495],{"class":316},[255,1105,444],{"class":1106},"sw10c",[255,1108,1110],{"class":1109},"s9uTm","...",[255,1112,332],{"class":1106},[255,1114,570],{"class":316},[255,1116,1117,1119,1121,1123,1125,1127,1129,1131],{"class":257,"line":462},[255,1118,1095],{"class":1094},[255,1120,1065],{"class":1098},[255,1122,332],{"class":1094},[255,1124,495],{"class":316},[255,1126,444],{"class":1106},[255,1128,547],{"class":1109},[255,1130,332],{"class":1106},[255,1132,570],{"class":316},[255,1134,1135,1137,1139,1141,1143,1145,1148,1150],{"class":257,"line":513},[255,1136,1095],{"class":1094},[255,1138,1061],{"class":1098},[255,1140,332],{"class":1094},[255,1142,495],{"class":316},[255,1144,444],{"class":1106},[255,1146,1147],{"class":1109},"allow",[255,1149,332],{"class":1106},[255,1151,570],{"class":316},[255,1153,1154,1156,1159,1161,1163],{"class":257,"line":518},[255,1155,1095],{"class":1094},[255,1157,1158],{"class":1098},"user",[255,1160,332],{"class":1094},[255,1162,495],{"class":316},[255,1164,1165],{"class":316}," {\n",[255,1167,1168,1171,1175,1177,1179,1181,1183,1185],{"class":257,"line":525},[255,1169,1170],{"class":1094},"    \"",[255,1172,1174],{"class":1173},"s4VVQ","rupt_id",[255,1176,332],{"class":1094},[255,1178,495],{"class":316},[255,1180,444],{"class":1106},[255,1182,1110],{"class":1109},[255,1184,332],{"class":1106},[255,1186,570],{"class":316},[255,1188,1189,1191,1193,1195,1197,1199,1201,1203,1206],{"class":257,"line":555},[255,1190,1170],{"class":1094},[255,1192,1099],{"class":1173},[255,1194,332],{"class":1094},[255,1196,495],{"class":316},[255,1198,444],{"class":1106},[255,1200,565],{"class":1109},[255,1202,332],{"class":1106},[255,1204,1205],{"class":316},",",[255,1207,1208],{"class":521}," \u002F\u002F The user ID you provided to Rupt\n",[255,1210,1211,1213,1216,1218,1220,1222,1224,1226,1228],{"class":257,"line":573},[255,1212,1170],{"class":1094},[255,1214,1215],{"class":1173},"email",[255,1217,332],{"class":1094},[255,1219,495],{"class":316},[255,1221,444],{"class":1106},[255,1223,583],{"class":1109},[255,1225,332],{"class":1106},[255,1227,1205],{"class":316},[255,1229,1230],{"class":521}," \u002F\u002F The email you provided to Rupt\n",[255,1232,1233,1235,1238,1240,1242,1244,1246,1248],{"class":257,"line":590},[255,1234,1170],{"class":1094},[255,1236,1237],{"class":1173},"phone",[255,1239,332],{"class":1094},[255,1241,495],{"class":316},[255,1243,444],{"class":1106},[255,1245,600],{"class":1109},[255,1247,332],{"class":1106},[255,1249,1250],{"class":521}," \u002F\u002F The phone you provided to Rupt\n",[255,1252,1253],{"class":257,"line":607},[255,1254,1255],{"class":316},"  },\n",[255,1257,1258,1260,1263,1265,1267,1269,1271,1273,1275,1277,1279,1281,1283,1286],{"class":257,"line":633},[255,1259,1095],{"class":1094},[255,1261,1262],{"class":1098},"metadata",[255,1264,332],{"class":1094},[255,1266,495],{"class":316},[255,1268,615],{"class":316},[255,1270,444],{"class":1094},[255,1272,793],{"class":1173},[255,1274,332],{"class":1094},[255,1276,495],{"class":316},[255,1278,444],{"class":1106},[255,1280,625],{"class":1109},[255,1282,332],{"class":1106},[255,1284,1285],{"class":316}," },",[255,1287,1288],{"class":521}," \u002F\u002F The metadata you provided to Rupt\n",[255,1290,1292,1294,1296,1298,1300,1302,1304,1306,1308,1310,1312,1314,1316,1318,1320,1323,1325,1327,1329,1331,1333,1335,1337,1339,1341,1343,1345,1347,1351,1353,1355,1357,1359,1361,1363,1365],{"class":257,"line":1291},12,[255,1293,1095],{"class":1094},[255,1295,1069],{"class":1098},[255,1297,332],{"class":1094},[255,1299,495],{"class":316},[255,1301,615],{"class":316},[255,1303,444],{"class":1094},[255,1305,1099],{"class":1173},[255,1307,332],{"class":1094},[255,1309,495],{"class":316},[255,1311,444],{"class":1106},[255,1313,1110],{"class":1109},[255,1315,332],{"class":1106},[255,1317,1205],{"class":316},[255,1319,444],{"class":1094},[255,1321,1322],{"class":1173},"name",[255,1324,332],{"class":1094},[255,1326,495],{"class":316},[255,1328,444],{"class":1106},[255,1330,1110],{"class":1109},[255,1332,332],{"class":1106},[255,1334,1205],{"class":316},[255,1336,444],{"class":1094},[255,1338,1065],{"class":1173},[255,1340,332],{"class":1094},[255,1342,495],{"class":316},[255,1344,615],{"class":316},[255,1346,444],{"class":1094},[255,1348,1350],{"class":1349},"sfLoi","type",[255,1352,332],{"class":1094},[255,1354,495],{"class":316},[255,1356,444],{"class":1106},[255,1358,1147],{"class":1109},[255,1360,332],{"class":1106},[255,1362,505],{"class":316},[255,1364,1285],{"class":316},[255,1366,1367],{"class":521}," \u002F\u002F The policy that matched\n",[255,1369,1371,1373,1375,1377,1379,1383,1385],{"class":257,"line":1370},13,[255,1372,1095],{"class":1094},[255,1374,1077],{"class":1098},[255,1376,332],{"class":1094},[255,1378,495],{"class":316},[255,1380,1382],{"class":1381},"stE5w"," null",[255,1384,1205],{"class":316},[255,1386,1387],{"class":521}," \u002F\u002F The challenge details if one was issued\n",[255,1389,1391,1393,1396,1398,1400,1402,1404],{"class":257,"line":1390},14,[255,1392,1095],{"class":1094},[255,1394,1395],{"class":1098},"redirect",[255,1397,332],{"class":1094},[255,1399,495],{"class":316},[255,1401,1382],{"class":1381},[255,1403,1205],{"class":316},[255,1405,1406],{"class":521}," \u002F\u002F The redirect URL if one was issued\n",[255,1408,1410,1412,1415,1417,1419,1422,1424,1427,1429,1431,1433,1436,1438,1440,1442,1445,1447,1449,1451,1454,1456,1459],{"class":257,"line":1409},15,[255,1411,1095],{"class":1094},[255,1413,1414],{"class":1098},"risk_summary",[255,1416,332],{"class":1094},[255,1418,495],{"class":316},[255,1420,1421],{"class":316}," [{",[255,1423,444],{"class":1094},[255,1425,1426],{"class":1173},"category",[255,1428,332],{"class":1094},[255,1430,495],{"class":316},[255,1432,444],{"class":1106},[255,1434,1435],{"class":1109},"ato",[255,1437,332],{"class":1106},[255,1439,1205],{"class":316},[255,1441,444],{"class":1094},[255,1443,1444],{"class":1173},"severity",[255,1446,332],{"class":1094},[255,1448,495],{"class":316},[255,1450,444],{"class":1106},[255,1452,1453],{"class":1109},"low",[255,1455,332],{"class":1106},[255,1457,1458],{"class":316}," }],",[255,1460,1461],{"class":521}," \u002F\u002F The risks detected\n",[255,1463,1465,1467,1470,1472,1474,1476,1478,1480],{"class":257,"line":1464},16,[255,1466,1095],{"class":1094},[255,1468,1469],{"class":1098},"createdAt",[255,1471,332],{"class":1094},[255,1473,495],{"class":316},[255,1475,444],{"class":1106},[255,1477,1110],{"class":1109},[255,1479,332],{"class":1106},[255,1481,570],{"class":316},[255,1483,1485,1487,1490,1492,1494,1496,1498],{"class":257,"line":1484},17,[255,1486,1095],{"class":1094},[255,1488,1489],{"class":1098},"updatedAt",[255,1491,332],{"class":1094},[255,1493,495],{"class":316},[255,1495,444],{"class":1106},[255,1497,1110],{"class":1109},[255,1499,1500],{"class":1106},"\"\n",[255,1502,1504],{"class":257,"line":1503},18,[255,1505,1506],{"class":316},"}\n",[208,1508,1509,1510],{},"Confirm that the evaluation matches the action you expected, the user you expected, and the metadata you expected. ",[224,1511,1512],{},"Treat any mismatch as a bad actor and block the action.",[229,1514,1516],{"id":1515},"_4-handle-challenges","4. Handle challenges",[208,1518,1519,1520,1523,1524,1526],{},"Out of the box you have no ",[212,1521,1522],{"href":118},"policies",", so every evaluation comes back ",[252,1525,1147],{}," and no challenge fires. That's expected; the steps above give you the plumbing and all the data you need to start writing policies that challenge, deny, or gate an action.",[208,1528,1529,1530,1532,1533,1535],{},"When a policy does issue a challenge, the evaluation comes back with a ",[252,1531,1395],{},". Sending the user through the hosted challenge and confirming they passed is a short round trip — the ",[212,1534,18],{"href":19}," walks through it end to end.",[208,1537,1538],{},"Start with the two foundations; every other use case builds on them:",[381,1540,1541,1548],{},[352,1542,1543,1547],{},[224,1544,1545],{},[212,1546,27],{"href":28}," — at signup the user is new and has no ID yet, so you store a little state to bind the pending signup to its challenge.",[352,1549,1550,1554],{},[224,1551,1552],{},[212,1553,31],{"href":32}," — at login you don't store anything; you just hold off issuing the session until the challenge completes.",[1556,1557],"hr",{},[229,1559,1561],{"id":1560},"next-steps","Next steps",[381,1563,1564,1569,1574],{},[352,1565,1566,1568],{},[212,1567,88],{"href":94}," — what evaluations, signals, checks, risks, verdicts, policies, and challenges actually mean.",[352,1570,1571,1573],{},[212,1572,39],{"href":40}," — recommendations on specific fraud-prevention scenarios.",[352,1575,1576,1578],{},[212,1577,195],{"href":196}," — route Rupt traffic through your own domain to bypass adblockers and JS-domain blocking.",[1580,1581,1582],"style",{},"html pre.shiki code .sHrIR, html code.shiki .sHrIR{--shiki-light:#E2931D;--shiki-default:#61AFEF;--shiki-dark:#A6E22E}html pre.shiki code .siibJ, html code.shiki .siibJ{--shiki-light:#91B859;--shiki-default:#98C379;--shiki-dark:#E6DB74}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .shEKG, html code.shiki .shEKG{--shiki-light:#39ADB5;--shiki-default:#ABB2BF;--shiki-dark:#F8F8F2}html pre.shiki code .slwgX, html code.shiki .slwgX{--shiki-light:#E53935;--shiki-default:#E06C75;--shiki-dark:#F92672}html pre.shiki code .sXIpk, html code.shiki .sXIpk{--shiki-light:#9C3EDA;--shiki-default:#D19A66;--shiki-dark:#A6E22E}html pre.shiki code .s9QZx, html code.shiki .s9QZx{--shiki-light:#39ADB5;--shiki-default:#98C379;--shiki-dark:#E6DB74}html pre.shiki code .sAPXc, html code.shiki .sAPXc{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#C678DD;--shiki-default-font-style:inherit;--shiki-dark:#F92672;--shiki-dark-font-style:inherit}html pre.shiki code .seeE2, html code.shiki .seeE2{--shiki-light:#90A4AE;--shiki-default:#E06C75;--shiki-dark:#F8F8F2}html pre.shiki code .sHm3x, html code.shiki .sHm3x{--shiki-light:#9C3EDA;--shiki-light-font-style:inherit;--shiki-default:#C678DD;--shiki-default-font-style:inherit;--shiki-dark:#66D9EF;--shiki-dark-font-style:italic}html pre.shiki code .sZ9uN, html code.shiki .sZ9uN{--shiki-light:#90A4AE;--shiki-default:#E5C07B;--shiki-dark:#F8F8F2}html pre.shiki code .sut_7, html code.shiki .sut_7{--shiki-light:#39ADB5;--shiki-default:#56B6C2;--shiki-dark:#F92672}html pre.shiki code .srTuz, html code.shiki .srTuz{--shiki-light:#39ADB5;--shiki-default:#C678DD;--shiki-dark:#F92672}html pre.shiki code .sjp9t, html code.shiki .sjp9t{--shiki-light:#6182B8;--shiki-default:#61AFEF;--shiki-dark:#A6E22E}html pre.shiki code .sJCYa, html code.shiki .sJCYa{--shiki-light:#90A4AE;--shiki-default:#ABB2BF;--shiki-dark:#F8F8F2}html pre.shiki code .sUwfj, html code.shiki .sUwfj{--shiki-light:#E53935;--shiki-default:#E06C75;--shiki-dark:#F8F8F2}html pre.shiki code .s42Qa, html code.shiki .s42Qa{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#7F848E;--shiki-default-font-style:italic;--shiki-dark:#88846F;--shiki-dark-font-style:inherit}html pre.shiki code .sX0Ul, html code.shiki .sX0Ul{--shiki-light:#E2931D;--shiki-light-text-decoration:inherit;--shiki-default:#E5C07B;--shiki-default-text-decoration:inherit;--shiki-dark:#A6E22E;--shiki-dark-text-decoration:underline}html pre.shiki code .s2NTT, html code.shiki .s2NTT{--shiki-light:#F76D47;--shiki-default:#C678DD;--shiki-dark:#F92672}html pre.shiki code .sKfv_, html code.shiki .sKfv_{--shiki-light:#39ADB5;--shiki-default:#ABB2BF;--shiki-dark:#F92672}html pre.shiki code .sh6BQ, html code.shiki .sh6BQ{--shiki-light:#6182B8;--shiki-default:#61AFEF;--shiki-dark:#66D9EF}html pre.shiki code .s3gOb, html code.shiki .s3gOb{--shiki-light:#E2931D;--shiki-default:#ABB2BF;--shiki-dark:#F8F8F2}html pre.shiki code .s32IW, html code.shiki .s32IW{--shiki-light:#39ADB5;--shiki-light-font-style:inherit;--shiki-default:#E06C75;--shiki-default-font-style:inherit;--shiki-dark:#66D9EF;--shiki-dark-font-style:italic}html pre.shiki code .s49Q_, html code.shiki .s49Q_{--shiki-light:#9C3EDA;--shiki-light-font-style:inherit;--shiki-default:#E06C75;--shiki-default-font-style:inherit;--shiki-dark:#66D9EF;--shiki-dark-font-style:italic}html pre.shiki code .sw10c, html code.shiki .sw10c{--shiki-light:#39ADB5;--shiki-default:#98C379;--shiki-dark:#CFCFC2}html pre.shiki code .s9uTm, html code.shiki .s9uTm{--shiki-light:#91B859;--shiki-default:#98C379;--shiki-dark:#CFCFC2}html pre.shiki code .s4VVQ, html code.shiki .s4VVQ{--shiki-light:#E2931D;--shiki-light-font-style:inherit;--shiki-default:#E06C75;--shiki-default-font-style:inherit;--shiki-dark:#66D9EF;--shiki-dark-font-style:italic}html pre.shiki code .sfLoi, html code.shiki .sfLoi{--shiki-light:#F76D47;--shiki-light-font-style:inherit;--shiki-default:#E06C75;--shiki-default-font-style:inherit;--shiki-dark:#66D9EF;--shiki-dark-font-style:italic}html pre.shiki code .stE5w, html code.shiki .stE5w{--shiki-light:#39ADB5;--shiki-default:#D19A66;--shiki-dark:#AE81FF}",{"title":239,"searchDepth":455,"depth":455,"links":1584},[1585,1586,1587,1588,1589],{"id":231,"depth":455,"text":232},{"id":409,"depth":455,"text":410},{"id":958,"depth":455,"text":959},{"id":1515,"depth":455,"text":1516},{"id":1560,"depth":455,"text":1561},"Rupt works the same on every platform: run an evaluation when the user takes an action, then confirm it on your server before you honor it. Here's the flow:","md",{},"---\ntitle: Quick start\n---\n\n# Quick start\n\nRupt works the same on every platform: run an [evaluation](\u002Fdocs\u002Fv3\u002Fconcepts\u002Fevaluations) when the user takes an action, then confirm it on your server before you honor it. Here's the flow:\n\n\u003C!-- prettier-ignore-start -->\n::MermaidDiagram\n---\ncode: |\n  sequenceDiagram\n    actor U as User\n    participant C as Client app\n    participant S as Your server\n    participant R as Rupt\n    U->>C: Takes action (login \u002F signup \u002F access)\n    C->>R: evaluate(action, user?, email?, phone?, metadata?)\n    R-->>C: evaluation_id\n    C->>S: Forward evaluation_id with the action request\n    S->>R: GET \u002Fv3\u002Fevaluations\u002F{evaluation_id}\n    R-->>S: Evaluation (verdict, user, challenge, …)\n    Note over S: Integrity check\n    S-->>U: Honor or block the action\n---\n::\n\u003C!-- prettier-ignore-end -->\n\nThe **integrity check** is where your server confirms the evaluation matches what your client app sent and hasn't been tampered with.\n\n## 1. Install the Rupt SDK\n\n::ClientPlatform\n\n#web\n\n:::CodeTabs\n\n#npm\n\n```sh\nnpm install @ruptjs\u002Fclient\n```\n\n#yarn\n\n```sh\nyarn add @ruptjs\u002Fclient\n```\n\n#bun\n\n```sh\nbun add @ruptjs\u002Fclient\n```\n\n#CDN\n\n```html\n\u003Cscript src=\"https:\u002F\u002Fcdn.rupt.dev\u002Fjs\u002Fv3\u002Frupt.js\">\u003C\u002Fscript>\n```\n\n:::\n\n#ios\n\n1. Download the SDK binary from \u003Ca href=\"\u002Fios\u002Fsdk\u002FRuptClient.xcframework.zip\" target=\"_blank\">RuptClient.xcframework.zip\u003C\u002Fa>.\n2. Unzip and drag `RuptClient.xcframework` into your Xcode project.\n3. Select **Copy items if needed** and click **Finish**.\n\n#android\n\n- Make sure `mavenCentral()` and `jitpack` are listed under `dependencyResolutionManagement` in `settings.gradle`.\n- Add Rupt to your dependencies: `implementation(\"dev.rupt.android:rupt-android:4.0.0\")`.\n\n::\n\n## 2. Run an evaluation (client-side)\n\nCall `evaluate()` at the moment the user takes the action (e.g. right after they submit the login, sign up, or checkout).\n\n::ClientPlatform\n\n#web\n\n```js\nimport Rupt from \"@ruptjs\u002Fclient\";\n\nconst rupt = new Rupt({ clientId: \"your_client_id\" });\n\n\u002F\u002F Call rupt.evaluate.login \u002F .signup \u002F .access for the action you're protecting.\nconst response = await rupt.evaluate.login({\n  user: \"USER_ID\",\n  email: \"EMAIL\",\n  phone: \"PHONE\",\n  metadata: { key: \"value\" },\n});\n```\n\n#ios\n\n```swift\nimport Rupt\n\nlet rupt = Rupt(clientID: \"your_client_id\")\n\nlet response = try await rupt.evaluate(\n  action: \"login\", \u002F\u002F \"login\", \"signup\", or \"access\" (you can add more later)\n  user: \"USER_ID\",\n  email: \"EMAIL\",\n  phone: \"PHONE\",\n  metadata: [\"key\": \"value\"]\n)\n```\n\n#android\n\n```kotlin\nimport dev.rupt.Rupt\n\nval rupt = Rupt(context, clientId = \"your_client_id\")\n\nval response = rupt.evaluate(\n  action = \"login\", \u002F\u002F \"login\", \"signup\", or \"access\" (you can add more later)\n  user = \"USER_ID\",\n  email = \"EMAIL\",\n  phone = \"PHONE\",\n  metadata = mapOf(\"key\" to \"value\"),\n)\n```\n\n::\n\nThe response includes the `evaluation_id` that you need to send to your server in step 3.\n\n## 3. Confirm the evaluation (server-side)\n\nThis step takes place on your server. Your server should take the `evaluation_id` from the client and get that evaluation details from Rupt.\n\n```js\nimport RuptAPI from \"@rupt\u002Fapi\";\n\nconst rupt = new RuptAPI(\"API_SECRET\");\nconst evaluation = await rupt.evaluation.get(evaluation_id);\n\n\u002F** Alternatively: curl https:\u002F\u002Fapi.rupt.dev\u002Fv3\u002Fevaluations\u002F$EVALUATION_ID \\ -H \"Authorization: Bearer $API_SECRET\" **\u002F\n```\n\nThe response includes the [verdict](\u002Fdocs\u002Fv3\u002Fconcepts\u002Fverdicts), the [action](\u002Fdocs\u002Fv3\u002Fconcepts\u002Factions), the user details Rupt received, the [policy](\u002Fdocs\u002Fv3\u002Fconcepts\u002Fpolicies) that matched, the [risks](\u002Fdocs\u002Fv3\u002Fconcepts\u002Frisks) detected, and the [challenge](\u002Fdocs\u002Fv3\u002Fconcepts\u002Fchallenges) if one was issued, and more:\n\n```json\n{\n  \"id\": \"...\",\n  \"action\": \"login\",\n  \"verdict\": \"allow\",\n  \"user\": {\n    \"rupt_id\": \"...\",\n    \"id\": \"USER_ID\", \u002F\u002F The user ID you provided to Rupt\n    \"email\": \"EMAIL\", \u002F\u002F The email you provided to Rupt\n    \"phone\": \"PHONE\" \u002F\u002F The phone you provided to Rupt\n  },\n  \"metadata\": { \"key\": \"value\" }, \u002F\u002F The metadata you provided to Rupt\n  \"policy\": { \"id\": \"...\", \"name\": \"...\", \"action\": { \"type\": \"allow\" } }, \u002F\u002F The policy that matched\n  \"challenge\": null, \u002F\u002F The challenge details if one was issued\n  \"redirect\": null, \u002F\u002F The redirect URL if one was issued\n  \"risk_summary\": [{ \"category\": \"ato\", \"severity\": \"low\" }], \u002F\u002F The risks detected\n  \"createdAt\": \"...\",\n  \"updatedAt\": \"...\"\n}\n```\n\nConfirm that the evaluation matches the action you expected, the user you expected, and the metadata you expected. **Treat any mismatch as a bad actor and block the action.**\n\n## 4. Handle challenges\n\nOut of the box you have no [policies](\u002Fdocs\u002Fv3\u002Fconcepts\u002Fpolicies), so every evaluation comes back `allow` and no challenge fires. That's expected; the steps above give you the plumbing and all the data you need to start writing policies that challenge, deny, or gate an action.\n\nWhen a policy does issue a challenge, the evaluation comes back with a `redirect`. Sending the user through the hosted challenge and confirming they passed is a short round trip — the [Challenge flow](\u002Fdocs\u002Fv3\u002Fchallenge-flow) walks through it end to end.\n\nStart with the two foundations; every other use case builds on them:\n\n- **[Signup protection](\u002Fdocs\u002Fv3\u002Ffundamentals\u002Fsignup-protection)** — at signup the user is new and has no ID yet, so you store a little state to bind the pending signup to its challenge.\n- **[Login protection](\u002Fdocs\u002Fv3\u002Ffundamentals\u002Flogin-protection)** — at login you don't store anything; you just hold off issuing the session until the challenge completes.\n\n---\n\n## Next steps\n\n- [Concepts](\u002Fdocs\u002Fv3\u002Fconcepts\u002Fevaluations) — what evaluations, signals, checks, risks, verdicts, policies, and challenges actually mean.\n- [Guides](\u002Fdocs\u002Fv3\u002Fguides) — recommendations on specific fraud-prevention scenarios.\n- [Proxy setup](\u002Fdocs\u002Fv3\u002Fadvanced\u002Fproxy-setup) — route Rupt traffic through your own domain to bypass adblockers and JS-domain blocking.\n",{"title":14,"description":1590},"3aTcfZCnXCIq8EXfIsvKnjSYlwdHTMnJW6Vb93UQggo",1780344892555]