[{"data":1,"prerenderedAt":546},["ShallowReactive",2],{"navigation_docs":3,"-docs-workflows":102,"-docs-workflows-surround":541},[4,8,12,16,20,24,28,32,36,40,44,82,86,90,94,98],{"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},"Changelog","\u002Fdocs\u002Fchangelog","docs\u002F15.changelog",{"id":103,"title":29,"body":104,"description":534,"extension":535,"links":536,"meta":537,"navigation":538,"path":30,"seo":539,"stem":31,"__hash__":540},"docs\u002Fdocs\u002F06.workflows.md",{"type":105,"value":106,"toc":526},"minimark",[107,128,133,136,155,172,176,182,227,238,242,253,269,272,276,279,313,316,320,327,331,337,376,515,522],[108,109,110,111,115,116,119,120,123,124,127],"p",{},"A workflow lists the categories to check and, for each, a ",[112,113,114],"code",{},"reject"," threshold and a ",[112,117,118],{},"review"," threshold. Every check names a workflow with its ",[112,121,122],{},"workflow"," parameter, and ",[112,125,126],{},"default"," when it names none.",[129,130,132],"h2",{"id":131},"how-a-decision-is-made","How a decision is made",[108,134,135],{},"Each category gets a score between 0 and 1. For each category the workflow lists:",[137,138,139,146,152],"ul",{},[140,141,142,143,145],"li",{},"a score at or above ",[112,144,114],{}," rejects the content;",[140,147,148,149,151],{},"else, a score at or above ",[112,150,118],{}," sends it to review;",[140,153,154],{},"a category the workflow does not list is not checked at all.",[108,156,157,158,161,162,164,165,167,168,171],{},"The answer's ",[112,159,160],{},"summary.action"," is ",[112,163,114],{}," when any category reaches its reject threshold, else ",[112,166,118],{}," when any reaches its review threshold, else ",[112,169,170],{},"accept",". The thresholds are numbers from 0 to 1. A category needs at least one of the two, and its review threshold is not above its reject threshold.",[129,173,175],{"id":174},"the-default-workflow","The default workflow",[108,177,178,179,181],{},"Every organization starts with a ",[112,180,126],{}," workflow, copied from openmod's own. It is semi-permissive: it rejects what is plainly unacceptable, sends the doubtful cases to review and lets everyday content pass.",[183,184,185,201],"table",{},[186,187,188],"thead",{},[189,190,191,195,198],"tr",{},[192,193,194],"th",{},"Kind",[192,196,197],{},"Rejected",[192,199,200],{},"Sent to review",[202,203,204,216],"tbody",{},[189,205,206,210,213],{},[207,208,209],"td",{},"Image",[207,211,212],{},"Nudity, gore, weapons, hate symbols and self-harm at 0.8. Extremist text, and links in text or QR codes to adult or unsafe sites.",[207,214,215],{},"The same five categories from 0.5. Drugs and minors from 0.5. Links to gambling sites.",[189,217,218,221,224],{},[207,219,220],{},"Text",[207,222,223],{},"Unsafe text, violence, sexual content, hate, illegal activity and unethical content at 0.8. Bank account numbers, payment card numbers and unsafe links.",[207,225,226],{},"The same six categories from 0.5. Self-harm from 0.5. Email addresses, phone numbers, requests to continue on another messaging app, spam, scams, extremism, and links to adult or gambling sites.",[108,228,229,230,233,234,237],{},"Two more templates are available when you create a workflow: ",[112,231,232],{},"strict",", which checks everything openmod can, and ",[112,235,236],{},"nudity_only",", for profile pictures. Organizations keep their own copy, so a change to a template never changes a workflow of yours. When a newer default is available, the dashboard shows what changed and offers to update, which makes a new version.",[129,239,241],{"id":240},"editing-a-workflow","Editing a workflow",[108,243,244,245,252],{},"Edit workflows in the ",[246,247,251],"a",{"href":248,"rel":249},"https:\u002F\u002Fopenshield.dev\u002Fdashboard\u002Fworkflows",[250],"nofollow","dashboard",":",[137,254,255,258,266],{},[140,256,257],{},"pick the categories from the catalogue, one list for images and one for texts, and set a review and a reject threshold for each;",[140,259,260,261,265],{},"add ",[262,263,264],"strong",{},"custom categories"," (below);",[140,267,268],{},"see every version, and compare any two.",[108,270,271],{},"A name is 1 to 64 characters. Your plan sets how many workflows you can have: 3 on the free plan, 10 on Starter, 50 on Growth and 200 on Scale. A saved version compiles in the background: until it has, the previous version keeps serving checks, and the dashboard says the new one is waiting.",[129,273,275],{"id":274},"custom-categories","Custom categories",[108,277,278],{},"A custom category teaches a workflow something that is specific to your product, in plain words. You give it:",[137,280,281,292,299,306],{},[140,282,283,284,287,288,291],{},"an ",[262,285,286],{},"id",": lower-case letters, digits and underscores, up to 64 characters, such as ",[112,289,290],{},"competitor_mention",";",[140,293,294,295,298],{},"up to 8 ",[262,296,297],{},"prompts",": short descriptions of what to look for, each up to 200 characters;",[140,300,301,302,305],{},"optionally up to 8 ",[262,303,304],{},"negatives",": descriptions of what looks similar but is fine;",[140,307,308,309,312],{},"a ",[262,310,311],{},"shift",", from -20 to 20, to make the category stricter or more lenient.",[108,314,315],{},"A workflow can have up to 20 custom categories. They count as one check, like any other category. Once defined, a custom category appears in the workflow's category list, and you set its thresholds like any other.",[129,317,319],{"id":318},"versions","Versions",[108,321,322,323,326],{},"Every save makes a new version. The answer says which one decided, in ",[112,324,325],{},"workflow_version",", and so does the journal: you can always tell which rules were in force for a past decision.",[129,328,330],{"id":329},"listing-your-workflows-from-the-api","Listing your workflows from the API",[108,332,333,336],{},[112,334,335],{},"GET \u002Fv1\u002Fworkflows"," lists the names and current versions of the workflows the key may use:",[338,339,344],"pre",{"className":340,"code":341,"language":342,"meta":343,"style":343},"language-bash shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","curl -H \"Authorization: Bearer $OPENMOD_API_KEY\" https:\u002F\u002Fapi.openshield.dev\u002Fv1\u002Fworkflows\n","bash","",[112,345,346],{"__ignoreMap":343},[347,348,351,355,359,363,366,370,373],"span",{"class":349,"line":350},"line",1,[347,352,354],{"class":353},"sBMFI","curl",[347,356,358],{"class":357},"sfazB"," -H",[347,360,362],{"class":361},"sMK4o"," \"",[347,364,365],{"class":357},"Authorization: Bearer ",[347,367,369],{"class":368},"sTEyZ","$OPENMOD_API_KEY",[347,371,372],{"class":361},"\"",[347,374,375],{"class":357}," https:\u002F\u002Fapi.openshield.dev\u002Fv1\u002Fworkflows\n",[338,377,381],{"className":378,"code":379,"language":380,"meta":343,"style":343},"language-json shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","{\n  \"status\": \"success\",\n  \"workflows\": [\n    { \"name\": \"default\", \"version\": 3 },\n    { \"name\": \"profile_picture\", \"version\": 1 }\n  ]\n}\n","json",[112,382,383,388,412,427,467,503,509],{"__ignoreMap":343},[347,384,385],{"class":349,"line":350},[347,386,387],{"class":361},"{\n",[347,389,391,394,398,400,402,404,407,409],{"class":349,"line":390},2,[347,392,393],{"class":361},"  \"",[347,395,397],{"class":396},"spNyl","status",[347,399,372],{"class":361},[347,401,252],{"class":361},[347,403,362],{"class":361},[347,405,406],{"class":357},"success",[347,408,372],{"class":361},[347,410,411],{"class":361},",\n",[347,413,415,417,420,422,424],{"class":349,"line":414},3,[347,416,393],{"class":361},[347,418,419],{"class":396},"workflows",[347,421,372],{"class":361},[347,423,252],{"class":361},[347,425,426],{"class":361}," [\n",[347,428,430,433,435,438,440,442,444,446,448,451,453,456,458,460,464],{"class":349,"line":429},4,[347,431,432],{"class":361},"    {",[347,434,362],{"class":361},[347,436,437],{"class":353},"name",[347,439,372],{"class":361},[347,441,252],{"class":361},[347,443,362],{"class":361},[347,445,126],{"class":357},[347,447,372],{"class":361},[347,449,450],{"class":361},",",[347,452,362],{"class":361},[347,454,455],{"class":353},"version",[347,457,372],{"class":361},[347,459,252],{"class":361},[347,461,463],{"class":462},"sbssI"," 3",[347,465,466],{"class":361}," },\n",[347,468,470,472,474,476,478,480,482,485,487,489,491,493,495,497,500],{"class":349,"line":469},5,[347,471,432],{"class":361},[347,473,362],{"class":361},[347,475,437],{"class":353},[347,477,372],{"class":361},[347,479,252],{"class":361},[347,481,362],{"class":361},[347,483,484],{"class":357},"profile_picture",[347,486,372],{"class":361},[347,488,450],{"class":361},[347,490,362],{"class":361},[347,492,455],{"class":353},[347,494,372],{"class":361},[347,496,252],{"class":361},[347,498,499],{"class":462}," 1",[347,501,502],{"class":361}," }\n",[347,504,506],{"class":349,"line":505},6,[347,507,508],{"class":361},"  ]\n",[347,510,512],{"class":349,"line":511},7,[347,513,514],{"class":361},"}\n",[108,516,517,518,521],{},"A workflow with no rule for the kind of content you send answers ",[112,519,520],{},"503 workflow_unavailable"," for it: an image sent to a workflow that only has text rules, for example.",[523,524,525],"style",{},"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);}html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}",{"title":343,"searchDepth":390,"depth":390,"links":527},[528,529,530,531,532,533],{"id":131,"depth":390,"text":132},{"id":174,"depth":390,"text":175},{"id":240,"depth":390,"text":241},{"id":274,"depth":390,"text":275},{"id":318,"depth":390,"text":319},{"id":329,"depth":390,"text":330},"A workflow decides which categories are checked and how strictly, with thresholds, custom categories and versions.","md",null,{},true,{"title":29,"description":534},"oVA0ezsmOnMfm96kPPEvspuf12w6gaGNM5XIiK2lgKQ",[542,544],{"title":25,"path":26,"stem":27,"description":543,"children":-1},"Three SightEngine workflow routes work here with the same paths, request fields and answer envelope. Change the base URL and key, map the category ids.",{"title":33,"path":34,"stem":35,"description":545,"children":-1},"Every field of an answer, the error envelope with its types, and the headers on every response.",1792436179911]