[{"data":1,"prerenderedAt":383},["ShallowReactive",2],{"navigation_docs":3,"-docs-journal-and-ref":114,"-docs-journal-and-ref-surround":378},[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":41,"body":116,"description":371,"extension":372,"links":373,"meta":374,"navigation":375,"path":42,"seo":376,"stem":43,"__hash__":377},"docs\u002Fdocs\u002F09.journal-and-ref.md",{"type":117,"value":118,"toc":364},"minimark",[119,131,136,139,177,184,188,224,227,231,236,302,308,315,319,322,339,346,350,360],[120,121,122,123,130],"p",{},"The journal is the record of the decisions the API made for your organization. You read it in the ",[124,125,129],"a",{"href":126,"rel":127},"https:\u002F\u002Fopenshield.dev\u002Fdashboard\u002Fjournal",[128],"nofollow","dashboard",", filter it, and export it.",[132,133,135],"h2",{"id":134},"what-a-row-holds","What a row holds",[120,137,138],{},"One row per check:",[140,141,142,151,154,157,160,167,170],"ul",{},[143,144,145,146,150],"li",{},"the time and the ",[147,148,149],"code",{},"request_id",";",[143,152,153],{},"the key, by id and name;",[143,155,156],{},"the kind (image or text), the workflow and its version;",[143,158,159],{},"the decision, and the reasons with their scores and thresholds;",[143,161,162,163,166],{},"the categories the workflow could not check (",[147,164,165],{},"unchecked",");",[143,168,169],{},"how long the check took, and the size of the content in bytes;",[143,171,172,173,176],{},"your ",[147,174,175],{},"ref",", if you sent one.",[120,178,179,183],{},[180,181,182],"strong",{},"Never stored",": the content itself, whatever it is, the IP address of your users, and their browser. The journal keeps what the API decided, never what it was asked about.",[132,185,187],{"id":186},"how-long-it-is-kept","How long it is kept",[189,190,191,204],"table",{},[192,193,194],"thead",{},[195,196,197,201],"tr",{},[198,199,200],"th",{},"Tier",[198,202,203],{},"Days kept",[205,206,207,216],"tbody",{},[195,208,209,213],{},[210,211,212],"td",{},"Free (never topped up)",[210,214,215],{},"7",[195,217,218,221],{},[210,219,220],{},"Tier 1, 2 and 3",[210,222,223],{},"30",[120,225,226],{},"Older rows are deleted every day. Export what you need to keep for longer.",[132,228,230],{"id":229},"ref-your-own-id-for-the-content","ref: your own id for the content",[120,232,233,235],{},[147,234,175],{}," is the id your system gives the image or the text: a post id, a message id, a user id. It is 1 to 128 characters with no control character.",[237,238,243],"pre",{"className":239,"code":240,"language":241,"meta":242,"style":242},"language-bash shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","curl -X POST \"https:\u002F\u002Fapi.openshield.dev\u002Fv1\u002Fimage?ref=post_8812\" \\\n  -H \"Authorization: Bearer $OPENSHIELD_API_KEY\" \\\n  --data-binary @photo.jpg\n","bash","",[147,244,245,275,293],{"__ignoreMap":242},[246,247,250,254,258,261,265,268,271],"span",{"class":248,"line":249},"line",1,[246,251,253],{"class":252},"sBMFI","curl",[246,255,257],{"class":256},"sfazB"," -X",[246,259,260],{"class":256}," POST",[246,262,264],{"class":263},"sMK4o"," \"",[246,266,267],{"class":256},"https:\u002F\u002Fapi.openshield.dev\u002Fv1\u002Fimage?ref=post_8812",[246,269,270],{"class":263},"\"",[246,272,274],{"class":273},"sTEyZ"," \\\n",[246,276,278,281,283,286,289,291],{"class":248,"line":277},2,[246,279,280],{"class":256},"  -H",[246,282,264],{"class":263},[246,284,285],{"class":256},"Authorization: Bearer ",[246,287,288],{"class":273},"$OPENSHIELD_API_KEY",[246,290,270],{"class":263},[246,292,274],{"class":273},[246,294,296,299],{"class":248,"line":295},3,[246,297,298],{"class":256},"  --data-binary",[246,300,301],{"class":256}," @photo.jpg\n",[120,303,304,305,307],{},"The API echoes it in the answer and keeps it in the journal. When a user asks why their upload was refused, you search the journal for the ",[147,306,175],{}," and see the decision, the reasons and the workflow version, and openshield never had to keep the upload to answer.",[309,310,311,312,314],"warning",{},"Do not put personal data in a ",[147,313,175],{},". Use an opaque id from your own database.",[132,316,318],{"id":317},"filtering-and-exporting","Filtering and exporting",[120,320,321],{},"The journal screen filters by:",[140,323,324,327,330,333],{},[143,325,326],{},"the decision (accepted, to review, rejected);",[143,328,329],{},"the kind, the key and the workflow;",[143,331,332],{},"a range of time;",[143,334,335,336,338],{},"the start of a ",[147,337,175],{},".",[120,340,341,342,345],{},"A row opens a detail panel with every reason. ",[180,343,344],{},"Export"," writes the rows of the filter, for any range inside the retention window, as JSONL or CSV.",[132,347,349],{"id":348},"from-a-refusal-to-the-row","From a refusal to the row",[120,351,352,353,355,356,359],{},"Every answer carries a ",[147,354,149],{},", in the body and in the ",[147,357,358],{},"X-Request-Id"," header. Log it next to your own records: it is the id of the journal row, and the first thing to quote if you write to support.",[361,362,363],"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);}",{"title":242,"searchDepth":277,"depth":277,"links":365},[366,367,368,369,370],{"id":134,"depth":277,"text":135},{"id":186,"depth":277,"text":187},{"id":229,"depth":277,"text":230},{"id":317,"depth":277,"text":318},{"id":348,"depth":277,"text":349},"What the decision journal keeps, how long, and how your own id (ref) lets you find a decision.","md",null,{},true,{"title":41,"description":371},"nhOIehOuRoXKSawz2lIxl9MGrpF6ytu7O5dwpabIu1c",[379,381],{"title":37,"path":38,"stem":39,"description":380,"children":-1},"What a check costs, how the prepaid balance works, how fast you may call the API, and what happens when a limit is reached.",{"title":50,"path":51,"stem":52,"description":382,"children":-1},"A small moderation module for Node.js 18 or later, with timeouts and a decision that fails closed.",1792938462347]