# Create a schedule

`POST /accounts/{accountID}/schedules`

API version: `v2026.07.00`. Send `X-Moov-Version: v2026.07.00` to get the behavior described here.

> AI agents: search and read all Moov docs with the docs MCP server at https://docs.moov.io/mcp (no API key). Setup: https://docs.moov.io/guides/developer-tools/mcp-ai/docs-mcp/index.md

Describes the schedule to create or modify.

To access this endpoint using an [access token](https://docs.moov.io/api/authentication/access-tokens/) 
you'll need to specify the `/accounts/{accountID}/transfers.write` scope.

## Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `X-Moov-Version` | header | string |  | Set this header to v2026.07.00 to use the API described in this specification. When omitted, the server defaults to v2024.01.00, the earliest supported version, which may not match the behavior documented here. An unrecognized well-formed version uses the latest supported version that is not newer than the requested version, when one exists. For example, `v2026.08.00` uses `v2026.07.00`. A malformed value, such as `2022`, returns a `404` response. Values: `v2026.07.00`. |
| `accountID` | path | string | Yes | Account ID of the account that will run the transfer. |

## Request body

Content type: `application/json`

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `description` | string |  | Simple description of what the schedule is. |
| `occurrences` | array of object |  |  |
| `occurrences[].canceled` | boolean |  | If set to true, will cancel the occurrence. If set false will resume the occurrence. If unset leaves the value unchanged. |
| `occurrences[].occurrenceID` | string |  | If set this defines what occurrence to modify, if invalid will fail the request. If null or "" it defines to add a new occurrence. |
| `occurrences[].runOn` | string (date-time) |  | Timestamp to run the transfer after. Value must be into the future. |
| `occurrences[].runTransfer` | object |  | Defines the attributes of a transfer. |
| `occurrences[].runTransfer.amount` | object | Yes |  |
| `occurrences[].runTransfer.amount.currency` | string | Yes | A 3-letter ISO 4217 currency code. |
| `occurrences[].runTransfer.amount.value` | integer (int64) | Yes | Quantity in the smallest unit of the specified currency. In USD this is cents, for example, $12.04 is 1204 and $0.99 is 99. |
| `occurrences[].runTransfer.salesTaxAmount` | object |  | Optional sales tax amount. This amount is included in the total transfer amount. |
| `occurrences[].runTransfer.salesTaxAmount.currency` | string | Yes | A 3-letter ISO 4217 currency code. |
| `occurrences[].runTransfer.salesTaxAmount.value` | integer (int64) | Yes | Quantity in the smallest unit of the specified currency. In USD this is cents, for example, $12.04 is 1204 and $0.99 is 99. |
| `occurrences[].runTransfer.destination` | object | Yes |  |
| `occurrences[].runTransfer.destination.paymentMethodID` | string | Yes |  |
| `occurrences[].runTransfer.destination.achDetails` | object |  |  |
| `occurrences[].runTransfer.destination.achDetails.companyEntryDescription` | string |  | An optional override of the default NACHA company entry description for a transfer. |
| `occurrences[].runTransfer.destination.achDetails.originatingCompanyName` | string |  | An optional override of the default NACHA company name for a transfer. |
| `occurrences[].runTransfer.destination.cardDetails` | object |  |  |
| `occurrences[].runTransfer.destination.cardDetails.dynamicDescriptor` | string |  | An optional override of the default card statement descriptor for a transfer. Accounts must be enabled by Moov to set this field. |
| `occurrences[].runTransfer.partnerAccountID` | string | Yes |  |
| `occurrences[].runTransfer.source` | object | Yes |  |
| `occurrences[].runTransfer.source.paymentMethodID` | string | Yes |  |
| `occurrences[].runTransfer.source.achDetails` | object |  |  |
| `occurrences[].runTransfer.source.achDetails.companyEntryDescription` | string |  | An optional override of the default NACHA company entry description for a transfer. |
| `occurrences[].runTransfer.source.achDetails.originatingCompanyName` | string |  | An optional override of the default NACHA company name for a transfer. |
| `occurrences[].runTransfer.source.cardDetails` | object |  |  |
| `occurrences[].runTransfer.source.cardDetails.dynamicDescriptor` | string |  | An optional override of the default card statement descriptor for a transfer. Accounts must be enabled by Moov to set this field. |
| `occurrences[].runTransfer.description` | string | Yes | Simple description to place on the transfer. |
| `occurrences[].runTransfer.lineItems` | object |  | An optional collection of line items for a scheduled transfer. When line items are provided their total must equal `amount` minus `salesTaxAmount`. |
| `occurrences[].runTransfer.lineItems.items` | array of object | Yes | The list of line items. |
| `occurrences[].runTransfer.lineItems.items[].name` | string | Yes | The name of the item. |
| `occurrences[].runTransfer.lineItems.items[].basePrice` | object | Yes | The base price of the item before applying option modifiers. |
| `occurrences[].runTransfer.lineItems.items[].quantity` | integer (int32) | Yes | The quantity of this item. |
| `occurrences[].runTransfer.lineItems.items[].options` | array of object |  | Optional list of modifiers applied to this item (e.g., toppings, upgrades, customizations). |
| `occurrences[].runTransfer.lineItems.items[].productID` | string |  | Optional unique identifier associating the line item with a product. This is for reporting or tracking purposes, and does not populate other details of the line item. |
| `occurrences[].runTransfer.lineItems.items[].imageIDs` | array of string |  | Optional list of images associated with this line item. This field is being deprecated in favor using the images associated with a productID and will soon be unsupported. |
| `recur` | object |  | Defines configuration for recurring transfers. |
| `recur.recurrenceRule` | string | Yes | RRule as defined by RFC 5545 (https://www.rfc-editor.org/rfc/rfc5545#section-3.3.10). Generators available online at the following sites - https://freetools.textmagic.com/rrule-generator, https://jkbrzt.github.io/rrule/ |
| `recur.runTransfer` | object | Yes | Defines the attributes of a transfer. |
| `recur.runTransfer.amount` | object | Yes |  |
| `recur.runTransfer.amount.currency` | string | Yes | A 3-letter ISO 4217 currency code. |
| `recur.runTransfer.amount.value` | integer (int64) | Yes | Quantity in the smallest unit of the specified currency. In USD this is cents, for example, $12.04 is 1204 and $0.99 is 99. |
| `recur.runTransfer.salesTaxAmount` | object |  | Optional sales tax amount. This amount is included in the total transfer amount. |
| `recur.runTransfer.salesTaxAmount.currency` | string | Yes | A 3-letter ISO 4217 currency code. |
| `recur.runTransfer.salesTaxAmount.value` | integer (int64) | Yes | Quantity in the smallest unit of the specified currency. In USD this is cents, for example, $12.04 is 1204 and $0.99 is 99. |
| `recur.runTransfer.destination` | object | Yes |  |
| `recur.runTransfer.destination.paymentMethodID` | string | Yes |  |
| `recur.runTransfer.destination.achDetails` | object |  |  |
| `recur.runTransfer.destination.achDetails.companyEntryDescription` | string |  | An optional override of the default NACHA company entry description for a transfer. |
| `recur.runTransfer.destination.achDetails.originatingCompanyName` | string |  | An optional override of the default NACHA company name for a transfer. |
| `recur.runTransfer.destination.cardDetails` | object |  |  |
| `recur.runTransfer.destination.cardDetails.dynamicDescriptor` | string |  | An optional override of the default card statement descriptor for a transfer. Accounts must be enabled by Moov to set this field. |
| `recur.runTransfer.partnerAccountID` | string | Yes |  |
| `recur.runTransfer.source` | object | Yes |  |
| `recur.runTransfer.source.paymentMethodID` | string | Yes |  |
| `recur.runTransfer.source.achDetails` | object |  |  |
| `recur.runTransfer.source.achDetails.companyEntryDescription` | string |  | An optional override of the default NACHA company entry description for a transfer. |
| `recur.runTransfer.source.achDetails.originatingCompanyName` | string |  | An optional override of the default NACHA company name for a transfer. |
| `recur.runTransfer.source.cardDetails` | object |  |  |
| `recur.runTransfer.source.cardDetails.dynamicDescriptor` | string |  | An optional override of the default card statement descriptor for a transfer. Accounts must be enabled by Moov to set this field. |
| `recur.runTransfer.description` | string | Yes | Simple description to place on the transfer. |
| `recur.runTransfer.lineItems` | object |  | An optional collection of line items for a scheduled transfer. When line items are provided their total must equal `amount` minus `salesTaxAmount`. |
| `recur.runTransfer.lineItems.items` | array of object | Yes | The list of line items. |
| `recur.runTransfer.lineItems.items[].name` | string | Yes | The name of the item. |
| `recur.runTransfer.lineItems.items[].basePrice` | object | Yes | The base price of the item before applying option modifiers. |
| `recur.runTransfer.lineItems.items[].quantity` | integer (int32) | Yes | The quantity of this item. |
| `recur.runTransfer.lineItems.items[].options` | array of object |  | Optional list of modifiers applied to this item (e.g., toppings, upgrades, customizations). |
| `recur.runTransfer.lineItems.items[].productID` | string |  | Optional unique identifier associating the line item with a product. This is for reporting or tracking purposes, and does not populate other details of the line item. |
| `recur.runTransfer.lineItems.items[].imageIDs` | array of string |  | Optional list of images associated with this line item. This field is being deprecated in favor using the images associated with a productID and will soon be unsupported. |
| `recur.indefinite` | boolean |  | True if the RRule set runs indefinitely. |
| `recur.start` | string (date-time) |  |  |

## Response 200

The request completed successfully.

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `description` | string |  | Simple description to place on the transfer. |
| `destinationAccountID` | string | Yes |  |
| `mode` | string | Yes | The operating mode for an account. Values: `sandbox`, `production`. |
| `occurrences` | array of object |  |  |
| `occurrences[].scheduleID` | string |  |  |
| `occurrences[].occurrenceID` | string |  |  |
| `occurrences[].mode` | string |  | Sandbox or production account mode of this schedule. Values: `sandbox`, `production`. |
| `occurrences[].generated` | boolean |  | True if this was generated by a RRule. |
| `occurrences[].indefinite` | boolean |  | True if the RRule set runs indefinitely. |
| `occurrences[].canceledOn` | string (date-time) |  |  |
| `occurrences[].runOn` | string (date-time) | Yes |  |
| `occurrences[].runTransfer` | object | Yes |  |
| `occurrences[].ranOn` | string (date-time) |  |  |
| `occurrences[].ranTransferID` | string |  |  |
| `occurrences[].status` | string |  | Status of the completed occurrence. Values: `pending`, `failed`, `completed`. |
| `occurrences[].error` | object |  | Contains details on why the occurrence errored. |
| `ownerAccountID` | string | Yes |  |
| `partnerAccountID` | string | Yes |  |
| `recur` | object |  |  |
| `recur.recurrenceRule` | string | Yes | RRule as defined by RFC 5545 (https://www.rfc-editor.org/rfc/rfc5545#section-3.3.10). Generators available online at the following sites - https://freetools.textmagic.com/rrule-generator, https://jkbrzt.github.io/rrule/ |
| `recur.runTransfer` | object | Yes |  |
| `recur.indefinite` | boolean |  | True if the RRule set runs indefinitely. |
| `recur.start` | string (date-time) |  |  |
| `scheduleID` | string | Yes |  |
| `sourceAccountID` | string | Yes |  |
| `createdOn` | string (date-time) | Yes |  |
| `updatedOn` | string (date-time) | Yes |  |
| `disabledOn` | string (date-time) |  |  |

## Errors

| Status | Meaning |
| --- | --- |
| 400 | The server could not understand the request due to invalid syntax. |
| 401 | The request contained missing or expired authentication. |
| 403 | The user is not authorized to make the request. |
| 404 | The requested resource was not found. |
| 409 | The request conflicted with the current state of the target resource. |
| 422 | The request was well-formed, but the contents failed validation. Check the request for missing or invalid fields. |
| 429 | Request was refused due to rate limiting. |
| 500 | The request failed due to an unexpected error. |
| 504 | The request failed because a downstream service failed to respond. |

## Examples

### cURL

```bash
curl -X POST "https://api.moov.io/accounts/{accountID}/schedules" \
  -H "Authorization: Bearer {token}" \
  -H "X-Moov-Version: v2026.07.00"
```

### Typescript (SDK)

```typescript
import { Moov } from "@moovio/sdk";

const moov = new Moov({
  security: {
    username: "",
    password: "",
  },
});

async function run() {
  const result = await moov.scheduling.create({
    accountID: "38fd6ae1-0e70-4162-9359-d64482d61854",
    upsertSchedule: {
      occurrences: [
        {
          occurrenceID: "c520f1b9-0ba7-42f5-b977-248cdbe41c69",
          runOn: new Date("2009-11-10T23:00:00Z"),
          runTransfer: {
            amount: {
              currency: "USD",
              value: 1204,
            },
            destination: {
              paymentMethodID: "c520f1b9-0ba7-42f5-b977-248cdbe41c69",
              achDetails: {
                companyEntryDescription: "Gym dues",
                originatingCompanyName: "Whole Body Fit",
              },
              cardDetails: {
                dynamicDescriptor: "WhlBdy *Yoga 11-12",
              },
            },
            partnerAccountID: "c520f1b9-0ba7-42f5-b977-248cdbe41c69",
            source: {
              paymentMethodID: "c520f1b9-0ba7-42f5-b977-248cdbe41c69",
              achDetails: {
                companyEntryDescription: "Gym dues",
                originatingCompanyName: "Whole Body Fit",
              },
              cardDetails: {
                dynamicDescriptor: "WhlBdy *Yoga 11-12",
              },
            },
            description: "sediment yahoo a rudely mmm massive helpful brr",
          },
        },
        {
          occurrenceID: "c520f1b9-0ba7-42f5-b977-248cdbe41c69",
          runOn: new Date("2009-11-10T23:00:00Z"),
          runTransfer: {
            amount: {
              currency: "USD",
              value: 1204,
            },
            destination: {
              paymentMethodID: "c520f1b9-0ba7-42f5-b977-248cdbe41c69",
              achDetails: {
                companyEntryDescription: "Gym dues",
                originatingCompanyName: "Whole Body Fit",
              },
              cardDetails: {
                dynamicDescriptor: "WhlBdy *Yoga 11-12",
              },
            },
            partnerAccountID: "c520f1b9-0ba7-42f5-b977-248cdbe41c69",
            source: {
              paymentMethodID: "c520f1b9-0ba7-42f5-b977-248cdbe41c69",
              achDetails: {
                companyEntryDescription: "Gym dues",
                originatingCompanyName: "Whole Body Fit",
              },
              cardDetails: {
                dynamicDescriptor: "WhlBdy *Yoga 11-12",
              },
            },
            description: "sediment yahoo a rudely mmm massive helpful brr",
          },
        },
      ],
      recur: {
        recurrenceRule: "<value>",
        runTransfer: {
          amount: {
            currency: "USD",
            value: 1204,
          },
          salesTaxAmount: {
            currency: "USD",
            value: 1204,
          },
          destination: {
            paymentMethodID: "c520f1b9-0ba7-42f5-b977-248cdbe41c69",
            achDetails: {
              companyEntryDescription: "Gym dues",
              originatingCompanyName: "Whole Body Fit",
            },
            cardDetails: {
              dynamicDescriptor: "WhlBdy *Yoga 11-12",
            },
          },
          partnerAccountID: "c520f1b9-0ba7-42f5-b977-248cdbe41c69",
          source: {
            paymentMethodID: "c520f1b9-0ba7-42f5-b977-248cdbe41c69",
            achDetails: {
              companyEntryDescription: "Gym dues",
              originatingCompanyName: "Whole Body Fit",
            },
            cardDetails: {
              dynamicDescriptor: "WhlBdy *Yoga 11-12",
            },
          },
          description: "sediment yahoo a rudely mmm massive helpful brr",
          lineItems: {
            items: [],
          },
        },
        start: new Date("2009-11-10T23:00:00Z"),
      },
    },
  });

  console.log(result);
}

run();
```

Full reference with SDK examples in every language: https://docs.moov.io/api/money-movement/schedules/create/
