Skip to article

Companies, contacts and device links

Available in the current Bridge and signed Windows/Linux CLI 0.17.5. See releases.

The customer directory provides descriptive context shared by human members of a workspace. It does not create logins, grant access, send messages or act as a full CRM. OpenCode is retired. Replacement Whisper runs as the authenticated human controller in the approved six-workspace pilot, not as a shared workspace actor. Use your own authorized CLI or the website; ordinary machine/test credentials cannot read or mutate the directory.

Use the website's Companies and Contacts pages, or the commands below.

Find before creating

In a support request, a person means a customer/contact unless explicitly identified as a technician. Do not create an invitation, membership or access permission to represent a customer.

Search companies, contacts and related cases first. Reuse a clear match by its returned UUID. Names may repeat: ask a focused question when matches are ambiguous, and continue next_cursor with unchanged filters before treating a partial page as exhaustive. Check archived records when appropriate; do not silently restore one or create a duplicate to evade its archive state.

forge companies search --search "Example"
forge contacts search --search "Example contact"

Create only when no suitable match exists, using facts the technician/customer supplied. Email, phone, company and device relationships are optional; do not invent them to fill fields. A contact's company does not automatically become a device's or case's company.

Save this illustrative content as a private company.json:

{
  "display_name": "Example company",
  "email": null,
  "phone": null
}
forge companies create --input company.json
forge companies show --id <company-id>

For a contact, save contact.json with the company UUID returned by Forge:

{
  "display_name": "Example contact",
  "email": "contact@example.com",
  "phone": null,
  "company_id": "<company-id>"
}
forge contacts create --input contact.json
forge contacts list --company <company-id>

<company-id> is a replacement marker, not a valid UUID. Use null when the contact has no company. example.com addresses are illustrative, not real recipients.

Names may repeat and are never merged automatically. Use returned IDs for mutations, not name matching. Search is a case-insensitive literal substring; % and _ are not wildcards.

Read before editing

Each record has a positive version. An update is a full replacement, not a patch. Include its current version and all optional fields you intend to retain:

{
  "display_name": "Example company",
  "email": "service@example.com",
  "phone": null,
  "version": 1
}
forge companies update --id <company-id> --input company-update.json

The 1 illustrates a version; replace it with the version just read. Omitted optional content fields become null, and a stale version conflicts. Reload and reconcile the newer content rather than overwriting it blindly.

Directory input uses snake-case fields and is limited to 16,384 characters. --input - reads redirected stdin. Keep names, addresses and other customer content in private files/stdin rather than command arguments.

A device may have one company and one primary contact. These links are independent; choosing a contact does not infer its company.

forge device customer-links show --device <device-id>

Save the replacement using the independent link version returned above:

{
  "company_id": "<company-id>",
  "primary_contact_id": "<contact-id>",
  "version": 1
}
forge device customer-links update --device <device-id> --input device-links.json

Replace both ID markers and the illustrative version. Include both nullable ID fields explicitly; null unlinks. A link must point to a record in the same workspace.

This does not change device access or the older free-text display name, primary-user and organization labels. A device transfer clears these links; customer data does not follow the device into another workspace.

Archive, restore and page results

forge companies archive --id <company-id> --version <current-version>
forge companies list --archive archived
forge companies restore --id <company-id> --version <current-version>

The same lifecycle commands exist for contacts. Archive preserves records and existing relationships. Archived records cannot be selected for new relationships, though an existing archived reference can be retained. Restoring does not recreate links that were explicitly removed.

Lists default to active records and 25 results. --archive accepts active, archived or all; --limit accepts 1–100. When next_cursor is returned, pass it as --cursor with the same filters to continue. Pages reflect live state, not a frozen snapshot of concurrent edits.

There is no delete, duplicate-merge or import workflow in this release.

Retry-safe intake (source increment, not CLI 0.17.5)

The customer-intake CLI source adds optional idempotency_key to the existing company/contact, case and draft creation JSON. It requires a compatible Bridge advertising X-Forge-Intake-Version: 1; this is not a signed release announcement. For example, add "idempotency_key": "replace-with-a-unique-stable-request-key" to the private create object before dispatch. Use a different key for each distinct operation, not each attempt. Keys contain 1-100 non-control characters and cannot be blank. Do not put a key into update JSON.

Persist the exact request privately before --input; with stdin, the caller must retain its durable source. Keep the same authenticated actor, workspace, parent case (for drafts), key and payload on an intentional retry. The CLI does not generate keys, store a second customer-content journal or retry mutations automatically. A fresh authenticated GET precedes each keyed create. Missing or unknown support prevents the write; never strip the key to bypass that refusal.

Identical replay returns the current record, including later edits/archive or draft review state; it does not recreate links. Directory status is created_or_reused, not proof that a new record was created. Changed payloads conflict. Keys do not merge duplicate names or deduplicate different actors.

intake_outcome_unknown means a write may have committed despite cancellation, timeout, transport loss, server failure or an unreadable response. Reconcile current records before retrying. Never issue a new key for an uncertain outcome, and do not retry across a server rollback without operator reconciliation. No-key creates remain compatible but are not retry-safe. Versioned edits/links require reload and reconciliation, not blind replay.

Suspected disk data loss

For "Bob A/S, Michael, suspected disk data loss", resolve/reuse or create the company/contact and a linked case from supplied facts, keeping suspected distinct from confirmed damage. Preserve unrelated links when editing. Prioritize preservation: stop avoidable writes and stress, clarify backups, data value and authority, and prefer read-only inspection with an appropriate image/clone or specialist recovery before filesystem repairs or write-heavy tests. Do not fabricate diagnostic findings or promise recovery.

Once context and any device identity are clear, clarify temporary attended Rescue, persistent enrollment, or the existing Repair Live USB preparation handoff. Live USB means supported local assembly and separate authorized case context, not a new hosted ISO or automatic USB writing. Download completion, a hostname or possession of a link does not verify device identity or establish association.

Retry-safe access-link command integration remains pending the shared enrollment and Rescue interfaces. Existing enrollment/Rescue commands keep their existing behavior; do not invent endpoints or repeat uncertain issuance. Usable links may be returned directly to the authorized agent, technician and intended customer in JSON/results or customer drafts. Keep capabilities out of operational logs and access audit. Prepare factual communication for explicit review; do not send it or invent recipient details.

Continue with cases to associate customer context with work. For exact request/response fields, see the directory API reference.