SQS data feed
AWS Simple Queue Service (SQS) is a buffered transport for trading facts, approved aggregates, backfills, and replayable exports. It is a delivery step, not a reward result. The queue, Event Ingest trigger, workflow, and user readback must each be checked.
Acceptance is one checkpoint
A successful SQS send proves that AWS accepted a message. It does not prove Event Ingest validation, workflow execution, a saved user value, or a refreshed widget. Keep the message identity and source event time so the next checkpoint can be traced without sending the event again.
From source facts to an authoritative value
Ownership and asynchronous boundaries stay visible in the text order below.
- Broker data owner
Resolve each account to the canonical customer, classify symbols, and retain immutable source IDs and original close times.
- Broker transport owner
Serialize the complete Event Ingest envelope, keep the agreed body budget, and record the returned SQS message ID.
Validate and persist Event Ingest
Returning.AI data workflowCheck the configured trigger, batch path, record paths, and row results. Queue acceptance is not this checkpoint.
- Returning.AI workflow owner
Follow dispatcher and workflow history separately from the persisted ingest row.
- Returning.AI data owner
Inspect any queued user update and per-row failures, then use the operation-specific authoritative readback.
- Portal owner
Check the displayed value for the same signed-in user after readback confirms the saved update. Token renewal is separate authentication work.
When to use SQS
Direct SQS requires a provisioned queue and AWS permissions. Some brokers instead receive a provisioned HTTP or multipart file endpoint. Choose the transport that the integration owner has actually provisioned.
| Transport | Choose it for | Acceptance proves | Confirm with |
|---|---|---|---|
| Direct AWS SQS | Buffered facts, replayable exports, and high-volume delivery. | The individual AWS send was accepted. Inspect each batch entry. | Integration owner: queue, IAM role, region, DLQ, and sender access. |
| Provisioned HTTP JSON | A broker-facing ingest gateway when one has been supplied. | The gateway accepted the request. Follow Event Ingest afterward. | Platform owner: URL, x-api-key permission, and body limit. |
| Provisioned multipart file | CSV batches above the agreed direct-message budget. | The application queued the file job if its response says so. | Returning.AI owner: URL, auth, edge limit, and multi-chunk identity contract. |
| Workflow webhook | Configured lifecycle events such as registration or KYC. | The configured webhook request reached its queue. | Workflow webhook guide. |
Message shape
Use the root Event Ingest envelope only when the configured trigger expects it. The trigger_id is a fixed ObjectId for that configured integration, not a new value for each message. If batch dedupe is enabled, the configured path must be checked before sending. In the documented contract, metadata.batch_id is at the root, whiledata contains complete rows.
{
"trigger_id": "<FIXED_EVENT_INGEST_TRIGGER_OBJECT_ID>",
"metadata": {
"source": "broker-dwh",
"batch_id": "trades-2026-09-07-001"
},
"data": [
{
"customer_id": "CUSTOMER_1001",
"source_event_id": "deal-2001-fx-001",
"occurred_at": "2026-09-07T10:15:00.000Z",
"event_type": "trade.closed",
"platform": "mt5",
"server": "broker-live-1",
"account_login": "ACCOUNT_2001",
"raw_symbol": "EURUSD.a",
"normalized_volume": 1.2,
"volume_unit": "standard_lot"
}
]
}The row names above are a synthetic example mapping, not a universal Returning.AI trading schema. Confirm the workflow's fields, required record ID path, asset-class mapping, and unit conversion with the setup owner. Keep account lineage and source IDs even when the delivered row is an aggregate.
Sender setup
- Store the fixed trigger reference and provisioned transport settings on the server. Keep AWS IAM credentials or a data-ingest key out of browser code and logs.
- Build the complete serialized envelope before measuring it. Count UTF-8 bytes, including root metadata, row data, and any chunk identity fields.
- Send one candidate or an AWS batch only after it fits the agreed budget. For
SendMessageBatch, inspect every successful and failed entry even when the HTTP response is 200. - Record the logical batch ID, transport chunk ID, source record IDs, and original event times for reconciliation. Do not log credentials or full customer exports.
The repository example is a no-network packaging helper. It prepares JSON candidates and prints their sizes; it never sends to AWS or a Returning.AI endpoint.
Download the no-network data-feed example. Requires Node.js 20 or newer. This is a tested packaging example, not a live sender.
unzip data-feed.zip
cd data-feed
npm ci
npm test
npm run demoLarge payloads and byte budgets
AWS SQS currently allows up to 1,048,576 bytes (1 MiB) per message. SendMessageBatch allows up to 10 messages and a 1 MiB aggregate payload ceiling. These AWS limits are separate from the lower limit of a provisioned queue, HTTP gateway, file route, or sender choice.
| Limit or budget | How to use it | Status |
|---|---|---|
| AWS message size | At most 1,048,576 bytes for one SQS message. | AWS documented limit |
| AWS batch request | At most 10 messages and 1 MiB aggregate payload; inspect per-entry results. | AWS documented limit |
| Conservative sender body budget | Use no more than 256 KiB when that is the agreed application budget. Count the full serialized envelope and chunk identity overhead. | Sender choice, not an AWS or universal receiver maximum |
| Attributes and request overhead | Message attributes also count toward AWS message size. Reserve room for them inside the AWS budget; gateway request limits are separate. Do not size from row text alone. | Sender responsibility |
| HTTP or file limit | Use only the body or multipart size supplied for the provisioned environment. A source default is not proof of the deployed edge limit. | Returning.AI setup owner must confirm |
See the verified AWS references for the message quotas and SendMessageBatch request.
File option: provisioned multipart CSV
Use a file only when Returning.AI has provisioned the URL, credentials, effective edge limit, and a multi-chunk identity and dedupe contract for the configured trigger. The command below intentionally uses named values, not a guessed public route.
curl --fail-with-body -sS -X POST \
"<PROVISIONED_FILE_INGEST_URL>?trigger_id=<FIXED_EVENT_INGEST_TRIGGER_OBJECT_ID>" \
-H "x-api-key: <PROVISIONED_DATA_WORKFLOW_KEY>" \
-F "data=@trades-2026-09-07.csv;type=text/csv" \
-F 'metadata={"source":"broker-dwh","batch_id":"file-2026-09-07-001"}'Do not use blind file fallback
A file path can preserve the same root metadata.batch_idacross chunks. If the trigger dedupes on that value, later chunks can be skipped. Before using file ingest, have the Returning.AI owner prove that every expected row in a multi-chunk upload reaches its final result under the provisioned dedupe settings. Keep the logical file batch, chunk identity, and row source IDs separate.
A response such as queued: true means the file job was accepted by the application path. It does not mean that all rows passed validation or that a reward was applied. Check the persisted ingest result and downstream workflow status.
Dedupe and retry identities
Dedupe has more than one boundary. Confirm which paths are configured on the actual trigger before promising replay behavior.
| Identity | Example | Rule |
|---|---|---|
| Integration trigger | trigger_id | Fixed for the configured Event Ingest integration. |
| Logical source batch | trades-2026-09-07-001 | Names the source export or window. It is not automatically a safe correction key. |
| Transport chunk | trades-2026-09-07-001:chunk-1 | Identifies one bounded message in the local helper. Confirm this shape against the deployed batch path. |
| Source record | deal-2001-fx-001 | Keep stable across exact retries when record-level idempotency is configured. |
- Retry an identical logical batch with the same configured identity only when the goal is to suppress an exact duplicate. A missing configured identity is not proof that a retry is safe.
- Persist each exact serialized body and its chunk plan. Do not change record order, metadata, or byte budget and reuse the same logical batch ID: an existing chunk ID could then refer to different records.
- A changed payload needs an approved correction policy. A new batch ID can create a second additive reward; it is not a generic correction method.
- Preserve the original
occurred_atand source record ID on a retry. Do not replace business event time with retry time. - Do not send both raw deals and their derived user aggregate to the same additive reward workflow unless one is explicitly non-crediting lineage.
Operational checks
Follow the delivery in order. If a checkpoint is missing, ask the owner for the named diagnostic rather than sending the same payload again.
| Checkpoint | Evidence to record | Does not prove |
|---|---|---|
| Transport accepted | SQS message ID, or the provisioned HTTP/file response. | Event validation or workflow completion. |
| Event Ingest persisted | Trigger, received payload, status, duplicate count, and failure reason. | Workflow execution or user mutation. |
| Dispatcher and workflow | Queued time, history ID or Returning.AI-owned diagnostic, and terminal status. | Final saved field or balance. |
| User update | Job status and per-row result when a configured bulk update exists, or its results callback if the step sends one. | Widget cache or browser display. |
| Authoritative readback | Before value, expected change, after value, and source identity. | Correctness of an unverified mapping. |
| Widget refresh | Same signed-in identity and the value shown after refreshing saved state. Token renewal does not prove data processing. | Revocation of an already-issued token. |
Next step
If the input is trading activity, define the canonical-user aggregation and units in the trading volume and rewards guide. If the input is registration, KYC, or another lifecycle event, use the workflow webhook guide instead. For the browser result, return to the widget quickstart only after the saved user state is confirmed.