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

# Invite Events

> Webhook events for the full invitation lifecycle — accepted, rejected, and expired

Invite events are triggered as an invitation moves through its lifecycle: accepted by the invitee, rejected by them, or left to expire. These events help you track invitation workflows and member onboarding, and let you close the loop on invitations that never convert.

## Overview

Rise supports the following invite-related webhook events:

<CardGroup cols={3}>
  <Card title="invite.accepted" icon="user-plus" href="#invite-accepted">
    Invitation accepted and user joined team or company
  </Card>

  <Card title="invite.rejected" icon="user-xmark" href="#invite-rejected">
    Invitation declined by the invitee
  </Card>

  <Card title="invite.expired" icon="clock" href="#invite-expired">
    Invitation lapsed after 90 days without a response
  </Card>
</CardGroup>

These three events cover the outcomes an **invitee** can produce: they accept, they decline, or they never respond and the invitation lapses.

<Note>
  Some invitations end **without** a webhook: one you revoke, one superseded by a resend, one dropped when the invitee's account is deactivated, and one that is set aside during sign-up because its role does not fit the role the invitee joined as. Do not treat "no event yet" as "still pending" indefinitely — reconcile against the invites API if you need the settled state of every invitation you sent.
</Note>

***

## invite.accepted

When a user accepts an invitation to join a company or team, this event is triggered. This event signals successful completion of the invitation workflow.

### Field reference

<ParamField path="object" type="string" required>
  The type of object this webhook represents (always "event")
</ParamField>

<ParamField path="created" type="number" required>
  The Unix timestamp when the event was created
</ParamField>

<ParamField path="event_type" type="string" required>
  The type of event that occurred
</ParamField>

<ParamField path="event_version" type="string" required>
  The version of the event schema
</ParamField>

<ParamField path="request_id" type="string">
  A unique identifier for the API request that triggered this event (optional)
</ParamField>

<ParamField path="idempotency_key" type="string" required>
  A unique key to ensure the webhook is processed only once
</ParamField>

<ParamField path="invite" type="object" required>
  Invitation information and details
</ParamField>

<Expandable title="invite" defaultOpen>
  <ParamField path="nanoid" type="string" required>
    Unique identifier for the invite (primary key)
  </ParamField>

  <ParamField path="user_nanoid" type="string" required>
    Nanoid of the user who accepted the invite
  </ParamField>

  <ParamField path="email" type="string" required>
    Email address of the invitee
  </ParamField>

  <ParamField path="role" type="string" required>
    Role assigned to the invitee
  </ParamField>

  <ParamField path="status" type="string" required>
    Status of the invite, e.g., pending, accepted, expired
  </ParamField>

  <ParamField path="anonymous" type="boolean">
    Indicates whether the invite was sent anonymously
  </ParamField>

  <ParamField path="invited_by" type="string" required>
    Nanoid of the user who created the invite
  </ParamField>

  <ParamField path="invited_to" type="string" required>
    Nanoid of the company or team the invite is associated with
  </ParamField>
</Expandable>

***

## invite.rejected

When an invitee explicitly declines an invitation, this event is triggered. The invitation is dead and will never be accepted.

### Field reference

<ParamField path="object" type="string" required>
  The type of object this webhook represents (always "event")
</ParamField>

<ParamField path="created" type="number" required>
  The Unix timestamp when the event was created
</ParamField>

<ParamField path="event_type" type="string" required>
  The type of event that occurred
</ParamField>

<ParamField path="event_version" type="string" required>
  The version of the event schema
</ParamField>

<ParamField path="request_id" type="string">
  A unique identifier for the API request that triggered this event (optional)
</ParamField>

<ParamField path="idempotency_key" type="string" required>
  A unique key to ensure the webhook is processed only once
</ParamField>

<ParamField path="invite" type="object" required>
  Invitation information and details
</ParamField>

<Expandable title="invite" defaultOpen>
  <ParamField path="nanoid" type="string" required>
    Unique identifier for the invite (primary key)
  </ParamField>

  <ParamField path="user_nanoid" type="string" required>
    Nanoid of the user who rejected the invite
  </ParamField>

  <ParamField path="email" type="string" required>
    Email address of the invitee
  </ParamField>

  <ParamField path="role" type="string" required>
    Role that was offered to the invitee
  </ParamField>

  <ParamField path="status" type="string" required>
    Always `rejected` for this event
  </ParamField>

  <ParamField path="anonymous" type="boolean">
    Indicates whether the invite was sent anonymously
  </ParamField>

  <ParamField path="invited_by" type="string" required>
    Nanoid of the user who created the invite
  </ParamField>

  <ParamField path="invited_to" type="string" required>
    Nanoid of the company or team the invite is associated with
  </ParamField>
</Expandable>

***

## invite.expired

Invitations are valid for **90 days from the moment they are created**. An invitation that is still pending when it passes that deadline lapses, and this event is triggered.

Expiry is swept periodically rather than exactly on the 90-day boundary, so expect this event shortly after the invitation lapses rather than to the second. Only invitations that were still pending expire — one that was already accepted or rejected has reached its final state and produces no `invite.expired`.

Because the invitee may never have created a Rise account, this payload carries **no `user_nanoid`**. That is the only shape difference from the other two invite events.

### Field reference

<ParamField path="object" type="string" required>
  The type of object this webhook represents (always "event")
</ParamField>

<ParamField path="created" type="number" required>
  The Unix timestamp when the event was created
</ParamField>

<ParamField path="event_type" type="string" required>
  The type of event that occurred
</ParamField>

<ParamField path="event_version" type="string" required>
  The version of the event schema
</ParamField>

<ParamField path="request_id" type="string">
  A unique identifier for the API request that triggered this event (optional)
</ParamField>

<ParamField path="idempotency_key" type="string" required>
  A unique key to ensure the webhook is processed only once
</ParamField>

<ParamField path="invite" type="object" required>
  Invitation information and details
</ParamField>

<Expandable title="invite" defaultOpen>
  <ParamField path="nanoid" type="string" required>
    Unique identifier for the invite (primary key)
  </ParamField>

  <ParamField path="email" type="string" required>
    Email address of the invitee
  </ParamField>

  <ParamField path="role" type="string" required>
    Role that was offered to the invitee
  </ParamField>

  <ParamField path="status" type="string" required>
    Always `expired` for this event
  </ParamField>

  <ParamField path="anonymous" type="boolean">
    Indicates whether the invite was sent anonymously
  </ParamField>

  <ParamField path="invited_by" type="string" required>
    Nanoid of the user who created the invite
  </ParamField>

  <ParamField path="invited_to" type="string" required>
    Nanoid of the company or team the invite is associated with
  </ParamField>

  <ParamField path="expires_at" type="string" required>
    ISO timestamp at which the invite lapsed (90 days after it was created)
  </ParamField>
</Expandable>

<RequestExample>
  ```json invite.accepted (v2) theme={null}
  {
    "object": "event",
    "created": 1751590453,
    "request_id": "req-1751590452487",
    "event_type": "invite.accepted",
    "event_version": "2.0",
    "idempotency_key": "85420805-0b5e-4b11-b7f4-c6f05db7120b",
    "invite": {
      "nanoid": "in-abc123def456789",
      "user_nanoid": "us-xyz789abc123456",
      "email": "newmember@example.com",
      "role": "team_admin",
      "status": "accepted",
      "anonymous": false,
      "invited_by": "us-def456ghi789012",
      "invited_to": "te-ghi789def456123"
    }
  }
  ```

  ```json invite.rejected (v2) theme={null}
  {
    "object": "event",
    "created": 1751590453,
    "request_id": null,
    "event_type": "invite.rejected",
    "event_version": "2.0",
    "idempotency_key": "0f2c9a41-5d3b-4a77-9f1e-3c8b5d7a2e40",
    "invite": {
      "nanoid": "in-abc123def456789",
      "user_nanoid": "us-xyz789abc123456",
      "email": "newmember@example.com",
      "role": "team_admin",
      "status": "rejected",
      "anonymous": false,
      "invited_by": "us-def456ghi789012",
      "invited_to": "te-ghi789def456123"
    }
  }
  ```

  ```json invite.expired (v2) theme={null}
  {
    "object": "event",
    "created": 1751590453,
    "request_id": null,
    "event_type": "invite.expired",
    "event_version": "2.0",
    "idempotency_key": "b7d41e08-6a92-4c15-8e33-1f9a6c2d5b74",
    "invite": {
      "nanoid": "in-abc123def456789",
      "email": "newmember@example.com",
      "role": "team_admin",
      "status": "expired",
      "anonymous": false,
      "invited_by": "us-def456ghi789012",
      "invited_to": "te-ghi789def456123",
      "expires_at": "2026-07-14T09:12:04.000Z"
    }
  }
  ```
</RequestExample>

***

## Implementation Notes

<Info>
  **Invitation lifecycle**: An invitee can do three things with an invitation, and each emits an event — `invite.accepted` when they join, `invite.rejected` when they decline, and `invite.expired` when they never respond and it lapses 90 days after it was created. Subscribe to all three to learn the outcome of the invitations you send.

  Invitations that *you* end — revoking one, resending one (which cancels the original), or deactivating the invitee's account — emit no webhook.
</Info>

<Warning>
  **Role permissions**: Always validate that the assigned role matches your expected permissions before granting access to systems or resources.
</Warning>

<Tip>
  **User tracking**: Use the `user_nanoid` to correlate `invite.accepted` and `invite.rejected` with other user-related activities across your system. `invite.expired` has no `user_nanoid` — correlate it on the invite's `nanoid` or `email` instead.
</Tip>

### Role Types

<AccordionGroup>
  <Accordion title="team_admin" icon="crown">
    Full administrative access to team settings, member management, and billing
  </Accordion>

  <Accordion title="member" icon="user">
    Standard team member with access to team resources and functionality
  </Accordion>

  <Accordion title="viewer" icon="eye">
    Read-only access to team resources without modification privileges
  </Accordion>
</AccordionGroup>

### Use Cases

Invite events are commonly used for:

* **Automated onboarding** - Trigger welcome emails, setup guides, or account provisioning
* **Access control** - Grant appropriate permissions in external systems
* **Analytics tracking** - Monitor team growth and invitation conversion rates
* **Compliance logging** - Maintain audit trails of team membership changes
* **Chasing stalled invitations** - Re-invite or clean up your own records when `invite.expired` or `invite.rejected` tells you an invitation will never convert

### Anonymous Invitations

When `anonymous` is `true`, the invitation was sent to a user who wasn't previously registered with Rise. These users create an account as part of accepting the invitation.

<Note>
  **Account creation**: Anonymous invitations trigger both account creation and team membership, so `invite.accepted` represents both user registration and team joining. An anonymous invitation that expires never produced an account, which is why `invite.expired` carries no `user_nanoid`.
</Note>
