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

# Email client

> Full reference for the Paubox Perl SDK Email API client: building messages, sending email, tracking delivery, and error handling.

## Instantiation

```perl theme={null}
my $service = Paubox_Email_SDK->new();
```

Credentials are read automatically from `config.cfg` (see [Authentication](/perl-sdk/authentication)). The constructor dies if `API_KEY` or `API_USERNAME` is missing.

## Building a message

Messages are created with a single constructor call using named parameters:

```perl theme={null}
my $msg = Paubox_Email_SDK::Message->new(
    'from'                    => 'sender@yourdomain.com',  # required
    'to'                      => ['alice@example.com'],     # required; arrayref
    'subject'                 => 'Your results are ready',  # required
    'text_content'            => 'Plain text body.',        # at least one required
    'html_content'            => '<p>HTML body.</p>',       # optional; auto base64-encoded
    'replyTo'                 => 'support@yourdomain.com',  # optional
    'cc'                      => ['manager@example.com'],   # optional; arrayref
    'bcc'                     => ['audit@example.com'],     # optional; arrayref
    'allowNonTLS'             => 0,                         # optional; default 0
    'forceSecureNotification' => 'true',                    # optional; "true"/"false"
    'attachments'             => [$attachment],             # optional; arrayref of hashrefs
);
```

### Attachments

Each attachment is a hashref with three keys. Use `MIME::Base64` to encode the file content:

```perl theme={null}
use MIME::Base64;
use String::Util qw(trim);

my $attachment = {
    fileName    => 'report.pdf',
    contentType => 'application/pdf',
    content     => trim(encode_base64(do { local $/; open my $fh, '<:raw', 'report.pdf' or die $!; <$fh> })),
};

my $msg = Paubox_Email_SDK::Message->new(
    'from'        => 'sender@yourdomain.com',
    'to'          => ['alice@example.com'],
    'subject'     => 'Report attached',
    'text_content'=> 'See attachment.',
    'attachments' => [$attachment],
);
```

`String::Util::trim` removes the trailing newline that `encode_base64` appends.

## Send a message

```perl theme={null}
my $response = $service->sendMessage($msg);
```

The response is a raw JSON string. Decode it to access fields:

```perl theme={null}
use JSON;
my $json = decode_json($response);
print "Tracking ID: " . $json->{sourceTrackingId} . "\n";
```

## Check delivery status

```perl theme={null}
my $disposition = $service->getEmailDisposition($sourceTrackingId);
my $json = decode_json($disposition);

for my $delivery (@{ $json->{data}{message}{message_deliveries} }) {
    print $delivery->{recipient} . " -> " . $delivery->{status}{deliveryStatus} . "\n";
}
```

Common `deliveryStatus` values: `delivered`, `opened`, `failed`, `pending`.

## Error handling

Both `sendMessage` and `getEmailDisposition` use `TryCatch` internally and die on API errors. Wrap calls in an `eval` block to catch failures:

```perl theme={null}
eval {
    my $response = $service->sendMessage($msg);
    print "Sent: $response\n";
};
if ($@) {
    print "Error: $@\n";
}
```
