Skip to content
Hoody.com

Schedules run a stored cURL request on a cron-based interval. They are persistent (they survive server restarts), can be enabled or disabled without being deleted, and accept the same request configuration as the one-shot request endpoint. Use these endpoints to register recurring jobs, inspect them, change their cron expression or request, pause or resume them, and remove them.

Common uses include periodic API data collection, regular health checks and monitoring, scheduled report generation, and automated backups or synchronisation.

Retrieve every recurring schedule, sorted by creation time (newest first). The response shows each schedule’s configuration, its next scheduled run, and whether it is currently enabled.

Schedule states

  • Enabled: active, fires at the next scheduled time.
  • Disabled: paused, does not fire (can be re-enabled with toggle).
NameInTypeRequiredDescription
pagequeryintegerNo1-based page number
limitqueryintegerNoItems per page; when omitted, the handler returns all items
{
"items": [
{
"created_at": "2024-01-15T10:00:00Z",
"cron": "0 0 9 * * MON-FRI",
"enabled": true,
"id": "770e8400-e29b-41d4-a716-446655440000",
"last_run": "2024-01-15T09:00:00Z",
"next_run": "2024-01-16T09:00:00Z",
"request": {
"method": "GET",
"url": "https://api.example.com/daily-report"
}
},
{
"created_at": "2024-01-14T15:30:00Z",
"cron": "0 0 * * * *",
"enabled": false,
"id": "880e8400-e29b-41d4-a716-446655440111",
"last_run": "2024-01-15T10:00:00Z",
"next_run": null,
"request": {
"method": "GET",
"url": "https://health-check.example.com/ping"
}
}
],
"meta": {
"limit": 50,
"page": 1,
"total": 2
}
}
import { HoodyClient } from 'hoody-sdk';
const client = new HoodyClient({ baseURL: 'https://{projectId}-{containerId}-curl-1.{server}.containers.hoody.com', token: process.env.HOODY_TOKEN });
for await (const schedule of client.curl.schedules.listIterator()) {
// ...
}

The error response schema’s code field is a closed enum. The codes tied to specific statuses above appear in the corresponding tab. The full set of values the field may take is:

Code
INVALID_PARAMETER
INVALID_URL
INVALID_CRON_EXPRESSION
PAYLOAD_TOO_LARGE
ORIGIN_NOT_ALLOWED
JOB_NOT_FOUND
JOB_RESULT_NOT_READY
SESSION_NOT_FOUND
FILE_NOT_FOUND
SCHEDULE_NOT_FOUND
SCHEDULE_EXISTS
REQUEST_TIMEOUT
JOB_NOT_FINISHED
JOB_CANCELLED
STORAGE_ERROR
INTERNAL_ERROR
SSE_PARSE_ERROR
UPSTREAM_ERROR
DNS_RESOLUTION_FAILED
RESPONSE_TOO_LARGE
QUEUE_FULL
SSE_CAPACITY_EXHAUSTED
UPSTREAM_TIMEOUT
NOT_FOUND
METHOD_NOT_ALLOWED
REQUEST_HEADERS_TOO_LARGE

Retrieve complete details for a single schedule: its id, cron expression, request configuration, last_run, next_run, and current enabled state.

NameInTypeRequiredDescription
idpathstringYesUnique schedule identifier (UUID format)

The schedule’s full details. The example below is taken from the spec; the schema requires created_at and request, which the example omits.

{
"cron": "0 0 9 * * MON-FRI",
"enabled": true,
"id": "770e8400-e29b-41d4-a716-446655440000"
}
import { HoodyClient } from 'hoody-sdk';
const client = new HoodyClient({ baseURL: 'https://{projectId}-{containerId}-curl-1.{server}.containers.hoody.com', token: process.env.HOODY_TOKEN });
const schedule = await client.curl.schedules.get('770e8400-e29b-41d4-a716-446655440000');

The error response schema’s code field is a closed enum. The codes tied to specific statuses above appear in the corresponding tab. The full set of values the field may take is:

Code
INVALID_PARAMETER
INVALID_URL
INVALID_CRON_EXPRESSION
PAYLOAD_TOO_LARGE
ORIGIN_NOT_ALLOWED
JOB_NOT_FOUND
JOB_RESULT_NOT_READY
SESSION_NOT_FOUND
FILE_NOT_FOUND
SCHEDULE_NOT_FOUND
SCHEDULE_EXISTS
REQUEST_TIMEOUT
JOB_NOT_FINISHED
JOB_CANCELLED
STORAGE_ERROR
INTERNAL_ERROR
SSE_PARSE_ERROR
UPSTREAM_ERROR
DNS_RESOLUTION_FAILED
RESPONSE_TOO_LARGE
QUEUE_FULL
SSE_CAPACITY_EXHAUSTED
UPSTREAM_TIMEOUT
NOT_FOUND
METHOD_NOT_ALLOWED
REQUEST_HEADERS_TOO_LARGE

Create a new cron-based schedule. Once accepted, the schedule is persistent and will fire at each cron occurrence while it is enabled.

Sending the same cron, request, job_name, and enabled again does not create a duplicate: the existing schedule’s id is returned with a 200, so a retried create still produces one schedule.

NameTypeRequiredDescription
cronstringYesSix-field cron expression: second minute hour day month weekday
requestobjectYescURL request configuration; validated the same as for one-shot execution

A schedule with the same cron, request, job_name, and enabled already exists, so nothing is created and the existing schedule’s id is returned.

import { HoodyClient } from 'hoody-sdk';
const client = new HoodyClient({ baseURL: 'https://{projectId}-{containerId}-curl-1.{server}.containers.hoody.com', token: process.env.HOODY_TOKEN });
await client.curl.schedules.create({
cron: '0 0 9 * * MON-FRI',
request: {
method: 'GET',
url: 'https://api.example.com/daily-report',
},
});

The error response schema’s code field is a closed enum. The codes tied to specific statuses above appear in the corresponding tab. The full set of values the field may take is:

Code
INVALID_PARAMETER
INVALID_URL
INVALID_CRON_EXPRESSION
PAYLOAD_TOO_LARGE
ORIGIN_NOT_ALLOWED
JOB_NOT_FOUND
JOB_RESULT_NOT_READY
SESSION_NOT_FOUND
FILE_NOT_FOUND
SCHEDULE_NOT_FOUND
SCHEDULE_EXISTS
REQUEST_TIMEOUT
JOB_NOT_FINISHED
JOB_CANCELLED
STORAGE_ERROR
INTERNAL_ERROR
SSE_PARSE_ERROR
UPSTREAM_ERROR
DNS_RESOLUTION_FAILED
RESPONSE_TOO_LARGE
QUEUE_FULL
SSE_CAPACITY_EXHAUSTED
UPSTREAM_TIMEOUT
NOT_FOUND
METHOD_NOT_ALLOWED
REQUEST_HEADERS_TOO_LARGE

Change an existing schedule in place: its id, created_at, and last_run are kept. Send any of cron, request, and enabled; absent fields keep their current value. A request replaces the whole stored request, it is not merged. Validation is the same as for create: the request must pass the same checks, and an enabled schedule needs an expression with a future occurrence.

The change applies from the next occurrence; an occurrence already running finishes with the old request.

Returns the updated schedule, credentials redacted as in getSchedule. A credential sent back exactly as getSchedule showed it ([REDACTED], or the redacted URL, json or data body) keeps its stored value, so a schedule can be read, edited and written back. This holds only while the request URL keeps the same scheme, host and port: when changing the destination, send the credentials again or remove them, otherwise the update is refused with 400. Changing only the path or query on the same scheme, host and port keeps them: whoever may update the schedule can already aim its stored credentials at any endpoint of that service.

NameInTypeRequiredDescription
idpathstringYesUnique schedule identifier
NameTypeRequiredDescription
cronstringNoNew six-field cron expression: second minute hour day month weekday
enabledbooleanNotrue enables the schedule, false disables it
requestobject | nullNoReplacement request; replaces the whole stored request, not merged; job_name becomes the schedule’s name

The updated schedule.

{
"created_at": "2024-01-15T10:00:00Z",
"cron": "0 */5 * * * *",
"enabled": true,
"id": "770e8400-e29b-41d4-a716-446655440000",
"last_run": "2024-01-15T09:00:00Z",
"next_run": "2024-01-15T10:05:00Z",
"request": {
"method": "GET",
"url": "https://api.example.com/daily-report"
}
}
import { HoodyClient } from 'hoody-sdk';
const client = new HoodyClient({ baseURL: 'https://{projectId}-{containerId}-curl-1.{server}.containers.hoody.com', token: process.env.HOODY_TOKEN });
await client.curl.schedules.update('770e8400-e29b-41d4-a716-446655440000', {
cron: '0 */5 * * * *',
});

The error response schema’s code field is a closed enum. The codes tied to specific statuses above appear in the corresponding tab. The full set of values the field may take is:

Code
INVALID_PARAMETER
INVALID_URL
INVALID_CRON_EXPRESSION
PAYLOAD_TOO_LARGE
ORIGIN_NOT_ALLOWED
JOB_NOT_FOUND
JOB_RESULT_NOT_READY
SESSION_NOT_FOUND
FILE_NOT_FOUND
SCHEDULE_NOT_FOUND
SCHEDULE_EXISTS
REQUEST_TIMEOUT
JOB_NOT_FINISHED
JOB_CANCELLED
STORAGE_ERROR
INTERNAL_ERROR
SSE_PARSE_ERROR
UPSTREAM_ERROR
DNS_RESOLUTION_FAILED
RESPONSE_TOO_LARGE
QUEUE_FULL
SSE_CAPACITY_EXHAUSTED
UPSTREAM_TIMEOUT
NOT_FOUND
METHOD_NOT_ALLOWED
REQUEST_HEADERS_TOO_LARGE

Toggle a schedule between enabled and disabled without deleting it. Send {"enabled": true} to enable, {"enabled": false} to disable.

NameInTypeRequiredDescription
idpathstringYesUnique schedule identifier
NameTypeRequiredDescription
enabledbooleanYestrue enables the schedule, false disables it

The schedule was toggled.

Terminal window
curl -X PATCH 'https://{projectId}-{containerId}-curl-1.{server}.containers.hoody.com/api/v1/curl/schedule/770e8400-e29b-41d4-a716-446655440000/toggle' \
-H "Authorization: Bearer $HOODY_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "enabled": false }'

The error response schema’s code field is a closed enum. The codes tied to specific statuses above appear in the corresponding tab. The full set of values the field may take is:

Code
INVALID_PARAMETER
INVALID_URL
INVALID_CRON_EXPRESSION
PAYLOAD_TOO_LARGE
ORIGIN_NOT_ALLOWED
JOB_NOT_FOUND
JOB_RESULT_NOT_READY
SESSION_NOT_FOUND
FILE_NOT_FOUND
SCHEDULE_NOT_FOUND
SCHEDULE_EXISTS
REQUEST_TIMEOUT
JOB_NOT_FINISHED
JOB_CANCELLED
STORAGE_ERROR
INTERNAL_ERROR
SSE_PARSE_ERROR
UPSTREAM_ERROR
DNS_RESOLUTION_FAILED
RESPONSE_TOO_LARGE
QUEUE_FULL
SSE_CAPACITY_EXHAUSTED
UPSTREAM_TIMEOUT
NOT_FOUND
METHOD_NOT_ALLOWED
REQUEST_HEADERS_TOO_LARGE

Permanently delete a recurring schedule. The schedule immediately stops executing and its configuration is removed.

NameInTypeRequiredDescription
idpathstringYesUnique schedule identifier

The schedule was deleted.

import { HoodyClient } from 'hoody-sdk';
const client = new HoodyClient({ baseURL: 'https://{projectId}-{containerId}-curl-1.{server}.containers.hoody.com', token: process.env.HOODY_TOKEN });
await client.curl.schedules.delete('770e8400-e29b-41d4-a716-446655440000');

The error response schema’s code field is a closed enum. The codes tied to specific statuses above appear in the corresponding tab. The full set of values the field may take is:

Code
INVALID_PARAMETER
INVALID_URL
INVALID_CRON_EXPRESSION
PAYLOAD_TOO_LARGE
ORIGIN_NOT_ALLOWED
JOB_NOT_FOUND
JOB_RESULT_NOT_READY
SESSION_NOT_FOUND
FILE_NOT_FOUND
SCHEDULE_NOT_FOUND
SCHEDULE_EXISTS
REQUEST_TIMEOUT
JOB_NOT_FINISHED
JOB_CANCELLED
STORAGE_ERROR
INTERNAL_ERROR
SSE_PARSE_ERROR
UPSTREAM_ERROR
DNS_RESOLUTION_FAILED
RESPONSE_TOO_LARGE
QUEUE_FULL
SSE_CAPACITY_EXHAUSTED
UPSTREAM_TIMEOUT
NOT_FOUND
METHOD_NOT_ALLOWED
REQUEST_HEADERS_TOO_LARGE