# Share a profile copy

> Send an encrypted copy of a profile to one person — what it carries, how they accept it, and what revoking can and cannot do.

Browlix has three different ways to give someone else a profile, and they are never mixed up:

- **A copy** (this guide): the recipient gets a new, independent profile of their own, made from a revision you saved. Your profile does not change, and nothing ever syncs between the two.
- **Team access**: invite the person into your workspace and limit them to a group ([workspaces and roles](https://browlix.com/en/docs/workspaces-roles)). They use your profile itself; every change is shared.
- **Workspace ownership**: hand over the whole workspace — every profile, machine and key — to another member. Only the owner can, and the new owner must accept. A single profile is never "transferred": it moves to someone else only as a copy.

## What a copy carries

- **Always**: the configuration — fingerprint, language, time zone, startup pages and browser preferences.
- **What you tick**, taken from the profile's latest **committed revision**: cookies, Local Storage, IndexedDB, Service Workers, extensions and their data, bookmarks, history, open tabs, saved passwords. Only categories that revision holds can be ticked.
- **Never**: the proxy, linked accounts, your workspace keys. The recipient assigns their own proxy; a copy of a proxy profile does not open until they do (Browlix never falls back to a direct connection).

Data a machine has not synced yet is not in the copy. `shares.preview` names those machines, so you can open and close the profile there first if the copy should include it.

Rights are checked per category, by the database, before anything is packed:

| You tick | You need |
|---|---|
| configuration, extensions, bookmarks, history, open tabs | `share.manage` |
| cookies, Local Storage, IndexedDB, Service Workers | `share.manage` + `share.session` |
| saved passwords | `share.manage` + `profile.export_sensitive` |

## Send a copy

```ts tab=TypeScript
const preview = await bx.call("shares.preview", { path: { id: profileId } });
// preview.data: revision, categories it holds, what your rights allow, machines that can prepare it now

const { data } = await bx.call("shares.create", {
  body: {
    profile_id: profileId,
    recipient_email: "ana@example.com",
    categories: ["cookies", "local_storage", "bookmarks"],
    expires_in_days: 7,
    message: "Shop account for the weekend campaign",
  },
});
console.log(data.package.state); // "preparing", or "available" for a configuration-only copy
```

```json tab=MCP
{
  "name": "shares_create",
  "arguments": {
    "profile_id": "00000000-0000-4000-8000-000000000001",
    "recipient_email": "ana@example.com",
    "categories": ["cookies", "local_storage", "bookmarks"],
    "expires_in_days": 7
  }
}
```

A copy is addressed to **one email**. Only the person who signs in to Browlix with that verified email sees it and can accept it — there is no link that works for whoever holds it.

One of your machines (worker 0.14.0 or newer) then prepares the package: it downloads the pinned revision, keeps only the categories you ticked, re-encrypts cookies and saved passwords under a key that belongs to this copy alone, and uploads it encrypted. Your profile's own key never leaves your machines. While no machine is online the copy waits (`progress.waiting_for_machine`), and `shares.list` shows its progress.

## Receive a copy

```ts tab=TypeScript
const inbox = await bx.call("shares.inbox", {});
const offer = inbox.data.find((p) => p.state === "available");

if (offer) {
  const accepted = await bx.call("shares.accept", { path: { id: offer.id }, body: { name: "Shop (from Ana)" } });
  console.log(accepted.data.profile_id); // a new profile id in your workspace
}
```

- Nothing is downloaded until you accept. Before that you see who sent it, from which workspace, which categories it carries and whether the original used a proxy.
- Accepting creates a new profile in your workspace (new id; optional `group_id`) and one of your machines imports the data as its revision 1. It opens once the import has finished — before that, opening it is `BUSY`.
- `shares.decline` refuses it; the sender sees "declined" and the package is deleted.

## Revoke, expiry and what cannot be undone

- **Before delivery**, `shares.revoke` stops everything: a machine still preparing or importing it is refused at its next step and removes its working files, and a half-imported copy is removed from the recipient's workspace.
- **After delivery** the copy belongs to the recipient. Revoking is `CONFLICT`: Browlix cannot recall or erase a profile that is now someone else's, and does not pretend to.
- A copy not accepted within `expires_in_days` (1–30) expires and its package is deleted.

## Errors you will see

| Code | When |
|---|---|
| `FORBIDDEN` | your role or key lacks a right the ticked categories need |
| `VALIDATION_FAILED` | a category the pinned revision does not hold, an invalid email or expiry |
| `NOT_FOUND` | the copy is not addressed to your verified email |
| `CONFLICT` | the copy is no longer available (revoked, expired, declined, already accepted) or already delivered when revoking |
| `BUSY` | opening a received copy whose import has not finished |

Every step is in the sending workspace's audit log (`share.create`, `share.prepared`, `share.accept`, `share.delivered`, or `share.revoked` / `share.declined` / `share.expired` / `share.failed`) and the receiving workspace records `share.receive` and then `share.receive.delivered` (or how it ended) on the new profile — with the revision and categories, never the data itself.
