[{"data":1,"prerenderedAt":509},["ShallowReactive",2],{"navigation_docs":3,"-docs-authentication":114,"-docs-authentication-surround":504},[4,8,12,16,20,24,28,32,36,40,44,82,86,90,94,98,102,106,110],{"title":5,"path":6,"stem":7},"Overview","\u002Fdocs","docs\u002Findex",{"title":9,"path":10,"stem":11},"Quickstart","\u002Fdocs\u002Fquickstart","docs\u002F01.quickstart",{"title":13,"path":14,"stem":15},"Authentication and keys","\u002Fdocs\u002Fauthentication","docs\u002F02.authentication",{"title":17,"path":18,"stem":19},"Images","\u002Fdocs\u002Fimages","docs\u002F03.images",{"title":21,"path":22,"stem":23},"Texts","\u002Fdocs\u002Ftexts","docs\u002F04.texts",{"title":25,"path":26,"stem":27},"Migrating from SightEngine","\u002Fdocs\u002Fmigrating-from-sightengine","docs\u002F05.migrating-from-sightengine",{"title":29,"path":30,"stem":31},"Workflows","\u002Fdocs\u002Fworkflows","docs\u002F06.workflows",{"title":33,"path":34,"stem":35},"Responses and errors","\u002Fdocs\u002Fresponses-and-errors","docs\u002F07.responses-and-errors",{"title":37,"path":38,"stem":39},"Limits and quotas","\u002Fdocs\u002Flimits-and-quotas","docs\u002F08.limits-and-quotas",{"title":41,"path":42,"stem":43},"The journal and ref","\u002Fdocs\u002Fjournal-and-ref","docs\u002F09.journal-and-ref",{"title":45,"path":46,"stem":47,"children":48,"page":81},"Integration guides","\u002Fdocs\u002Fintegration-guides","docs\u002F10.integration-guides",[49,53,57,61,65,69,73,77],{"title":50,"path":51,"stem":52},"Node.js and TypeScript","\u002Fdocs\u002Fintegration-guides\u002Fnodejs","docs\u002F10.integration-guides\u002F1.nodejs",{"title":54,"path":55,"stem":56},"Python","\u002Fdocs\u002Fintegration-guides\u002Fpython","docs\u002F10.integration-guides\u002F2.python",{"title":58,"path":59,"stem":60},"PHP","\u002Fdocs\u002Fintegration-guides\u002Fphp","docs\u002F10.integration-guides\u002F3.php",{"title":62,"path":63,"stem":64},"Go","\u002Fdocs\u002Fintegration-guides\u002Fgo","docs\u002F10.integration-guides\u002F4.go",{"title":66,"path":67,"stem":68},"Supabase Edge Functions","\u002Fdocs\u002Fintegration-guides\u002Fsupabase-edge-functions","docs\u002F10.integration-guides\u002F5.supabase-edge-functions",{"title":70,"path":71,"stem":72},"Cloudflare Workers","\u002Fdocs\u002Fintegration-guides\u002Fcloudflare-workers","docs\u002F10.integration-guides\u002F6.cloudflare-workers",{"title":74,"path":75,"stem":76},"Nuxt and Next","\u002Fdocs\u002Fintegration-guides\u002Fnuxt-and-next","docs\u002F10.integration-guides\u002F7.nuxt-and-next",{"title":78,"path":79,"stem":80},"Moderate an AI agent","\u002Fdocs\u002Fintegration-guides\u002Fmoderate-ai-agents","docs\u002F10.integration-guides\u002F8.moderate-ai-agents",false,{"title":83,"path":84,"stem":85},"AI coding agents","\u002Fdocs\u002Fai-agents","docs\u002F11.ai-agents",{"title":87,"path":88,"stem":89},"Best practices","\u002Fdocs\u002Fbest-practices","docs\u002F12.best-practices",{"title":91,"path":92,"stem":93},"Privacy and data","\u002Fdocs\u002Fprivacy-and-data","docs\u002F13.privacy-and-data",{"title":95,"path":96,"stem":97},"API reference","\u002Fdocs\u002Fapi-reference","docs\u002F14.api-reference",{"title":99,"path":100,"stem":101},"Fraud prevention","\u002Fdocs\u002Ffraud-prevention","docs\u002F16.fraud-prevention",{"title":103,"path":104,"stem":105},"Device token and challenges","\u002Fdocs\u002Fdevice-and-challenges","docs\u002F17.device-and-challenges",{"title":107,"path":108,"stem":109},"MCP server","\u002Fdocs\u002Fmcp-server","docs\u002F18.mcp-server",{"title":111,"path":112,"stem":113},"Changelog","\u002Fdocs\u002Fchangelog","docs\u002F99.changelog",{"id":115,"title":13,"body":116,"description":498,"extension":499,"links":500,"meta":501,"navigation":183,"path":14,"seo":502,"stem":15,"__hash__":503},"docs\u002Fdocs\u002F02.authentication.md",{"type":117,"value":118,"toc":489},"minimark",[119,123,128,131,209,216,232,236,239,292,295,299,302,305,309,323,326,330,333,353,356,382,386,390,414,418,485],[120,121,122],"p",{},"Every request to the checking API carries an API key. Keys belong to an organization, and you create them in the dashboard.",[124,125,127],"h2",{"id":126},"sending-the-key","Sending the key",[120,129,130],{},"Use either header. They are equivalent.",[132,133,138],"pre",{"className":134,"code":135,"language":136,"meta":137,"style":137},"language-bash shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","# The Authorization header\ncurl -H \"Authorization: Bearer $OPENSHIELD_API_KEY\" ...\n\n# The X-Api-Key header\ncurl -H \"X-Api-Key: $OPENSHIELD_API_KEY\" ...\n","bash","",[139,140,141,150,178,185,191],"code",{"__ignoreMap":137},[142,143,146],"span",{"class":144,"line":145},"line",1,[142,147,149],{"class":148},"sHwdD","# The Authorization header\n",[142,151,153,157,161,165,168,172,175],{"class":144,"line":152},2,[142,154,156],{"class":155},"sBMFI","curl",[142,158,160],{"class":159},"sfazB"," -H",[142,162,164],{"class":163},"sMK4o"," \"",[142,166,167],{"class":159},"Authorization: Bearer ",[142,169,171],{"class":170},"sTEyZ","$OPENSHIELD_API_KEY",[142,173,174],{"class":163},"\"",[142,176,177],{"class":159}," ...\n",[142,179,181],{"class":144,"line":180},3,[142,182,184],{"emptyLinePlaceholder":183},true,"\n",[142,186,188],{"class":144,"line":187},4,[142,189,190],{"class":148},"# The X-Api-Key header\n",[142,192,194,196,198,200,203,205,207],{"class":144,"line":193},5,[142,195,156],{"class":155},[142,197,160],{"class":159},[142,199,164],{"class":163},[142,201,202],{"class":159},"X-Api-Key: ",[142,204,171],{"class":170},[142,206,174],{"class":163},[142,208,177],{"class":159},[120,210,211,212,215],{},"A key looks like ",[139,213,214],{},"om_live_\u003Cid>_\u003Csecret>",": a prefix, 12 characters of id and 32 of secret. The id is not secret: it identifies the key in the dashboard and in the journal. The key is stored only as a hash, so we cannot show it again.",[120,217,218,219,223,224,227,228,231],{},"The ",[220,221,222],"a",{"href":26},"SightEngine-compatible endpoints"," take the key in the ",[139,225,226],{},"api_secret"," form field (or query parameter, for the ",[139,229,230],{},"GET"," form) instead.",[124,233,235],{"id":234},"scopes-and-workflows","Scopes and workflows",[120,237,238],{},"When you create a key you choose:",[240,241,242,274,282],"ul",{},[243,244,245,249,250,253,254,257,258,261,262,265,266,269,270,273],"li",{},[246,247,248],"strong",{},"Scopes",": ",[139,251,252],{},"image",", ",[139,255,256],{},"text"," or both, and for ",[220,259,260],{"href":100},"fraud prevention"," ",[139,263,264],{},"fraud"," (the whole fraud API) or ",[139,267,268],{},"fraud_events"," (decide and report events only). A key without the scope for a call gets ",[139,271,272],{},"403 forbidden"," for it.",[243,275,276,278,279,281],{},[246,277,29],{},": all of them, or a list. A key limited to some workflows gets ",[139,280,272],{}," for any other.",[243,283,284,287,288,291],{},[246,285,286],{},"Expiry",": optional. An expired key gets ",[139,289,290],{},"401 unauthorized",".",[120,293,294],{},"Give each service its own key, with the narrowest scope and workflows it needs.",[124,296,298],{"id":297},"editing-a-key","Editing a key",[120,300,301],{},"Edit an active key from the dashboard to change its name, scopes, workflows or expiry. The key itself does not change, so servers that use it keep working, and the gateway applies the new access within seconds. A key stays in its environment: a live key cannot become a test key, or the other way round. An expired or revoked key cannot be edited: create a new one. A key a rotation replaced cannot be edited either: it stops at the end of its grace delay, so edit the new key.",[120,303,304],{},"Owners and admins edit any key; developers edit the keys they created.",[124,306,308],{"id":307},"rotating-and-revoking","Rotating and revoking",[240,310,311,317],{},[243,312,313,316],{},[246,314,315],{},"Rotate"," a key from the dashboard to make a new one with the same scopes. The old key keeps working for a grace delay you choose, from 0 to 24 hours, so you can deploy the new one without a gap.",[243,318,319,322],{},[246,320,321],{},"Revoke"," a key to stop it at once.",[120,324,325],{},"A rotated key in its grace delay counts toward the number of keys your limits allow.",[124,327,329],{"id":328},"key-activity-and-status","Key activity and status",[120,331,332],{},"Open a key's activity from the dashboard to see:",[240,334,335,341,347],{},[243,336,337,340],{},[246,338,339],{},"Right now",": the key's requests this minute, and your organization's requests this minute against its per-minute limit, the checks running at once, and the quota used this period. Limits belong to the organization, so every key shares them.",[243,342,343,346],{},[246,344,345],{},"Usage",": the key's checks, fraud calls and cost this hour, over the last 24 hours and over the last 30 days. Sandbox calls cost nothing.",[243,348,349,352],{},[246,350,351],{},"Last calls",": the key's latest checks from the journal, kept as long as your plan's journal retention.",[120,354,355],{},"Beside its status, the key list flags what needs attention:",[240,357,358,364,370,376],{},[243,359,360,363],{},[246,361,362],{},"Expires soon",": the key expires within 14 days.",[243,365,366,369],{},[246,367,368],{},"Grace period",": a rotation replaced the key, and it stops working at the end of its grace delay.",[243,371,372,375],{},[246,373,374],{},"Never used",": no call has used the key yet.",[243,377,378,381],{},[246,379,380],{},"Idle 30 days",": the key has not been used for 30 days. Revoke a key you no longer need.",[124,383,385],{"id":384},"keep-keys-on-the-server","Keep keys on the server",[387,388,389],"warning",{},"Never put a key in a web page, a mobile app, a browser extension or a repository. Call the API from your backend, and give your front end the decision, not the key.",[240,391,392,398,407],{},[243,393,394,395,291],{},"Store the key in an environment variable or your platform's secret store. The examples in these docs use ",[139,396,397],{},"OPENSHIELD_API_KEY",[243,399,400,401,404,405,291],{},"The API does not answer browser cross-origin requests. A request carrying an ",[139,402,403],{},"Origin"," header gets ",[139,406,272],{},[243,408,409,410,413],{},"If a key leaks, revoke it and create another. The ",[220,411,412],{"href":42},"journal"," shows which key made each check, so you can see what the leaked key was used for.",[124,415,417],{"id":416},"errors","Errors",[419,420,421,439],"table",{},[422,423,424],"thead",{},[425,426,427,431,436],"tr",{},[428,429,430],"th",{},"Status",[428,432,433],{},[139,434,435],{},"error.type",[428,437,438],{},"When",[440,441,442,456,469],"tbody",{},[425,443,444,448,453],{},[445,446,447],"td",{},"401",[445,449,450],{},[139,451,452],{},"unauthorized",[445,454,455],{},"The key is missing, malformed, invalid, revoked or expired.",[425,457,458,461,466],{},[445,459,460],{},"403",[445,462,463],{},[139,464,465],{},"forbidden",[445,467,468],{},"The key may not check this kind of content or use this workflow, or the request came from a browser.",[425,470,471,473,478],{},[445,472,460],{},[445,474,475],{},[139,476,477],{},"organization_suspended",[445,479,480,481,291],{},"An operator suspended the organization. Write to ",[220,482,484],{"href":483},"mailto:contact@sway.events","contact@sway.events",[486,487,488],"style",{},"html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}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);}",{"title":137,"searchDepth":152,"depth":152,"links":490},[491,492,493,494,495,496,497],{"id":126,"depth":152,"text":127},{"id":234,"depth":152,"text":235},{"id":297,"depth":152,"text":298},{"id":307,"depth":152,"text":308},{"id":328,"depth":152,"text":329},{"id":384,"depth":152,"text":385},{"id":416,"depth":152,"text":417},"How to call the API with a key, what a key may do and how to keep it safe.","md",null,{},{"title":13,"description":498},"qU_17uhXIDTNjAaXo3-fk3o1VQo3vtDokh-oXl-noik",[505,507],{"title":9,"path":10,"stem":11,"description":506,"children":-1},"Your first check in five minutes, from an account to a key and one request.",{"title":17,"path":18,"stem":19,"description":508,"children":-1},"Check an image with POST \u002Fv1\u002Fimage, sent as bytes or as a public URL.",1792938461580]