> ## Documentation Index
> Fetch the complete documentation index at: https://docs.mirurobotics.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Invites

export const LEFT_TOOLTIP = {
  tip: "The member left the workspace; they cannot login to the workspace or access any resources",
  cta: "Learn more",
  href: "/admin/users/overview#status"
};

export const ROLE_TOOLTIP = {
  tip: "The access role of the user in the workspace.",
  cta: "Learn more",
  href: "/admin/users/access-control"
};

export const AdminBadge = ({size = "md"}) => {
  return <Tooltip tip="Workspace owners and administrators can execute this action." cta="Workspace roles" href="/admin/users/access-control">
            <Badge icon="shield-check" color="blue" size={size}>admin</Badge>
        </Tooltip>;
};

export const Framed = ({image, background, link, alt = "Framed content", borderWidth = "24px", outerRadius = "10px", innerRadius = "6px"}) => {
  const parseShorthand = value => {
    const values = String(value).trim().split(/\s+/);
    switch (values.length) {
      case 1:
        return [values[0], values[0], values[0], values[0]];
      case 2:
        return [values[0], values[1], values[0], values[1]];
      case 3:
        return [values[0], values[1], values[2], values[1]];
      default:
        return values.slice(0, 4);
    }
  };
  const isZero = v => parseFloat(v) === 0;
  const padding = parseShorthand(borderWidth);
  const outer = parseShorthand(outerRadius);
  const cornerMasks = [];
  if (isZero(padding[0]) && isZero(padding[3])) {
    cornerMasks.push(`radial-gradient(circle at 0% 0%, transparent ${outer[0]}, black ${outer[0]})`);
  }
  if (isZero(padding[0]) && isZero(padding[1])) {
    cornerMasks.push(`radial-gradient(circle at 100% 0%, transparent ${outer[1]}, black ${outer[1]})`);
  }
  if (isZero(padding[2]) && isZero(padding[1])) {
    cornerMasks.push(`radial-gradient(circle at 100% 100%, transparent ${outer[2]}, black ${outer[2]})`);
  }
  if (isZero(padding[2]) && isZero(padding[3])) {
    cornerMasks.push(`radial-gradient(circle at 0% 100%, transparent ${outer[3]}, black ${outer[3]})`);
  }
  const backgroundMask = cornerMasks.length > 0 ? cornerMasks.join(", ") : undefined;
  const innerImage = <img src={image} alt={alt} noZoom={link ? true : false} style={{
    display: "block",
    width: "100%",
    margin: 0,
    borderRadius: 0
  }} />;
  return <div style={{
    display: "inline-block",
    position: "relative",
    borderRadius: outerRadius,
    overflow: "hidden"
  }}>
            {}
            {background && <div style={{
    position: "absolute",
    inset: 0,
    backgroundImage: `url(${background})`,
    backgroundSize: "cover",
    maskImage: backgroundMask,
    WebkitMaskImage: backgroundMask,
    maskComposite: "intersect",
    WebkitMaskComposite: "source-in"
  }} />}
            {}
            <div style={{
    position: "relative",
    padding: borderWidth
  }}>
                <div style={{
    borderRadius: innerRadius,
    overflow: "hidden",
    lineHeight: 0
  }}>
                    {link ? <a href={link}>{innerImage}</a> : innerImage}
                </div>
            </div>
        </div>;
};

export const ImmutableBadge = ({size = "sm"}) => {
  return <Tooltip tip="Property cannot be modified">
            <Badge icon="lock" color="gray" size={size}>immutable</Badge>
        </Tooltip>;
};

export const MutableBadge = ({size = "sm"}) => {
  return <Tooltip tip="Property is automatically updated by the system; cannot be modified directly">
            <Badge icon="feather" color="orange" size={size}>mutable</Badge>
        </Tooltip>;
};

<Framed background="https://assets.mirurobotics.com/docs/v04/images/users/background.jpeg" image="https://assets.mirurobotics.com/docs/v04/images/invites/header:join-workspace.png" borderWidth="40px" innerRadius="10px" outerRadius="12px" />

An **invite** is a request sent to a new or existing user to join your workspace.

### Properties

<ParamField path="email" type="string">
  <ImmutableBadge />

  The email address of the invitee.

  Examples: `john.doe@example.com`, `jane.smith@example.com`
</ParamField>

<ParamField path="expires_at" type="timestamp">
  <ImmutableBadge />

  The date and time the invite expires. Invites are valid for seven days from creation.

  Examples: `2025-11-19T12:00:00Z`
</ParamField>

<ParamField path="role" type="enum">
  <MutableBadge />

  The <Tooltip tip={ROLE_TOOLTIP.tip} cta={ROLE_TOOLTIP.cta} href={ROLE_TOOLTIP.href}>role</Tooltip> of the invitee when they join the workspace. Must be one of the following:

  * `admin`
  * `member`
</ParamField>

## Sending invites

### Send an invite  <AdminBadge />

To invite a member to your workspace, navigate to the [members](https://app.mirurobotics.com/settings/members) page and click **Invite** in the top right corner.

Next, supply the email addresses of the members you want to invite as a comma-separated list, select their <Tooltip tip={ROLE_TOOLTIP.tip} cta={ROLE_TOOLTIP.cta} href={ROLE_TOOLTIP.href}>role</Tooltip>, and hit **Send**.

<Frame>
  ![Send Invite Dialog](https://assets.mirurobotics.com/docs/v04/images/invites/send-invite-dialog.png)
</Frame>

An email will be sent to each member with a link to accept the invite.

Invites expire after seven days. Once the invite expires, a new invite must be issued for a member to join your workspace.

### Revoke an invite  <AdminBadge />

To revoke an invite, click the **pending invites** button in the top right.

<Frame>
  ![Pending Invites Button](https://assets.mirurobotics.com/docs/v04/images/invites/pending-invites-button.png)
</Frame>

A panel will appear on the right side of the screen with a list of pending invites. Click the ellipses (...) of the invite to revoke and hit **Revoke Invite**.

<Frame>
  ![Pending Invite Dropdown](https://assets.mirurobotics.com/docs/v04/images/invites/pending-invite-dropdown.png)
</Frame>

Finally, confirm the revocation by clicking **Revoke** in the confirmation dialog.

<Frame>
  ![Revoke Invite Dialog](https://assets.mirurobotics.com/docs/v04/images/invites/revoke-invite-dialog.png)
</Frame>

### Resend an invite  <AdminBadge />

Resending an invite sends a new email to the invitee but does not affect the invite in any way — previous emails remain valid, and the invite's expiration date is unchanged.

Since resending an invite does not extend its expiration date, invitees must still accept it within seven days of its original creation. To give the invitee more time to accept, create a new invite.

To resend an invite, click the **pending invites** button in the top right.

<Frame>
  ![Pending Invites Button](https://assets.mirurobotics.com/docs/v04/images/invites/pending-invites-button.png)
</Frame>

A panel will appear on the right side of the screen with a list of pending invites. Click the ellipses (...) of the invite to resend and hit **Resend Invite**.

<Frame>
  ![Pending Invite Dropdown](https://assets.mirurobotics.com/docs/v04/images/invites/pending-invite-dropdown.png)
</Frame>

## Receiving invites

This section covers invites received by users *who already have a Miru account*. If you do not yet have a Miru account, follow the instructions sent in the invitation email to join a workspace.

### Accept an invite

Since user accounts can only belong to a single workspace, accepting an invite from another workspace transfers you from your current workspace to the workspace you've been invited to:

* You will lose all access to your current workspace
* Your status in your current workspace will be set to <Tooltip tip={LEFT_TOOLTIP.tip} cta={LEFT_TOOLTIP.cta} href={LEFT_TOOLTIP.href}>left</Tooltip>
* Logging in gives you access to the workspace you've accepted the invite from

Accepting an invite is reversible if you are *not the only active member*. An admin from the workspace you left can invite you back at any time.

However, if you are *the only* active member of your current workspace, accepting an invite will delete the workspace and all associated resources.

To accept an invite from another workspace, navigate to the [Profile page](https://app.mirurobotics.com/settings/profile) and hit **Join**.

<Frame>
  ![Invitations Panel](https://assets.mirurobotics.com/docs/v04/images/users/profile/invitations.png)
</Frame>

Finally, click **Join workspace** to accept the invite and transfer workspaces.

<Frame>
  ![Accept Invite Dialog](https://assets.mirurobotics.com/docs/v04/images/users/profile/accept-invite-dialog.png)
</Frame>

### Decline an invite

To decline an invite, navigate to your [Profile page](https://app.mirurobotics.com/settings/profile) and hit **Decline** on the invite you want to decline.

<Frame>
  ![Invitations Panel](https://assets.mirurobotics.com/docs/v04/images/users/profile/invitations.png)
</Frame>
