Skip to main content

Overview

LuaJob allows you to define scheduled tasks that run automatically without user interaction. Unlike the Jobs API which creates jobs dynamically, LuaJob is for pre-defined jobs that are part of your agent configuration.
No Conversational Context: LuaJob executes outside of user conversations. You MUST use User.get(userId) with a userId from metadata. The job does NOT have jobInstance.user() - that’s only for dynamic jobs.
Pre-defined jobs that are part of your agent configuration. Use with LuaAgent.

When to Use

LuaJob (Pre-defined)

For scheduled tasks defined at agent setup
  • Daily reports
  • Weekly summaries
  • Cleanup tasks
  • Monitoring jobs
User access: User.get(userId) from metadata

Jobs API (Dynamic)

For tasks created on-demand from tools
  • User reminders
  • Follow-ups
  • One-time notifications
  • Context-specific tasks
User access: jobInstance.user() (automatic!)
Key Difference: Pre-defined LuaJob has NO user context. Use User.get(userId) with ID from metadata. Dynamic jobs (Jobs API) automatically have user context via jobInstance.user().

Comparison: LuaJob vs Jobs API

Understanding user access in different job types: Example - Pre-defined LuaJob:
Example - Dynamic Job (Jobs API):

Constructor

new LuaJob(config)

Creates a new pre-defined job.
LuaJobConfig
required
Job configuration object

Configuration Parameters

Required Fields

string
required
Unique job nameFormat: lowercase, hyphens, underscoresExamples: 'daily-report', 'weekly-cleanup'
JobSchedule
required
When and how often the job runs
function
required
Function that runs when the job triggersSignature: (job: JobInstance) => Promise<any>

Optional Fields

string
Job description for documentation
object
Static metadata available to execute function
number
Maximum execution time in secondsDefault: 300 (5 minutes)
object
Retry configuration
boolean
Whether job is activeDefault: true

Schedule Types

Interval (Fixed intervals)

Examples:

Cron (Cron patterns)

Examples:

Complete Examples

Daily Sales Report

Weekly Cleanup Job

Hourly Monitoring

Reminders with Metadata

Using with LuaAgent

Jobs are added to your agent configuration:

JobInstance API

The execute function receives a JobInstance with these properties and methods:

Properties

jobInstance.user()

Get the user associated with the job. Returns: Promise<UserDataInstance>

jobInstance.metadata

Access job metadata.

jobInstance.updateMetadata(data)

Update job metadata dynamically.

jobInstance.trigger(versionId?)

Manually triggers the job execution (ignores schedule). Uses the active version by default. Parameters:
  • versionId (optional): Specific version to execute. Defaults to activeVersion.
Returns: Promise<JobExecution>

jobInstance.delete()

Delete the job (or deactivates if it has versions).

Delivery Semantics

Jobs run at least once. Each scheduled occurrence is durably queued and executed on isolated infrastructure, and a failed attempt is retried according to the job’s retry configuration (maxAttempts, backoffSeconds). A job may therefore run more than once for a single scheduled occurrence, so keep side effects idempotent — guard them with your own state (for example, a flag in metadata or a record in Data).
  • Retries happen only when an attempt fails, using your maxAttempts and backoffSeconds.
  • The platform caps attempts at 10 regardless of config — a higher maxAttempts is clamped to 10.
Each execution receives metadata on job.execution:
job.execution is only present when a job runs on Lua’s infrastructure. It is undefined during local lua test / lua dev runs, which execute in-process — so always read it optionally (job.execution?.occurrenceId).

Idempotency

Because a job runs at least once, design your side effects to be safe to repeat. The occurrenceId is stable across all retries of one occurrence, so it makes a natural idempotency key: record it after the side effect succeeds, and skip the work if you’ve already processed it. Attempts of one occurrence never run concurrently, so a simple check-then-write guard like the one below is safe.
Prefer occurrenceId over executionId for deduplication: executionId is re-minted on every retry, so keying on it would let each attempt’s side effect through. For scheduled jobs you can instead key on scheduledTime when you want one run per schedule slot.

Best Practices

Use cron for specific times, interval for regular checks
Jobs should not throw - return error status instead
Configure retries for important operations
Set appropriate timeouts and avoid long-running operations

Cron Pattern Reference

Common Patterns:
  • 0 * * * * - Every hour on the hour
  • 0 9 * * * - Every day at 9 AM
  • 0 9 * * 1 - Every Monday at 9 AM
  • 0 0 1 * * - First day of every month at midnight
  • */15 * * * * - Every 15 minutes
  • 0 9-17 * * 1-5 - 9 AM to 5 PM, Monday to Friday

Invoking an Agent from a Pre-defined Job

Use Agents.invoke to delegate work to a conversational agent from inside a scheduled job. Pre-defined jobs have no ambient user, so pass a userId when you have one (e.g. from job metadata). When no userId is available, omit it and the invocation runs without user identity — no conversation history is stored.

Agents API Reference

Full documentation for Agents.invoke — options, output shape, error handling, and more examples

Comparison: LuaJob vs Jobs API

Jobs API

Dynamic job creation

Agents API

Invoke another agent from a job

LuaAgent

Agent configuration

User API

Send messages

Data API

Store and retrieve data

See Also