JobOptions
Per-call overrides passed to IJobClient methods. Any property left as null falls through to the next level in the option precedence chain.
Namespace: Zeridion.Flare · Assembly: Zeridion.Flare.dll
public sealed class JobOptions
{
public string? Queue { get; set; }
public int? MaxAttempts { get; set; }
public TimeSpan? Timeout { get; set; }
public Dictionary<string, string>? Tags { get; set; }
public string? IdempotencyKey { get; set; }
public string? RequestId { get; set; }
}
Properties
| Property | Type | Default | Description |
|---|---|---|---|
Queue | string? | null | Override the queue name for this job. |
MaxAttempts | int? | null | Override the maximum retry attempts. |
Timeout | TimeSpan? | null | Override the job execution timeout. |
Tags | Dictionary<string, string>? | null | Custom key-value metadata attached to the job. |
IdempotencyKey | string? | null | Prevents duplicate jobs with the same key. |
RequestId | string? | null | Client-supplied request ID sent as the X-Request-Id HTTP header for end-to-end log correlation. |
JobOptions has the highest priority. Values set here override the [JobConfig] attribute defaults and hardcoded SDK defaults. See Option precedence for the full resolution order.
Queue
Override which queue the job is assigned to. Workers can be configured to poll specific queues, enabling workload isolation:
await jobs.EnqueueAsync<SendWelcomeEmail>(payload, new JobOptions
{
Queue = "email-priority"
});
MaxAttempts
Override how many times the job will be attempted before moving to the dead letter queue:
await jobs.EnqueueAsync<ProcessPayment>(payload, new JobOptions
{
MaxAttempts = 1 // no retries — fail immediately on error
});
Timeout
Override the maximum execution time. If the job runs longer than this, the CancellationToken in JobContext is cancelled:
await jobs.EnqueueAsync<GenerateReport>(payload, new JobOptions
{
Timeout = TimeSpan.FromMinutes(60) // allow up to 1 hour
});
Tags
Arbitrary key-value metadata attached to the job. Tags are stored with the job, returned in JobStatus.Tags, and visible in the dashboard. Use them for filtering, searching, and correlation:
await jobs.EnqueueAsync<SendWelcomeEmail>(payload, new JobOptions
{
Tags = new Dictionary<string, string>
{
["user_id"] = user.Id,
["campaign"] = "onboarding-q1",
["source"] = "api"
}
});
IdempotencyKey
Prevents duplicate jobs. If a job with the same idempotency key already exists, the API returns a 409 Conflict response and the SDK throws FlareConflictException.
This is critical for scenarios where the same event might trigger multiple enqueue calls — webhook handlers, payment processing, or retry logic in the caller:
await jobs.EnqueueAsync<ProcessPayment>(payload, new JobOptions
{
IdempotencyKey = $"payment:{payload.OrderId}"
});
The idempotency key is scoped to the project (API key). Two different projects can use the same key without conflict.
RequestId
Client-supplied correlation ID sent as the X-Request-Id HTTP header on the enqueue request. Pass your application's trace / correlation / request ID and grep for it in both Zeridion's logs and your own — every API log line and audit row for the request will carry it. If omitted, Zeridion's API generates a server-side ULID and returns it in the response's X-Request-Id header.
await jobs.EnqueueAsync<SendWelcomeEmail>(payload, new JobOptions
{
RequestId = Activity.Current?.TraceId.ToString() ?? Guid.NewGuid().ToString("N")
});
RequestId is set per-call only — it never cascades from [JobConfig] or ZeridionFlareOptions. The same applies to Tags and IdempotencyKey (see Option precedence).
Usage example
A complete example combining multiple options:
app.MapPost("/orders/{id}/fulfill", async (string id, IJobClient jobs) =>
{
var payload = new FulfillmentPayload { OrderId = id };
var jobId = await jobs.EnqueueAsync<FulfillOrder>(payload, new JobOptions
{
Queue = "fulfillment",
MaxAttempts = 3,
Timeout = TimeSpan.FromMinutes(10),
IdempotencyKey = $"fulfill:{id}",
Tags = new Dictionary<string, string>
{
["order_id"] = id,
["priority"] = "high"
}
});
return Results.Accepted(value: new { job_id = jobId });
});
See also
- [JobConfig] Attribute — class-level defaults (lower priority than
JobOptions) - ZeridionFlareOptions — global options (not currently used in the cascade)
- Option precedence — the two-level cascade
- Idempotency guide — patterns for preventing duplicate work