The SDK throws typed errors for HTTP failures so your application can branch on the error class instead of parsing raw responses.

```typescript
import {
  LumailAuthenticationError,
  LumailNotFoundError,
  LumailRateLimitError,
  LumailValidationError,
} from "lumail";

try {
  await lumail.subscribers.get("unknown@example.com");
} catch (error) {
  if (error instanceof LumailNotFoundError) {
    console.log("Subscriber not found");
  } else if (error instanceof LumailRateLimitError) {
    console.log(`Retry after ${error.retryAfter}ms`);
  } else if (error instanceof LumailAuthenticationError) {
    console.log("Invalid API key");
  } else if (error instanceof LumailValidationError) {
    console.log(error.message);
  } else {
    throw error;
  }
}
```

## Error Classes

| Error                        | Meaning                                              |
| ---------------------------- | ---------------------------------------------------- |
| `LumailValidationError`      | Request body or parameters are invalid               |
| `LumailAuthenticationError`  | API token is missing or invalid                      |
| `LumailPaymentRequiredError` | Plan limit or billing requirement blocks the request |
| `LumailNotFoundError`        | Requested resource does not exist                    |
| `LumailRateLimitError`       | Request was rate limited                             |
| `LumailError`                | Other Lumail API error                               |

## Retry Behavior

| Method                 | Retries | Why                                                |
| ---------------------- | ------- | -------------------------------------------------- |
| `GET`, `PUT`, `DELETE` | Up to 3 | Safer to retry after network errors or rate limits |
| `POST`, `PATCH`        | None    | Avoids duplicate writes                            |

Retry delays use exponential backoff: 1s, 2s, and 4s. Rate limit responses can include `Retry-After`; the SDK exposes it on `LumailRateLimitError.retryAfter`.

## Idempotent Recovery Pattern

```typescript
import { LumailNotFoundError } from "lumail";

export async function upsertSubscriber(
  email: string,
  fields: Record<string, string>,
) {
  try {
    return await lumail.subscribers.update(email, { fields });
  } catch (error) {
    if (error instanceof LumailNotFoundError) {
      return lumail.subscribers.create({ email, fields });
    }

    throw error;
  }
}
```

## Related

- [API Limits](/docs/api-reference/api-limits)
- [SDK Resources](/docs/sdk/resources)
- [Full SDK Reference](/docs/api-reference/sdk)
