Queue Type Reference

Detailed flows, settings, and sequence diagrams for all eight queue types

DataLink Nexus provides eight distinct queue types, each designed for different data patterns. From simple point-to-point messaging to real-time enrichment pipelines, time-series aggregation, and whole-file document repositories, there is a queue type for every use case.

Queue Types

One-to-One

one-to-one

The One-to-One queue delivers each message to exactly one consumer. A visibility key ensures that only one message per key group can be in-flight at any time, preventing duplicate processing. Messages are deduplicated by primary key hash on publish. Consumers must acknowledge (or nack) each message before receiving the next one for that visibility key. If a lease expires, the message is automatically requeued by the reaper.

Settings

SettingTypeDefaultDescription
primary_keystring | string[]"order_id"Field(s) used for SHA-256 deduplication hash. Duplicate publishes with the same primary key hash are rejected.
visibility_keystring | string[]"customer_id"Field(s) controlling in-flight exclusivity. Only one message per visibility key value can be leased at a time.
consume_ttl_secondsinteger (0–300)60Lease duration in seconds. If not acknowledged within this window, the message is automatically requeued.
max_message_age_secondsinteger (1–1209600)86400Maximum age of a message in seconds. Expired messages are moved to the dead letter queue by the reaper.
max_queue_depthinteger (0–100000)10000Maximum number of messages allowed in the queue (0 = unlimited). Behaviour when exceeded is controlled by overflow_policy.
overflow_policy"reject" | "drop_oldest_append""reject"What to do when max_queue_depth is reached. Reject returns 409; drop_oldest removes the oldest message and appends the new one.
auto_ackbooleanfalseWhen true, messages are automatically acknowledged on consume (no explicit ack required).
allow_subscriptionsbooleanfalseWhen true, other tenants can subscribe to this queue for cross-tenant fan-out.
masking_rulesobject[] | nullnullOptional data masking or tokenization rules applied to payload fields before encryption on publish.
schema_validation"none" | "partial" | "full""none"Payload validation mode. none = off; partial = every defined field required, extra fields allowed; full = exact match, no extra fields. A failing payload is rejected with 400. Frozen after creation.
schemaobject | nullnullJSON Schema (an object schema with a non-empty properties map) validated against each published payload. Required when schema_validation is partial or full. Frozen after creation.

Publish Flow

sequenceDiagram participant C as Client participant API as Server participant DB as Database participant Sub as Subs C->>API: POST /publish API->>API: Validate keys API->>API: Check duplicate key API->>API: Apply masking API->>API: Encrypt payload API->>DB: Publish (overflow check) DB-->>API: Message ID API->>Sub: Fan-out to subs API-->>C: 200 OK {message_id}

Consume Flow

sequenceDiagram participant C as Client participant API as Server participant DB as Database C->>API: POST /consume API->>DB: Find next (visibility key) DB-->>API: Message + lease_id API->>API: Decrypt payload API-->>C: 200 OK (payload + headers) Note over C: Process message... alt Acknowledge C->>API: POST /ack API->>DB: Delete message API-->>C: 200 OK else Nack - Requeue C->>API: POST /nack (requeue) API->>DB: Return to queue API-->>C: 200 OK else Nack - Dead Letter C->>API: POST /nack (deadletter) API->>DB: Move to DLQ API-->>C: 200 OK else Lease Expires Note over DB: Reaper auto-requeues message end

Dead Letter Flow

sequenceDiagram participant C as Client participant API as Server participant DB as Database Note over DB: Message age exceeded / Nacked to DLQ C->>API: POST /deadletter/consume API->>DB: Get next DLQ message DB-->>API: DLQ message + lease_id API-->>C: 200 OK (DLQ message) C->>API: POST /deadletter/nack (requeue) API->>DB: Move back to main queue API-->>C: 200 OK

Key Behaviors

One-to-Many

one-to-many

The One-to-Many queue delivers independent copies of each message to multiple consumers. Each consumer (identified by client_id) tracks their own position in the queue and must acknowledge a message before receiving the next one. There is no visibility key — consumption is tracked per consumer, not per message field. This is ideal for fan-out patterns where multiple services need to process the same data independently.

Settings

SettingTypeDefaultDescription
primary_keystring | string[]"message_id"Field(s) used for SHA-256 deduplication hash on publish.
consume_ttl_secondsinteger (0–300)60Lease duration in seconds per consumer. Expired leases are requeued for that consumer.
max_message_age_secondsinteger (1–1209600)86400Maximum age of a message. Expired messages are moved to the dead letter queue.
max_queue_depthinteger (0–100000)10000Maximum number of messages in the queue (0 = unlimited).
overflow_policy"reject" | "drop_oldest_append""reject"Behaviour when max_queue_depth is reached.
auto_ackbooleanfalseWhen true, messages are auto-acknowledged on consume.
allow_subscriptionsbooleanfalseAllow cross-tenant subscriptions to this queue.
masking_rulesobject[] | nullnullOptional data masking or tokenization rules.
schema_validation"none" | "partial" | "full""none"Payload validation mode. none = off; partial = every defined field required, extra fields allowed; full = exact match, no extra fields. A failing payload is rejected with 400. Frozen after creation.
schemaobject | nullnullJSON Schema (an object schema with a non-empty properties map) validated against each published payload. Required when schema_validation is partial or full. Frozen after creation.

Publish Flow

sequenceDiagram participant C as Client participant API as Server participant DB as Database participant Sub as Subs C->>API: POST /publish API->>API: Validate primary_key API->>API: Check duplicate key API->>API: Apply masking API->>API: Encrypt payload API->>DB: Publish (overflow check) DB-->>API: Message ID API->>Sub: Fan-out to subs API-->>C: 200 OK {message_id}

Consume Flow

sequenceDiagram participant C1 as Consumer A participant C2 as Consumer B participant API as Server participant DB as Database C1->>API: POST /consume API->>DB: Next unread (Consumer A) DB-->>API: Message + lease_id API->>API: Decrypt payload API-->>C1: 200 OK (payload) C2->>API: POST /consume API->>DB: Next unread (Consumer B) DB-->>API: Same message + lease_id API-->>C2: 200 OK (payload) Note over C1,C2: Each consumer independently acks/nacks C1->>API: POST /ack API->>DB: Mark consumed (A) API-->>C1: 200 OK C2->>API: POST /ack API->>DB: Mark consumed (B) API-->>C2: 200 OK

Dead Letter Flow

sequenceDiagram participant C as Client participant API as Server participant DB as Database Note over DB: Message age exceeded / Nacked to DLQ C->>API: POST /deadletter/consume API->>DB: Get next DLQ message DB-->>API: DLQ message + lease_id API-->>C: 200 OK (DLQ message) C->>API: POST /deadletter/nack (requeue) API->>DB: Move back to main queue API-->>C: 200 OK

Key Behaviors

Key-Value

key-value

The Key-Value queue is a state snapshot and lookup store. Items are keyed by their primary key and can be retrieved individually, in bulk, or as a delta since the consumer's last request. There is no consume/ack/nack cycle and no dead letter queue — this is a persistent store that consumers read from at any time. It also serves as the lookup source for Stream-to-One and Stream-to-Many enrichment queues.

Settings

SettingTypeDefaultDescription
primary_keystring | string[]"item_id"Field(s) used to uniquely identify each item.
on_duplicate"reject" | "replace""reject"What to do when publishing an item whose primary key already exists: reject returns 409; replace upserts (overwrites) the stored item. A queue setting, not a per-publish option.
sort_keystring | string[] | nullnullOptional field(s) to control the order items are returned in GET /items responses.
max_message_age_secondsinteger (1–1209600)86400Maximum age for items in seconds (1–2592000). Expired items are removed by the reaper. Capped at 14 days; retention cannot be disabled.
max_queue_depthinteger (0–100000)10000Maximum number of items allowed in the store (0 = unlimited).
overflow_policy"reject" | "drop_oldest_append""reject"Behaviour when max_queue_depth is reached.
allow_subscriptionsbooleanfalseAllow cross-tenant subscriptions to this store.
masking_rulesobject[] | nullnullOptional data masking or tokenization rules.
schema_validation"none" | "partial" | "full""none"Payload validation mode. none = off; partial = every defined field required, extra fields allowed; full = exact match, no extra fields. A failing payload is rejected with 400. Frozen after creation.
schemaobject | nullnullJSON Schema (an object schema with a non-empty properties map) validated against each published item. Required when schema_validation is partial or full. Frozen after creation.

Publish Flow

sequenceDiagram participant C as Client participant API as Server participant DB as Database participant Sub as Subs C->>API: POST /items API->>API: Extract primary key API->>API: Apply masking API->>API: Encrypt payload API->>DB: Upsert by key alt on_duplicate = "reject" (default) DB-->>API: 409 Duplicate else on_duplicate = "replace" DB-->>API: Replaced existing item end DB-->>API: Message ID API->>Sub: Fan-out to subs API-->>C: 200 OK {message_id}

Consume Flows

sequenceDiagram participant C as Client participant API as Server participant DB as Database Note over C,API: GET all items C->>API: GET /items API->>DB: Fetch all items (sorted) DB-->>API: Items array API->>API: Decrypt payloads API-->>C: 200 OK {items[], count} Note over C,API: Lookup by key C->>API: POST /items/by_key API->>DB: Fetch items matching keys DB-->>API: Matching items API->>API: Decrypt payloads API-->>C: 200 OK {items[], count} Note over C,API: Delta since last request C->>API: POST /items/updates API->>DB: Fetch modified items DB-->>API: Updated items API->>API: Decrypt payloads API-->>C: 200 OK {items[], count}

Delete Flow

sequenceDiagram participant C as Client participant API as Server participant DB as Database C->>API: DELETE /items API->>DB: Delete by keys DB-->>API: Deleted count API-->>C: 200 OK {deleted_count: N}

Key Behaviors

Time-Series

time-series

The Time-Series queue aggregates numeric data points into clock-aligned time buckets. Each bucket computes OHLC (open, high, low, close) statistics along with sum, count, and average for every configured aggregation field. Buckets are aligned to clock boundaries (e.g., a 5-minute interval starting at the top of the hour) for consistent reporting. Gap filling ensures continuous time ranges even when no data arrives.

Settings

SettingTypeDefaultDescription
aggregation_fieldsstring[](required)List of numeric field names from the payload to aggregate (e.g., ["price", "volume"]).
primary_keystring | string[] | nullnullOptional field(s) to partition data into separate series (e.g., "symbol" for multi-stock tracking).
aggregation_interval_minutes1 | 5 | 10 | 15 | 30 | 60 | 14405Width of each time bucket in minutes (1440 = daily). Must be one of the allowed values.
max_bucketsinteger (1–100000)1000Maximum number of buckets retained per series. Oldest buckets are dropped when exceeded.
max_message_age_secondsinteger (1–1209600)0 (disabled)Optional time-based bucket retention: the reaper evicts buckets older than this (up to 14 days). Omit to disable — buckets then stay bounded only by max_buckets.
timezonestring (IANA)(required)Required. A valid IANA timezone (e.g. "UTC", "America/New_York") that bucket boundaries align to; an invalid or missing value is rejected with a 400 at create.
decimal_placesinteger (0–10) | null2Rounding precision (decimal places) for aggregated values. Set to null to keep full precision.
allow_subscriptionsbooleanfalseAllow cross-tenant subscriptions to this time-series.
schema_validation"none" | "partial" | "full""none"Payload validation mode applied to each published event. none = off; partial = every defined field required, extra fields allowed; full = exact match, no extra fields. Frozen after creation.
schemaobject | nullnullJSON Schema (an object schema with a non-empty properties map) validated against each published event. Required when schema_validation is partial or full. Frozen after creation.

Publish Flow

sequenceDiagram participant C as Client participant API as Server participant DB as Database participant Sub as Subs C->>API: POST /publish {data point} API->>API: Validate fields API->>API: Determine bucket API->>DB: Upsert bucket (OHLC) Note over DB: open (first), high (max), low (min),
close (latest), sum, count, avg DB-->>API: Bucket updated API->>Sub: Fan-out to subs API-->>C: 200 OK {bucket}

Query Flows

sequenceDiagram participant C as Client participant API as Server participant DB as Database Note over C,API: Range query C->>API: POST /buckets (range query) API->>DB: Fetch buckets in range DB-->>API: Bucket array API-->>C: 200 OK {buckets[], count} Note over C,API: Current bucket C->>API: GET /buckets/current API->>DB: Fetch active bucket DB-->>API: Current bucket stats API-->>C: 200 OK {bucket} Note over C,API: Latest completed bucket C->>API: GET /buckets/latest API->>DB: Fetch latest bucket DB-->>API: Latest bucket stats API-->>C: 200 OK {bucket}

Key Behaviors

Stream-to-One

stream-to-one

The Stream-to-One queue combines the single-consumer delivery model of One-to-One with automatic data enrichment. On publish, the API performs a foreign key lookup against a linked Key-Value queue and merges the lookup data into the message payload before encryption and storage. If the lookup fails, the message is either rejected (with a DLQ entry) or deferred for later enrichment, depending on the missing_lookup policy. Consumption follows the same visibility-key-enforced, lease-based pattern as One-to-One.

Settings

SettingTypeDefaultDescription
primary_keystring | string[]"message_id"Field(s) for deduplication hash within this queue.
visibility_keystring | string[](required)Field(s) for in-flight exclusivity, same as One-to-One.
foreign_keystring | string[](required)Field(s) in the incoming payload whose value is looked up against the linked Key-Value queue's primary key. The field names may differ.
lookup_queue_idstring(required)Id of the Key-Value queue to join with on publish.
missing_lookup"reject" | "defer""reject"What to do when the foreign key is not found in the lookup queue. "reject" sends to DLQ; "defer" stores as pending.
consume_ttl_secondsinteger (0–300)60Lease duration in seconds.
max_message_age_secondsinteger (1–1209600)86400Maximum message age before dead-lettering.
max_queue_depthinteger (0–100000)10000Maximum number of messages in the queue (0 = unlimited).
overflow_policy"reject" | "drop_oldest_append""reject"Behaviour when max_queue_depth is reached.
auto_ackbooleanfalseAuto-acknowledge on consume.
allow_subscriptionsbooleanfalseAllow cross-tenant subscriptions.
masking_rulesobject[] | nullnullOptional data masking or tokenization rules.
schema_validation"none" | "partial" | "full""none"Payload validation mode. none = off; partial = every defined field required, extra fields allowed; full = exact match, no extra fields. A failing payload is rejected with 400. Frozen after creation.
schemaobject | nullnullJSON Schema (an object schema with a non-empty properties map) validated against each published payload. Required when schema_validation is partial or full. Frozen after creation.

Publish + Enrichment Flow

sequenceDiagram participant C as Client participant API as Server participant KV as KV Queue participant DB as Database C->>API: POST /publish API->>KV: Lookup foreign key alt Found KV-->>API: Customer data API->>API: Merge payload + lookup API->>API: Apply masking API->>API: Encrypt enriched payload API->>DB: Publish enriched message API-->>C: 200 OK {message_id} else Not Found (reject mode) KV-->>API: Not found API->>DB: Send to DLQ API-->>C: 422 Lookup failed else Not Found (defer mode) KV-->>API: Not found API->>DB: Store as pending API-->>C: 200 OK (deferred) end

Consume Flow

sequenceDiagram participant C as Client participant API as Server participant DB as Database C->>API: POST /consume API->>DB: Find next (visibility key) DB-->>API: Enriched msg + lease API->>API: Decrypt payload API-->>C: 200 OK (enriched) Note over C: Process enriched message... alt Acknowledge C->>API: POST /ack API->>DB: Delete message API-->>C: 200 OK else Nack - Requeue C->>API: POST /nack (requeue) API->>DB: Return to queue API-->>C: 200 OK else Nack - Dead Letter C->>API: POST /nack (deadletter) API->>DB: Move to DLQ API-->>C: 200 OK end

Key Behaviors

Stream-to-Many

stream-to-many

The Stream-to-Many queue is the multi-consumer variant of Stream-to-One. It performs the same automatic Key-Value lookup enrichment on publish, but delivers independent copies to multiple consumers — just like One-to-Many. There is no visibility key; each consumer independently tracks their position and acknowledges messages at their own pace.

Settings

SettingTypeDefaultDescription
primary_keystring | string[]"message_id"Field(s) for deduplication hash within this queue.
foreign_keystring | string[](required)Field(s) used as the lookup key against the linked Key-Value queue.
lookup_queue_idstring(required)Id of the Key-Value queue to join with on publish.
missing_lookup"reject" | "defer""reject"Policy when the foreign key is not found: reject to DLQ, or defer until the key appears.
consume_ttl_secondsinteger (0–300)60Lease duration per consumer.
max_message_age_secondsinteger (1–1209600)86400Maximum message age before dead-lettering.
max_queue_depthinteger (0–100000)10000Maximum number of messages in the queue (0 = unlimited).
overflow_policy"reject" | "drop_oldest_append""reject"Behaviour when max_queue_depth is reached.
auto_ackbooleanfalseAuto-acknowledge on consume.
allow_subscriptionsbooleanfalseAllow cross-tenant subscriptions.
masking_rulesobject[] | nullnullOptional data masking or tokenization rules.
schema_validation"none" | "partial" | "full""none"Payload validation mode. none = off; partial = every defined field required, extra fields allowed; full = exact match, no extra fields. A failing payload is rejected with 400. Frozen after creation.
schemaobject | nullnullJSON Schema (an object schema with a non-empty properties map) validated against each published payload. Required when schema_validation is partial or full. Frozen after creation.

Publish + Enrichment Flow

sequenceDiagram participant C as Client participant API as Server participant KV as KV Queue participant DB as Database C->>API: POST /publish API->>KV: Lookup foreign key alt Found KV-->>API: Customer data API->>API: Merge payload + lookup API->>API: Apply masking API->>API: Encrypt enriched payload API->>DB: Publish enriched message API-->>C: 200 OK {message_id} else Not Found (reject mode) KV-->>API: Not found API->>DB: Send to DLQ API-->>C: 422 Lookup failed else Not Found (defer mode) KV-->>API: Not found API->>DB: Store as pending API-->>C: 200 OK (deferred) end

Consume Flow

sequenceDiagram participant C1 as Consumer A participant C2 as Consumer B participant API as Server participant DB as Database C1->>API: POST /consume API->>DB: Next unread (Consumer A) DB-->>API: Enriched msg + lease API->>API: Decrypt payload API-->>C1: 200 OK (enriched payload) C2->>API: POST /consume API->>DB: Next unread (Consumer B) DB-->>API: Enriched msg + lease API-->>C2: 200 OK (enriched payload) Note over C1,C2: Each consumer independently acks/nacks C1->>API: POST /ack API-->>C1: 200 OK C2->>API: POST /nack (requeue) API->>DB: Requeue for B API-->>C2: 200 OK

Key Behaviors

Document

document

The Document queue is a repository for whole files. Unlike the message queue types, an uploaded XML, CSV, or JSON document is stored intact as a single item — it is never split into per-record messages. Clients list the stored documents, download an individual document in the format they ask for, and delete it. There is no consume/ack/nack cycle and no dead letter queue: a download is non-destructive, and a document stays until it is explicitly deleted or expires.

Settings

SettingTypeDefaultDescription
document_ttl_secondsinteger (1–2592000)2592000 (30 days)Retention in seconds; documents older than the TTL are hard-deleted by the reaper. Capped at 30 days and cannot be disabled (defaults to the 30-day maximum). Editable after creation.
max_queue_depthinteger (0–100000)0 (unlimited)Optional cap on the number of stored documents; an upload beyond it is rejected with 429. 0 = unlimited.
allow_subscriptionsbooleanfalseAllow cross-tenant document subscriptions from this queue (document → document fan-out).

Upload

POST /queues/{id}/documents with the raw file as the body and Content-Type set to the file's format (application/json, text/csv, or application/xml). Two headers are required: X-Document-Name and X-Document-Description. The document must be convertible to JSON or the upload is rejected. Maximum size is 1 MB. Duplicate filenames are allowed — each upload is an independent document with its own id.

List & Download

GET /queues/{id}/documents returns a paginated list (filename, description, size, upload time) with optional filename-prefix and uploaded-at filters. GET /queues/{id}/documents/{doc_id} downloads one document; the Accept header selects the format (JSON / CSV / XML) and the broker converts on the fly — the original format is returned byte-exact. The name and description come back as X-Document-Name / X-Document-Description response headers.

Delete

DELETE /queues/{id}/documents/{doc_id} removes a document. Only consumers may delete — upload requires the publish permission; list, download, and delete require the consume permission.

Cross-Tenant Fan-Out

A document queue can be a subscription source (allow_subscriptions). Each uploaded document is fanned out to subscriber tenants' document queues, re-encrypted under each subscriber's own key. Delivered copies are independent — a source-side delete or TTL expiry does not cascade to subscribers, and re-delivery is idempotent.

Key Behaviors

Text Document

text-document

The Text Document queue is a repository for plain-text files. It is the text/plain sibling of the Document queue: an uploaded document is stored intact as a single item and returned exactly as it was uploaded. Unlike the Document queue, text is treated as an opaque blob — it is never parsed, canonicalised to JSON, or converted between formats. Everything else (listing, download, delete, retention, cross-tenant fan-out, permissions) works exactly like the Document queue.

Settings

SettingTypeDefaultDescription
document_ttl_secondsinteger (1–2592000)2592000 (30 days)Retention in seconds; documents older than the TTL are hard-deleted by the reaper. Capped at 30 days and cannot be disabled (defaults to the 30-day maximum). Editable after creation.
max_queue_depthinteger (0–100000)0 (unlimited)Optional cap on the number of stored documents; an upload beyond it is rejected with 429. 0 = unlimited.
allow_subscriptionsbooleanfalseAllow cross-tenant text-document subscriptions from this queue (text-document → text-document fan-out).

Upload

POST /queues/{id}/documents with the raw file as the body and Content-Type: text/plain. Two headers are required: X-Document-Name and X-Document-Description. The body is stored verbatim — there is no JSON/CSV/XML validation, so any UTF-8 text is accepted. A non-text/plain Content-Type is rejected with 415. Maximum size is 1 MB; duplicate filenames are allowed (each upload is an independent document with its own id).

List & Download

GET /queues/{id}/documents returns the same paginated list as the Document queue. GET /queues/{id}/documents/{doc_id} downloads one document and always returns it verbatim as text/plain — the Accept header is ignored and no conversion is attempted, because the stored text is not structured.

Delete

DELETE /queues/{id}/documents/{doc_id} removes a document. Only consumers may delete — upload requires the publish permission; list, download, and delete require the consume permission.

Cross-Tenant Fan-Out

A text-document queue can be a subscription source (allow_subscriptions). Each uploaded document is fanned out to subscriber tenants' text-document queues, re-encrypted under each subscriber's own key. Delivered copies are independent — a source-side delete or TTL expiry does not cascade to subscribers, and re-delivery is idempotent.

Key Behaviors

Cross-Cutting Features

Cross-Tenant Subscriptions

Any queue type can opt in to cross-tenant subscriptions by setting allow_subscriptions: true. When a subscriber tenant creates a subscription, every message published to the source queue is automatically fan-out copied to the subscriber's queue. The subscriber's queue must match the source queue's type. Subscriptions are managed by the subscribing tenant and can be removed at any time.

sequenceDiagram participant Pub as Publisher (Tenant A) participant API as Server participant SrcQ as Source Queue (Tenant A) participant SubQ as Subscriber Queue (Tenant B) Pub->>API: POST /publish {payload} API->>SrcQ: Store in source queue API->>API: Check subscriptions API->>SubQ: Copy to subscriber Note over SubQ: Tenant B consumes independently

Overflow Policies

Depth limits apply to the message queue types. When a queue's max_queue_depth is set (non-zero), the overflow policy determines what happens when the queue is full:

  • reject (default) — the publish request is rejected with a 409 Conflict. The publisher must retry or handle the backpressure.
  • drop_oldest_append — the oldest message in the queue is silently removed to make room for the new message. Useful for "latest N" patterns where older data is less valuable.

Document queues have no overflow policy, but they do support an optional max_queue_depth document-count cap (an upload beyond it is rejected with 429); otherwise they are bounded by the per-document 1 MB size cap and optional document_ttl_seconds retention.

Retention Ceiling

Retention is bounded and cannot be disabled. Messages (and their dead letters) are capped at 14 days; documents are capped at 30 days. An explicit max_message_age_seconds (1–1,209,600) or document_ttl_seconds (1–2,592,000) is required — a 0 "keep forever" value is rejected. The message limit is measured from publish and applies across a message's whole lifetime: a message moved to the dead-letter queue is still hard-deleted once it is 14 days past publish, so time spent queued plus time spent dead-lettered never exceeds the ceiling. (Time-series buckets are aggregates rather than messages and are bounded instead by max_buckets.)

Message Size Limits

Each message payload is limited to 10 KB — an over-limit publish is rejected with a 413. This applies to every message queue type and to each record of a batch or file publish, so a batch is bounded by the per-message limit rather than a fixed message count (there is no hard cap on the number of records in a request). Messages are meant to be small events; large payloads belong in a Document queue, which stores each file whole under a separate 1 MB cap.

Content Types

All queue types support publishing and consuming in JSON, CSV, and XML formats. Set the Content-Type header on publish and the Accept header on consume to control the format. The broker automatically converts between formats — publish in CSV, consume in JSON, or any other combination. Internal storage is always JSON; conversion happens transparently at the API boundary.

Batch Publishing

Publish many records in one request — a JSON array, a multi-row CSV, or a multi-element XML document. The X-Batch-Mode header controls the semantics: best-effort (default) publishes every record that passes validation and returns a per-record results/errors report, while all-or-nothing validates every record first and publishes nothing if any record fails (for example a missing primary key).

File Upload

Upload a whole CSV, XML, or JSON file to POST /publish/file (up to 1 MB). A file is treated as one document and is always all-or-nothing: the entire file must parse and every record must be valid (a JSON object carrying the queue's primary key, within the 10 KB per-message limit) — otherwise the upload is rejected and nothing is published.

Payload Schema Validation

Any queue type can enforce a JSON Schema on every published payload. The schema and its mode (schema + schema_validation) are set at queue creation and frozen afterwards. Validation governs the top level of the payload — every field named in the schema's properties is required in both modes, and the mode controls whether unlisted fields are allowed:

  • none (default) — no validation; any payload is accepted.
  • partial — all defined fields are required, but the payload may carry additional fields the schema doesn't list. Good for evolving payloads where only the core fields are guaranteed.
  • full — exact match: all defined fields required and no extra fields permitted. A payload that fails validation is rejected with a 400.