> ## Documentation Index
> Fetch the complete documentation index at: https://developers.resistant.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Amazon SQS 

Amazon SQS event notifications provide an alternative to synchronous polling by notifying your systems when an analysis step completes. Events are delivered to your **Amazon SQS queue**, enabling scalable event-driven processing.

<Info>
  SQS event notifications are available subject to prior agreement and may involve an additional fee.
</Info>

***

## When to use SQS (vs polling)

Use SQS if you:

* Want to reduce polling traffic and latency-to-action
* Already operate AWS workloads and queues
* Process high volumes and prefer async consumption

Stick with polling if you:

* Want the simplest integration (no AWS infrastructure)
* Only have low/medium throughput

***

## How it works (high level)

* Events are delivered to your SQS queue in the target region.
* Resistant AI assumes a role in your AWS account using AWS STS; the **`tenant ID is used as ExternalId`**.
* Your consumer receives an event and then fetches the full result from the Documents API using `result_url`.

<img src="https://mintcdn.com/resistantai/D5OIGucA_1iVDM89/images/aws_sqs_event_notification_schema.png?fit=max&auto=format&n=D5OIGucA_1iVDM89&q=85&s=b5aff7b68b84e8f653c837d0bc1ad373" alt="Aws Sqs Event Notification Schema" title="Aws Sqs Event Notification Schema" className="mx-auto" style={{ width:"74%" }} width="1132" height="570" data-path="images/aws_sqs_event_notification_schema.png" />

***

## Supported events

Event notifications are available for the following analysis outputs:

* `documents.analysis.fraud.finished`
* `documents.analysis.quality.finished`
* `documents.analysis.classification.finished`

***

## Integration steps

### 1) Resistant AI provides configuration details

Resistant AI provides:

* example templates for setup
* the AWS Account ID used by Resistant AI
* your **tenant ID** (used as `ExternalId`)

### 2) You configure AWS infrastructure

You deploy:

* an SQS queue (and optionally DLQ)
* an IAM role that Resistant AI can assume

Then you provide to Resistant AI:

* **Role ARN**
* **Queue ARN**

### 3) Integration testing

You and Resistant AI validate:

* the role can be assumed successfully
* messages can be published to your queue

***

## Security and architecture notes

SQS delivery uses AWS STS AssumeRole with temporary credentials, reducing credential lifetime and avoiding static key sharing.

**AssumeRole model**

* Resistant AI assumes your role
* `ExternalId` = your tenant ID

***

## Limitations and important considerations

* **Single destination:** each tenant can have only one event destination.
* **KMS note:** a KMS key is not specified in the API call used to publish messages; your queue resource policy must support your encryption setup.

***

## Event schema

Each SQS message contains:

```typescript theme={null}
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "title": "Resistant.ai document analysis event",
  "type": "object",
  "properties": {
    "tenant_id": {
      "description": "Internal Resistant.ai identifier of tenant",
      "type": "string"
    },
    "submission_id": {
      "description": "Submission identifier as produced by the create submission request",
      "type": "string"
    },
    "query_id": {
      "description": "User-defined ID of analyzed file as given in the create submission request",
      "type": "string",
      "nullable": true
    },
    "event_type": {
      "description": "Type of event: documents.analysis.fraud.finished or documents.analysis.quality.finished or documents.analysis.classification.finished",
      "type": "string"
    },
    "status": {
      "description": "Status of the analysis step result",
      "type": "string",
      "enum": ["SUCCESS", "SKIPPED", "INVALID_INPUT", "FAILED"]
    },
    "score": {
      "description": "Result of the analysis. Content depends on event_type. Examples: NORMAL/TRUSTED/WARNING/HIGH_RISK (fraud); HIGH_QUALITY/LOW_QUALITY/NOT_RELEVANT_DOCUMENT (quality); CLASSIFIED/DOCUMENT_MISSING/NOT_CLASSIFIED (classification).",
      "type": "string",
      "nullable": true
    },
    "result_url": {
      "description": "URL where more details about the analysis result can be fetched with a GET request",
      "type": "string"
    }
  }
}
```

***

## Typical Consumer Pattern

```python theme={null}
import boto3, json

sqs = boto3.client("sqs", region_name="eu-west-1")
queue_url = "https://sqs.eu-west-1.amazonaws.com/123456789/my-rai-queue"

while True:
    messages = sqs.receive_message(QueueUrl=queue_url, MaxNumberOfMessages=10, WaitTimeSeconds=20)
    for msg in messages.get("Messages", []):
        event = json.loads(msg["Body"])
        if event["status"] == "SUCCESS":
            fetch_details(event["result_url"])  # GET the result_url
        sqs.delete_message(QueueUrl=queue_url, ReceiptHandle=msg["ReceiptHandle"])
```

***
