[{"data":1,"prerenderedAt":257},["ShallowReactive",2],{"nav-docs":3,"nav-api":60,"docs-api-keys":89},[4],{"title":5,"path":6,"stem":7,"children":8},"Docs","\u002Fdocs","docs",[9,12,16,20,24,28,32,36,40,44,48,52,56],{"title":10,"path":6,"stem":11},"Installation","docs\u002Findex",{"title":13,"path":14,"stem":15},"Sending files","\u002Fdocs\u002Fsending-files","docs\u002F02.sending-files",{"title":17,"path":18,"stem":19},"Receiving files","\u002Fdocs\u002Freceiving-files","docs\u002F03.receiving-files",{"title":21,"path":22,"stem":23},"Passwords, galleries and backgrounds","\u002Fdocs\u002Fshare-options","docs\u002F04.share-options",{"title":25,"path":26,"stem":27},"Expiry and deletion","\u002Fdocs\u002Fexpiry","docs\u002F05.expiry",{"title":29,"path":30,"stem":31},"Users","\u002Fdocs\u002Fusers","docs\u002F06.users",{"title":33,"path":34,"stem":35},"Configuration","\u002Fdocs\u002Fconfiguration","docs\u002F07.configuration",{"title":37,"path":38,"stem":39},"Colours and branding","\u002Fdocs\u002Fcolors","docs\u002F08.colors",{"title":41,"path":42,"stem":43},"Docker","\u002Fdocs\u002Fdocker","docs\u002F09.docker",{"title":45,"path":46,"stem":47},"API keys","\u002Fdocs\u002Fapi-keys","docs\u002F10.api-keys",{"title":49,"path":50,"stem":51},"MCP server","\u002Fdocs\u002Fmcp-server","docs\u002F11.mcp-server",{"title":53,"path":54,"stem":55},"Troubleshooting","\u002Fdocs\u002Ftroubleshooting","docs\u002F12.troubleshooting",{"title":57,"path":58,"stem":59},"Contributing","\u002Fdocs\u002Fcontributing","docs\u002F13.contributing",[61],{"title":62,"path":63,"stem":64,"children":65},"Api","\u002Fapi","api",[66,69,73,77,81,85],{"title":67,"path":63,"stem":68},"REST API","api\u002Findex",{"title":70,"path":71,"stem":72},"Transfers","\u002Fapi\u002Ftransfers","api\u002F02.transfers",{"title":74,"path":75,"stem":76},"Uploading files","\u002Fapi\u002Fupload","api\u002F03.upload",{"title":78,"path":79,"stem":80},"Sending a transfer","\u002Fapi\u002Fsend","api\u002F04.send",{"title":82,"path":83,"stem":84},"Downloading","\u002Fapi\u002Fdownload","api\u002F05.download",{"title":86,"path":87,"stem":88},"Recipients","\u002Fapi\u002Frecipients","api\u002F06.recipients",{"id":90,"title":45,"body":91,"description":251,"extension":252,"meta":253,"navigation":254,"path":46,"seo":255,"stem":47,"__hash__":256},"docs\u002Fdocs\u002F10.api-keys.md",{"type":92,"value":93,"toc":243},"minimark",[94,98,109,114,121,128,136,172,176,183,186,202,206,209,212,216,222,225,229,236,239],[95,96,45],"h1",{"id":97},"api-keys",[99,100,101,102,105,106,108],"p",{},"Everything the interface does with transfers can be driven over HTTP. That is\nwhat the ",[103,104,67],"a",{"href":63}," and the ",[103,107,49],{"href":50}," use, and both\nauthenticate the same way.",[110,111,113],"h2",{"id":112},"creating-one","Creating one",[99,115,116,120],{},[117,118,119],"strong",{},"Account → API keys → Create key."," Give it a name you will recognise later,\noptionally an expiry (up to a year), and choose whether it is read-only.",[99,122,123,124,127],{},"The key is shown ",[117,125,126],{},"once",". The database stores only a SHA-256 hash, so it cannot\nbe shown again and a leaked database yields no usable keys. Copy it now or\ncreate another.",[99,129,130,131,135],{},"Send it in the ",[132,133,134],"code",{},"x-api-key"," header:",[137,138,143],"pre",{"className":139,"code":140,"language":141,"meta":142,"style":142},"language-bash shiki shiki-themes github-light github-dark","curl -H \"x-api-key: $KEY\" https:\u002F\u002Ftransfer.example.com\u002Fapi\u002Ftransfers\n","bash","",[132,144,145],{"__ignoreMap":142},[146,147,150,154,158,162,166,169],"span",{"class":148,"line":149},"line",1,[146,151,153],{"class":152},"sScJk","curl",[146,155,157],{"class":156},"sj4cs"," -H",[146,159,161],{"class":160},"sZZnC"," \"x-api-key: ",[146,163,165],{"class":164},"sVt8B","$KEY",[146,167,168],{"class":160},"\"",[146,170,171],{"class":160}," https:\u002F\u002Ftransfer.example.com\u002Fapi\u002Ftransfers\n",[110,173,175],{"id":174},"what-a-key-can-and-cannot-do","What a key can and cannot do",[99,177,178,179,182],{},"A key ",[117,180,181],{},"acts as the person who created it"," and carries exactly their\npermissions. It is a delegated credential, never an escalation.",[99,184,185],{},"Two limits are deliberate:",[187,188,189,196],"ul",{},[190,191,192,195],"li",{},[117,193,194],{},"A key can never administer users."," Admin endpoints refuse API keys\noutright, even one belonging to an administrator. Those endpoints create and\ndelete accounts, and deleting a user takes every transfer they ever sent with\nthem — while long-lived credentials have a way of ending up in CI configs.\nAccount administration stays something a person does while signed in.",[190,197,198,201],{},[117,199,200],{},"A key can never create, list or revoke another key."," Otherwise one leaked\nkey could mint a permanent replacement for itself, and revoking the original\nwould achieve nothing.",[110,203,205],{"id":204},"read-only-keys","Read-only keys",[99,207,208],{},"Mark a key read-only and it can list and read transfers but not create, send or\ndelete them. Over REST that is enforced on the HTTP method; over MCP each\nmutating tool declares itself, because a tool call is a POST whatever it does.",[99,210,211],{},"Use one for anything that only reports — a dashboard, a backup inventory, a\nmonitoring check.",[110,213,215],{"id":214},"revoking","Revoking",[99,217,218,221],{},[117,219,220],{},"Account → API keys → Revoke."," It takes effect on the very next request. There\nis no cache to wait out.",[99,223,224],{},"Keys record when they were last used, which is usually enough to tell whether\none is still wanted before you remove it.",[110,226,228],{"id":227},"why-not-bcrypt","Why not bcrypt",[99,230,231,232,235],{},"Because these are not passwords. An API key is 32 bytes from the system's\nrandom generator, so there is no dictionary and no plausible brute force —\nwhich is the only thing a slow hash buys. Meanwhile bcrypt would cost about\n100 ms of CPU on ",[117,233,234],{},"every"," authenticated request, which for an interface\ndesigned for agents making repeated calls is a large permanent tax for no gain.",[99,237,238],{},"Passwords in this app are bcrypt-hashed, as they should be. Tokens are not\npasswords, and the same tools do not fit both.",[240,241,242],"style",{},"html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}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":142,"searchDepth":244,"depth":244,"links":245},2,[246,247,248,249,250],{"id":112,"depth":244,"text":113},{"id":174,"depth":244,"text":175},{"id":204,"depth":244,"text":205},{"id":214,"depth":244,"text":215},{"id":227,"depth":244,"text":228},"Everything the interface does with transfers can be driven over HTTP. That is\nwhat the REST API and the MCP server use, and both\nauthenticate the same way.","md",{},true,{"title":45,"description":251},"TeSlbsjcsqU36exOaIhP0dC6wcTXaZSaLj-ahDKfxpE",1790104591922]