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

# Create workspace invite

> Create a workspace invitation by email, userId, or username

## Overview

`useCreateWorkspaceInvite` returns a callable that creates an [invitation](/data-models/workspace-invitation). Address the invitee by **exactly one** of `email`, `userId`, or `username` (here `userId`/`username` is the invite **target**, not the actor — the inviter is the signed-in user).

**Authorization:** capability-gated + rank-bounded. Requires the `invite` capability (or ownership). The invited `capabilities`/`permissions` are subject to [no-escalation](/data-models/workspace-member#no-privilege-escalation), and if the inviter holds a direct member row the invited `rank` must be strictly larger (less senior) than their own.

<Warning>
  **Your project must have `workspaces.inviteAcceptUrl` set before this hook can succeed.** The invitation email deep-links to that URL, and it has **no default** — so a freshly added `workspaces` bundle has none and every call fails with `409 workspace/missing-invite-accept-url` until you configure it. This holds **even when the invitee already has an account**. See [Project settings](/sdk/workspaces/overview#project-settings).
</Warning>

## Usage Example

```tsx theme={null}
import { useCreateWorkspaceInvite } from "@sublay/react-js";

function InviteForm({ workspaceId }: { workspaceId: string }) {
  const createWorkspaceInvite = useCreateWorkspaceInvite();

  const handleInvite = async (email: string) => {
    const invite = await createWorkspaceInvite({
      workspaceId,
      email,
      capabilities: ["view"],
      permissions: ["deploy"],
      rank: 5,
    });
    console.log("Invited:", invite.id);
  };
}
```

## Parameters

<ParamField path="workspaceId" type="string" required>The workspace UUID.</ParamField>
<ParamField path="email" type="string">Invitee email. One of `email`/`userId`/`username`. Trimmed + lowercased server-side, and matched **case-insensitively** against existing accounts — so an account stored as `Jane@Example.com` still gets its `userId` bound when invited as `jane@example.com`.</ParamField>
<ParamField path="userId" type="string">Invitee user id (existing users only) — the invite **target**.</ParamField>
<ParamField path="username" type="string">Invitee username (existing users only).</ParamField>
<ParamField path="capabilities" type="WorkspaceCapability[]">Capabilities to apply on accept. Subject to no-escalation.</ParamField>
<ParamField path="permissions" type="string[]">Opaque permissions to apply on accept.</ParamField>
<ParamField path="rank" type="number" required>Initial rank. For a direct-member inviter it must be strictly larger (less senior) than their own; a reach-holder inviter (no direct row) may set any rank.</ParamField>
<ParamField path="title" type="string | null">Optional cosmetic title.</ParamField>

## Returns

Returns the created [WorkspaceInvitation](/data-models/workspace-invitation) object.

## Error codes

| Code                                  | Status | Meaning                                                                                                                                                                                                                                                                                                        |
| ------------------------------------- | ------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `workspace/already-member`            | 409    | The target is already a member — edit their grant instead.                                                                                                                                                                                                                                                     |
| `workspace/no-escalation`             | 403    | You tried to grant a capability/permission you do not hold.                                                                                                                                                                                                                                                    |
| `workspace/insufficient-rank`         | 403    | The invited rank is not strictly below your own.                                                                                                                                                                                                                                                               |
| `workspace/unauthorized`              | 403    | You lack the `invite` capability.                                                                                                                                                                                                                                                                              |
| `workspace/missing-invite-accept-url` | 409    | The **project** has no [`workspaces.inviteAcceptUrl`](/sdk/workspaces/overview#project-settings) configured, so the invite email would have nowhere to link. Nothing is persisted. A misconfiguration to fix in project settings, not something the end user can act on — surface it to yourself, not to them. |

## Related

* [`useFetchWorkspaceInvites`](/hooks/workspaces/use-fetch-workspace-invites) — the invites this workspace has issued
* [`useRevokeWorkspaceInvite`](/hooks/workspaces/use-revoke-workspace-invite) · [`useResendWorkspaceInvite`](/hooks/workspaces/use-resend-workspace-invite)
* [Project settings](/sdk/workspaces/overview#project-settings) — the required `workspaces.inviteAcceptUrl`
* [Create Invite API](/api-reference/workspaces/invitations/create-invite)
