> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://cla-demo.postmansolutions.com/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://cla-demo.postmansolutions.com/_mcp/server.

# Postal Service

## 1. Summary

The Postal Service is a **message routing microservice** that ensures platform-generated messages are delivered to the appropriate client application (platform tenant). It does not modify, parse, or template messages. Instead, it forwards them exactly as received via HTTP POST to the client's registered endpoint.

This approach minimizes integration friction while enabling observability, fairness, and operational consistency at scale.

## 2. Why This Matters

Many delivery mechanisms today rely on implied behavior, like silent retries or default timeouts, that can lead to missed messages, confusing logs, or inconsistent client experience.

We're aiming to solve that by building a system where:

* Delivery decisions are based on clear conditions (like time and registration status),
* Failures are surfaced immediately and handled explicitly,
* Retry logic is controlled and predictable,
* Clients always know what to expect.

This reduces confusion, accelerates onboarding, and simplifies support.

## 3. Key Characteristics

* **Structured delivery flow**: Messages are evaluated and sent based on clear metadata (e.g. which client they belong to and when they should be delivered).
* **Safe retry behavior**: The system retries failed deliveries with exponential backoff, avoiding overwhelming clients or silently repeating indefinitely.
* **Clarity over cleverness**: We avoid guesswork and defaults. Everything, including registration, retry timing, and routing, is explicitly defined.
* **Time-aware without being time-fragile**: The system expects a consistent sense of time (e.g. NTP-synced infrastructure) and uses delayed Service Bus enqueue for precise retry scheduling.

## 4. System Components

| Component                      | Description                                                                                                  |
| ------------------------------ | ------------------------------------------------------------------------------------------------------------ |
| **To-Send Topic**              | Central Service Bus topic where messages are published for delivery.                                         |
| **Message Processing Runtime** | Listens to the to-send topic and routes messages to the correct client destination via HTTP POST.            |
| **Registration Service**       | External microservice that stores client application delivery endpoints, queried by Postal on each delivery. |
| **Retry Topic**                | Service Bus topic used to schedule and re-attempt failed deliveries with exponential backoff.                |
| **Retry Service**              | Subscribes to the retry topic, re-attempts delivery, and reschedules with updated backoff timing.            |
| **Problem Topic**              | Receives events for permanently failed deliveries (e.g. unregistered client). Uses RFC 7807 problem format.  |

## 5. What Client-Applications Need to Do

These requirements are introduced during the onboarding of each client-application to the platform. The goal is to keep integration simple, predictable, and consistent across teams.

Client-applications don't need to manage queues, inspect message internals, or participate in custom workflows. Instead, they interact with the platform through a narrow, well-defined delivery contract:

* **Register once** using a unique client-application *name* and HTTP delivery endpoint. Registration is handled through the **Registration Service** as part of the client-application onboarding process.
* **Receive messages via standard HTTP**. Each client-application exposes a lightweight HTTP endpoint that accepts JSON payloads with delivery metadata.
* **Return appropriate status codes**:
  * `2xx` signals successful handling. This is the only accepted success range.

## 6. Delivery Mechanism and Message Format

Postal delivers messages via HTTP POST to the client's registered endpoint.

### Message Payload

Each message has the following shape:

```json
{
  "clientApplicationId": "client-app-123",
  "body": {
    "messageId": "message1111",
    "eventType": "file.extraction.completed",
    "timestamp": "2025-08-01T11:00:00Z",
    "payload": {
      "fileId": "file7777",
      "status": "complete",
      "location": "azure://topic/path/file.csv"
    }
  }
}
```

* `clientApplicationId`: identifies the target client application.
* `body`: arbitrary JSON payload. Postal does not inspect or transform this value; it is forwarded exactly as received.

### 6a. Client Responsibilities

Client applications must:

* **Register** with a unique name and HTTP delivery endpoint via the Registration Service.
* **Expose an HTTP endpoint** that accepts JSON payloads.
* **Return `2xx`** to confirm successful delivery.
* **Handle retries idempotently** to avoid duplicate processing.
* **Monitor** for messages and problem topic entries.

## 7. Developer Integration Checklist

To integrate with Postal:

* Register your client-application name and HTTP endpoint with the Registration Service.
* Expose a valid HTTP endpoint that accepts the message payload format above.
* Ensure your endpoint returns a `2xx` status code on success.
* Implement idempotent handling of messages.
* Monitor retry activity and the problem topic for delivery failures.

## 8. Authentication

### Inbound (requests to Postal)

Incoming HTTP requests are validated using **Azure AD JWT tokens**. The service validates tokens against the Azure AD JWKS endpoint using the configured tenant and client ID.

### Outbound (Postal calling the Registration Service and client endpoints)

Postal authenticates outbound service-to-service calls using **Azure Managed Identity**, acquiring tokens scoped to the configured App ID URI.

## 9. Retry Behavior

When HTTP delivery fails, Postal schedules a retry using Azure Service Bus delayed enqueue (`scheduledEnqueueTimeUtc`). Backoff is exponential, capped at 60 seconds:

| Attempt | Delay |
| ------- | ----- |
| 1       | 10s   |
| 2       | 20s   |
| 3       | 40s   |
| 4+      | 60s   |

Retries also support a **ramp-up** direction: if delivery begins recovering, the retry interval halves on each success, converging back to zero.

Each topic subscription has a `MaxDeliveryCount` of 3. If a message fails that many consecutive attempts at the Service Bus level, it is automatically moved to the subscription's dead-letter queue as a safety backstop.

## 10. Problem Topic

When a delivery failure is **permanent** (e.g. the client application is not registered), Postal publishes a problem event to the **Problem Topic** instead of retrying. Problem events follow the [RFC 7807](https://datatracker.ietf.org/doc/html/rfc7807) format:

```json
{
  "timestamp": "2025-08-01T11:00:00Z",
  "problem": {
    "type": "https://claconnect.com/platform/autoextract/problems/not-found",
    "title": "Not Found",
    "detail": "Client application with ID 'client-app-123' not found.",
    "instance": "client-app-123",
    "status": 404
  }
}
```

A 404 response from the Registration Service is treated as a permanent failure. All other errors trigger the retry flow.

## 11. Diagrams

### Architectural Diagram

```mermaid
graph TD
    A[To-Send Topic] --> B[Postal Service]

    B -->|fetch endpoint| C[Registration Service]
    B -->|HTTP POST| D[Client Application]
    B -->|transient failure| E[Retry Topic]
    B -->|permanent failure| F[Problem Topic]

    E --> G[Retry Service]
    G -->|HTTP POST| D
    G -->|still failing| E
    G -->|permanent failure| F
```

### Message Flow Diagram

```mermaid
graph TD
    A[\Platform Message Sources/] -->|publish| B["to-send" Topic]
    B -->|subscribe| C[Postal Service]

    C -->|lookup endpoint| H[Registration Service]
    C -->|attempt delivery| D[Client Application]
    C -->|transient error| E[Retry Topic]
    C -->|permanent error 404| F[Problem Topic]

    E -->|subscribe| G[Retry Service]

    G -->|attempt re-delivery| D
    G -->|still failing - update backoff and republish| E
    G -->|permanent error 404| F
```