# Scheduler

OpenAPI spec: [https://api.payweave.app/app/app_okelkytzwl127o1m5yz8m3c6/openapi.json](https://api.payweave.app/app/app_okelkytzwl127o1m5yz8m3c6/openapi.json)

## Networks

| Name | Mode | CAIP-2 | Chain ID / Cluster |
|---|---|---|---|
| Tempo Mainnet | live | `eip155:4217` | 4217 |
| Solana Mainnet | live | `solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp` | mainnet-beta |

## Accepted Currencies

| Symbol | Name | Decimals | Network | Address |
|---|---|---|---|---|
| USDC.e | Bridged USDC (Stargate) | 6 | `eip155:4217` | `0x20c000000000000000000000b9537d11c60e8b50` |
| USDC | USD Coin (Solana) | 6 | `solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp` | `EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v` |

## Endpoints (4)

### Scheduler: List Schedules

List the schedules owned by the calling wallet, each with id, label, status, and next run time. Returns up to 100.

- Method: GET
- Path: `/schedules`
- Price: $0.00100000

**Output Schema**

```json
{
  "type": "object",
  "properties": {
    "schedules": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "label": {
            "type": "string"
          },
          "status": {
            "type": "string"
          },
          "nextRunAt": {
            "type": [
              "number",
              "null"
            ]
          },
          "createdAt": {
            "type": "number"
          }
        },
        "required": [
          "id",
          "status",
          "nextRunAt",
          "createdAt"
        ],
        "additionalProperties": false
      }
    }
  },
  "required": [
    "schedules"
  ],
  "additionalProperties": false
}
```

## How to invoke

Payment is handled automatically — the client signs the 402 challenge and retries.

### TypeScript — Tempo (mppx + fetch) ([docs](https://mpp.dev/sdk/typescript/client))

```ts
import { privateKeyToAccount } from 'viem/accounts'
import { Mppx, tempo } from 'mppx/client'

Mppx.create({
  methods: [tempo({ account: privateKeyToAccount('0x...') })],
})

const res = await fetch('https://scheduler.payweave.services/schedules')
const data = await res.json()
```

### TypeScript — Solana (@solana/mpp + fetch) ([docs](https://github.com/solana-foundation/mpp-sdk))

```ts
import { createKeyPairSignerFromBytes } from '@solana/kit'
import { Mppx } from 'mppx/client'
import { solana } from '@solana/mpp/client'

const signer = await createKeyPairSignerFromBytes(/* 64-byte secret key */)
Mppx.create({ methods: [solana({ signer })] })

const res = await fetch('https://scheduler.payweave.services/schedules')
const data = await res.json()
```

### mppx CLI ([docs](https://mpp.dev/sdk/typescript/cli))

```sh
npx mppx "https://scheduler.payweave.services/schedules"
```

### Tempo Wallet ([docs](https://docs.tempo.xyz/cli/wallet))

```sh
tempo request "https://scheduler.payweave.services/schedules"
```

### pay.sh — Solana Foundation ([docs](https://pay.sh))

```sh
pay --mainnet curl "https://scheduler.payweave.services/schedules"
```

### Scheduler: Create Schedule

Schedule an HTTPS callback to fire once (`at` / `delaySeconds`) or on a bounded recurring cadence (`everySeconds` + `maxRuns`). Deliveries are signed (HMAC over timestamp + body using the returned `signingSecret`) and retried with backoff. Priced per fire ($0.002): one-shot = $0.002, recurring = $0.002 x maxRuns (prepaid; cancelling early forfeits unused fires).

- Method: POST
- Path: `/schedules`
- Price: $0.00200000

**Input Schema**

```json
{
  "type": "object",
  "properties": {
    "callbackUrl": {
      "type": "string",
      "description": "HTTPS URL to POST when the schedule fires. Must be public (no private/internal IPs)."
    },
    "at": {
      "type": [
        "string",
        "number"
      ],
      "description": "One-shot fire time: ISO 8601 string or epoch ms. Must be future, within 90 days."
    },
    "delaySeconds": {
      "type": "integer",
      "exclusiveMinimum": 0,
      "description": "One-shot: fire once after N seconds."
    },
    "everySeconds": {
      "type": "integer",
      "description": "Recurring interval in seconds (min 60). Requires maxRuns."
    },
    "maxRuns": {
      "type": "integer",
      "description": "Recurring: total number of fires (1..1000). Requires everySeconds."
    },
    "payload": {
      "description": "Optional JSON body delivered to callbackUrl on each fire."
    },
    "headers": {
      "type": "object",
      "additionalProperties": {
        "type": "string"
      },
      "description": "Optional extra request headers (reserved/sensitive headers are stripped)."
    },
    "label": {
      "type": "string",
      "minLength": 1,
      "maxLength": 128,
      "description": "Short purpose label. Returned on info/list."
    },
    "metadata": {
      "type": "object",
      "additionalProperties": {},
      "description": "Arbitrary small JSON object describing the schedule. Returned on info/list."
    }
  },
  "required": [
    "callbackUrl"
  ],
  "additionalProperties": false
}
```

**Output Schema**

```json
{
  "type": "object",
  "properties": {
    "id": {
      "type": "string"
    },
    "status": {
      "type": "string"
    },
    "kind": {
      "type": "string"
    },
    "nextRunAt": {
      "type": [
        "number",
        "null"
      ]
    },
    "runsRemaining": {
      "type": "number"
    },
    "signingSecret": {
      "type": "string"
    },
    "label": {
      "type": "string"
    },
    "metadata": {
      "type": "object",
      "additionalProperties": {}
    }
  },
  "required": [
    "id",
    "status",
    "kind",
    "nextRunAt",
    "runsRemaining",
    "signingSecret"
  ],
  "additionalProperties": false
}
```

## How to invoke

Payment is handled automatically — the client signs the 402 challenge and retries.

### TypeScript — Tempo (mppx + fetch) ([docs](https://mpp.dev/sdk/typescript/client))

```ts
import { privateKeyToAccount } from 'viem/accounts'
import { Mppx, tempo } from 'mppx/client'

Mppx.create({
  methods: [tempo({ account: privateKeyToAccount('0x...') })],
})

const res = await fetch('https://scheduler.payweave.services/schedules', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    "callbackUrl": "",
    "at": "",
    "delaySeconds": 0
  }),
})
const data = await res.json()
```

### TypeScript — Solana (@solana/mpp + fetch) ([docs](https://github.com/solana-foundation/mpp-sdk))

```ts
import { createKeyPairSignerFromBytes } from '@solana/kit'
import { Mppx } from 'mppx/client'
import { solana } from '@solana/mpp/client'

const signer = await createKeyPairSignerFromBytes(/* 64-byte secret key */)
Mppx.create({ methods: [solana({ signer })] })

const res = await fetch('https://scheduler.payweave.services/schedules', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    "callbackUrl": "",
    "at": "",
    "delaySeconds": 0
  }),
})
const data = await res.json()
```

### mppx CLI ([docs](https://mpp.dev/sdk/typescript/cli))

```sh
npx mppx "https://scheduler.payweave.services/schedules" -X POST -H 'Content-Type: application/json' -d '{"callbackUrl":"","at":"","delaySeconds":0}'
```

### Tempo Wallet ([docs](https://docs.tempo.xyz/cli/wallet))

```sh
tempo request "https://scheduler.payweave.services/schedules" -X POST --json '{"callbackUrl":"","at":"","delaySeconds":0}'
```

### pay.sh — Solana Foundation ([docs](https://pay.sh))

```sh
pay --mainnet curl "https://scheduler.payweave.services/schedules" -X POST -H 'Content-Type: application/json' -d '{"callbackUrl":"","at":"","delaySeconds":0}'
```

### Scheduler: Cancel Schedule

Cancel a schedule and stop future fires. Owner-scoped. Prepaid recurring fires that have not run are forfeited (refunds are full-only).

- Method: DELETE
- Path: `/schedules/:id`
- Price: $0.00050000

## How to invoke

Payment is handled automatically — the client signs the 402 challenge and retries.

### TypeScript — Tempo (mppx + fetch) ([docs](https://mpp.dev/sdk/typescript/client))

```ts
import { privateKeyToAccount } from 'viem/accounts'
import { Mppx, tempo } from 'mppx/client'

Mppx.create({
  methods: [tempo({ account: privateKeyToAccount('0x...') })],
})

const res = await fetch('https://scheduler.payweave.services/schedules/:id', {
  method: 'DELETE',
})
const data = await res.json()
```

### TypeScript — Solana (@solana/mpp + fetch) ([docs](https://github.com/solana-foundation/mpp-sdk))

```ts
import { createKeyPairSignerFromBytes } from '@solana/kit'
import { Mppx } from 'mppx/client'
import { solana } from '@solana/mpp/client'

const signer = await createKeyPairSignerFromBytes(/* 64-byte secret key */)
Mppx.create({ methods: [solana({ signer })] })

const res = await fetch('https://scheduler.payweave.services/schedules/:id', {
  method: 'DELETE',
})
const data = await res.json()
```

### mppx CLI ([docs](https://mpp.dev/sdk/typescript/cli))

```sh
npx mppx "https://scheduler.payweave.services/schedules/:id" -X DELETE
```

### Tempo Wallet ([docs](https://docs.tempo.xyz/cli/wallet))

```sh
tempo request "https://scheduler.payweave.services/schedules/:id" -X DELETE
```

### pay.sh — Solana Foundation ([docs](https://pay.sh))

```sh
pay --mainnet curl "https://scheduler.payweave.services/schedules/:id" -X DELETE
```

### Scheduler: Schedule Info

Get a schedule status, next/last run, run count, runs remaining, label/metadata, and recent delivery history. Owner-scoped.

- Method: GET
- Path: `/schedules/:id`
- Price: $0.00050000

**Output Schema**

```json
{
  "type": "object",
  "properties": {
    "id": {
      "type": "string"
    },
    "kind": {
      "type": "string"
    },
    "status": {
      "type": "string"
    },
    "createdAt": {
      "type": "number"
    },
    "nextRunAt": {
      "type": [
        "number",
        "null"
      ]
    },
    "lastRunAt": {
      "type": [
        "number",
        "null"
      ]
    },
    "runCount": {
      "type": "number"
    },
    "runsRemaining": {
      "type": "number"
    },
    "runs": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "firedAt": {
            "type": "number"
          },
          "ok": {
            "type": "boolean"
          },
          "httpStatus": {
            "type": [
              "number",
              "null"
            ]
          },
          "attempts": {
            "type": "number"
          },
          "error": {
            "type": "string"
          }
        },
        "required": [
          "firedAt",
          "ok",
          "httpStatus",
          "attempts"
        ],
        "additionalProperties": false
      }
    },
    "label": {
      "type": "string"
    },
    "metadata": {
      "type": "object",
      "additionalProperties": {}
    }
  },
  "required": [
    "id",
    "kind",
    "status",
    "createdAt",
    "nextRunAt",
    "lastRunAt",
    "runCount",
    "runsRemaining",
    "runs"
  ],
  "additionalProperties": false
}
```

## How to invoke

Payment is handled automatically — the client signs the 402 challenge and retries.

### TypeScript — Tempo (mppx + fetch) ([docs](https://mpp.dev/sdk/typescript/client))

```ts
import { privateKeyToAccount } from 'viem/accounts'
import { Mppx, tempo } from 'mppx/client'

Mppx.create({
  methods: [tempo({ account: privateKeyToAccount('0x...') })],
})

const res = await fetch('https://scheduler.payweave.services/schedules/:id')
const data = await res.json()
```

### TypeScript — Solana (@solana/mpp + fetch) ([docs](https://github.com/solana-foundation/mpp-sdk))

```ts
import { createKeyPairSignerFromBytes } from '@solana/kit'
import { Mppx } from 'mppx/client'
import { solana } from '@solana/mpp/client'

const signer = await createKeyPairSignerFromBytes(/* 64-byte secret key */)
Mppx.create({ methods: [solana({ signer })] })

const res = await fetch('https://scheduler.payweave.services/schedules/:id')
const data = await res.json()
```

### mppx CLI ([docs](https://mpp.dev/sdk/typescript/cli))

```sh
npx mppx "https://scheduler.payweave.services/schedules/:id"
```

### Tempo Wallet ([docs](https://docs.tempo.xyz/cli/wallet))

```sh
tempo request "https://scheduler.payweave.services/schedules/:id"
```

### pay.sh — Solana Foundation ([docs](https://pay.sh))

```sh
pay --mainnet curl "https://scheduler.payweave.services/schedules/:id"
```
