The producer client is the validated boundary for application enqueueing. It validates the
entire batch before store I/O, derives fingerprints, runs authorization and middleware,
and reports typed duplicate or availability errors.
Choose the enqueue boundary
Bulk enqueue is one atomic request. If validation or authorization rejects one member,
Headgate writes none of its siblings.
Enqueue from TypeScript or Python
Headgate does not require the producer to use the Rust or Go SDK. A Node.js, NestJS,
Python, or other service can call the control API. Send the task arguments as bytes in
standard base64; for JSON arguments, UTF-8 encode the JSON first and then base64-encode
those bytes. Headgate derives the content fingerprint on the server.
Use a stable Idempotency-Key for one logical enqueue operation. Retrying with the same
key returns the original job instead of creating another one. Use a new key when you
intend to create a new job, even when its payload is identical.
The kind must exactly match a handler registered by a Rust or Go worker, and the decoded
payload bytes must follow the schema that handler expects. Authentication is supplied by
the application hosting Headgate; do not expose an unauthenticated control API publicly.
See the control API reference for every
optional enqueue field and response status.
IDs and scheduling
Callers may provide a strict job ID for correlation and idempotency. Reusing that ID with
different job content is an ID conflict, not a uniqueness match. Priority orders jobs only
inside a queue; queue weight chooses among queues. Delayed jobs remain scheduled until
store time reaches their timestamp.
Uniqueness, replacement, and debounce
Headgate supports lifecycle uniqueness and time-window throttling. A lifecycle key remains
held while the job is live. A throttle key is released by its clock even if the original
job already completed.
On conflict, a replacement mask can update only the payload bundle, scheduled time,
priority, and maximum attempts. Debounce is the common replacement shape: one durable job
keeps moving forward while new payloads replace its pending work. Replacement never
mutates a running or terminal job.
The plaintext fingerprint participates in uniqueness and quarantine. With encrypted jobs,
this preserves behavior but reveals payload equality.
Backpressure and outages
Producer admission can cap queue depth and reject enqueue before overload becomes database
growth. Retryable store failures are classified separately from validation, authorization,
duplicate, and ID-conflict errors. The producer circuit breaker fails fast while the store
is unhealthy and probes again after its cooldown.
Applications should retry only typed unavailable errors, with their own deadline and
jitter. Retrying a forbidden, malformed, or conflicting request cannot make it valid.
Authorization, middleware, and hooks
An enqueue authorizer receives application-supplied identity and every envelope. Headgate
does not trust an HTTP identity header or invent application roles. A denial rejects the
whole batch before store access. The raw store is intentionally a trusted low-level bypass.
Producer middleware wraps the operation. Insert hooks run around the durable write.
Plugins package middleware and hooks together with global or task-kind scope. Their order
is deterministic: standalone components, global plugins in install order, then matching
kind-scoped plugins in install order.
Configure exact queue-depth backpressure through the control API: