Automated Batch Scheduling
Automated Batch Scheduling
Koard supports automated batch close and re-open scheduling per terminal. Instead of manually closing batches at the end of each day, you can configure a schedule and Koard handles it automatically.
Supported Processors
| Processor | Supported | Notes |
|---|---|---|
| TSYS | ✅ | Full support. Batch numbers auto-managed (001-999). |
| Elavon | ✅ | Full support via ViaConex TC 920/921/929. |
| Worldpay | ✅ | Full support via 610 settlement interface. |
| Fiserv | ❌ | Not supported for automated scheduling. |
| Payroc | ❌ | Not supported for automated scheduling. |
How It Works
- Configure a schedule on the terminal via
PUT /v2/terminals/{terminal_id} - Koard's scheduler runs every minute, checking for terminals due for batch close
- When due, Koard closes the current batch and opens a new one
- If a close fails, Koard retries up to 10 times with backoff
- On persistent failure, a webhook error event is sent
Setting Up a Schedule
Add a batch_schedule field to your terminal update:
PUT /v2/terminals/{terminal_id}
{
"batch_schedule": {
"timezone": "US/Eastern",
"is_active": true,
"schedule": [
{ "day": "MON", "times": ["23:00"] },
{ "day": "TUE", "times": ["23:00"] },
{ "day": "WED", "times": ["23:00"] },
{ "day": "THU", "times": ["23:00"] },
{ "day": "FRI", "times": ["23:00"] },
{ "day": "SAT", "times": ["23:00"] }
]
}
}
Response
The terminal response includes confirmation that the schedule was saved:
{
"terminal_id": "term-abc123",
"name": "Front Counter POS",
"mid": "886000001130",
"tid": "00000001",
"processor_config_id": "cfg-tsys-001",
"status": "active",
"var_sheet": { "applicationId": "B001" }
}
Schedule Format
Days
Use 3-letter day codes:
| Code | Day |
|---|---|
MON |
Monday |
TUE |
Tuesday |
WED |
Wednesday |
THU |
Thursday |
FRI |
Friday |
SAT |
Saturday |
SUN |
Sunday |
Times
Times are in 24-hour HH:MM format. You can set multiple closes per day:
{
"day": "WED",
"times": ["12:00", "18:00", "23:00"]
}
This closes the batch at noon, 6pm, and 11pm on Wednesdays.
No Close on a Day
Simply omit the day from the schedule. If Saturday and Sunday are not listed, no batch close happens on weekends.
Timezones
DST vs Fixed Timezones: Choose carefully between DST-aware and fixed-offset timezones. Most merchants want DST-aware timezones so the batch close follows "wall clock" time.
DST-Aware Timezones (Recommended)
These follow daylight saving time transitions. 23:00 US/Eastern means 11pm EDT in summer and 11pm EST in winter.
| Timezone | Description |
|---|---|
US/Eastern |
Eastern Time (New York) |
US/Central |
Central Time (Chicago) |
US/Mountain |
Mountain Time (Denver) |
US/Pacific |
Pacific Time (Los Angeles) |
US/Alaska |
Alaska Time |
US/Hawaii |
Hawaii Time (no DST) |
US/Arizona |
Arizona Time (no DST) |
You can also use full IANA zone names like America/New_York, America/Chicago, etc.
Fixed-Offset Timezones
These never change for DST. Use only if you want a fixed UTC offset year-round.
| Timezone | UTC Offset | Notes |
|---|---|---|
EST |
UTC-5 always | Does not switch to EDT in summer |
MST |
UTC-7 always | Does not switch to MDT in summer |
HST |
UTC-10 always | Same as US/Hawaii |
UTC |
UTC+0 always | Universal Coordinated Time |
Example: DST Impact
A batch close at 23:00 US/Eastern:
- Winter (EST): Fires at 04:00 UTC
- Summer (EDT): Fires at 03:00 UTC
A batch close at 23:00 EST:
- Always: Fires at 04:00 UTC (even in summer when "wall clock" Eastern time is EDT)
Managing Schedules
Update an Existing Schedule
PUT /v2/terminals/{terminal_id}
{
"batch_schedule": {
"timezone": "US/Pacific",
"schedule": [
{ "day": "MON", "times": ["22:00"] },
{ "day": "FRI", "times": ["14:00", "22:00"] }
]
}
}
Pause Scheduling (Keep Config)
Set is_active to false to temporarily disable without losing your schedule:
PUT /v2/terminals/{terminal_id}
{
"batch_schedule": {
"is_active": false
}
}
Resume Scheduling
PUT /v2/terminals/{terminal_id}
{
"batch_schedule": {
"is_active": true,
"schedule": [
{ "day": "MON", "times": ["23:00"] },
{ "day": "TUE", "times": ["23:00"] }
]
}
}
Important: An active schedule must have at least one day with times configured. Setting is_active: true with an empty schedule will return an error.
Remove Schedule Entirely (Back to Manual)
Set batch_schedule to null:
PUT /v2/terminals/{terminal_id}
{
"batch_schedule": null
}
After removal, the terminal returns to manual batch management.
Updates Without batch_schedule
Updating other terminal fields (name, MID, var_sheet, etc.) does not affect the schedule:
PUT /v2/terminals/{terminal_id}
{
"name": "New Terminal Name"
}
The existing batch schedule is preserved.
Switching Between Auto and Manual
Switching from Auto to Manual
To switch a terminal back to manual batch management, remove the schedule:
PUT /v2/terminals/{terminal_id}
{
"batch_schedule": null
}
Important: When switching to manual, the current open batch stays open. You are now responsible for:
- Closing the current batch manually (
POST /v1/batches/{batch_id}/close) - Opening new batches manually (
POST /v1/batches/open) - Closing all future batches — they will no longer auto-close
Switching from Manual to Auto
Enable a schedule on an existing terminal:
PUT /v2/terminals/{terminal_id}
{
"batch_schedule": {
"timezone": "US/Central",
"is_active": true,
"schedule": [
{ "day": "MON", "times": ["22:00"] },
{ "day": "TUE", "times": ["22:00"] },
{ "day": "WED", "times": ["22:00"] },
{ "day": "THU", "times": ["22:00"] },
{ "day": "FRI", "times": ["22:00"] }
]
}
}
If the terminal already has an open batch, the scheduler will close it at the next scheduled time and open a new one automatically.
Closing a Batch Early
You can always close a batch early, even when automated scheduling is enabled:
POST /v1/batches/{batch_id}/close
You must open a new batch immediately after an early close. Transactions cannot be processed without an open batch. Call POST /v1/batches/open right after the early close.
When the scheduler fires later at its scheduled time:
- If it finds an open batch with transactions, it closes and reopens normally
- If it finds an open batch with no transactions (e.g., you just opened it), it cancels the empty batch and opens a fresh one
- If it finds no open batch (e.g., you closed early and didn't reopen), it opens a new one
This means early closes are safe and the scheduler self-heals on the next run.
Example: Early Close at 3pm, Scheduled Close at 11pm
- 3:00 PM — You close the batch early via API
- 3:01 PM — You open a new batch via API
- 3:01 PM – 11:00 PM — Transactions accumulate in the new batch
- 11:00 PM — Scheduler fires, closes the batch (with transactions), opens a new one
If you forget to reopen at step 2, the scheduler at 11pm will detect no open batch and open one for you — but any transactions between 3:01 PM and 11:00 PM will have failed because there was no open batch.
TSYS-Specific Behavior
Batch Number Auto-Management
TSYS batch numbers must be between 001-999 and cannot be reused within 5 consecutive days. Koard handles this automatically:
- On open: Queries the last closed batch for the terminal and increments
- On close: Verifies no conflicting batch number, auto-increments if needed
- On duplicate (QD): Automatically retries with the next batch number (up to 10 attempts)
Batch Number Wrapping
When the batch number reaches 999, it wraps around to 001.
Error Handling
| Scenario | Koard's Response |
|---|---|
| Processor unavailable | Retries up to 10 times with backoff |
| Duplicate batch number (TSYS QD) | Auto-increments and retries |
| All retries exhausted | Sends webhook error event, logs error |
| No open batch to close | Skips close, opens a new batch |
Webhook Events
When using automated scheduling, you'll receive the standard batch webhook events:
| Event | When |
|---|---|
batch.submitted |
Batch sent to processor |
batch.accepted |
Processor accepted the batch |
batch.rejected |
Processor rejected the batch |
batch.opened |
New batch opened after close |
batch.error |
Scheduler failed after all retries |
Permissions
The following roles can view and manage batch schedules:
| Role | View | Create/Edit | Delete |
|---|---|---|---|
| Admin | ✅ | ✅ | ✅ |
| PSP | ✅ | ✅ | ✅ |
| Partner | ✅ | ✅ | ✅ |
| Merchant | ✅ | ✅ | ✅ |
See also
- Batch and Settlements Overview - Batch concepts
- Running Batches - Manual batch management
- Setting up Webhooks - Webhook configuration

