Documentation Index
Fetch the complete documentation index at: https://docs.snackbase.dev/llms.txt
Use this file to discover all available pages before exploring further.
The Invitations service allows you to invite users to join your account and tracks the invitation status.
Overview
import { SnackBaseClient } from "@snackbase/sdk";
const client = new SnackBaseClient({
baseUrl: "https://api.example.com",
});
// Access the invitations service
const invitations = client.invitations;
List Invitations
Get all invitations for the current account:
const invitations = await client.invitations.list();
With pagination:
const invitations = await client.invitations.list({
limit: 20,
skip: 0
});
Create an Invitation
Invite a new user to join your account:
const invitation = await client.invitations.create({
email: "[email protected]",
role_id: "role-id"
});
The response includes:
{
"id": "invitation-id",
"email": "[email protected]",
"role_id": "role-id",
"status": "pending",
"token": "unique-invitation-token",
"expires_at": "2024-02-15T00:00:00Z",
"created_at": "2024-01-15T00:00:00Z"
}
Resend an Invitation
Resend the invitation email if it wasn’t received:
await client.invitations.resend("invitation-id");
Get Public Invitation Details
Retrieve invitation details using the token (no authentication required):
const invitation = await client.invitations.getPublic("invitation-token");
Useful for invitation acceptance pages where the user isn’t authenticated yet.
Accept an Invitation
Accept an invitation and create a user account:
const authResponse = await client.invitations.accept(
"invitation-token",
"new-password"
);
The response includes authentication tokens and the created user:
{
"user": { ... },
"account": { ... },
"token": "access-token",
"refresh_token": "refresh-token",
"expires_at": "2024-01-16T00:00:00Z"
}
// The auth state is automatically stored
console.log(client.isAuthenticated); // true
console.log(client.user); // User object
Cancel an Invitation
Cancel a pending invitation:
await client.invitations.cancel("invitation-id");
Complete Example
Invitation management component:
import { useState } from "react";
import { useQuery, useMutation, useQueryClient } from "@snackbase/sdk/react";
function InvitationManager() {
const queryClient = useQueryClient();
const [email, setEmail] = useState("");
const { data: invitations, isLoading } = useQuery({
queryKey: ["invitations"],
queryFn: () => client.invitations.list()
});
const createMutation = useMutation({
mutationFn: (data) => client.invitations.create(data),
onSuccess: () => {
setEmail("");
queryClient.invalidateQueries(["invitations"]);
}
});
const resendMutation = useMutation({
mutationFn: (id) => client.invitations.resend(id)
});
const cancelMutation = useMutation({
mutationFn: (id) => client.invitations.cancel(id),
onSuccess: () => {
queryClient.invalidateQueries(["invitations"]);
}
});
const handleCreate = (e) => {
e.preventDefault();
createMutation.mutate({ email, role_id: "default-role" });
};
if (isLoading) return <div>Loading...</div>;
return (
<div>
<h2>User Invitations</h2>
<form onSubmit={handleCreate}>
<input
type="email"
value={email}
onChange={(e) => setEmail(e.target.value)}
placeholder="[email protected]"
required
/>
<button type="submit" disabled={createMutation.isPending}>
Send Invitation
</button>
</form>
<table>
<thead>
<tr>
<th>Email</th>
<th>Status</th>
<th>Expires</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
{invitations?.map(inv => (
<tr key={inv.id}>
<td>{inv.email}</td>
<td>{inv.status}</td>
<td>{new Date(inv.expires_at).toLocaleDateString()}</td>
<td>
{inv.status === "pending" && (
<>
<button
onClick={() => resendMutation.mutate(inv.id)}
disabled={resendMutation.isPending}
>
Resend
</button>
<button
onClick={() => cancelMutation.mutate(inv.id)}
disabled={cancelMutation.isPending}
>
Cancel
</button>
</>
)}
</td>
</tr>
))}
</tbody>
</table>
</div>
);
}
Invitation Acceptance Flow
For public invitation acceptance pages:
import { useEffect, useState } from "react";
import { SnackBaseClient } from "@snackbase/sdk";
const client = new SnackBaseClient({
baseUrl: "https://api.example.com"
});
function InvitationAcceptPage({ token }) {
const [invitation, setInvitation] = useState(null);
const [password, setPassword] = useState("");
const [error, setError] = useState(null);
useEffect(() => {
client.invitations.getPublic(token)
.then(setInvitation)
.catch(setError);
}, [token]);
const handleAccept = async (e) => {
e.preventDefault();
try {
await client.invitations.accept(token, password);
// User is now logged in, redirect to dashboard
window.location.href = "/dashboard";
} catch (err) {
setError(err.message);
}
};
if (!invitation) return <div>Loading...</div>;
if (error) return <div>Error: {error}</div>;
return (
<div>
<h1>Accept Invitation</h1>
<p>You've been invited to join {invitation.account_name}</p>
<form onSubmit={handleAccept}>
<input
type="password"
value={password}
onChange={(e) => setPassword(e.target.value)}
placeholder="Create a password"
required
minLength={8}
/>
<button type="submit">Accept & Create Account</button>
</form>
</div>
);
}
Next Steps