Uploads
Anchorify has two multi-file upload surfaces: the web upload page and the CLI upload-folder subcommand. Both let an admin publish a batch of files to a single project with one visibility tier.
Web — /<org>/<project>/upload
Admin-only. The page is a file picker (<input type=file multiple>) plus a visibility radio that applies to the whole batch. Submit POSTs the multipart form to the same path.
Behavior per file:
- Size limit: 1 MiB (
MAX_SHARE_BYTES). Oversize files are rejected with a per-row error; the rest of the batch continues. - Slug: kebab-cased basename.
Q1 Report.md→q1-report. Slug collisions auto-suffix-2,-3, … up to 50 attempts. - Content type: filename extension (see content types).
- Binary detection: a NUL byte in the first 1KB routes the file to the binary path — bytes go to R2 storage under
shares/<share_id>/<filename>and the share's content column gets the sentinel"@@blob". The content type isimage,pdf, orbinarybased on MIME + extension.
The success page lists one row per file with a status (✓ created, ✓ created as <slug> for auto-renames, ✗ <error> for failures) and the new URL.
CLI — anchorify upload-folder <dir>
Recursive: walks the directory tree, flattens nested paths into slugs (docs/intro.md → docs-intro), publishes each text file via POST /.
anchorify upload-folder ./drafts
anchorify upload-folder ./drafts --project q1-reports
anchorify upload-folder ./drafts --visibility members
anchorify upload-folder ./drafts --dry-run # list slugs, no POST
Flags:
--project <slug>— required when the org has 2+ projects. Without it, the server returns a 400 with the list of projects + the exact retry command.--visibility <tier>— applies to every file in the batch.--dry-run— prints<slug>\t<rel-path>per file and exits without hitting the server.
Skipped at walk time: dotfiles (.git, .DS_Store) and node_modules. Binaries are rejected per-file ("not yet supported"); use the web upload page for those.
Exit code is 1 if any file errored, 0 otherwise. The first error is printed; the loop continues so a single broken file doesn't sink the batch.
Moving shares between projects
A share can move to a different project in the same org without re-uploading. Old URLs 301 to the new canonical URL via the K4 redirect chain.
- Dashboard: open the share's actions menu (
⋯) → Move to… → pick a project. - CLI:
anchorify move <slug-or-id> --to <project>. - API:
POST /api/v1/shares/<id>/move {project_id|project_slug}.
Cross-org moves are blocked — use invites to bring the recipient into your org first.