Actions
Call external services or perform non-transactional Convex work with reactive operation state.
Use a Convex action for work that cannot run inside a query or mutation, such as calling a third-party API.
const generateSummary = useConvexAction(api.ai.generateSummary)
const result = await generateSummary.safe({ documentId })Mutation or action
| Work | Use |
|---|---|
| Read Convex data | Query |
| Transactionally write Convex data | Mutation |
| Call an external API | Action |
| Schedule durable Convex work | Mutation/action plus Convex scheduler as appropriate |
| Hold a Nuxt-only secret | Nitro server route |
Do not use an action for ordinary database writes. Actions are not transactional across their external effects.
State and callbacks
Actions expose the same callable state as mutations:
statuspendingdataerrorreset().safe()onSuccessandonError
const sendInvite = useConvexAction(api.email.sendInvite, {
onSuccess: () => toast.success('Invitation sent'),
onError: (error) => toast.error(error.message),
})Progress
The composable tracks whether the action call is pending. It does not provide step-by-step action progress.
For long workflows, write progress to Convex data and subscribe to that data with a query. The action remains the worker; the query becomes the observable product state.
Retries
An action may have completed an external side effect before its response fails. Design idempotency into external calls and do not retry unknown failures blindly.
Like mutations, action results that cross an identity generation are retired from the new user's UI and surface IDENTITY_CHANGED to the caller.