Skip to main content

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.

ts
const generateSummary = useConvexAction(api.ai.generateSummary)
const result = await generateSummary.safe({ documentId })

Mutation or action

WorkUse
Read Convex dataQuery
Transactionally write Convex dataMutation
Call an external APIAction
Schedule durable Convex workMutation/action plus Convex scheduler as appropriate
Hold a Nuxt-only secretNitro 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:

  • status
  • pending
  • data
  • error
  • reset()
  • .safe()
  • onSuccess and onError
ts
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.