Schedules

Create platform-managed cron jobs with HTTP and sandbox destinations

Use schedules when timing should live in Agentuity instead of inside your app process. The platform validates the cron expression, computes the next run, fires the schedule on time, and records each delivery attempt. Start with ScheduleClient; Hono apps can use c.var.schedule after installing the Agentuity middleware.

npm install @agentuity/schedule
import { ScheduleClient } from '@agentuity/schedule';
 
const schedules = new ScheduleClient();
 
export async function createDailySync(targetUrl: string): Promise<string> {
  const { schedule } = await schedules.create({
    name: 'Daily customer sync',
    description: 'Calls the sync endpoint every weekday at 9am',
    expression: '0 9 * * 1-5',
    destinations: [
      {
        type: 'url',
        config: {
          url: targetUrl,
          method: 'POST',
        },
      },
    ],
  });
 
  return schedule.id;
}

ScheduleClient reads AGENTUITY_SDK_KEY, then AGENTUITY_CLI_KEY, from the environment. Keep that key in .env for local development and configure the same variable for deployed apps.

When to use schedules

NeedUse
recurring delivery with history and retriesSchedules
event-driven async workQueues
inbound HTTP events with receiptsWebhooks
isolated command executionSandbox

Client Setup

Construct the client once at module scope and reuse it from handlers, routes, or scripts.

import { ScheduleClient } from '@agentuity/schedule';
 
const schedules = new ScheduleClient({
  orgId: process.env.AGENTUITY_CLOUD_ORG_ID,
});
OptionDescription
apiKeyOptional API key. Defaults to AGENTUITY_SDK_KEY, then AGENTUITY_CLI_KEY.
orgIdOptional organization ID. Used when the API key is org-scoped or when calling from a CLI context.
urlOptional Schedule API URL. Defaults to AGENTUITY_SCHEDULE_URL, then the regional Agentuity service URL.
loggerOptional logger instance.

Create a Schedule

create() requires a name and a five-field cron expression. Destinations are optional but most schedules pass at least one. Destinations are created atomically with the schedule, so a bad URL fails the whole call.

const result = await schedules.create({
  name: 'Hourly inventory refresh',
  expression: '0 * * * *',
  destinations: [
    {
      type: 'url',
      config: {
        url: 'https://api.example.com/inventory/refresh',
        method: 'POST',
        headers: {
          'X-Schedule-Source': 'agentuity',
        },
      },
    },
  ],
});
 
const nextRun = result.schedule.due_date;
FieldRequiredDescription
nameYesHuman-readable schedule name.
expressionYesStandard five-field cron expression.
descriptionNoOptional purpose or owner note.
destinationsNoArray of destinations to create with the schedule.

Cron Expressions

ExpressionFires
* * * * *Every minute.
*/5 * * * *Every 5 minutes.
0 * * * *Every hour, on the hour.
0 0 * * *Daily at midnight.
0 9 * * 1-5Weekdays at 9am.
0 0 * * 1Mondays at midnight.
0 0 1 * *The 1st of each month at midnight.

The service validates cron expressions on create and update, then computes due_date for the next run. Times are evaluated in UTC.

Destination Types

Each schedule can have multiple destinations. When the schedule fires, Agentuity creates one delivery record per destination.

TypeConfigUse
url{ url, method?, headers?, timeout? }Send an HTTP request to a public endpoint.
sandbox{ sandbox_id }Trigger an Agentuity sandbox. The sandbox ID must start with sbx_.

Add a destination after the schedule exists:

const { destination } = await schedules.createDestination(result.schedule.id, {
  type: 'url',
  config: {
    url: 'https://api.example.com/reports/daily',
    method: 'POST',
  },
});

List and Update

Use list() for dashboards or admin tools, get() for a schedule and its destinations, and update() to change the name, description, or cron expression.

const { schedules: page, total } = await schedules.list({ limit: 20, offset: 0 });
 
const { schedule, destinations } = await schedules.get(result.schedule.id);
 
const { schedule: updated } = await schedules.update(schedule.id, {
  expression: '0 6 * * 1-5',
});

Changing expression recomputes due_date immediately. The new value applies from the next firing onward.

Delivery Tracking

Use listDeliveries() to inspect recent delivery attempts for a schedule.

const { deliveries } = await schedules.listDeliveries(result.schedule.id, {
  limit: 50,
  offset: 0,
});
 
const failures = deliveries.filter((d) => d.status === 'failed');
StatusMeaning
pendingDelivery is queued for the destination.
successThe destination accepted the scheduled request.
failedDelivery failed. The error field carries the reason when available.

Each delivery record includes the schedule ID, destination ID, retry count, optional error message, and optional response payload. Failed deliveries are retried automatically inside Agentuity.

Manage Schedules from a Server Route

The same client works inside a framework route, so an admin UI can create or list schedules without standing up a separate service.

typescriptsrc/routes/schedules.ts
import { Hono } from 'hono';
import { agentuity } from '@agentuity/hono';
import type { Services } from '@agentuity/hono';
 
type Variables = Pick<Services, 'schedule'>;
 
const app = new Hono<{ Variables: Variables }>();
 
app.use('*', agentuity());
 
app.post('/schedules/daily-sync', async (c) => {
  const body = await c.req.json<{ url: string }>();
 
  const { schedule } = await c.var.schedule.create({
    name: 'Daily sync',
    expression: '0 9 * * *',
    destinations: [{ type: 'url', config: { url: body.url, method: 'POST' } }],
  });
 
  return c.json({ scheduleId: schedule.id, nextRun: schedule.due_date }, 201);
});
 
app.get('/schedules/:id/deliveries', async (c) => {
  const { deliveries } = await c.var.schedule.listDeliveries(c.req.param('id'), { limit: 50 });
  return c.json({ deliveries });
});
 
export default app;

Delete

Delete a destination when the schedule should keep running but stop calling one target. Delete the schedule when the job is no longer needed.

await schedules.deleteDestination(destination.id);
await schedules.delete(result.schedule.id);

Next Steps

  • Queues: pass scheduled work into a queue for fan-out or retries
  • Webhooks: receive external callbacks with receipts and delivery tracking
  • Sandbox: run scheduled commands in isolated environments
  • Using Standalone Packages: configure service clients outside Agentuity projects
  • Schedules API Reference: inspect REST fields and delivery response shapes