Documentation Index
Fetch the complete documentation index at: https://alphabet-06152314.mintlify.app/llms.txt
Use this file to discover all available pages before exploring further.
Alphabet’s scheduler supports four job types, each suited to a different automation pattern. When you create a job you choose the type once and supply a jobConfiguration object whose fields depend on that type. The schedule, retry policy, and timeout are shared across all types and sit alongside jobConfiguration in the same request body.
Creating a job
POST /api/v1/scheduler/jobs
The request body accepts the following fields:
{
"name": "string",
"description": "string",
"jobType": "HttpCall | StoredProcedure | CodeExecution | FileOperation",
"scheduleType": "Cron | Interval | OneTime",
"scheduleExpression": "string",
"intervalSeconds": 0,
"runAt": "2025-01-01T00:00:00Z",
"jobConfiguration": {},
"retryPolicy": {
"maxAttempts": 3,
"delaySeconds": 60
},
"timeoutSeconds": 300,
"timezone": "UTC",
"isEnabled": true,
"tags": ["string"],
"createdBy": "string"
}
| Field | Required | Notes |
|---|
name | Yes | Human-readable name for the job. |
jobType | Yes | One of: HttpCall, StoredProcedure, CodeExecution, FileOperation. |
scheduleType | Yes | One of: Cron, Interval, OneTime. |
scheduleExpression | Cron only | Standard five-field cron expression. |
intervalSeconds | Interval only | Repeat period in seconds. |
runAt | OneTime only | UTC timestamp for a single execution. |
jobConfiguration | Yes | Type-specific object; see sections below. |
retryPolicy | No | Overrides the global defaults from Scheduler.Retry config. |
timeoutSeconds | No | Overrides Jobs.DefaultTimeoutSeconds (300). |
timezone | No | IANA time zone name; defaults to UTC. |
isEnabled | No | Set to false to create the job without activating its schedule. |
tags | No | Free-form labels for filtering. |
A successful request returns 201 Created with a JobDto that includes the assigned id and the calculated nextRunAt timestamp.
{
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"name": "Hourly webhook",
"status": "Pending",
"nextRunAt": "2025-06-01T13:00:00Z"
}
HTTP call jobs
Use jobType: "HttpCall" to have the scheduler make an outbound HTTP request on your schedule. The jobConfiguration object supports the following fields:
| Field | Required | Notes |
|---|
url | Yes | The fully-qualified URL to call. |
method | Yes | HTTP method: GET, POST, PUT, PATCH, DELETE. |
headers | No | Key-value object of request headers. |
body | No | String body for POST/PUT/PATCH requests. Supports variable substitution. |
timeoutSeconds | No | Per-request timeout in seconds. |
Example: call a webhook every hour
{
"name": "Hourly webhook",
"description": "Notify the reporting service at the top of every hour.",
"jobType": "HttpCall",
"scheduleType": "Cron",
"scheduleExpression": "0 * * * *",
"jobConfiguration": {
"url": "https://your-service.example.com/api/heartbeat",
"method": "POST",
"headers": {
"Content-Type": "application/json",
"X-Source": "alphabet-scheduler"
},
"body": "{\"jobId\":\"{{Job.Id}}\",\"triggeredAt\":\"{{Now}}\"}",
"timeoutSeconds": 30
},
"retryPolicy": {
"maxAttempts": 3,
"delaySeconds": 60
},
"isEnabled": true,
"createdBy": "api-setup"
}
Stored procedure jobs
Use jobType: "StoredProcedure" to execute a named stored procedure against the application database. The jobConfiguration object supports the following fields:
| Field | Required | Notes |
|---|
storedProcedureName | Yes | Exact name of the stored procedure. |
parameters | No | Key-value object of parameter names and values. Supports variable substitution. |
timeoutSeconds | No | Per-call timeout in seconds. |
Example: run a nightly cleanup procedure at 2 AM
{
"name": "Nightly cleanup",
"description": "Remove soft-deleted records older than 90 days.",
"jobType": "StoredProcedure",
"scheduleType": "Cron",
"scheduleExpression": "0 2 * * *",
"jobConfiguration": {
"storedProcedureName": "usp_PurgeDeletedRecords",
"parameters": {
"CutoffDate": "{{Today}}",
"RetentionDays": "90"
},
"timeoutSeconds": 120
},
"retryPolicy": {
"maxAttempts": 2,
"delaySeconds": 300
},
"timezone": "UTC",
"isEnabled": true,
"createdBy": "api-setup"
}
Code execution jobs
Use jobType: "CodeExecution" to run a custom .NET handler class on a schedule. The jobConfiguration object requires a single field:
| Field | Required | Notes |
|---|
handlerType | Yes | Assembly-qualified type name of the class that implements IJobHandler. |
The handler class must:
- Implement the
IJobHandler interface (from Alphabet.Domain.Interfaces).
- Be registered in the application’s dependency injection container.
The scheduler resolves the type by name from DI at execution time. If the type is not registered or the name is wrong, the execution will fail immediately.
Example: run a custom report generation handler daily
{
"name": "Daily report generation",
"description": "Build and archive the daily summary report.",
"jobType": "CodeExecution",
"scheduleType": "Cron",
"scheduleExpression": "0 6 * * *",
"jobConfiguration": {
"handlerType": "YourApp.Jobs.ReportGenerationJob, YourApp.Infrastructure"
},
"retryPolicy": {
"maxAttempts": 3,
"delaySeconds": 60
},
"isEnabled": true,
"createdBy": "api-setup"
}
Use the assembly-qualified type name format Namespace.ClassName, AssemblyName. You can find this by calling typeof(YourHandler).AssemblyQualifiedName in a unit test or startup log.
File operation jobs
Use jobType: "FileOperation" to run a file system task on a schedule. The jobConfiguration object supports the following fields:
| Field | Required | Notes |
|---|
sourcePath | Yes | Absolute path to the file or directory. Must be within an AllowedFileRoots entry in config. |
operation | Yes | One of: delete, move, archive, compress. |
Paths are validated against the Scheduler:Jobs:AllowedFileRoots list configured on the server. Requests with paths outside those roots are rejected with 400 Bad Request. Contact your deployment team to extend the allowed roots.
Example: archive the logs folder every Sunday at midnight
{
"name": "Weekly log archive",
"description": "Compress and archive the application log directory every Sunday.",
"jobType": "FileOperation",
"scheduleType": "Cron",
"scheduleExpression": "0 0 * * 0",
"jobConfiguration": {
"sourcePath": "C:\\Logs\\AppLogs",
"operation": "archive"
},
"retryPolicy": {
"maxAttempts": 2,
"delaySeconds": 120
},
"isEnabled": true,
"createdBy": "api-setup"
}
Variable substitution
Alphabet resolves the following placeholders at execution time. You can use them in HTTP body strings, stored procedure parameter values, and anywhere else the scheduler accepts a string configuration value.
| Variable | Resolves to |
|---|
{{Today}} | Current date in yyyy-MM-dd format (UTC). |
{{Now}} | Current UTC date-time in ISO 8601 format. |
{{Job.Id}} | The GUID identifier of the job. |
{{Job.Name}} | The name of the job as stored in the database. |
{{Environment.MachineName}} | The hostname of the server running the job. |
{{User.Email}} | The email address of the user recorded in createdBy. |
Managing jobs
Once a job exists you can list, inspect, update, delete, reschedule, pause, resume, or trigger it immediately.
List jobs
GET /api/v1/scheduler/jobs
Returns a paged list of jobs. All query parameters are optional.
| Parameter | Type | Description |
|---|
jobType | string | Filter by job type: HttpCall, StoredProcedure, CodeExecution, FileOperation. |
status | string | Filter by current status. |
tag | string | Filter to jobs that carry this tag. |
search | string | Text search across name and description. |
sortBy | string | Field to sort by. |
pageNumber | int | Page number (default: 1). |
pageSize | int | Items per page (default: 20). |
Get a single job
GET /api/v1/scheduler/jobs/{jobId}
Returns the full job definition including schedule details, retry policy, and current state. Returns 404 Not Found when the job ID does not exist.
Update a job
PUT /api/v1/scheduler/jobs/{jobId}
Replaces the job definition. Supply the same fields as the create request (minus createdBy). If the schedule or isEnabled flag changes, the underlying Hangfire registration is updated immediately.
Delete a job
DELETE /api/v1/scheduler/jobs/{jobId}?hardDelete=false
Soft-deletes the job by default, preserving execution history. Set hardDelete=true to permanently remove the record.
Change the schedule only
PATCH /api/v1/scheduler/jobs/{jobId}/reschedule
Updates schedule fields without touching the rest of the job definition:
{
"scheduleType": "Cron",
"scheduleExpression": "0 8 * * 1-5",
"intervalSeconds": null,
"runAt": null,
"effectiveFrom": "2025-07-01T00:00:00Z"
}
Pause and resume
POST /api/v1/scheduler/jobs/{jobId}/pause — Suspends future scheduled runs without deleting the job or its history.
POST /api/v1/scheduler/jobs/{jobId}/resume — Restores a paused job and re-registers its schedule in Hangfire.
POST /api/v1/scheduler/jobs/{jobId}/trigger
Queues the job for immediate execution regardless of its schedule. Returns 202 Accepted with the new executionId you can use to track the run:
"3fa85f64-5717-4562-b3fc-2c963f66afa6"
Use GET /api/v1/scheduler/executions/{executionId} to poll the result.