All posts
2 min readConvoy Team

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.

productannouncement

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.typeWhere results land
aws_durable_callbackResumes your suspended Lambda durable function in place
aws_sfn_task_tokenResumes a Step Functions .waitForTaskToken state
aws_lambda_invokeAsync-invokes a Lambda function you name with the result
aws_eventbridgePublishes a Cargo Completed / Cargo Failed event onto your bus
aws_sqsSends to your queue — FIFO dedupes sends for 5 min; stay idempotent
aws_kinesisPuts a record on your stream, partition key of your choosing
aws_sfn_startStarts a new state machine execution named convoy-{cargo_id}
aws_s3Writes 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:SendMessage on your queue, events:PutEvents on your bus, s3:PutObject on 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.

More posts

All Aboard?

Ready to simplify your batch processing and start saving on AI costs? Get started in minutes.