Skip to main content
Use a payment schedule when a payment should go out on a later date, or on a repeat, without a request from you on the day. A schedule made through the API is the same schedule your team sees on the dashboard, and changes made in either place show in both. To pay right away, use POST /payments instead. Reads need the payments.read API key permission; every other operation needs payments.write. The Payment Schedules group in the API reference has the full request and response schemas.

Create a schedule

Amounts are integer cents. Dates are YYYY-MM-DD calendar dates in US Eastern time. A one-time schedule’s sendOn must be after today. A repeating schedule’s sendOn can be today or earlier: its first send moves to the repeat’s next upcoming date, and the returned sendOn shows that date. The first send must be within 12 months. Each recipient takes exactly one of recipientId or payeeEmail; the email must belong to an existing recipient, so add new ones with POST /recipients first. Listing the same recipient twice returns 400 DUPLICATE_RECIPIENT. One-time: omit recurrence.
Repeating: set recurrence.frequency to weekly, biweekly (every two weeks), or monthly. Weekly and every-two-weeks schedules send on sendOn’s weekday; monthly schedules send on its day of the month, and on the last day of months that are shorter. endsOn is optional and must be on or after sendOn; it is the last date a send can happen, and a send due on endsOn still goes out. Omit it to repeat until you cancel the schedule. Schedules created in the dashboard can use repeat rules the API doesn’t offer. Those schedules read back with recurrence.frequency set to custom.
A successful creation returns HTTP 201 with the schedule in data, including status, totalAmount, and nextOccurrences (the next 10 send dates and what each sends). Omit sourceAccountId to let Karat select the default account, or pass an account ID from GET /accounts to choose which checking account funds the schedule. The idempotencyKey is a UUID and becomes the schedule’s id. Retrying with the same key and body returns the same schedule; reusing the key with a different body returns 409 IDEMPOTENCY_KEY_REUSED. If scheduled payments are not enabled for your organization, creation returns 403 SCHEDULES_NOT_ENABLED; contact Karat.

Update a schedule

PATCH /payment-schedules/{id} changes only the fields you send; include at least one of name, sourceAccountId, recipients, or sendOn. recipients replaces the whole list: recipients left out are removed, and a description left out is cleared. sendOn and recurrence must be sent together; "recurrence": null turns a repeating schedule into a one-time one. If the schedule’s recipients change between Karat reading the schedule and saving your update, for example when a teammate edits it on the dashboard, the update is refused with 409 SCHEDULE_CHANGED. Read the schedule again with GET /payment-schedules/{id}, rebuild your change from what you read, and send it with a new idempotencyKey. Reuse the same key only to retry a request whose response you didn’t receive. A teammate’s change to a recipient’s amount or description in between is not detected: your recipients list replaces it.

Skip, pause, or cancel

  • PUT .../skip with { "date": "2026-11-09" } skips one send date for every recipient; PUT .../restore with the same body undoes it. A skipped date shows in skippedDates and as "skipped": true in nextOccurrences. The date must be one the schedule sends on, and a one-time schedule can’t be skipped; cancel it instead. A date that has passed can’t be restored, including today’s once the 14:00 UTC send run has started.
  • PUT .../pause stops all sends until PUT .../resume. A paused schedule has status: "paused".
  • PUT .../cancel stops the schedule for good and returns data.status: "canceled", also when the schedule was already canceled. A canceled schedule is no longer listed or retrievable and can’t be resumed.
Pause, resume, and cancel take no request body. Each schedule has a status:

When payments send

Scheduled payments send once a day, on their date, at 14:00 UTC: 9:00 AM Eastern in standard time and 10:00 AM during daylight saving time. If the source account’s balance can’t cover a payment that day, that payment is not sent and is not retried, and Karat emails you (the user who created the schedule). Later dates still send. Schedules send as the user whose API key created them. Revoking the key does not stop its schedules; pause or cancel them.

Payments a schedule sent

Each recipient’s payment on a send date is an ordinary payment: it fires the usual payout.updated webhooks and appears in GET /payments. Payments include a schedule field with the schedule’s id and the occurrenceDate that sent it, or null for payments not sent by a schedule.
To match a payout.updated webhook to its schedule, fetch the payment with GET /payments/{payment_id} using the event’s payout_intent_id and read schedule.

Errors

Errors use the standard envelope from Pagination and errors, with error.code set for these cases: Invalid request bodies, and a payeeEmail that matches no recipient, return 400 with a message and no code. A key without the required permission returns 403 with a message such as API key requires payments.write. Karat is a fintech company, not an FDIC-insured bank. Banking and Card services provided by Grasshopper Bank, N.A., First Internet Bank of Indiana, and Cross River Bank, Members FDIC.