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

# Request and response formats

> Exact serialization rules for BosonMail JSON and multipart requests, response parsing, and how the SDK maps results.

The BosonMail SDK automatically chooses between JSON and multipart encoding, normalizes inputs, and maps API responses into typed results. This page documents those rules so you can debug requests, build direct API calls, or write wrappers.

## JSON requests (no attachments)

When the email has no attachments, the SDK sends:

```text theme={null}
Content-Type: application/json
```

### Serialization rules

| Field | Rule |
| - | - |
| `to` | Single string passed as-is. Array joined with "," (no space). |
| `cc`, `bcc` | Same joining rule as `to`: "," with no space. |
| `subject` | Trimmed before serialization. |
| `text`, `html` | Passed as-is when defined. |
| `attachments` | Omitted entirely when undefined or empty. |

Undefined fields are omitted by `JSON.stringify`, so the request body contains only populated values.

### Example JSON body

```json theme={null}
{
  "to": "customer@example.com,partner@example.com",
  "subject": "Invoice #1024",
  "text": "Your invoice is attached.",
  "html": "<p>Your invoice is attached.</p>"
}
```

## Multipart requests (with attachments)

When one or more attachments are present, the SDK builds a `FormData` body and deliberately does not set `Content-Type`. The runtime sets the header automatically with the correct boundary.

### Field mapping

| SDK field | Multipart field name | Rule |
| - | - | - |
| `to` | `to` | Array items trimmed, then joined with ", " (comma + space). Single string trimmed. |
| `subject` | `subject` | Trimmed. |
| `text` | `textContent` | Only included when provided. |
| `html` | `htmlContent` | Only included when provided. |
| `cc` | `cc` | Joined with ", " (comma + space). |
| `bcc` | `bcc` | Joined with ", " (comma + space). |
| `attachments` | `attachments` | One field per file. Filename preserved. |

### Blob construction

The SDK wraps attachment content as follows:

* `Blob` or `File`: passed as-is. The Blob's own `type` is used; the SDK ignores `contentType` for Blob inputs.
* `Uint8Array` or `ArrayBuffer`: wrapped in a `Blob` with `type` set to `contentType` if provided, otherwise `"application/octet-stream"`.
* `Buffer` (Node.js): accepted because it is a `Uint8Array` subclass.

Attachments are never Base64-encoded inside JSON.

## Response parsing

The SDK parses every response body as JSON. If parsing fails or the body is not an object, the SDK treats it as `{}`.

### Success detection

A response is considered successful only when all of the following are true:

1. `response.ok` is `true` (HTTP 200-299).
2. The parsed body is an object.
3. `body.success === true`.

If any condition fails, the SDK returns a failure result.

### sendEmail result mapping

On success, the SDK maps the API response to a `Result` object:

| Result field | Source in API body |
| - | - |
| `success` | `true` |
| `statusCode` | HTTP status code |
| `id` | `String(data.id)` if present |
| `messageId` | `data.messageId`, `data.emailId`, or `data.message_id` (first match) |
| `status` | `data.status` or `"queued"` as default |

On failure:

| Result field | Value |
| - | - |
| `success` | `false` |
| `statusCode` | HTTP status code (omitted for network errors) |
| `errorMessage` | `body.error` (string), `body.error.message`, `body.message`, or fallback `Request failed (HTTP <status> <statusText>)` |

### getEmailStatus result mapping

On success, the SDK maps the API response to an `EmailStatusResult`:

| Result field | Source in API body |
| - | - |
| `success` | `true` |
| `statusCode` | HTTP status code |
| `data.id` | `data.id` |
| `data.uuid` | `data.uuid` or `""` |
| `data.message_id` | `data.message_id` or `""` |
| `data.status` | `data.status` |
| `data.delivery_status` | `data.delivery_status` |
| `data.recipient` | `data.recipient` or `""` |
| `data.subject` | `data.subject` or `""` |
| `data.created_at` | `data.created_at` or `""` |

On failure:

| Result field | Value |
| - | - |
| `success` | `false` |
| `statusCode` | HTTP status code |
| `errorCode` | `body.error` code, `body.code`, or `http_<status>` fallback |
| `errorMessage` | `body.error` message, `body.message`, or fallback `Failed to retrieve email status (HTTP <status>)` |

## Timeouts

The SDK uses `AbortController` with `setTimeout` per request. The default timeout is 30,000 ms and is configurable via the `timeoutMs` constructor option.

When a timeout occurs, the SDK resolves with:

```text theme={null}
success: false
errorMessage: "Request timed out after <timeoutMs>ms. The outcome may be unknown; check email status before retrying."
```

No `statusCode` is included for timeouts or network errors.

## Next steps

> [card] [API reference](https://docs.bosonware.com/advanced/api-reference.md)
>
> Endpoint paths, curl examples, and parameter details.

> [card] [Error codes](https://docs.bosonware.com/advanced/error-codes.md)
>
> Full catalog of error codes and how to resolve them.

> [card] [Rate limits](https://docs.bosonware.com/advanced/rate-limits.md)
>
> Plan allowances and defensive sending practices.

> [card] [Troubleshooting](https://docs.bosonware.com/advanced/troubleshooting.md)
>
> Fix serialization and timeout issues.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.