Skip to content

Transferring a project to another company

A project transfer moves ownership of a project from one production company to another. It’s a three-phase workflow: the originator invites a recipient, the recipient accepts or rejects, and both parties get notified of the outcome.

sequenceDiagram
    actor OriginatorAdmin as Originator (admin)
    participant App as Your app
    actor RecipientAdmin as Recipient (admin)

    OriginatorAdmin->>App: Open project, click Transfer
    OriginatorAdmin->>App: Enter recipient contact name + email
    App->>RecipientAdmin: Invitation email with link
    RecipientAdmin->>App: Open link, log in (or sign up)
    RecipientAdmin->>App: Pick target company, accept or reject
    alt Accept
        App-->>RecipientAdmin: Project appears in their company
        App->>OriginatorAdmin: Email — transfer accepted
    else Reject
        App->>OriginatorAdmin: Email — transfer rejected
    end

If the project has a supplier ID, all projects with that supplier ID transfer as a group. This is the most important thing to know before initiating — the producer is transferring a bundle, not just one project.

The originator’s admin opens a project and starts a transfer.

A modal form with these fields:

FieldTranslation key
Contact nametransfer.initiate.contactName (placeholder: transfer.initiate.contactNamePlaceholder)
Contact emailtransfer.initiate.contactEmail (placeholder: transfer.initiate.contactEmailPlaceholder)
Supplier-ID note (informational)transfer.initiate.supplierNote

Plus title transfer.initiate.title and submit button transfer.initiate.submit.

OutcomeTranslation key
Successtransfer.initiate.success (with the email shown)
Already a pending transfer for this projectA toast appears with a link to view the existing invitation
Other failuretransfer.initiate.errorGeneric

The originator can view all of their company’s outgoing transfers on a dashboard page.

Visible textTranslation key
Page titletransfer.dashboard.title
Status badgestransfer.status.pending, transfer.status.accepted, transfer.status.rejected, transfer.status.expired, transfer.status.canceled
Empty statetransfer.dashboard.emptyState

The table shows project name, supplier ID, recipient contact, status, when the invitation was sent and last resent, and when it expires.

For pending invitations, two actions are available:

ActionTranslation key
Resend the invitation emailtransfer.dashboard.resend
Cancel the invitationtransfer.dashboard.cancel (with confirmation: transfer.dashboard.cancelTitle + transfer.dashboard.cancelConfirm; success: transfer.dashboard.cancelSuccess)

A small badge on the projects list (the “pending transfer chip”) indicates which projects have an open invitation. If a transfer spans multiple sibling projects (via supplier ID), each gets the same group letter on the badge.

The recipient opens the invitation email and clicks the link.

The page they land on depends on whether they’re signed in:

SituationWhat’s shown
Not signed inDescription transfer.accept.unauthDescription + login button
Signed in but not admin of any companyError transfer.accept.selectCompany.emptyAdmin
Signed in, admin of one or more companiesDescription transfer.accept.authDescription, a target-company select (transfer.accept.selectCompany.label), and two buttons: Accept (primary) / Reject (danger)

On accept, the recipient is redirected to the projects list — and the transferred project (or group) now appears there.

On reject, they see a success message confirming the rejection and are redirected back to projects.

ErrorTranslation key
Invitation not foundprojectTransfer.errors.notFound.title + body
Invitation expiredprojectTransfer.errors.expired.title + body
Already accepted or rejectedprojectTransfer.errors.alreadyCompleted.title + body
GenericprojectTransfer.errors.generic.title + body

All transfer text lives under transfer.* and projectTransfer.errors.* in tep-configuration/translations/{locale}/main/transfer.json. Override per client.

All three transfer notifications can be overridden per client:

EmailWhenDefault template
InvitationOriginator invites recipienttep-project-transfer-invitation.mjml
AcceptedRecipient acceptstep-project-transfer-accepted.mjml
RejectedRecipient rejectstep-project-transfer-rejected.mjml

Currently only the TEP client has these templates — the project-transfer feature is TEP-only. If you’re CDN, NZ, or Omni you’d need to ship your own templates as part of enabling the feature.

Your deploymentWhat’s different
TEPProject transfer is enabled; the three templates above are available
CDN, NZ, OmniProject transfer is not currently configured. Enabling it requires shipping the three transfer email templates for your client.
Projects with supplier IDsA transfer applies to all sibling projects sharing that supplier ID (shown as a group badge on the projects list)

For the three mutation hooks, the URL-deep-link pattern for existing invitations, the token validation, and the “forwardable invitation” design decision, see Transferring a project (engineering).