Skip to main content

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"
}
FieldRequiredNotes
nameYesHuman-readable name for the job.
jobTypeYesOne of: HttpCall, StoredProcedure, CodeExecution, FileOperation.
scheduleTypeYesOne of: Cron, Interval, OneTime.
scheduleExpressionCron onlyStandard five-field cron expression.
intervalSecondsInterval onlyRepeat period in seconds.
runAtOneTime onlyUTC timestamp for a single execution.
jobConfigurationYesType-specific object; see sections below.
retryPolicyNoOverrides the global defaults from Scheduler.Retry config.
timeoutSecondsNoOverrides Jobs.DefaultTimeoutSeconds (300).
timezoneNoIANA time zone name; defaults to UTC.
isEnabledNoSet to false to create the job without activating its schedule.
tagsNoFree-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:
FieldRequiredNotes
urlYesThe fully-qualified URL to call.
methodYesHTTP method: GET, POST, PUT, PATCH, DELETE.
headersNoKey-value object of request headers.
bodyNoString body for POST/PUT/PATCH requests. Supports variable substitution.
timeoutSecondsNoPer-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:
FieldRequiredNotes
storedProcedureNameYesExact name of the stored procedure.
parametersNoKey-value object of parameter names and values. Supports variable substitution.
timeoutSecondsNoPer-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:
FieldRequiredNotes
handlerTypeYesAssembly-qualified type name of the class that implements IJobHandler.
The handler class must:
  1. Implement the IJobHandler interface (from Alphabet.Domain.Interfaces).
  2. 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:
FieldRequiredNotes
sourcePathYesAbsolute path to the file or directory. Must be within an AllowedFileRoots entry in config.
operationYesOne 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.
VariableResolves 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.
ParameterTypeDescription
jobTypestringFilter by job type: HttpCall, StoredProcedure, CodeExecution, FileOperation.
statusstringFilter by current status.
tagstringFilter to jobs that carry this tag.
searchstringText search across name and description.
sortBystringField to sort by.
pageNumberintPage number (default: 1).
pageSizeintItems 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.

Trigger immediately

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.