> ## Documentation Index
> Fetch the complete documentation index at: https://docs.bijection.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Scheduled turns

> Run an agent from a cron, a scheduled function or a webhook as a service the application declares.

A turn needs a caller whose authority it carries. A cron, a scheduled function
or a webhook has none, so the agent declares the [service](https://docs.bijection.com/access/access-model.md)
such a turn acts as, once:

```ts bijection/agents.ts theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
export const support = agents.define({
  model: models.language("support", { requires: ["tools"] }),
  instructions: "You are Skyline Air guest support. Answer briefly.",
  ...guest,
  service: "support",
});
```

```ts bijection/crons.ts theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
crons.daily(
  "digest",
  { hourUTC: 7, minuteUTC: 0 },
  internal.support.scheduleDigest,
  { prompt: "Summarize yesterday's cancellations." },
);
```

The application explicitly exports an internal mutation for the cron:

```ts bijection/support.ts theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
export const scheduleDigest = internalMutation({
  args: { prompt: v.string() },
  handler: (ctx, args) => support.scheduleMessage(ctx, args),
});
```

The library schedules its internal worker under the declared service and returns
the scheduled function ID. Current service grants authorize tools; a proposal
requiring personal review stays pending. The internal worker refuses a different
service identity. Personal sends use `sendMessage`; service scheduling requires
the agent's declared service and a live deployment credential.

The service is the one the [access model](https://docs.bijection.com/access/access-model.md) declares, with
its ceiling, and a person grants it roles as for any service. The deployment
acts as it only while an administrator's deployment credential for it is live:

```sh theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
bijection auth credential create support --kind deployment
```

Revoking that credential refuses scheduled turns at their next boundary. A
person's call never becomes the service's: scheduling as a service is refused
from a person's or another service's call.

The service is declared on the agent, not on each schedule, because it is the
agent's standing identity: every cron, timer and webhook that starts the agent
gets the same authority, and no internal caller can pick a more powerful one.

## How it works

The internal admission gate calls
`services.runAfter(0, "support", internal.agents.supportRun, args)` from
`bijection/runtime`. The application may schedule one of its own actions as a
service from a mutation, only when the caller is no person, delegate, issued
session or other service. The scheduled function records the service; when it
runs, the scheduler acts as the service itself, authenticated by its deployment
credential, and every boundary rechecks that credential as it rechecks any
service's. A [`_threads`](https://docs.bijection.com/agents/getting-started) document the turn opens has
the service's token identifier as its `owner`.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.