Endpoint
Cancel a pending invitation. Only the user who created the invitation can cancel it.
Authentication
This endpoint requires authentication. User must be logged in with a valid session.
Request Body
The invitation token to cancel.
Response
Success Response (200)
Confirmation message: "Invite cancelled successfully"
Examples
Cancel Pending Invitation
Request:
POST /invite/cancel
Content-Type: application/json
Cookie: better-auth.session_token=...
{
"token": "abc123xyz789"
}
Response:
{
"status": true,
"message": "Invite cancelled successfully"
}
The invitation is marked as “canceled” (or deleted if cleanupInvitesOnDecision is enabled).
Cancel with Cleanup Enabled
When cleanupInvitesOnDecision: true is configured:
Request:
POST /invite/cancel
Content-Type: application/json
Cookie: better-auth.session_token=...
{
"token": "invite-to-delete"
}
Response:
{
"status": true,
"message": "Invite cancelled successfully"
}
The invitation record is permanently deleted from the database along with all associated invite uses.
Error Responses
Invalid Token (400)
{
"message": "Invalid or non-existent token",
"errorCode": "INVALID_TOKEN"
}
Returned when:
- Token doesn’t exist in the database
- Invitation has already been canceled, rejected, or used
- Invitation has expired
Insufficient Permissions (400)
{
"message": "User does not have sufficient permissions to create invite",
"errorCode": "INSUFFICIENT_PERMISSIONS"
}
Returned when:
- The logged-in user is not the creator of the invitation
- User doesn’t have permission based on
canCancelInvite option
Behavior
Cancellation Process
- Validates the invitation token exists
- Verifies the logged-in user created this invitation
- Checks the invitation status is “pending”
- Checks
canCancelInvite permissions
- Triggers
beforeCancelInvite hook
- Either deletes or updates the invitation based on
cleanupInvitesOnDecision setting:
- If
cleanupInvitesOnDecision: true: Deletes invitation and all invite uses
- If
cleanupInvitesOnDecision: false (default): Updates status to “canceled”
- Triggers
afterCancelInvite hook
- Returns success confirmation
Authorization Rules
Always enforced:
- Only the user who created the invitation can cancel it (checked via
createdByUserId)
Configurable via canCancelInvite:
- Additional custom permission checks
- Role-based restrictions
Cleanup Behavior
With cleanupInvitesOnDecision: false (default)
// Invitation status is updated
{
id: "inv_123",
token: "abc123xyz789",
status: "canceled", // Updated from "pending"
// ... other fields
}
The invitation remains in the database for audit purposes but cannot be used.
With cleanupInvitesOnDecision: true
// Invitation is deleted
// DELETE FROM invite WHERE token = 'abc123xyz789'
// DELETE FROM inviteUse WHERE inviteId = 'inv_123'
The invitation and all associated records are permanently removed.
Hooks
The following hooks are triggered during this endpoint:
-
beforeCancelInvite: Called before canceling the invitation
beforeCancelInvite: async ({ ctx, invitation }) => {
// Log cancellation attempt
console.log(`Canceling invite ${invitation.id}`);
}
-
afterCancelInvite: Called after the invitation is canceled
afterCancelInvite: async ({ ctx, invitation }) => {
// Notify the invitee (if applicable)
if (invitation.email) {
await sendEmail({
to: invitation.email,
subject: 'Invitation Cancelled',
body: `The invitation to ${invitation.role} has been cancelled.`,
});
}
}
Permissions
Permission is checked using the canCancelInvite option:
// Function-based permission
canCancelInvite: async ({ inviterUser, invitation, ctx }) => {
// Only admins can cancel invitations
return inviterUser.role === 'admin';
}
// Permission object
canCancelInvite: {
statement: "user:invite:cancel",
permissions: ["admin"]
}
// Always allow (default)
canCancelInvite: true
Note: Even with canCancelInvite: true, the user must still be the creator of the invitation.
Use Cases
Cancel Unused Invitations
// Cancel an invitation that's no longer needed
const result = await authClient.invite.cancelInvite({
token: unusedInviteToken,
});
if (result.status) {
console.log('Invitation cancelled successfully');
}
Cancel Before Creating New Invitation
// Cancel old invitation before sending a new one
await authClient.invite.cancelInvite({ token: oldToken });
const newInvite = await authClient.invite.createInvite({
email: '[email protected]',
role: 'admin',
});
Revoke Access
// Revoke an invitation before it's accepted
try {
await authClient.invite.cancelInvite({ token: inviteToken });
alert('Invitation has been revoked');
} catch (error) {
if (error.errorCode === 'INVALID_TOKEN') {
alert('Invitation has already been used or cancelled');
}
}
Invitation Status Flow
pending → canceled (via cancelInvite)
pending → rejected (via rejectInvite)
pending → used (via activateInvite)
Once an invitation is canceled, it cannot be activated or rejected.
Source Code Reference
Implementation: src/routes/cancel-invite.ts:9-133