diff --git a/.bruno/Chromium/Convert/HTML to PDF.bru b/.bruno/Chromium/Convert/HTML to PDF.bru
new file mode 100644
index 00000000..a370bfb6
--- /dev/null
+++ b/.bruno/Chromium/Convert/HTML to PDF.bru
@@ -0,0 +1,72 @@
+meta {
+ name: HTML to PDF
+ type: http
+ seq: 2
+}
+
+post {
+ url: {{baseUrl}}/forms/chromium/convert/html
+ body: multipartForm
+ auth: none
+}
+
+body:multipart-form {
+ files: @file(../../test/integration/testdata/page-1-html/index.html)
+ ~landscape: false
+ ~printBackground: false
+ ~scale: 1.0
+ ~singlePage: false
+ ~paperWidth: 8.5
+ ~paperHeight: 11
+ ~marginTop: 0.39
+ ~marginBottom: 0.39
+ ~marginLeft: 0.39
+ ~marginRight: 0.39
+ ~nativePageRanges: 1-2
+ ~preferCssPageSize: false
+ ~generateDocumentOutline: false
+ ~generateTaggedPdf: false
+ ~skipNetworkIdleEvent: false
+ ~failOnHttpStatusCodes: [499,599]
+ ~failOnResourceHttpStatusCodes: []
+ ~ignoreResourceHttpStatusDomains: []
+ ~failOnResourceLoadingFailed: false
+ ~failOnConsoleExceptions: false
+ ~waitDelay: 0s
+ ~waitWindowStatus:
+ ~waitForExpression:
+ ~waitForSelector:
+ ~cookies: [{"name":"my_cookie","value":"my_value","domain":"example.com"}]
+ ~userAgent:
+ ~extraHttpHeaders: {"X-Custom-Header":"value"}
+ ~emulatedMediaType: print
+ ~emulatedMediaFeatures: {"prefers-color-scheme":"dark"}
+ ~omitBackground: false
+ ~splitMode: intervals
+ ~splitSpan: 1
+ ~splitUnify: false
+ ~pdfa: PDF/A-1b
+ ~pdfua: true
+ ~metadata: {"Author":"Bruno","Title":"Test"}
+ ~userPassword:
+ ~ownerPassword:
+ ~watermarkSource: text
+ ~watermarkExpression: CONFIDENTIAL
+ ~watermarkPages:
+ ~watermarkOptions: {"scale":"0.5 abs","rot":"45","fillcolor":"#FF0000"}
+ ~stampSource: text
+ ~stampExpression: DRAFT
+ ~stampPages:
+ ~stampOptions: {"scale":"0.5 abs","rot":"45"}
+ ~rotateAngle: 90
+ ~rotatePages:
+}
+
+headers {
+ ~Gotenberg-Output-Filename: my-file
+ ~Gotenberg-Webhook-Url: http://localhost:8080/webhook
+ ~Gotenberg-Webhook-Error-Url: http://localhost:8080/webhook/error
+ ~Gotenberg-Webhook-Method: POST
+ ~Gotenberg-Webhook-Error-Method: POST
+ ~Gotenberg-Webhook-Extra-Http-Headers: {"X-Custom":"value"}
+}
diff --git a/.bruno/Chromium/Convert/Markdown to PDF.bru b/.bruno/Chromium/Convert/Markdown to PDF.bru
new file mode 100644
index 00000000..7ecd91b8
--- /dev/null
+++ b/.bruno/Chromium/Convert/Markdown to PDF.bru
@@ -0,0 +1,73 @@
+meta {
+ name: Markdown to PDF
+ type: http
+ seq: 3
+}
+
+post {
+ url: {{baseUrl}}/forms/chromium/convert/markdown
+ body: multipartForm
+ auth: none
+}
+
+body:multipart-form {
+ files: @file(../../test/integration/testdata/page-1-markdown/index.html)
+ files: @file(../../test/integration/testdata/page-1-markdown/page_1.md)
+ ~landscape: false
+ ~printBackground: false
+ ~scale: 1.0
+ ~singlePage: false
+ ~paperWidth: 8.5
+ ~paperHeight: 11
+ ~marginTop: 0.39
+ ~marginBottom: 0.39
+ ~marginLeft: 0.39
+ ~marginRight: 0.39
+ ~nativePageRanges: 1-2
+ ~preferCssPageSize: false
+ ~generateDocumentOutline: false
+ ~generateTaggedPdf: false
+ ~skipNetworkIdleEvent: false
+ ~failOnHttpStatusCodes: [499,599]
+ ~failOnResourceHttpStatusCodes: []
+ ~ignoreResourceHttpStatusDomains: []
+ ~failOnResourceLoadingFailed: false
+ ~failOnConsoleExceptions: false
+ ~waitDelay: 0s
+ ~waitWindowStatus:
+ ~waitForExpression:
+ ~waitForSelector:
+ ~cookies: [{"name":"my_cookie","value":"my_value","domain":"example.com"}]
+ ~userAgent:
+ ~extraHttpHeaders: {"X-Custom-Header":"value"}
+ ~emulatedMediaType: print
+ ~emulatedMediaFeatures: {"prefers-color-scheme":"dark"}
+ ~omitBackground: false
+ ~splitMode: intervals
+ ~splitSpan: 1
+ ~splitUnify: false
+ ~pdfa: PDF/A-1b
+ ~pdfua: true
+ ~metadata: {"Author":"Bruno","Title":"Test"}
+ ~userPassword:
+ ~ownerPassword:
+ ~watermarkSource: text
+ ~watermarkExpression: CONFIDENTIAL
+ ~watermarkPages:
+ ~watermarkOptions: {"scale":"0.5 abs","rot":"45","fillcolor":"#FF0000"}
+ ~stampSource: text
+ ~stampExpression: DRAFT
+ ~stampPages:
+ ~stampOptions: {"scale":"0.5 abs","rot":"45"}
+ ~rotateAngle: 90
+ ~rotatePages:
+}
+
+headers {
+ ~Gotenberg-Output-Filename: my-file
+ ~Gotenberg-Webhook-Url: http://localhost:8080/webhook
+ ~Gotenberg-Webhook-Error-Url: http://localhost:8080/webhook/error
+ ~Gotenberg-Webhook-Method: POST
+ ~Gotenberg-Webhook-Error-Method: POST
+ ~Gotenberg-Webhook-Extra-Http-Headers: {"X-Custom":"value"}
+}
diff --git a/.bruno/Chromium/Convert/URL to PDF.bru b/.bruno/Chromium/Convert/URL to PDF.bru
new file mode 100644
index 00000000..d1ce9637
--- /dev/null
+++ b/.bruno/Chromium/Convert/URL to PDF.bru
@@ -0,0 +1,72 @@
+meta {
+ name: URL to PDF
+ type: http
+ seq: 1
+}
+
+post {
+ url: {{baseUrl}}/forms/chromium/convert/url
+ body: multipartForm
+ auth: none
+}
+
+body:multipart-form {
+ url: https://example.com
+ ~landscape: false
+ ~printBackground: false
+ ~scale: 1.0
+ ~singlePage: false
+ ~paperWidth: 8.5
+ ~paperHeight: 11
+ ~marginTop: 0.39
+ ~marginBottom: 0.39
+ ~marginLeft: 0.39
+ ~marginRight: 0.39
+ ~nativePageRanges: 1-2
+ ~preferCssPageSize: false
+ ~generateDocumentOutline: false
+ ~generateTaggedPdf: false
+ ~skipNetworkIdleEvent: false
+ ~failOnHttpStatusCodes: [499,599]
+ ~failOnResourceHttpStatusCodes: []
+ ~ignoreResourceHttpStatusDomains: []
+ ~failOnResourceLoadingFailed: false
+ ~failOnConsoleExceptions: false
+ ~waitDelay: 0s
+ ~waitWindowStatus:
+ ~waitForExpression:
+ ~waitForSelector:
+ ~cookies: [{"name":"my_cookie","value":"my_value","domain":"example.com"}]
+ ~userAgent:
+ ~extraHttpHeaders: {"X-Custom-Header":"value"}
+ ~emulatedMediaType: print
+ ~emulatedMediaFeatures: {"prefers-color-scheme":"dark"}
+ ~omitBackground: false
+ ~splitMode: intervals
+ ~splitSpan: 1
+ ~splitUnify: false
+ ~pdfa: PDF/A-1b
+ ~pdfua: true
+ ~metadata: {"Author":"Bruno","Title":"Test"}
+ ~userPassword:
+ ~ownerPassword:
+ ~watermarkSource: text
+ ~watermarkExpression: CONFIDENTIAL
+ ~watermarkPages:
+ ~watermarkOptions: {"scale":"0.5 abs","rot":"45","fillcolor":"#FF0000"}
+ ~stampSource: text
+ ~stampExpression: DRAFT
+ ~stampPages:
+ ~stampOptions: {"scale":"0.5 abs","rot":"45"}
+ ~rotateAngle: 90
+ ~rotatePages:
+}
+
+headers {
+ ~Gotenberg-Output-Filename: my-file
+ ~Gotenberg-Webhook-Url: http://localhost:8080/webhook
+ ~Gotenberg-Webhook-Error-Url: http://localhost:8080/webhook/error
+ ~Gotenberg-Webhook-Method: POST
+ ~Gotenberg-Webhook-Error-Method: POST
+ ~Gotenberg-Webhook-Extra-Http-Headers: {"X-Custom":"value"}
+}
diff --git a/.bruno/Chromium/Screenshot/HTML Screenshot.bru b/.bruno/Chromium/Screenshot/HTML Screenshot.bru
new file mode 100644
index 00000000..027856c1
--- /dev/null
+++ b/.bruno/Chromium/Screenshot/HTML Screenshot.bru
@@ -0,0 +1,46 @@
+meta {
+ name: HTML Screenshot
+ type: http
+ seq: 2
+}
+
+post {
+ url: {{baseUrl}}/forms/chromium/screenshot/html
+ body: multipartForm
+ auth: none
+}
+
+body:multipart-form {
+ files: @file(../../test/integration/testdata/page-1-html/index.html)
+ ~width: 800
+ ~height: 600
+ ~clip: false
+ ~format: png
+ ~quality: 100
+ ~optimizeForSpeed: false
+ ~skipNetworkIdleEvent: false
+ ~failOnHttpStatusCodes: [499,599]
+ ~failOnResourceHttpStatusCodes: []
+ ~ignoreResourceHttpStatusDomains: []
+ ~failOnResourceLoadingFailed: false
+ ~failOnConsoleExceptions: false
+ ~waitDelay: 0s
+ ~waitWindowStatus:
+ ~waitForExpression:
+ ~waitForSelector:
+ ~cookies: [{"name":"my_cookie","value":"my_value","domain":"example.com"}]
+ ~userAgent:
+ ~extraHttpHeaders: {"X-Custom-Header":"value"}
+ ~emulatedMediaType: screen
+ ~emulatedMediaFeatures: {"prefers-color-scheme":"dark"}
+ ~omitBackground: false
+}
+
+headers {
+ ~Gotenberg-Output-Filename: my-screenshot
+ ~Gotenberg-Webhook-Url: http://localhost:8080/webhook
+ ~Gotenberg-Webhook-Error-Url: http://localhost:8080/webhook/error
+ ~Gotenberg-Webhook-Method: POST
+ ~Gotenberg-Webhook-Error-Method: POST
+ ~Gotenberg-Webhook-Extra-Http-Headers: {"X-Custom":"value"}
+}
diff --git a/.bruno/Chromium/Screenshot/Markdown Screenshot.bru b/.bruno/Chromium/Screenshot/Markdown Screenshot.bru
new file mode 100644
index 00000000..a5ed077e
--- /dev/null
+++ b/.bruno/Chromium/Screenshot/Markdown Screenshot.bru
@@ -0,0 +1,47 @@
+meta {
+ name: Markdown Screenshot
+ type: http
+ seq: 3
+}
+
+post {
+ url: {{baseUrl}}/forms/chromium/screenshot/markdown
+ body: multipartForm
+ auth: none
+}
+
+body:multipart-form {
+ files: @file(../../test/integration/testdata/page-1-markdown/index.html)
+ files: @file(../../test/integration/testdata/page-1-markdown/page_1.md)
+ ~width: 800
+ ~height: 600
+ ~clip: false
+ ~format: png
+ ~quality: 100
+ ~optimizeForSpeed: false
+ ~skipNetworkIdleEvent: false
+ ~failOnHttpStatusCodes: [499,599]
+ ~failOnResourceHttpStatusCodes: []
+ ~ignoreResourceHttpStatusDomains: []
+ ~failOnResourceLoadingFailed: false
+ ~failOnConsoleExceptions: false
+ ~waitDelay: 0s
+ ~waitWindowStatus:
+ ~waitForExpression:
+ ~waitForSelector:
+ ~cookies: [{"name":"my_cookie","value":"my_value","domain":"example.com"}]
+ ~userAgent:
+ ~extraHttpHeaders: {"X-Custom-Header":"value"}
+ ~emulatedMediaType: screen
+ ~emulatedMediaFeatures: {"prefers-color-scheme":"dark"}
+ ~omitBackground: false
+}
+
+headers {
+ ~Gotenberg-Output-Filename: my-screenshot
+ ~Gotenberg-Webhook-Url: http://localhost:8080/webhook
+ ~Gotenberg-Webhook-Error-Url: http://localhost:8080/webhook/error
+ ~Gotenberg-Webhook-Method: POST
+ ~Gotenberg-Webhook-Error-Method: POST
+ ~Gotenberg-Webhook-Extra-Http-Headers: {"X-Custom":"value"}
+}
diff --git a/.bruno/Chromium/Screenshot/URL Screenshot.bru b/.bruno/Chromium/Screenshot/URL Screenshot.bru
new file mode 100644
index 00000000..fbd4c81b
--- /dev/null
+++ b/.bruno/Chromium/Screenshot/URL Screenshot.bru
@@ -0,0 +1,46 @@
+meta {
+ name: URL Screenshot
+ type: http
+ seq: 1
+}
+
+post {
+ url: {{baseUrl}}/forms/chromium/screenshot/url
+ body: multipartForm
+ auth: none
+}
+
+body:multipart-form {
+ url: https://example.com
+ ~width: 800
+ ~height: 600
+ ~clip: false
+ ~format: png
+ ~quality: 100
+ ~optimizeForSpeed: false
+ ~skipNetworkIdleEvent: false
+ ~failOnHttpStatusCodes: [499,599]
+ ~failOnResourceHttpStatusCodes: []
+ ~ignoreResourceHttpStatusDomains: []
+ ~failOnResourceLoadingFailed: false
+ ~failOnConsoleExceptions: false
+ ~waitDelay: 0s
+ ~waitWindowStatus:
+ ~waitForExpression:
+ ~waitForSelector:
+ ~cookies: [{"name":"my_cookie","value":"my_value","domain":"example.com"}]
+ ~userAgent:
+ ~extraHttpHeaders: {"X-Custom-Header":"value"}
+ ~emulatedMediaType: screen
+ ~emulatedMediaFeatures: {"prefers-color-scheme":"dark"}
+ ~omitBackground: false
+}
+
+headers {
+ ~Gotenberg-Output-Filename: my-screenshot
+ ~Gotenberg-Webhook-Url: http://localhost:8080/webhook
+ ~Gotenberg-Webhook-Error-Url: http://localhost:8080/webhook/error
+ ~Gotenberg-Webhook-Method: POST
+ ~Gotenberg-Webhook-Error-Method: POST
+ ~Gotenberg-Webhook-Extra-Http-Headers: {"X-Custom":"value"}
+}
diff --git a/.bruno/Health & Info/Debug.bru b/.bruno/Health & Info/Debug.bru
new file mode 100644
index 00000000..fbbab1a6
--- /dev/null
+++ b/.bruno/Health & Info/Debug.bru
@@ -0,0 +1,11 @@
+meta {
+ name: Debug
+ type: http
+ seq: 3
+}
+
+get {
+ url: {{baseUrl}}/debug
+ body: none
+ auth: none
+}
diff --git a/.bruno/Health & Info/Health.bru b/.bruno/Health & Info/Health.bru
new file mode 100644
index 00000000..696ddc4c
--- /dev/null
+++ b/.bruno/Health & Info/Health.bru
@@ -0,0 +1,11 @@
+meta {
+ name: Health
+ type: http
+ seq: 1
+}
+
+get {
+ url: {{baseUrl}}/health
+ body: none
+ auth: none
+}
diff --git a/.bruno/Health & Info/Prometheus Metrics.bru b/.bruno/Health & Info/Prometheus Metrics.bru
new file mode 100644
index 00000000..ea8209de
--- /dev/null
+++ b/.bruno/Health & Info/Prometheus Metrics.bru
@@ -0,0 +1,11 @@
+meta {
+ name: Prometheus Metrics
+ type: http
+ seq: 4
+}
+
+get {
+ url: {{baseUrl}}/prometheus/metrics
+ body: none
+ auth: none
+}
diff --git a/.bruno/Health & Info/Version.bru b/.bruno/Health & Info/Version.bru
new file mode 100644
index 00000000..9b155e41
--- /dev/null
+++ b/.bruno/Health & Info/Version.bru
@@ -0,0 +1,11 @@
+meta {
+ name: Version
+ type: http
+ seq: 2
+}
+
+get {
+ url: {{baseUrl}}/version
+ body: none
+ auth: none
+}
diff --git a/.bruno/LibreOffice/Convert to PDF.bru b/.bruno/LibreOffice/Convert to PDF.bru
new file mode 100644
index 00000000..1e757cf1
--- /dev/null
+++ b/.bruno/LibreOffice/Convert to PDF.bru
@@ -0,0 +1,74 @@
+meta {
+ name: Convert to PDF
+ type: http
+ seq: 1
+}
+
+post {
+ url: {{baseUrl}}/forms/libreoffice/convert
+ body: multipartForm
+ auth: none
+}
+
+body:multipart-form {
+ files: @file(../../test/integration/testdata/page_1.docx)
+ ~password:
+ ~landscape: false
+ ~nativePageRanges:
+ ~updateIndexes: false
+ ~exportFormFields: true
+ ~allowDuplicateFieldNames: false
+ ~exportBookmarks: true
+ ~exportBookmarksToPdfDestination: false
+ ~exportPlaceholders: false
+ ~exportNotes: false
+ ~exportNotesPages: false
+ ~exportOnlyNotesPages: false
+ ~exportNotesInMargin: false
+ ~convertOooTargetToPdfTarget: false
+ ~exportLinksRelativeFsys: false
+ ~exportHiddenSlides: false
+ ~skipEmptyPages: false
+ ~addOriginalDocumentAsStream: false
+ ~singlePageSheets: false
+ ~losslessImageCompression: false
+ ~quality: 90
+ ~reduceImageResolution: false
+ ~maxImageResolution: 300
+ ~nativeWatermarkText:
+ ~nativeWatermarkColor: 0
+ ~nativeWatermarkFontHeight: 0
+ ~nativeWatermarkRotateAngle: 0
+ ~nativeWatermarkFontName:
+ ~nativeTiledWatermarkText:
+ ~nativePdfFormats: true
+ ~merge: false
+ ~flatten: false
+ ~splitMode: intervals
+ ~splitSpan: 1
+ ~splitUnify: false
+ ~pdfa: PDF/A-1b
+ ~pdfua: true
+ ~metadata: {"Author":"Bruno","Title":"Test"}
+ ~userPassword:
+ ~ownerPassword:
+ ~watermarkSource: text
+ ~watermarkExpression: CONFIDENTIAL
+ ~watermarkPages:
+ ~watermarkOptions: {"scale":"0.5 abs","rot":"45","fillcolor":"#FF0000"}
+ ~stampSource: text
+ ~stampExpression: DRAFT
+ ~stampPages:
+ ~stampOptions: {"scale":"0.5 abs","rot":"45"}
+ ~rotateAngle: 90
+ ~rotatePages:
+}
+
+headers {
+ ~Gotenberg-Output-Filename: my-file
+ ~Gotenberg-Webhook-Url: http://localhost:8080/webhook
+ ~Gotenberg-Webhook-Error-Url: http://localhost:8080/webhook/error
+ ~Gotenberg-Webhook-Method: POST
+ ~Gotenberg-Webhook-Error-Method: POST
+ ~Gotenberg-Webhook-Extra-Http-Headers: {"X-Custom":"value"}
+}
diff --git a/.bruno/PDF Engines/Bookmarks/Read Bookmarks.bru b/.bruno/PDF Engines/Bookmarks/Read Bookmarks.bru
new file mode 100644
index 00000000..22328ecd
--- /dev/null
+++ b/.bruno/PDF Engines/Bookmarks/Read Bookmarks.bru
@@ -0,0 +1,23 @@
+meta {
+ name: Read Bookmarks
+ type: http
+ seq: 1
+}
+
+post {
+ url: {{baseUrl}}/forms/pdfengines/bookmarks/read
+ body: multipartForm
+ auth: none
+}
+
+body:multipart-form {
+ files: @file(../../test/integration/testdata/page_1.pdf)
+}
+
+headers {
+ ~Gotenberg-Webhook-Url: http://localhost:8080/webhook
+ ~Gotenberg-Webhook-Error-Url: http://localhost:8080/webhook/error
+ ~Gotenberg-Webhook-Method: POST
+ ~Gotenberg-Webhook-Error-Method: POST
+ ~Gotenberg-Webhook-Extra-Http-Headers: {"X-Custom":"value"}
+}
diff --git a/.bruno/PDF Engines/Bookmarks/Write Bookmarks.bru b/.bruno/PDF Engines/Bookmarks/Write Bookmarks.bru
new file mode 100644
index 00000000..0ec1b508
--- /dev/null
+++ b/.bruno/PDF Engines/Bookmarks/Write Bookmarks.bru
@@ -0,0 +1,25 @@
+meta {
+ name: Write Bookmarks
+ type: http
+ seq: 2
+}
+
+post {
+ url: {{baseUrl}}/forms/pdfengines/bookmarks/write
+ body: multipartForm
+ auth: none
+}
+
+body:multipart-form {
+ files: @file(../../test/integration/testdata/page_1.pdf)
+ bookmarks: [{"title":"Chapter 1","page":1,"children":[{"title":"Section 1.1","page":1}]}]
+}
+
+headers {
+ ~Gotenberg-Output-Filename: with-bookmarks
+ ~Gotenberg-Webhook-Url: http://localhost:8080/webhook
+ ~Gotenberg-Webhook-Error-Url: http://localhost:8080/webhook/error
+ ~Gotenberg-Webhook-Method: POST
+ ~Gotenberg-Webhook-Error-Method: POST
+ ~Gotenberg-Webhook-Extra-Http-Headers: {"X-Custom":"value"}
+}
diff --git a/.bruno/PDF Engines/Convert/Convert PDF.bru b/.bruno/PDF Engines/Convert/Convert PDF.bru
new file mode 100644
index 00000000..5de2769d
--- /dev/null
+++ b/.bruno/PDF Engines/Convert/Convert PDF.bru
@@ -0,0 +1,26 @@
+meta {
+ name: Convert PDF
+ type: http
+ seq: 1
+}
+
+post {
+ url: {{baseUrl}}/forms/pdfengines/convert
+ body: multipartForm
+ auth: none
+}
+
+body:multipart-form {
+ files: @file(../../test/integration/testdata/page_1.pdf)
+ pdfa: PDF/A-1b
+ ~pdfua: true
+}
+
+headers {
+ ~Gotenberg-Output-Filename: converted
+ ~Gotenberg-Webhook-Url: http://localhost:8080/webhook
+ ~Gotenberg-Webhook-Error-Url: http://localhost:8080/webhook/error
+ ~Gotenberg-Webhook-Method: POST
+ ~Gotenberg-Webhook-Error-Method: POST
+ ~Gotenberg-Webhook-Extra-Http-Headers: {"X-Custom":"value"}
+}
diff --git a/.bruno/PDF Engines/Embed/Embed Files.bru b/.bruno/PDF Engines/Embed/Embed Files.bru
new file mode 100644
index 00000000..9bc1dc2a
--- /dev/null
+++ b/.bruno/PDF Engines/Embed/Embed Files.bru
@@ -0,0 +1,25 @@
+meta {
+ name: Embed Files
+ type: http
+ seq: 1
+}
+
+post {
+ url: {{baseUrl}}/forms/pdfengines/embed
+ body: multipartForm
+ auth: none
+}
+
+body:multipart-form {
+ files: @file(../../test/integration/testdata/page_1.pdf)
+ embeds: @file(../../test/integration/testdata/page_1.pdf)
+}
+
+headers {
+ ~Gotenberg-Output-Filename: with-embeds
+ ~Gotenberg-Webhook-Url: http://localhost:8080/webhook
+ ~Gotenberg-Webhook-Error-Url: http://localhost:8080/webhook/error
+ ~Gotenberg-Webhook-Method: POST
+ ~Gotenberg-Webhook-Error-Method: POST
+ ~Gotenberg-Webhook-Extra-Http-Headers: {"X-Custom":"value"}
+}
diff --git a/.bruno/PDF Engines/Encrypt/Encrypt PDF.bru b/.bruno/PDF Engines/Encrypt/Encrypt PDF.bru
new file mode 100644
index 00000000..c60c5c53
--- /dev/null
+++ b/.bruno/PDF Engines/Encrypt/Encrypt PDF.bru
@@ -0,0 +1,26 @@
+meta {
+ name: Encrypt PDF
+ type: http
+ seq: 1
+}
+
+post {
+ url: {{baseUrl}}/forms/pdfengines/encrypt
+ body: multipartForm
+ auth: none
+}
+
+body:multipart-form {
+ files: @file(../../test/integration/testdata/page_1.pdf)
+ userPassword: secret123
+ ~ownerPassword: owner456
+}
+
+headers {
+ ~Gotenberg-Output-Filename: encrypted
+ ~Gotenberg-Webhook-Url: http://localhost:8080/webhook
+ ~Gotenberg-Webhook-Error-Url: http://localhost:8080/webhook/error
+ ~Gotenberg-Webhook-Method: POST
+ ~Gotenberg-Webhook-Error-Method: POST
+ ~Gotenberg-Webhook-Extra-Http-Headers: {"X-Custom":"value"}
+}
diff --git a/.bruno/PDF Engines/Flatten/Flatten PDF.bru b/.bruno/PDF Engines/Flatten/Flatten PDF.bru
new file mode 100644
index 00000000..114792ca
--- /dev/null
+++ b/.bruno/PDF Engines/Flatten/Flatten PDF.bru
@@ -0,0 +1,24 @@
+meta {
+ name: Flatten PDF
+ type: http
+ seq: 1
+}
+
+post {
+ url: {{baseUrl}}/forms/pdfengines/flatten
+ body: multipartForm
+ auth: none
+}
+
+body:multipart-form {
+ files: @file(../../test/integration/testdata/page_1.pdf)
+}
+
+headers {
+ ~Gotenberg-Output-Filename: flattened
+ ~Gotenberg-Webhook-Url: http://localhost:8080/webhook
+ ~Gotenberg-Webhook-Error-Url: http://localhost:8080/webhook/error
+ ~Gotenberg-Webhook-Method: POST
+ ~Gotenberg-Webhook-Error-Method: POST
+ ~Gotenberg-Webhook-Extra-Http-Headers: {"X-Custom":"value"}
+}
diff --git a/.bruno/PDF Engines/Merge/Merge PDFs.bru b/.bruno/PDF Engines/Merge/Merge PDFs.bru
new file mode 100644
index 00000000..aeadad1a
--- /dev/null
+++ b/.bruno/PDF Engines/Merge/Merge PDFs.bru
@@ -0,0 +1,43 @@
+meta {
+ name: Merge PDFs
+ type: http
+ seq: 1
+}
+
+post {
+ url: {{baseUrl}}/forms/pdfengines/merge
+ body: multipartForm
+ auth: none
+}
+
+body:multipart-form {
+ files: @file(../../test/integration/testdata/page_1.pdf)
+ files: @file(../../test/integration/testdata/page_2.pdf)
+ ~flatten: false
+ ~autoIndexBookmarks: false
+ ~pdfa: PDF/A-1b
+ ~pdfua: true
+ ~metadata: {"Author":"Bruno","Title":"Test"}
+ ~bookmarks: [{"title":"Page 1","page":1},{"title":"Page 2","page":2}]
+ ~userPassword:
+ ~ownerPassword:
+ ~watermarkSource: text
+ ~watermarkExpression: CONFIDENTIAL
+ ~watermarkPages:
+ ~watermarkOptions: {"scale":"0.5 abs","rot":"45","fillcolor":"#FF0000"}
+ ~stampSource: text
+ ~stampExpression: DRAFT
+ ~stampPages:
+ ~stampOptions: {"scale":"0.5 abs","rot":"45"}
+ ~rotateAngle: 90
+ ~rotatePages:
+}
+
+headers {
+ ~Gotenberg-Output-Filename: merged
+ ~Gotenberg-Webhook-Url: http://localhost:8080/webhook
+ ~Gotenberg-Webhook-Error-Url: http://localhost:8080/webhook/error
+ ~Gotenberg-Webhook-Method: POST
+ ~Gotenberg-Webhook-Error-Method: POST
+ ~Gotenberg-Webhook-Extra-Http-Headers: {"X-Custom":"value"}
+}
diff --git a/.bruno/PDF Engines/Metadata/Read Metadata.bru b/.bruno/PDF Engines/Metadata/Read Metadata.bru
new file mode 100644
index 00000000..3d8f9a53
--- /dev/null
+++ b/.bruno/PDF Engines/Metadata/Read Metadata.bru
@@ -0,0 +1,23 @@
+meta {
+ name: Read Metadata
+ type: http
+ seq: 1
+}
+
+post {
+ url: {{baseUrl}}/forms/pdfengines/metadata/read
+ body: multipartForm
+ auth: none
+}
+
+body:multipart-form {
+ files: @file(../../test/integration/testdata/page_1.pdf)
+}
+
+headers {
+ ~Gotenberg-Webhook-Url: http://localhost:8080/webhook
+ ~Gotenberg-Webhook-Error-Url: http://localhost:8080/webhook/error
+ ~Gotenberg-Webhook-Method: POST
+ ~Gotenberg-Webhook-Error-Method: POST
+ ~Gotenberg-Webhook-Extra-Http-Headers: {"X-Custom":"value"}
+}
diff --git a/.bruno/PDF Engines/Metadata/Write Metadata.bru b/.bruno/PDF Engines/Metadata/Write Metadata.bru
new file mode 100644
index 00000000..6beff763
--- /dev/null
+++ b/.bruno/PDF Engines/Metadata/Write Metadata.bru
@@ -0,0 +1,25 @@
+meta {
+ name: Write Metadata
+ type: http
+ seq: 2
+}
+
+post {
+ url: {{baseUrl}}/forms/pdfengines/metadata/write
+ body: multipartForm
+ auth: none
+}
+
+body:multipart-form {
+ files: @file(../../test/integration/testdata/page_1.pdf)
+ metadata: {"Author":"Bruno","Copyright":"Bruno","Creator":"Gotenberg","Keywords":["test"],"Marked":true,"Producer":"Gotenberg","Subject":"Test","Title":"Test Document","Trapped":"Unknown"}
+}
+
+headers {
+ ~Gotenberg-Output-Filename: with-metadata
+ ~Gotenberg-Webhook-Url: http://localhost:8080/webhook
+ ~Gotenberg-Webhook-Error-Url: http://localhost:8080/webhook/error
+ ~Gotenberg-Webhook-Method: POST
+ ~Gotenberg-Webhook-Error-Method: POST
+ ~Gotenberg-Webhook-Extra-Http-Headers: {"X-Custom":"value"}
+}
diff --git a/.bruno/PDF Engines/Rotate/Rotate PDF.bru b/.bruno/PDF Engines/Rotate/Rotate PDF.bru
new file mode 100644
index 00000000..3ec7c59e
--- /dev/null
+++ b/.bruno/PDF Engines/Rotate/Rotate PDF.bru
@@ -0,0 +1,26 @@
+meta {
+ name: Rotate PDF
+ type: http
+ seq: 1
+}
+
+post {
+ url: {{baseUrl}}/forms/pdfengines/rotate
+ body: multipartForm
+ auth: none
+}
+
+body:multipart-form {
+ files: @file(../../test/integration/testdata/page_1.pdf)
+ rotateAngle: 90
+ ~rotatePages: 1-2
+}
+
+headers {
+ ~Gotenberg-Output-Filename: rotated
+ ~Gotenberg-Webhook-Url: http://localhost:8080/webhook
+ ~Gotenberg-Webhook-Error-Url: http://localhost:8080/webhook/error
+ ~Gotenberg-Webhook-Method: POST
+ ~Gotenberg-Webhook-Error-Method: POST
+ ~Gotenberg-Webhook-Extra-Http-Headers: {"X-Custom":"value"}
+}
diff --git a/.bruno/PDF Engines/Split/Split PDF.bru b/.bruno/PDF Engines/Split/Split PDF.bru
new file mode 100644
index 00000000..130696f3
--- /dev/null
+++ b/.bruno/PDF Engines/Split/Split PDF.bru
@@ -0,0 +1,43 @@
+meta {
+ name: Split PDF
+ type: http
+ seq: 1
+}
+
+post {
+ url: {{baseUrl}}/forms/pdfengines/split
+ body: multipartForm
+ auth: none
+}
+
+body:multipart-form {
+ files: @file(../../test/integration/testdata/pages_3.pdf)
+ splitMode: intervals
+ splitSpan: 1
+ ~splitUnify: false
+ ~flatten: false
+ ~pdfa: PDF/A-1b
+ ~pdfua: true
+ ~metadata: {"Author":"Bruno","Title":"Test"}
+ ~userPassword:
+ ~ownerPassword:
+ ~watermarkSource: text
+ ~watermarkExpression: CONFIDENTIAL
+ ~watermarkPages:
+ ~watermarkOptions: {"scale":"0.5 abs","rot":"45","fillcolor":"#FF0000"}
+ ~stampSource: text
+ ~stampExpression: DRAFT
+ ~stampPages:
+ ~stampOptions: {"scale":"0.5 abs","rot":"45"}
+ ~rotateAngle: 90
+ ~rotatePages:
+}
+
+headers {
+ ~Gotenberg-Output-Filename: split
+ ~Gotenberg-Webhook-Url: http://localhost:8080/webhook
+ ~Gotenberg-Webhook-Error-Url: http://localhost:8080/webhook/error
+ ~Gotenberg-Webhook-Method: POST
+ ~Gotenberg-Webhook-Error-Method: POST
+ ~Gotenberg-Webhook-Extra-Http-Headers: {"X-Custom":"value"}
+}
diff --git a/.bruno/PDF Engines/Stamp/Stamp PDF.bru b/.bruno/PDF Engines/Stamp/Stamp PDF.bru
new file mode 100644
index 00000000..feb2e0d1
--- /dev/null
+++ b/.bruno/PDF Engines/Stamp/Stamp PDF.bru
@@ -0,0 +1,28 @@
+meta {
+ name: Stamp PDF
+ type: http
+ seq: 1
+}
+
+post {
+ url: {{baseUrl}}/forms/pdfengines/stamp
+ body: multipartForm
+ auth: none
+}
+
+body:multipart-form {
+ files: @file(../../test/integration/testdata/page_1.pdf)
+ stampSource: text
+ stampExpression: APPROVED
+ ~stampPages: 1-2
+ ~stampOptions: {"font":"Helvetica","fontSize":"48","color":"#00FF00","opacity":"0.5","rotation":"0"}
+}
+
+headers {
+ ~Gotenberg-Output-Filename: stamped
+ ~Gotenberg-Webhook-Url: http://localhost:8080/webhook
+ ~Gotenberg-Webhook-Error-Url: http://localhost:8080/webhook/error
+ ~Gotenberg-Webhook-Method: POST
+ ~Gotenberg-Webhook-Error-Method: POST
+ ~Gotenberg-Webhook-Extra-Http-Headers: {"X-Custom":"value"}
+}
diff --git a/.bruno/PDF Engines/Watermark/Watermark PDF.bru b/.bruno/PDF Engines/Watermark/Watermark PDF.bru
new file mode 100644
index 00000000..92ac67e3
--- /dev/null
+++ b/.bruno/PDF Engines/Watermark/Watermark PDF.bru
@@ -0,0 +1,28 @@
+meta {
+ name: Watermark PDF
+ type: http
+ seq: 1
+}
+
+post {
+ url: {{baseUrl}}/forms/pdfengines/watermark
+ body: multipartForm
+ auth: none
+}
+
+body:multipart-form {
+ files: @file(../../test/integration/testdata/page_1.pdf)
+ watermarkSource: text
+ watermarkExpression: CONFIDENTIAL
+ ~watermarkPages: 1-2
+ ~watermarkOptions: {"font":"Helvetica","fontSize":"48","color":"#FF0000","opacity":"0.3","rotation":"45"}
+}
+
+headers {
+ ~Gotenberg-Output-Filename: watermarked
+ ~Gotenberg-Webhook-Url: http://localhost:8080/webhook
+ ~Gotenberg-Webhook-Error-Url: http://localhost:8080/webhook/error
+ ~Gotenberg-Webhook-Method: POST
+ ~Gotenberg-Webhook-Error-Method: POST
+ ~Gotenberg-Webhook-Extra-Http-Headers: {"X-Custom":"value"}
+}
diff --git a/.bruno/bruno.json b/.bruno/bruno.json
new file mode 100644
index 00000000..c9231281
--- /dev/null
+++ b/.bruno/bruno.json
@@ -0,0 +1,6 @@
+{
+ "version": "1",
+ "name": "Gotenberg",
+ "type": "collection",
+ "ignore": ["node_modules", ".git"]
+}
diff --git a/.bruno/collection.bru b/.bruno/collection.bru
new file mode 100644
index 00000000..ec1cd3c3
--- /dev/null
+++ b/.bruno/collection.bru
@@ -0,0 +1,3 @@
+headers {
+ Gotenberg-Trace: {{traceId}}
+}
diff --git a/.bruno/environments/Demo.bru b/.bruno/environments/Demo.bru
new file mode 100644
index 00000000..dfd776a8
--- /dev/null
+++ b/.bruno/environments/Demo.bru
@@ -0,0 +1,4 @@
+vars {
+ baseUrl: https://demo.gotenberg.dev
+ traceId: bruno-demo
+}
diff --git a/.bruno/environments/Local.bru b/.bruno/environments/Local.bru
new file mode 100644
index 00000000..f6f827da
--- /dev/null
+++ b/.bruno/environments/Local.bru
@@ -0,0 +1,4 @@
+vars {
+ baseUrl: http://localhost:3000
+ traceId: bruno-local
+}