diff --git a/README.md b/README.md
index 6f05967f..550a79e2 100644
--- a/README.md
+++ b/README.md
@@ -61,6 +61,16 @@ var response = client.getStatement(r -> r.id("4df42866-40e7-45b6-bf7c-8d5fccbdcc
Statement statement = response.getBody();
```
+### Getting a Statement with attachments
+
+Example:
+
+```java
+var response = client.getStatement(r -> r.id("4df42866-40e7-45b6-bf7c-8d5fccbdccd6").attachments(true).block();
+
+Statement statement = response.getBody();
+```
+
### Getting Statements
Example:
diff --git a/samples/get-statement-with-attachment/pom.xml b/samples/get-statement-with-attachment/pom.xml
new file mode 100644
index 00000000..aaf2d627
--- /dev/null
+++ b/samples/get-statement-with-attachment/pom.xml
@@ -0,0 +1,22 @@
+
+
+ 4.0.0
+
+ dev.learning.xapi.samples
+ xapi-samples-build
+ 1.1.2-SNAPSHOT
+
+ get-statement-with-attachment
+ Get xAPI Statement With Attachment Sample
+ Get xAPI Statement With Attachment
+
+
+ dev.learning.xapi
+ xapi-client
+
+
+ dev.learning.xapi.samples
+ core
+
+
+
diff --git a/samples/get-statement-with-attachment/src/main/java/dev/learning/xapi/samples/poststatement/GetStatementWithAttachmentApplication.java b/samples/get-statement-with-attachment/src/main/java/dev/learning/xapi/samples/poststatement/GetStatementWithAttachmentApplication.java
new file mode 100644
index 00000000..b751ba88
--- /dev/null
+++ b/samples/get-statement-with-attachment/src/main/java/dev/learning/xapi/samples/poststatement/GetStatementWithAttachmentApplication.java
@@ -0,0 +1,100 @@
+/*
+ * Copyright 2016-2023 Berry Cloud Ltd. All rights reserved.
+ */
+
+package dev.learning.xapi.samples.poststatement;
+
+import dev.learning.xapi.client.XapiClient;
+import dev.learning.xapi.model.Statement;
+import dev.learning.xapi.model.Verb;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.net.URI;
+import java.nio.file.Files;
+import java.util.Arrays;
+import java.util.Locale;
+import java.util.UUID;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.CommandLineRunner;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.http.ResponseEntity;
+import org.springframework.util.ResourceUtils;
+
+/**
+ * Sample using xAPI client to get a statement with attachments.
+ *
+ * @author Thomas Turrell-Croft
+ * @author István Rátkai (Selindek)
+ */
+@SpringBootApplication
+public class GetStatementWithAttachmentApplication implements CommandLineRunner {
+
+ /**
+ * Default xAPI client. Properties are picked automatically from application.properties.
+ */
+ @Autowired
+ private XapiClient client;
+
+ public static void main(String[] args) {
+ SpringApplication.run(GetStatementWithAttachmentApplication.class, args).close();
+ }
+
+ @Override
+ public void run(String... args) throws Exception {
+
+ // Post a test statement with attachments
+ var id = postStatement();
+
+ // Get Statement
+ ResponseEntity response =
+ client.getStatement(r -> r.id(id).attachments(true)).block();
+
+ // If the attachment parameter is set to true in a getStatement (or a getStatements) request
+ // then the server will send the response in a multipart/mixed format (even if the
+ // Statement doesn't have attachments.) The xApi client automatically converts these responses
+ // back to the regular Statement / StatementResponse format and populate the returned
+ // statement's or statements' attachments' content from the additional parts from the response.
+
+ // Print the returned statement's attachments to the console
+ System.out.println(new String(response.getBody().getAttachments().get(0).getContent()));
+
+ System.out.println(Arrays.toString(response.getBody().getAttachments().get(1).getContent()));
+
+ }
+
+ private UUID postStatement() throws FileNotFoundException, IOException {
+
+ // Load jpg attachment from class-path
+ var data = Files.readAllBytes(ResourceUtils.getFile("classpath:example.jpg").toPath());
+
+ // Post a statement
+ ResponseEntity<
+ UUID> response =
+ client
+ .postStatement(r -> r.statement(
+ s -> s.actor(a -> a.name("A N Other").mbox("mailto:another@example.com"))
+
+ .verb(Verb.ATTEMPTED)
+
+ .activityObject(o -> o.id("https://example.com/activity/simplestatement")
+ .definition(d -> d.addName(Locale.ENGLISH, "Simple Statement")))
+
+ // Add simple text attachment
+ .addAttachment(a -> a.content("Simple attachment").length(17)
+ .contentType("text/plain")
+ .usageType(URI.create("https://example.com/attachments/greeting"))
+ .addDisplay(Locale.ENGLISH, "text attachment"))
+
+ // Add binary attachment
+ .addAttachment(a -> a.content(data).length(data.length)
+ .contentType("image/jpeg")
+ .usageType(URI.create("https://example.com/attachments/greeting"))
+ .addDisplay(Locale.ENGLISH, "JPEG attachment"))
+
+ )).block();
+
+ return response.getBody();
+ }
+
+}
diff --git a/samples/get-statement-with-attachment/src/main/resources/application.properties b/samples/get-statement-with-attachment/src/main/resources/application.properties
new file mode 100644
index 00000000..de20217a
--- /dev/null
+++ b/samples/get-statement-with-attachment/src/main/resources/application.properties
@@ -0,0 +1,3 @@
+xapi.client.username = admin
+xapi.client.password = password
+xapi.client.baseUrl = https://example.com/xapi/
diff --git a/samples/get-statement-with-attachment/src/main/resources/example.jpg b/samples/get-statement-with-attachment/src/main/resources/example.jpg
new file mode 100644
index 00000000..82123354
Binary files /dev/null and b/samples/get-statement-with-attachment/src/main/resources/example.jpg differ
diff --git a/samples/pom.xml b/samples/pom.xml
index 34cfb6fc..d4101ab3 100644
--- a/samples/pom.xml
+++ b/samples/pom.xml
@@ -35,6 +35,7 @@
core
get-statement
+ get-statement-with-attachment
post-statement
post-statement-with-attachment
get-statements
diff --git a/xapi-client/src/main/java/dev/learning/xapi/client/StatementHttpMessageReader.java b/xapi-client/src/main/java/dev/learning/xapi/client/StatementHttpMessageReader.java
new file mode 100644
index 00000000..3700b51d
--- /dev/null
+++ b/xapi-client/src/main/java/dev/learning/xapi/client/StatementHttpMessageReader.java
@@ -0,0 +1,144 @@
+/*
+ * Copyright 2016-2023 Berry Cloud Ltd. All rights reserved.
+ */
+
+package dev.learning.xapi.client;
+
+import dev.learning.xapi.model.Attachment;
+import dev.learning.xapi.model.Statement;
+import dev.learning.xapi.model.StatementResult;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+import org.springframework.core.ResolvableType;
+import org.springframework.core.io.buffer.DataBuffer;
+import org.springframework.core.io.buffer.DataBufferUtils;
+import org.springframework.http.HttpStatusCode;
+import org.springframework.http.MediaType;
+import org.springframework.http.ReactiveHttpInputMessage;
+import org.springframework.http.codec.HttpMessageReader;
+import org.springframework.http.codec.LoggingCodecSupport;
+import org.springframework.http.codec.multipart.DefaultPartHttpMessageReader;
+import org.springframework.http.codec.multipart.Part;
+import org.springframework.lang.Nullable;
+import org.springframework.web.reactive.function.client.ClientResponse;
+import reactor.core.publisher.Flux;
+import reactor.core.publisher.Mono;
+
+/**
+ * {@link HttpMessageReader} for reading {@code "multipart/mixed"} responses into a
+ * {@link Statement} or {@link StatementResult}s object.
+ *
+ * @author István Rátkai (Selindek)
+ */
+public class StatementHttpMessageReader extends LoggingCodecSupport
+ implements HttpMessageReader