Overview
The Jobs API allows you to dynamically create scheduled tasks from within your tools. Use this to defer work, schedule reminders, or automate recurring tasks.Automatic User Context: Dynamic jobs created from tools automatically know which user triggered them. Use
jobInstance.user() to get the user - no userId required! This is different from pre-defined LuaJob which requires User.get(userId).Dynamically create jobs at runtime from within your tools. Pairs with the LuaJob class for pre-defined jobs.
Import
Capabilities
Dynamic Creation
Create jobs on-demand from tools
One-time Tasks
Schedule tasks for specific times
Recurring Jobs
Set up intervals or cron patterns
Automatic User Context
Jobs automatically know which user triggered them - use
jobInstance.user()Jobs API vs LuaJob
Understanding user access in different job types:Why the difference? Dynamic jobs are created during a user conversation, so they automatically capture that user’s context. Pre-defined jobs run on a schedule with no specific user, so you must explicitly provide a userId if you want to notify someone.
Methods
Jobs.create(config)
Creates a new scheduled job.JobConfig
required
Job configuration object
Promise<JobInstance>
Example:
Jobs.getJob(jobId)
Retrieves a job by ID.string
required
Job ID to retrieve
Promise<JobInstance>
Example:
Jobs.getAll(options?)
Retrieves all jobs for the current agent.boolean
Include dynamically created jobs (default: false)
Promise<JobInstance[]>
Example:
Job Configuration
Required Fields
string
required
Unique job name
JobSchedule
required
When/how often to run the job
function
required
Function that executes when job runsSignature:
(job: JobInstance) => Promise<any>Optional Fields
string
Job description for documentation
object
Data to pass to execute functionImportant: Use metadata to pass data - the execute function cannot access parent scope!
number
Maximum execution time in secondsDefault: 300 (5 minutes)
object
Retry configuration
boolean
Whether to activate immediatelyDefault: true
Schedule Types
Once (One-time execution)
Interval (Recurring at fixed intervals)
Cron (Schedule with cron pattern)
Complete Examples
Reminder Tool
Follow-up Tool
Recurring Report
Important: Metadata Pattern
JobInstance Methods
TheJobInstance passed to execute functions provides:
Properties
jobInstance.user()
Gets the user who triggered the job. Returns:Promise<UserDataInstance>
Automatic User Context: This method is ONLY available for dynamic jobs created via
Jobs.create(). The user context is automatically captured when the job is created from a tool. Pre-defined LuaJob must use User.get(userId) instead.job.metadata
Access to the metadata passed during creation. Example:job.updateMetadata(data)
Updates job metadata. Example:job.trigger(versionId?)
Manually triggers the job execution (ignores schedule). Uses the active version by default. Parameters:versionId(optional): Specific version to execute. Defaults toactiveVersion.
Promise<JobExecution>
Example:
job.delete()
Deletes the job (or deactivates if it has versions). Example:job.activate()
Activates the job, enabling it to run on schedule. Returns:Promise<JobInstance>
Example:
job.deactivate()
Deactivates the job, preventing it from running on schedule. Useful for jobs that should stop themselves. Returns:Promise<JobInstance>
Example:
Retry Configuration
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 your retry configuration. 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 inmetadata or a record in Data).
- Retries happen only when an attempt fails, using your
maxAttemptsandbackoffSeconds. - The platform caps attempts at 10 regardless of config — a higher
maxAttemptsis clamped to 10.
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. TheoccurrenceId 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.Timeout Configuration
Best Practices
✅ Use Unique Names
✅ Use Unique Names
Give each job a descriptive, unique name
✅ Pass Data via Metadata
✅ Pass Data via Metadata
Always use metadata to pass data to execute function
✅ Handle Errors Gracefully
✅ Handle Errors Gracefully
Implement error handling in execute function
❌ Don't Access Parent Scope
❌ Don't Access Parent Scope
Execute functions are isolated - use metadata!
If a job isn’t behaving as expected, add Then check:
console.log statements and check execution logs:lua logs --type job --name my-job-name --limit 10. See the Debugging Skills guide for the full workflow.Related APIs
LuaJob
Pre-defined scheduled jobs
User API
Send messages from jobs
Data API
Store and retrieve data
LuaAgent
Agent configuration
Debugging Skills
Inspect runtime return values
See Also
- LuaJob Class - Pre-defined jobs
- Tool Examples
- Concepts: Workflows

