How to Export and Import Company Configurations in Paperclip: Complete Guide

Paperclip lets you move an entire company's configuration—branding, agents, org chart, projects, tasks, and skills—as a portable markdown-first package using REST APIs or the CLI.

Exporting and importing company configurations in Paperclip enables portability across environments, version control of organizational data, and disaster recovery. The system treats company data as a markdown-first package: a zipped archive containing human-readable files plus a .paperclip.yaml side-car for runtime-specific metadata. This guide covers the full workflow using the Paperclip API and paperclipai CLI, with implementation details from the paperclipai/paperclip source code.

Export Workflow: Creating a Portable Company Package

Paperclip exports follow a three-stage pattern: select components, preview the output, then generate the archive.

Selecting Export Components

The include parameter controls which entities ship in the package. Valid flags are company, agents, projects, issues, and skills. The CLI defaults to company plus agents.

In server/src/routes/companies.ts, the export endpoint validates requests using companyPortabilityExportSchema:

router.post("/:companyId/export", async (req, res) => {
  const companyId = req.params.companyId as string;
  await assertSameCompanyCeoAgentOrBoard(req, companyId, "company exports");
  const body = companyPortabilityExportSchema.parse(req.body);
  const result = await portability.exportBundle(companyId, body);
  res.json(result);
});

Source: companies.ts – export endpoint

Required permission: CEO or Board member of the source company.

Previewing Before Export

Call POST /api/companies/:companyId/exports/preview or use --dry-run to see the exact file list and any environment-input prompts without creating a bundle.

Running the Export

The export produces a .zip with this internal structure:

  • COMPANY.md — company branding, settings, org chart
  • agents/ — agent definitions (one file per agent)
  • skills/ — skill configurations
  • projects/ — project definitions (if included)
  • tasks/ or issues/ — task/issue data (if included)
  • .paperclip.yaml — runtime metadata (adapter configs, budgets, secret references)

CLI command:

paperclipai company export 123e4567-89ab-cdef-0123-456789abcdef \
  --out ./my-company \
  --include company,agents,projects,issues,skills

Import Workflow: Restoring or Migrating Company Data

Imports support two targets: new company (create) or existing company (update/merge).

Import Targets and Collision Strategies

Target Endpoint Use Case
New company POST /api/companies/import Fresh migration, sandbox creation
Existing company POST /api/companies/:companyId/imports/apply Update agents, sync configurations

Collision strategies (rename, skip, replace) determine behavior when entities already exist.

Previewing the Import Plan

The preview endpoint parses and validates the package, returning a plan showing which entities will be created, updated, or skipped. In server/src/routes/companies.ts:

router.post("/import/preview", async (req, res) => {
  assertBoard(req);
  const body = companyPortabilityPreviewSchema.parse(await resolveImportPayload(req, res));
  assertImportTargetAccess(req, body.target);
  const preview = await portability.previewImport(body);
  res.json(preview);
});

Source: companies.ts – import preview

CLI dry-run:

paperclipai company import ./my-company --dry-run

Applying the Import

New company import:

paperclipai company import ./my-company

Existing company import with collision handling:

paperclipai company import ./my-company \
  --target existing \
  --company-id 123e4567-89ab-cdef-0123-456789abcdef \
  --collision rename

The server-side apply logic in server/src/routes/companies.ts:

router.post(COMPANY_IMPORT_ROUTE_PATH, async (req, res) => {
  assertBoard(req);
  const rawImportBody: unknown = await resolveImportPayload(req, res);
  await executeImportRequest(req, res, rawImportBody);
});

Source: companies.ts – import execution

Handling Large Packages: Chunked Transfer Protocol

When packages exceed the inline JSON limit (~48 MiB), Paperclip automatically switches to a resumable chunked transfer.

Chunked Transfer Flow

  1. Declare transfer — POST /api/companies/import-transfers returns a transfer ID and missing parts list
  2. Upload parts — PUT /api/companies/import-transfers/:transferId/parts/:partIndex with SHA-256 verification per chunk
  3. Preview assembled package — POST /api/companies/import-transfers/:transferId/preview
  4. Apply import — POST /api/companies/import-transfers/:transferId/apply (verifies whole-file hash before processing)

The CLI handles this transparently through resolveChunkedImportZip and uploadCompanyImportTransfer in cli/src/commands/client/company.ts:

// Key functions in cli/src/commands/client/company.ts:
// - resolveInlineSourceFromPath: converts folder/zip to portable JSON
// - resolveChunkedImportZip: decides chunked vs. inline transfer
// - uploadCompanyImportTransfer: orchestrates chunked upload

Source: company.ts – CLI helpers

Source Files and Package Format

File Purpose
server/src/routes/companies.ts HTTP endpoints for export, import, preview, and chunked transfer (lines ~90-150)
packages/shared/src/types/company-portability.ts TypeScript types: CompanyPortabilityExportResult, CompanyPortabilityImportResult
packages/shared/src/validators/company-portability.ts Zod schemas: companyPortabilityExportSchema, companyPortabilityPreviewSchema
cli/src/commands/client/company.ts CLI implementation, zip handling, transfer orchestration
doc/plans/2026-03-13-company-import-export-v2.md Product specification for markdown-first format
doc/companies/companies-spec.md Canonical package layout specification

Summary

  • Export and import company configurations as versioned, markdown-first packages using POST /api/companies/:companyId/exports and POST /api/companies/import
  • Preview changes before applying via --dry-run or dedicated preview endpoints to avoid surprises
  • Handle large archives automatically through Paperclip's chunked transfer protocol with SHA-256 verification
  • Control collision behavior with rename, skip, or replace strategies when importing into existing companies
  • Require Board-level permissions for all import operations and company exports

Frequently Asked Questions

What permissions are required to export or import a company?

Exports require CEO or Board member status on the source company. Imports require Board member status system-wide, plus specific access to the target company when importing into an existing organization. These checks are enforced in assertSameCompanyCeoAgentOrBoard() and assertBoard() middleware in server/src/routes/companies.ts.

Can I import a company package into an existing organization without creating duplicates?

Yes. Use the --target existing --collision rename|skip|replace flags when importing. The preview endpoint shows exactly which entities will be created, updated, or skipped before you apply changes. The rename strategy appends numeric suffixes to conflicting names; skip preserves existing values; replace overwrites them.

What happens if my company export is larger than 48 MB?

The CLI automatically detects the size threshold and switches to chunked transfer mode. It declares a transfer ID, uploads the zip in verified parts, then assembles the package server-side before running the import preview or apply. This resume-capable protocol prevents network timeouts and supports unreliable connections.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →