Skip to content

SNS

Amazon Simple Notification Service for pub/sub messaging, fan-out to queues and Lambda, and mobile push notifications.

Protocol: AwsJson1_0 (X-Amz-Target: AmazonSimpleNotificationService.*) Signing name: snsPersistent: Yes

Quick Start

Create a topic, subscribe an SQS queue, and publish a message:

bash
# Create a topic
TOPIC_ARN=$(curl -s http://localhost:4566 \
  -H "Content-Type: application/x-amz-json-1.0" \
  -H "X-Amz-Target: AmazonSimpleNotificationService.CreateTopic" \
  -H "Authorization: AWS4-HMAC-SHA256 Credential=test/20260421/us-east-1/sns/aws4_request, SignedHeaders=host, Signature=fake" \
  -d '{"Name":"my-topic"}' \
  | jq -r '.TopicArn')

echo "Topic ARN: $TOPIC_ARN"

# Subscribe an SQS queue to the topic
curl -s http://localhost:4566 \
  -H "Content-Type: application/x-amz-json-1.0" \
  -H "X-Amz-Target: AmazonSimpleNotificationService.Subscribe" \
  -H "Authorization: AWS4-HMAC-SHA256 Credential=test/20260421/us-east-1/sns/aws4_request, SignedHeaders=host, Signature=fake" \
  -d "{\"TopicArn\":\"$TOPIC_ARN\",\"Protocol\":\"sqs\",\"Endpoint\":\"arn:aws:sqs:us-east-1:000000000000:my-queue\"}"

# Publish a message
curl -s http://localhost:4566 \
  -H "Content-Type: application/x-amz-json-1.0" \
  -H "X-Amz-Target: AmazonSimpleNotificationService.Publish" \
  -H "Authorization: AWS4-HMAC-SHA256 Credential=test/20260421/us-east-1/sns/aws4_request, SignedHeaders=host, Signature=fake" \
  -d "{\"TopicArn\":\"$TOPIC_ARN\",\"Message\":\"Hello subscribers!\",\"Subject\":\"Test message\"}"

Operations

Topics

OperationDescription
CreateTopicCreate a topic (standard or FIFO). Input: Name, optional Attributes ({FifoTopic: "true", ContentBasedDeduplication: "true"}), Tags. Returns: TopicArn
DeleteTopicDelete a topic and all its subscriptions. Input: TopicArn
ListTopicsList all topics with pagination. Returns: Topics list with TopicArn
GetTopicAttributesGet topic configuration. Input: TopicArn. Returns: map of attribute names to values (policy, subscriptions count, etc.)
SetTopicAttributesSet a specific topic attribute. Input: TopicArn, AttributeName, AttributeValue

Subscriptions

OperationDescription
SubscribeSubscribe an endpoint to a topic. Input: TopicArn, Protocol (see below), Endpoint (ARN or URL), optional Attributes (filter policy, raw message delivery). Returns: SubscriptionArn
UnsubscribeRemove a subscription. Input: SubscriptionArn
ListSubscriptionsList all subscriptions across all topics. Returns paginated Subscriptions
ListSubscriptionsByTopicList subscriptions for a specific topic. Input: TopicArn
GetSubscriptionAttributesGet subscription attributes. Input: SubscriptionArn
SetSubscriptionAttributesUpdate subscription attributes (filter policy, raw delivery). Input: SubscriptionArn, AttributeName, AttributeValue
ConfirmSubscriptionConfirm a pending subscription (used for HTTP/HTTPS). In AWSim subscriptions are auto-confirmed

Publishing

OperationDescription
PublishPublish a message to a topic. Input: TopicArn, Message (required), Subject, MessageAttributes ({key: {DataType, StringValue}}), MessageStructure (json for per-protocol messages). Returns: MessageId
PublishBatchPublish up to 10 messages in one call. Input: TopicArn, PublishBatchRequestEntries (list of {Id, Message, Subject}). Returns: Successful, Failed

Tags

OperationDescription
TagResourceAdd tags to a topic (by ARN)
UntagResourceRemove tags from a topic
ListTagsForResourceList topic tags

SMS

OperationDescription
CheckIfPhoneNumberIsOptedOutCheck whether a phone number is opted out of receiving SMS messages. Input: phoneNumber. Returns: isOptedOut (boolean)
ListPhoneNumbersOptedOutList phone numbers that are opted out of SMS. Returns paginated phoneNumbers list
GetSMSAttributesGet account-level SMS attributes (default sender ID, monthly spend limit, etc.). Returns: attributes map
SetSMSAttributesSet account-level SMS attributes. Input: attributes map

Supported Subscription Protocols

ProtocolDescription
sqsDelivers to an SQS queue (by queue ARN). AWSim immediately fans out to the queue
lambdaInvokes a Lambda function (by function ARN). AWSim calls the Lambda synchronously
http / httpsDelivers to an HTTP endpoint. Not enforced in local mode (no HTTP call is made)
emailSends email (no email is delivered in AWSim)
email-jsonSends JSON-formatted email

SDK Example

typescript
import {
  SNSClient,
  CreateTopicCommand,
  SubscribeCommand,
  PublishCommand,
  PublishBatchCommand,
  SetSubscriptionAttributesCommand,
} from '@aws-sdk/client-sns';

const sns = new SNSClient({
  region: 'us-east-1',
  endpoint: 'http://localhost:4566',
  credentials: { accessKeyId: 'test', secretAccessKey: 'test' },
});

// Create a standard topic
const { TopicArn } = await sns.send(new CreateTopicCommand({
  Name: 'user-events',
  Attributes: {},
}));

// Subscribe SQS queue for fan-out
const { SubscriptionArn } = await sns.send(new SubscribeCommand({
  TopicArn,
  Protocol: 'sqs',
  Endpoint: 'arn:aws:sqs:us-east-1:000000000000:user-events-queue',
}));

// Subscribe Lambda for processing
await sns.send(new SubscribeCommand({
  TopicArn,
  Protocol: 'lambda',
  Endpoint: 'arn:aws:lambda:us-east-1:000000000000:function:process-user-event',
}));

// Add a filter policy (stored but not enforced in AWSim)
await sns.send(new SetSubscriptionAttributesCommand({
  SubscriptionArn: SubscriptionArn!,
  AttributeName: 'FilterPolicy',
  AttributeValue: JSON.stringify({ eventType: ['signup', 'login'] }),
}));

// Publish with message attributes
const { MessageId } = await sns.send(new PublishCommand({
  TopicArn,
  Message: JSON.stringify({ userId: '123', action: 'signup', timestamp: Date.now() }),
  Subject: 'UserEvent',
  MessageAttributes: {
    eventType: { DataType: 'String', StringValue: 'signup' },
    userId: { DataType: 'String', StringValue: '123' },
  },
}));

console.log('Published message ID:', MessageId);

// Publish batch (up to 10 messages)
const { Successful, Failed } = await sns.send(new PublishBatchCommand({
  TopicArn,
  PublishBatchRequestEntries: [
    { Id: '1', Message: JSON.stringify({ userId: '1', action: 'view' }) },
    { Id: '2', Message: JSON.stringify({ userId: '2', action: 'purchase' }) },
    { Id: '3', Message: JSON.stringify({ userId: '3', action: 'logout' }) },
  ],
}));
console.log('Published:', Successful?.length, 'Failed:', Failed?.length);

CLI Example

bash
# Create topic
aws --endpoint-url http://localhost:4566 sns create-topic --name my-topic

# Subscribe SQS queue
aws --endpoint-url http://localhost:4566 sns subscribe \
  --topic-arn arn:aws:sns:us-east-1:000000000000:my-topic \
  --protocol sqs \
  --notification-endpoint arn:aws:sqs:us-east-1:000000000000:my-queue

# Publish message
aws --endpoint-url http://localhost:4566 sns publish \
  --topic-arn arn:aws:sns:us-east-1:000000000000:my-topic \
  --message '{"event":"order_placed","orderId":"abc123"}' \
  --subject "OrderEvent" \
  --message-attributes '{"eventType":{"DataType":"String","StringValue":"order_placed"}}'

# List subscriptions by topic
aws --endpoint-url http://localhost:4566 sns list-subscriptions-by-topic \
  --topic-arn arn:aws:sns:us-east-1:000000000000:my-topic

Fan-out

When a message is published, AWSim immediately delivers it to:

  • All subscribed SQS queues (message appears in the queue)
  • All subscribed Lambda functions (function is invoked synchronously)

HTTP/HTTPS and email endpoints are registered but not called.

See Cross-Service Integrations.

Behavior Notes

  • SNS is persistent: topics and subscriptions survive AWSim restarts.
  • HTTP/HTTPS subscription confirmation handshake is not performed — subscriptions are auto-confirmed immediately.
  • Subscription filter policies are stored but not enforced — all messages are delivered to all subscribers regardless of attributes.
  • Message attributes are passed through to SQS/Lambda but attribute-based filtering is not applied.
  • FIFO topics (Name.fifo) are accepted but message ordering and deduplication are not strictly enforced.
  • SMS opt-out state (CheckIfPhoneNumberIsOptedOut, ListPhoneNumbersOptedOut) is stored in memory and always returns no opted-out numbers by default.
  • SMS attributes (GetSMSAttributes, SetSMSAttributes) are accepted and stored but no actual SMS messages are delivered in AWSim.

Released under MIT / Apache-2.0 License