# Best Practices

{% hint style="info" %}
These practices are strongly recommended for production use.
{% endhint %}

***

### Handle disconnects gracefully

Network interruptions, proxy timeouts, and server restarts can break the SSE connection at any time.

{% hint style="warning" %}
Do not assume a single SSE connection will stay alive until the scan completes.
{% endhint %}

**What to do**

* Implement reconnection logic using `last_id`
* Resume from the last processed event whenever possible

**Why it matters**\
Without reconnection support, users may lose progress updates or final results when the connection drops unexpectedly.

***

### Set appropriate timeouts

Scans can take up to **90 seconds**.

{% hint style="danger" %}
Use a read timeout of at least **120 seconds**. Shorter timeouts may terminate valid long-running scans.
{% endhint %}

| Setting              | Recommended value |
| -------------------- | ----------------- |
| Scan duration        | Up to 90 seconds  |
| Minimum read timeout | 120 seconds       |

***

### Disable buffering

SSE only works well when events are streamed immediately. If buffering is enabled, updates may arrive late or all at once.

**Make sure buffering is disabled in**

* Your HTTP client
* Reverse proxy
* CDN layer

#### Do / Don’t

| Do                              | Don’t                                           |
| ------------------------------- | ----------------------------------------------- |
| Stream events as they arrive    | Buffer the full response before processing      |
| Validate proxy/CDN SSE behavior | Assume SSE works by default through every layer |

***

### Respect rate limits

Clients should enforce rate limiting before sending requests.

{% hint style="warning" %}
Do not submit more than **30 requests per minute per API key**.
{% endhint %}

**Recommended approach**

* Add client-side throttling or queuing
* Prevent burst submissions from the UI or worker layer

***

### Close the connection after a final event

After receiving a `result` or `error` event, the stream is complete.

**Best practice**

* Close the connection immediately on the client side

**Why this matters**\
The server will close the connection as well, but explicitly closing it helps prevent unnecessary open connections and resource leaks.

***

### Use callbacks for progress updates

Progress events should be handled incrementally as they arrive.

**Recommended approach**

* Use callbacks to update UI state
* Send progress to logs
* Surface real-time feedback to users

#### Do / Don’t

| Do                                   | Don’t                               |
| ------------------------------------ | ----------------------------------- |
| Process progress events in real time | Store all progress events in memory |
| Update UI/logs incrementally         | Wait until the stream finishes      |

***

### Handle empty `trust_analysis`

When a scan fails, `trust_analysis` will be returned as an empty object.

```json
{}
```

{% hint style="warning" %}
Always check `crawl_status` before accessing nested fields inside `trust_analysis`.
{% endhint %}

**Why it matters**\
Accessing nested analysis fields without validating the scan status may cause runtime errors.

***

### Treat screenshot URLs as temporary

`page_info.screenshot_url` is a pre-signed S3 URL.

{% hint style="danger" %}
The URL expires after **10 minutes**.
{% endhint %}

**Best practice**

* Download the image immediately if needed
* Cache it if the UI may need to display it later

***

### Use `lang` for localization

Pass the user’s preferred language via `lang` to localize reasoning and evidence.

**Behavior**

* Returns reasoning and evidence in the requested language
* Falls back to English if translation fails

**Recommendation**

* Always send `lang` when building multilingual experiences

***

## Quick checklist

Before shipping to production, make sure your integration:

* Handles reconnects with `last_id`
* Uses a read timeout of at least **120 seconds**
* Disables buffering across all SSE layers
* Enforces **30 requests per minute per API key**
* Closes the connection after `result` or `error`
* Processes progress events incrementally
* Checks `crawl_status` before reading `trust_analysis`
* Downloads or caches screenshot URLs before expiration
* Passes `lang` for localized output

{% hint style="success" %}
If your integration passes every item above, you're in a strong position for production readiness.
{% endhint %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://oten.gitbook.io/oten-trust-support/documentation/api-reference/best-practices.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
