Eight AWS-Native Delivery Targets for Your Batch Results
Convoy now delivers batch results straight into SQS, Kinesis, EventBridge, S3, Lambda, and Step Functions — your IAM role, no webhook endpoint required.
Until now, getting batch results out of Convoy meant one of two things: a webhook POST to your endpoint, or polling the result mailbox. Both work, but if your architecture already lives on AWS, a webhook receiver is a public endpoint you have to build, protect, and keep running — just to move a JSON payload from our account to yours.
Today that's optional. Convoy can now deliver cargo results directly into eight AWS-native targets, using a narrowly-scoped IAM role in your account instead of a URL.
The targets
callback.type | Where results land |
|---|---|
aws_durable_callback | Resumes your suspended Lambda durable function in place |
aws_sfn_task_token | Resumes a Step Functions .waitForTaskToken state |
aws_lambda_invoke | Async-invokes a Lambda function you name with the result |
aws_eventbridge | Publishes a Cargo Completed / Cargo Failed event onto your bus |
aws_sqs | Sends to your queue — FIFO dedupes sends for 5 min; stay idempotent |
aws_kinesis | Puts a record on your stream, partition key of your choosing |
aws_sfn_start | Starts a new state machine execution named convoy-{cargo_id} |
aws_s3 | Writes the full, uncapped result to {prefix}{cargo_id}.json |
Using one is a single field on /cargo/load — pass a callback object
instead of a callback_url:
{
"callback": {
"type": "aws_sqs",
"connection_id": "awsconn_...",
"queue_arn": "arn:aws:sqs:us-east-1:123456789012:cargo-results.fifo",
"message_group_id": "tenant-acme"
}
}
Every target delivers the same result envelope (cargo_id, success,
response, your metadata), with two durable-callback caveats: results
too large to inline arrive with response: null and a result_url field
for fetching the full body, and a failed cargo raises a CallbackError in
your durable function rather than returning a failure envelope. For
aws_sqs, FIFO deduplication only covers sends within a five-minute
window — a message whose visibility timeout expires before deletion is
delivered again, so consumers must be idempotent.
One security model, least privilege by design
All eight targets share the same connection model, built around the direct durable callback we shipped alongside this release:
- The dashboard's Connect AWS wizard registers a connection and hands
you a one-time
cnvyext_...ExternalId. - You create an IAM role that trusts Convoy's delivery account only
with that ExternalId, and grants only one target's action on only
the resources you name —
sqs:SendMessageon your queue,events:PutEventson your bus,s3:PutObjecton your prefix (write-only; Convoy can never read or list your bucket), and so on. - A verification probe confirms the grant before any cargo flows, and revoking the connection stops delivery immediately.
We publish one CloudFormation template per target plus Terraform
equivalents, so the whole setup is a wizard run and one deploy command.
Why this matters
Batch results arriving hours later shouldn't force a synchronous HTTP shape onto your system. Queue consumers want a queue. Event-driven architectures want a bus. Step Functions workflows want their task token back. Large results want S3, not a 256 KB webhook body. Now each of those gets results in its native shape — with IAM as the auth and nothing public to protect.
The full guides are in the integration docs. Ready to delete a webhook receiver? Create a Convoy account and wire up your first AWS target in minutes.