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

# Async Write Operations

> Use asynchronous write operations for fire-and-forget resource creation and updates on TSPs

Asynchronous mode is the **default processing mode** for all write operations. When you submit a request, Catena immediately returns a `202 Accepted` response with a resource operation ID, then processes the request in the background with automatic retries and rate limiting.

<Check>
  **Best for production workloads** where you want to create or update multiple resources without waiting for each TSP response. Catena handles retries, rate limiting, and error recovery automatically.
</Check>

***

## How It Works

```mermaid theme={null}
sequenceDiagram
    participant You as Your App
    participant Catena as Catena API
    participant TSP as TSP API
    participant WH as Your Webhook

    You->>Catena: POST /v2/telematics/messages
    Catena-->>You: 202 Accepted (resource operation)
    Note over Catena: status: pending
    Catena->>WH: resource_operation.created
    Catena->>TSP: Forward request (with retries)
    alt Success
        TSP-->>Catena: 200 OK
        Catena->>WH: resource_operation.succeeded
        Note over WH: includes resource_id & source_id
    else Failure
        TSP-->>Catena: Error
        Catena->>WH: resource_operation.failed
        Note over WH: includes error logs
    end
```

<Steps>
  <Step title="You submit a write request">
    Send a `POST` or `PATCH` request to the Telematics API with `is_sync=false` (or omit the parameter, since async is the default).
  </Step>

  <Step title="Catena returns immediately">
    You receive a `202 Accepted` response containing a resource operation object with `status: "pending"`. The `id` field is the operation tracking ID.
  </Step>

  <Step title="Catena processes in the background">
    The request is queued and processed with automatic retries and rate limiting to respect TSP API limits.
  </Step>

  <Step title="You receive the result via webhook">
    Catena sends a `resource_operation.succeeded` or `resource_operation.failed` webhook event with the final status and details.
  </Step>
</Steps>

***

## Example: Sending a Message

### Request

```bash cURL theme={null}
curl -X POST 'https://api.catenatelematics.com/v2/telematics/messages' \
  -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \
  -H 'Content-Type: application/json' \
  -d '{
    "connection_id": "019ddd87-eedd-710f-967c-1c6cc72ac985",
    "sender_id": "f9c7ee1c-2e16-5858-9b7e-ff7c89a4dd04",
    "recipient_id": "b224f322-b3d2-57e0-b245-cda313f68a1d",
    "message_text": "Delivery confirmed at warehouse B",
    "priority": "low"
  }'
```

<Info>
  The `sender_id` and `recipient_id` are **Catena user IDs**. Catena automatically resolves them to the TSP-specific identifiers (e.g., `source_sender_id`, `source_recipient_id`) before forwarding the request.
</Info>

### Response (202 Accepted)

```json theme={null}
{
  "id": "019df228-725e-7568-aaa8-d0029dffb003",
  "created_at": "2026-05-04T08:43:50.238535Z",
  "updated_at": "2026-05-04T08:43:50.238540Z",
  "deleted_at": null,
  "partner_id": "9df92c50-d8a7-460e-aab2-a93f1de9280a",
  "connection_id": "019ddd87-eedd-710f-967c-1c6cc72ac985",
  "resource": "message",
  "resource_id": null,
  "source_id": null,
  "operation_type": "create",
  "payload": {
    "connection_id": "019ddd87-eedd-710f-967c-1c6cc72ac985",
    "sender_id": "f9c7ee1c-2e16-5858-9b7e-ff7c89a4dd04",
    "recipient_id": "b224f322-b3d2-57e0-b245-cda313f68a1d",
    "message_text": "Delivery confirmed at warehouse B",
    "priority": "low",
    "reply_to_message_id": null,
    "source_sender_id": "51477344",
    "source_recipient_id": "51477717",
    "source_reply_to_message_id": null
  },
  "status": "pending",
  "logs": []
}
```

Key fields in the response:

| Field            | Description                                                                   |
| ---------------- | ----------------------------------------------------------------------------- |
| `id`             | The resource operation ID. Use this to track the operation status.            |
| `status`         | Always `"pending"` for async operations at creation time.                     |
| `resource`       | The type of resource being created (e.g., `message`, `vehicle`).              |
| `operation_type` | Either `"create"` or `"update"`.                                              |
| `resource_id`    | The Catena ID of the created resource. `null` until the operation succeeds.   |
| `source_id`      | The TSP-side ID of the created resource. `null` until the operation succeeds. |
| `payload`        | The full payload sent to the TSP, including auto-resolved source IDs.         |
| `logs`           | Empty initially. Populated with attempt logs if the operation fails.          |

<Tip>
  Notice how the `payload` contains both your Catena IDs (`sender_id`, `recipient_id`) and the automatically resolved TSP IDs (`source_sender_id`, `source_recipient_id`). You don't need to look these up yourself.
</Tip>

***

## Receiving Results via Webhooks

To know whether an async operation succeeded or failed, subscribe to resource operation webhook events.

### Subscribe to Events

Create a webhook subscription for resource operation events:

```bash cURL theme={null}
curl -X POST 'https://api.catenatelematics.com/v2/notifications/webhooks' \
  -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \
  -H 'Content-Type: application/json' \
  -d '{
    "url": "https://your-domain.com/webhooks/catena",
    "event_name": "resource_operation.*",
    "secret": "your-webhook-secret-min-12-chars"
  }'
```

<Info>
  Using `resource_operation.*` subscribes you to all three events: `created`, `succeeded`, and `failed`. You can also subscribe to individual events if you only need specific notifications.
</Info>

### Success Webhook Payload

When the operation succeeds, the `resource_operation.succeeded` event includes the `resource_id` (Catena ID) and `source_id` (TSP ID) of the created resource:

```json theme={null}
{
  "version": "1.0",
  "event_name": "resource_operation.succeeded",
  "webhook_id": "...",
  "timestamp": "2026-05-04T08:43:55.000Z",
  "data": [
    {
      "id": "019df228-725e-7568-aaa8-d0029dffb003",
      "status": "success",
      "resource": "message",
      "resource_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
      "source_id": "98765432",
      "operation_type": "create",
      "connection_id": "019ddd87-eedd-710f-967c-1c6cc72ac985",
      "payload": { "..." },
      "logs": []
    }
  ]
}
```

### Failure Webhook Payload

When the operation fails, the event includes error logs with details about what went wrong:

```json theme={null}
{
  "version": "1.0",
  "event_name": "resource_operation.failed",
  "webhook_id": "...",
  "timestamp": "2026-05-04T08:43:55.000Z",
  "data": [
    {
      "id": "019df228-725e-7568-aaa8-d0029dffb003",
      "status": "failed",
      "resource": "message",
      "resource_id": null,
      "source_id": null,
      "operation_type": "create",
      "connection_id": "019ddd87-eedd-710f-967c-1c6cc72ac985",
      "payload": { "..." },
      "logs": [
        {
          "id": "019df22f-093f-7949-908d-d5564941fdbe",
          "created_at": "2026-05-04T08:51:02.079501Z",
          "resource_operation_id": "019df228-725e-7568-aaa8-d0029dffb003",
          "status": "failed",
          "error_type": "auth",
          "error_details": "Client error '401 Unauthorized' for url '...'"
        }
      ]
    }
  ]
}
```

Error types you may encounter:

| Error Type   | Description                                                    |
| ------------ | -------------------------------------------------------------- |
| `auth`       | Authentication failed with the TSP (e.g., expired credentials) |
| `validation` | The TSP rejected the payload (e.g., missing required fields)   |
| `network`    | Network error connecting to the TSP                            |
| `tsp`        | The TSP returned an unexpected error                           |

***

## Polling for Status

If you prefer not to use webhooks, you can poll the operation status using the Integrations API:

```bash cURL theme={null}
curl -X GET 'https://api.catenatelematics.com/v2/integrations/connections/019ddd87-eedd-710f-967c-1c6cc72ac985/resource-operations/019df228-725e-7568-aaa8-d0029dffb003' \
  -H 'Authorization: Bearer YOUR_ACCESS_TOKEN'
```

Or list all recent operations with filtering:

```bash cURL theme={null}
curl -X GET 'https://api.catenatelematics.com/v2/integrations/connections/resource-operations?connection_id=019ddd87-eedd-710f-967c-1c6cc72ac985&resource=message' \
  -H 'Authorization: Bearer YOUR_ACCESS_TOKEN'
```

<Warning>
  Webhooks are the recommended approach for tracking async operations. Polling introduces latency and unnecessary API calls. Reserve polling for debugging or one-off status checks.
</Warning>

***

## When to Use Async Mode

<AccordionGroup>
  <Accordion title="Bulk operations" icon="layer-group">
    When creating or updating many resources at once (e.g., sending messages to an entire fleet), async mode lets you fire requests rapidly without waiting for each TSP response.
  </Accordion>

  <Accordion title="Non-blocking workflows" icon="forward">
    When your application doesn't need to wait for the TSP's response to continue its workflow. For example, dispatching a message where delivery confirmation can arrive later.
  </Accordion>

  <Accordion title="Production workloads" icon="server">
    Async mode provides built-in retries and rate limiting, making it more resilient for production use. Catena manages the complexity of TSP-specific rate limits and transient failures.
  </Accordion>
</AccordionGroup>

<Warning>
  **You must implement webhook handling** to catch failed operations. Without it, you won't know if a request failed on the TSP side. Build controls to listen for `resource_operation.failed` events and resolve issues (e.g., invalid credentials, missing required fields).
</Warning>

***

## Next Steps

<CardGroup cols={2}>
  <Card title="Sync Operations" icon="bolt" href="/get-started/writing-data-sync">
    Learn about synchronous mode for immediate TSP feedback.
  </Card>
</CardGroup>
