[{"data":1,"prerenderedAt":32},["ShallowReactive",2],{"doc-transfer":3},{"html":4,"headings":5},"\u003Cp>Export a whole workspace or a single project, and import it into another HelpBites: self-hosted to cloud, cloud to\nself-hosted, or one self-hosted install to another. Import from a file you downloaded, or have your new HelpBites pull\neverything straight from the old one in the background with a login for it.\u003C\u002Fp>\n\u003Cp>Nothing is changed on the instance you export from, so you can try an import, check it, and switch your sites over when\nyou are ready.\u003C\u002Fp>\n\u003Ch2 id=\"what-moves\">What moves\u003Ca class=\"heading-anchor\" href=\"#what-moves\" aria-label=\"Link to this section\">#\u003C\u002Fa>\u003C\u002Fh2>\n\u003Cp>Everything you built and everyone who wrote in:\u003C\u002Fp>\n\u003Cul>\n\u003Cli>projects and their settings (look, sender, allowed origins, board, changelog and legal options, feature flags)\u003C\u002Fli>\n\u003Cli>conversations, messages and the customers behind them (contacts, their segments, email suppressions)\u003C\u002Fli>\n\u003Cli>the knowledge base: models, folders, documents, FAQs, and which assistants use which\u003C\u002Fli>\n\u003Cli>assistants\u003C\u002Fli>\n\u003Cli>the feedback board with votes, comments and subscribers, and the project board\u003C\u002Fli>\n\u003Cli>the changelog: releases, entries, comments and subscribers\u003C\u002Fli>\n\u003Cli>legal documents with every version, and onboarding flows\u003C\u002Fli>\n\u003Cli>email templates, folders, components, the email log and AI chat history of each template\u003C\u002Fli>\n\u003Cli>sequences (see below), and error analyses\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Ch2 id=\"what-stays-behind\">What stays behind\u003Ca class=\"heading-anchor\" href=\"#what-stays-behind\" aria-label=\"Link to this section\">#\u003C\u002Fa>\u003C\u002Fh2>\n\u003Cdiv class=\"table-wrap\">\u003Ctable>\n\u003Cthead>\n\u003Ctr>\n\u003Cth>Left out\u003C\u002Fth>\n\u003Cth>Why\u003C\u002Fth>\n\u003Cth>What to do\u003C\u002Fth>\n\u003C\u002Ftr>\n\u003C\u002Fthead>\n\u003Ctbody>\n\u003Ctr>\n\u003Ctd>Passwords, API keys, project secrets, webhook secrets\u003C\u002Ftd>\n\u003Ctd>Credentials never go in an export\u003C\u002Ftd>\n\u003Ctd>Each imported project gets a new secret; rotate it under the project's keys. Make new admin API keys.\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>Stripe, GitHub, Telegram, error-tracker and contact-database connections\u003C\u002Ftd>\n\u003Ctd>Their credentials are not exported\u003C\u002Ftd>\n\u003Ctd>Connect them again.\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>Team members and invitations\u003C\u002Ftd>\n\u003Ctd>Accounts live on one instance\u003C\u002Ftd>\n\u003Ctd>Invite the team again.\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>Uploaded files (message attachments, logos, brand assets, knowledge documents' originals)\u003C\u002Ftd>\n\u003Ctd>They sit in the old instance's bucket\u003C\u002Ftd>\n\u003Ctd>The text, FAQs and links come across; re-upload images you still need.\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>Campaigns and who is on a sequence\u003C\u002Ftd>\n\u003Ctd>They could send again by themselves\u003C\u002Ftd>\n\u003Ctd>Recreate the campaign from its template. Sequences come across \u003Cstrong>paused\u003C\u002Fstrong>; turn them on when ready.\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>Which operator replied or was assigned\u003C\u002Ftd>\n\u003Ctd>Operators are accounts on the old instance\u003C\u002Ftd>\n\u003Ctd>Messages keep their text and time; assignments are empty.\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>Sending domains, usage counters\u003C\u002Ftd>\n\u003Ctd>Per instance\u003C\u002Ftd>\n\u003Ctd>Set up the domain again.\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003C\u002Ftbody>\n\u003C\u002Ftable>\u003C\u002Fdiv>\n\u003Cp>Your projects' \u003Cstrong>public keys\u003C\u002Fstrong> (\u003Ccode>pk_…\u003C\u002Fcode>) are kept when nothing on the new instance uses them, so the widget on your site\nkeeps working once you point it at the new address. If a key is taken, the project gets a new one and the import\nsummary says so.\u003C\u002Fp>\n\u003Ch2 id=\"in-the-panel\">In the panel\u003Ca class=\"heading-anchor\" href=\"#in-the-panel\" aria-label=\"Link to this section\">#\u003C\u002Fa>\u003C\u002Fh2>\n\u003Cp>\u003Cstrong>Settings → Workspace → Move to another HelpBites\u003C\u002Fstrong>\u003C\u002Fp>\n\u003Cul>\n\u003Cli>\u003Cstrong>Download\u003C\u002Fstrong> gives you one \u003Ccode>.jsonl.gz\u003C\u002Fcode> file for the whole workspace. In a project's \u003Cstrong>Settings → Data\u003C\u002Fstrong> it is that\nproject alone.\u003C\u002Fli>\n\u003Cli>\u003Cstrong>Import → From a file\u003C\u002Fstrong> takes a file from either of the above (or the workspace export that arrives by email).\u003C\u002Fli>\n\u003Cli>\u003Cstrong>Import → From another HelpBites\u003C\u002Fstrong> asks for its address and either an admin API key or a username and password. It\nlists the workspaces and projects it can see; pick everything or one project and start. You can close the page: the\nimport runs in the background and the list shows progress, then what came in and what was left out.\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Cp>An import always \u003Cstrong>adds\u003C\u002Fstrong> new projects to the workspace you are in. It never overwrites, so importing twice gives you two\ncopies. If it fails for any reason, everything it had created is deleted again and the list says why. One import runs\nat a time per workspace. You need to be an owner or admin on both sides.\u003C\u002Fp>\n\u003Cp>The login you give is kept sealed until the import ends and then removed; a session made from a username and password\nis signed out again. Prefer an admin API key: make a short-lived one (a few days) on the old instance and revoke it\nafterwards.\u003C\u002Fp>\n\u003Ch2 id=\"plans-cloud\">Plans (cloud)\u003Ca class=\"heading-anchor\" href=\"#plans-cloud\" aria-label=\"Link to this section\">#\u003C\u002Fa>\u003C\u002Fh2>\n\u003Cp>Importing counts against the plan like creating the data by hand: projects, contacts, knowledge models, assistants and\nFAQs are checked before they are created, and an import that would go over is refused whole. Legal documents and\nsequences are left out (and listed) on a plan that does not include them. Exporting is never limited.\u003C\u002Fp>\n\u003Ch2 id=\"the-api\">The API\u003Ca class=\"heading-anchor\" href=\"#the-api\" aria-label=\"Link to this section\">#\u003C\u002Fa>\u003C\u002Fh2>\n\u003Cp>All \u003Ccode>\u002Fv1\u002Fadmin\u002Ftransfers\u003C\u002Fcode> calls take an operator session or an admin API key (\u003Ccode>Authorization: Bearer …\u003C\u002Fcode>), act in the\nworkspace named by \u003Ccode>X-Workspace\u003C\u002Fcode> (or the key's own), and need the owner or admin role. A key limited to some projects is\nrefused. They are in the OpenAPI reference under \u003Cstrong>Workspace\u003C\u002Fstrong>.\u003C\u002Fp>\n\u003Cp>Export a workspace, or one project, to a file:\u003C\u002Fp>\n\u003Cdiv class=\"code-block\">\u003Cbutton type=\"button\" class=\"copy-btn\" data-copy aria-label=\"Copy to clipboard\">Copy\u003C\u002Fbutton>\u003Cpre class=\"shj-lang-bash\">\u003Ccode>\u003Cspan class=\"shj-syn-func\">curl\u003C\u002Fspan>\u003Cspan class=\"shj-syn-kwd\"> -H\u003C\u002Fspan> \u003Cspan class=\"shj-syn-str\">\"Authorization: Bearer ak_…\"\u003C\u002Fspan>\u003Cspan class=\"shj-syn-kwd\"> -o\u003C\u002Fspan> helpbites.jsonl.gz \\\n  \u003Cspan class=\"shj-syn-str\">\"https:\u002F\u002Fhelp.example.com\u002Fv1\u002Fadmin\u002Ftransfers\u002Fexport\"\u003C\u002Fspan>\n\u003Cspan class=\"shj-syn-func\">curl\u003C\u002Fspan>\u003Cspan class=\"shj-syn-kwd\"> -H\u003C\u002Fspan> \u003Cspan class=\"shj-syn-str\">\"Authorization: Bearer ak_…\"\u003C\u002Fspan>\u003Cspan class=\"shj-syn-kwd\"> -o\u003C\u002Fspan> project.jsonl.gz \\\n  \u003Cspan class=\"shj-syn-str\">\"https:\u002F\u002Fhelp.example.com\u002Fv1\u002Fadmin\u002Ftransfers\u002Fexport?project=PROJECT_ID\"\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>\u003C\u002Fdiv>\n\u003Cp>Import a file into another instance (needs file storage there; up to 2 GB; send it as the body):\u003C\u002Fp>\n\u003Cdiv class=\"code-block\">\u003Cbutton type=\"button\" class=\"copy-btn\" data-copy aria-label=\"Copy to clipboard\">Copy\u003C\u002Fbutton>\u003Cpre class=\"shj-lang-bash\">\u003Ccode>\u003Cspan class=\"shj-syn-func\">curl\u003C\u002Fspan>\u003Cspan class=\"shj-syn-kwd\"> -X\u003C\u002Fspan> POST\u003Cspan class=\"shj-syn-kwd\"> -H\u003C\u002Fspan> \u003Cspan class=\"shj-syn-str\">\"Authorization: Bearer ak_…\"\u003C\u002Fspan>\u003Cspan class=\"shj-syn-kwd\"> -H\u003C\u002Fspan> \u003Cspan class=\"shj-syn-str\">\"Content-Type: application\u002Fgzip\"\u003C\u002Fspan> \\\n  \u003Cspan class=\"shj-syn-func\">--data-binary\u003C\u002Fspan> @helpbites.jsonl.gz \u003Cspan class=\"shj-syn-str\">\"https:\u002F\u002Fnew.example.com\u002Fv1\u002Fadmin\u002Ftransfers\u002Fupload\"\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>\u003C\u002Fdiv>\n\u003Cp>Or have the new instance pull from the old one (\u003Ccode>projectId\u003C\u002Fcode> is optional; leave it out for the whole workspace). Use\n\u003Ccode>apiKey\u003C\u002Fcode>, or \u003Ccode>login\u003C\u002Fcode> and \u003Ccode>password\u003C\u002Fcode>:\u003C\u002Fp>\n\u003Cdiv class=\"code-block\">\u003Cbutton type=\"button\" class=\"copy-btn\" data-copy aria-label=\"Copy to clipboard\">Copy\u003C\u002Fbutton>\u003Cpre class=\"shj-lang-bash\">\u003Ccode>\u003Cspan class=\"shj-syn-func\">curl\u003C\u002Fspan>\u003Cspan class=\"shj-syn-kwd\"> -X\u003C\u002Fspan> POST \u003Cspan class=\"shj-syn-str\">\"https:\u002F\u002Fnew.example.com\u002Fv1\u002Fadmin\u002Ftransfers\"\u003C\u002Fspan> \\\n \u003Cspan class=\"shj-syn-kwd\"> -H\u003C\u002Fspan> \u003Cspan class=\"shj-syn-str\">\"Authorization: Bearer ak_…\"\u003C\u002Fspan>\u003Cspan class=\"shj-syn-kwd\"> -H\u003C\u002Fspan> \u003Cspan class=\"shj-syn-str\">\"Content-Type: application\u002Fjson\"\u003C\u002Fspan> \\\n \u003Cspan class=\"shj-syn-kwd\"> -d\u003C\u002Fspan> \u003Cspan class=\"shj-syn-str\">'{ \"source\": { \"url\": \"https:\u002F\u002Fold.example.com\", \"apiKey\": \"ak_…\" }, \"projectId\": \"PROJECT_ID\" }'\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>\u003C\u002Fdiv>\n\u003Cp>Check a source first (lists its workspaces and projects, stores nothing):\u003C\u002Fp>\n\u003Cdiv class=\"code-block\">\u003Cbutton type=\"button\" class=\"copy-btn\" data-copy aria-label=\"Copy to clipboard\">Copy\u003C\u002Fbutton>\u003Cpre class=\"shj-lang-bash\">\u003Ccode>\u003Cspan class=\"shj-syn-func\">curl\u003C\u002Fspan>\u003Cspan class=\"shj-syn-kwd\"> -X\u003C\u002Fspan> POST \u003Cspan class=\"shj-syn-str\">\"https:\u002F\u002Fnew.example.com\u002Fv1\u002Fadmin\u002Ftransfers\u002Finspect\"\u003C\u002Fspan> \\\n \u003Cspan class=\"shj-syn-kwd\"> -H\u003C\u002Fspan> \u003Cspan class=\"shj-syn-str\">\"Authorization: Bearer ak_…\"\u003C\u002Fspan>\u003Cspan class=\"shj-syn-kwd\"> -H\u003C\u002Fspan> \u003Cspan class=\"shj-syn-str\">\"Content-Type: application\u002Fjson\"\u003C\u002Fspan> \\\n \u003Cspan class=\"shj-syn-kwd\"> -d\u003C\u002Fspan> \u003Cspan class=\"shj-syn-str\">'{ \"url\": \"https:\u002F\u002Fold.example.com\", \"login\": \"me@example.com\", \"password\": \"…\" }'\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>\u003C\u002Fdiv>\n\u003Cp>Both import calls answer \u003Ccode>202\u003C\u002Fcode> with the queued import. Follow it:\u003C\u002Fp>\n\u003Cdiv class=\"code-block\">\u003Cbutton type=\"button\" class=\"copy-btn\" data-copy aria-label=\"Copy to clipboard\">Copy\u003C\u002Fbutton>\u003Cpre class=\"shj-lang-bash\">\u003Ccode>\u003Cspan class=\"shj-syn-func\">curl\u003C\u002Fspan>\u003Cspan class=\"shj-syn-kwd\"> -H\u003C\u002Fspan> \u003Cspan class=\"shj-syn-str\">\"Authorization: Bearer ak_…\"\u003C\u002Fspan> \u003Cspan class=\"shj-syn-str\">\"https:\u002F\u002Fnew.example.com\u002Fv1\u002Fadmin\u002Ftransfers\"\u003C\u002Fspan>\n\u003Cspan class=\"shj-syn-cmnt\"># { \"transfers\": [{ \"id\", \"source\": \"file|instance\", \"host\", \"scope\", \"status\": \"queued|running|done|failed\",\u003C\u002Fspan>\n\u003Cspan class=\"shj-syn-cmnt\">#   \"progress\": { \"className\", \"rows\" }, \"summary\": { \"rows\", \"skipped\", \"projects\", \"notes\" }, \"error\", … }] }\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>\u003C\u002Fdiv>\n\u003Ch3 id=\"rules\">Rules\u003Ca class=\"heading-anchor\" href=\"#rules\" aria-label=\"Link to this section\">#\u003C\u002Fa>\u003C\u002Fh3>\n\u003Cul>\n\u003Cli>One import at a time per workspace (\u003Ccode>409\u003C\u002Fcode> otherwise); 10 imports and 20 source checks an hour (\u003Ccode>429\u003C\u002Fcode>); 20 exports an\nhour.\u003C\u002Fli>\n\u003Cli>Not idempotent by design: every import creates new projects. Delete a project you imported by mistake.\u003C\u002Fli>\n\u003Cli>All or nothing: a failed import deletes what it created. An import interrupted by a server restart cannot say what it\ncreated and is marked failed; delete the half-imported project and import again.\u003C\u002Fli>\n\u003Cli>The other instance must be a version that has \u003Ccode>\u002Fv1\u002Fadmin\u002Ftransfers\u002Fexport\u003C\u002Fcode> (\u003Ccode>404\u003C\u002Fcode> otherwise: update it, or move a file\nfrom an older export, which imports the same way).\u003C\u002Fli>\n\u003Cli>This is an operator tool, not something to embed in a site, so there is no web snippet or Swift view for it. Build your\nown on the API above if you need one.\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Ch2 id=\"the-file\">The file\u003Ca class=\"heading-anchor\" href=\"#the-file\" aria-label=\"Link to this section\">#\u003C\u002Fa>\u003C\u002Fh2>\n\u003Cp>\u003Ccode>.jsonl.gz\u003C\u002Fcode>: gzip of JSON Lines. The first line is \u003Ccode>{ &quot;format&quot;: &quot;helpbites-export&quot;, &quot;version&quot;: 2, &quot;scope&quot;: &quot;workspace|project&quot;, &quot;workspaceId&quot;, &quot;exportedAt&quot; }\u003C\u002Fcode>, then one \u003Ccode>{ &quot;class&quot;, &quot;data&quot; }\u003C\u002Fcode> line per row, a class at a time and\neach class after the ones it points at. Version 1 files (the earlier workspace export) import too. You can read it with\n\u003Ccode>zcat file | jq\u003C\u002Fcode>.\u003C\u002Fp>\n\u003Ch2 id=\"self-hosting-notes\">Self-hosting notes\u003Ca class=\"heading-anchor\" href=\"#self-hosting-notes\" aria-label=\"Link to this section\">#\u003C\u002Fa>\u003C\u002Fh2>\n\u003Cul>\n\u003Cli>\u003Cstrong>File storage.\u003C\u002Fstrong> Importing a file stores it in your bucket (\u003Ccode>S3_*\u003C\u002Fcode>) while the job runs, then deletes it. Pulling from\nanother instance needs no storage.\u003C\u002Fli>\n\u003Cli>\u003Cstrong>Keeping the original dates.\u003C\u002Fstrong> Parse only accepts a row's original creation time through its \u003Cem>maintenance key\u003C\u002Fem>. Set\nthe same random value as \u003Ccode>PARSE_SERVER_MAINTENANCE_KEY\u003C\u002Fcode> on the Parse server (with \u003Ccode>PARSE_SERVER_MAINTENANCE_KEY_IPS\u003C\u002Fcode>\ncovering the app, like \u003Ccode>PARSE_SERVER_MASTER_KEY_IPS\u003C\u002Fcode>) and as \u003Ccode>PARSE_MAINTENANCE_KEY\u003C\u002Fcode> on the app. Without it, rows get\nthe time of the import and are created oldest first, so conversations keep their order, but dates read &quot;today&quot;, and a\nsingle class may not exceed 250,000 rows.\u003C\u002Fli>\n\u003Cli>\u003Cstrong>Private networks.\u003C\u002Fstrong> Pulling from an instance on a private address (another box on your LAN) needs\n\u003Ccode>ALLOW_PRIVATE_NETWORK=1\u003C\u002Fcode> on the importing instance, as for any address you type in. Cloud and public hosts need\nnothing.\u003C\u002Fli>\n\u003Cli>\u003Cstrong>Search and knowledge.\u003C\u002Fstrong> Imported conversations and contacts are added to search, and each knowledge model is\nre-indexed in the background, so AI answers work a little after the import finishes.\u003C\u002Fli>\n\u003C\u002Ful>\n",[6,10,13,16,19,22,26,29],{"id":7,"text":8,"level":9},"what-moves","What moves",2,{"id":11,"text":12,"level":9},"what-stays-behind","What stays behind",{"id":14,"text":15,"level":9},"in-the-panel","In the panel",{"id":17,"text":18,"level":9},"plans-cloud","Plans (cloud)",{"id":20,"text":21,"level":9},"the-api","The API",{"id":23,"text":24,"level":25},"rules","Rules",3,{"id":27,"text":28,"level":9},"the-file","The file",{"id":30,"text":31,"level":9},"self-hosting-notes","Self-hosting notes",1792677543075]