thyme/labs
Start building
Thyme Flow
Build and run Flow with your AI agent

Contracts that act on a schedule.

Write a TypeScript task that reads the chain and returns the calls to send, or describe the job and let your AI agent write it. Flow runs it on a cron, an interval or a webhook, sends the calls from a Safe you own, and handles the gas.

$ npm install -g @thyme-labs/cli
A simulated minute on PolygonThirty tick marks for the blocks in one minute, white marks where scheduled tasks fire, and green dots where their transactions were included.:00:3016:10:2195,734,710simulated block height
This minute, simulated. Ticks are Polygon blocks, white marks are scheduled triggers, and green dots are transactions that landed.
Illustrative run history · live clock, simulated transactions
ExecutableResult
sync-oracleIncluded in 95,734,707
harvest-rewardsIncluded in 95,734,701
sync-oracleIncluded in 95,734,692

From your editor to a block in four steps.

Your code decides whether to act and which calls to make. Flow handles the schedule, the signing and the gas. Every step also runs from the thyme CLI, so your AI agent can take them for you.

Follow the quickstart
functions/harvest-rewards/index.ts1 of 4
import { defineTask, z } from '@thyme-labs/sdk'
import { encodeFunctionData, parseAbi } from 'viem'

const abi = parseAbi([
  'function harvest()',
  'function pendingRewards() view returns (uint256)',
])

export default defineTask({
  schema: z.object({
    vault: z.address(),
    minRewards: z.coerce.bigint(),
  }),
  async run(ctx) {
    const { vault, minRewards } = ctx.args
    const pending = await ctx.client.readContract({
      address: vault, abi, functionName: 'pendingRewards',
    })

    // Skip this run: not worth the gas yet.
    if (pending < minRewards) {
      return { canExec: false, message: `${pending} pending` }
    }

    return {
      canExec: true,
      calls: [{
        to: vault,
        data: encodeFunctionData({ abi, functionName: 'harvest' }),
      }],
    }
  },
})

Run it on a clock, or on a call.

Every executable has one schedule. Webhooks and Execute now in the console fire extra runs without touching it.

Cron

0 */6 * * *

One day

Any standard cron expression. The console reads it back in plain words, so you can check "At minute 0 past every 6th hour" before you save.

Interval

every 30s

Six minutes

Pick a preset from 30 seconds to 24 hours or enter your own interval, with an optional start time. Useful for polling state that has no event to listen for.

Webhook

POST /hooks/…

Whenever you call it

Up to ten named, secret URLs per executable. Post an empty body to use the saved arguments, or a JSON body that replaces them for that run.

terminal
curl -X POST "$HARVEST_WEBHOOK_URL" \
  -H 'content-type: application/json' \
  -d '{ "vault": "0x8f3C…a21E", "minRewards": "5000000000000000000" }'

The body is checked against the same schema as your task's arguments. Fast runs answer with their result; slower ones return 202 and a URL to collect it from.

Reacting to an on-chain event? Poll for it on an interval and return canExec: false when there is nothing to do. Read about triggers.

The runtime

Read first. Send only when it makes sense.

A task is plain TypeScript. Check live chain state, use its saved arguments, then return the contract calls Flow should execute. A skipped run sends no transaction.

Explore the task context
one run / one decisionTypeScript
ctx.args

Typed inputs

Define a schema once. The console and webhooks validate arguments against it.

ctx.client

Chain reads

Read contract state inside your task before deciding which calls to return.

ctx.secrets

Project secrets

Attach only the values this executable needs, without adding them to your source.

canExec: falseNo call to send. Try again at the next trigger.

AI agents

Let AI write and run your functions.

Tell your agent what should happen on chain. It writes the task, tests it, ships it and keeps an eye on the runs. Set it up with one prompt in Claude Code, Codex, OpenCode, Cursor or any other AI coding agent.

prompt

Read https://flow.thymelabs.io/docs/skills/thyme-flow/SKILL.md and follow it to work with Thyme Flow in this project. If you support skills, save that file as a skill named thyme-flow so you can reuse it. Then check that the thyme CLI is installed and which deployment it points at, and tell me what you need me to approve.

Paste it into Claude Code, Codex, OpenCode, Cursor or any other agent.

The agent signs in through a pairing login you approve in your browser. Your wallet stays with you: creating a Safe profile, or widening what it may call, is still signed by you in the console.

Generate the task

Describe the job in plain words. The agent scaffolds a task, writes the chain reads and the calls, and declares the calls it may send.

Harvest my vault every hour once pending rewards pass 10 USDC.

Test it on live state

It runs the task locally against a real RPC and simulates the calls before anything goes live.

Run it against Polygon and show me what it would send.

Ship and operate

It uploads a version, creates the executable, sets the schedule, binds secrets, and reads run logs.

Why did the last run fail? Fix it and upload a new version.

Run history

See what happened after the clock fired.

Each execution has a status and a record in the console. Follow it from trigger to transaction, or inspect why it skipped or failed.

  1. 01

    Triggered

    A schedule, webhook or manual run starts the executable.

  2. 02

    Evaluated

    The task reads the chain and either skips or returns calls.

  3. 03

    Submitted

    Flow sends the approved calls using the selected profile.

  4. 04

    Confirmed

    The run records its receipt, transaction hash and outcome.

Skipped and failed runs end before confirmation and remain visible in run history.

The account stays in your hands.

Give Flow permission to execute the calls your task returns. Keep ownership and the ability to remove that permission.

Read about profiles

Permission map

Who controls the account

Flow can submit calls within the permissions set on your Safe. Your wallet remains its owner.Diagram preview only.

Your Safe stays yours

Your wallet owns the Safe. Flow receives a scoped executor role for the calls you allow. You can revoke that role from the Safe.

Inspect before signing

During profile setup, the console checks deployed contract code against pinned hashes before it asks for your signature.

Secrets stay out of your bundle

Bind project secrets in the console. Flow passes their values to the runtime when the executable runs.

Networks

Same task. Any of these chains.

A profile belongs to one chain, so create one per network you automate. The task, the triggers and the API are the same everywhere, and mainnet gas is sponsored on every chain below.

Chain details in the docs

Arc

New

Gas paid in USDC · sub-second finality

5042

Polygon

Mainnet

137

Optimism

Mainnet

10

BNB Smart Chain

Mainnet

56

Base

Mainnet

8453

Arbitrum One

Mainnet

42161

Testnets

  • Ethereum Sepolia
  • Polygon Amoy
  • Unichain Sepolia

Testnet gas is free. Arc Testnet is coming shortly.

Pricing

Start on testnet. Grow into mainnet.

Choose a plan for your workspace. Paid plans add capacity, mainnet access and metered usage above the included compute units.

Free

$0 / mo

Try scheduled work on testnets.

  • 60,000 compute units / month
  • 3 executables
  • 3 function uploads
  • Free testnet gas
Choose Free

Pro

$29 / mo

Put recurring work into production.

  • 600,000 compute units / month
  • 20 executables
  • 25 free RPC requests / execution
  • $1.00 / M CU above the allowance
Choose Pro

Ultimate

$149 / mo

Room for higher volume execution.

  • 6,000,000 compute units / month
  • 100 executables
  • 100 free RPC requests / execution
  • Unlimited function uploads
Choose Ultimate

Free is testnet only. Mainnet gas is charged separately; plan limits and current pricing are shown in the console before you subscribe.

Start here

Write the taskSet the time

terminal
$ npm install -g @thyme-labs/cli

Make your first scheduled executable in the console, work through the quickstart from your editor, or hand the job to your AI agent with one prompt.

Moving from Gelato Web3 Functions, Chainlink Automation or Mimic Protocol? Follow a migration guide.