Lightweight document protection — includes watermarks and metadata establishing clear proof of origination.
The API uses asynchronous processing to handle submissions without timeouts. Choose whichever delivery method fits your workflow:
webhook_url → Get job_id instantlyBoth options return the same watermarked files. Webhooks eliminate the need to poll, making them ideal for high-volume or event-driven workflows.
Requires Bearer token. Returns the watermarked ZIP file directly. All downloads are logged for audit purposes.
Authorization: Bearer aqua-api-watermark-77204041104282
This API key is universal and can be used immediately for testing.
| Parameter | Type | Description |
|---|---|---|
user_email |
String | Your company email (authorized broker account) Use [email protected] for testing |
files |
Array of Objects | Array of file objects, each containing:name (required): Filename with .pdf extensionurl or data (required): Public URL or base64-encoded PDFCan mix URL and base64 files in the same request |
webhook_url |
String (optional) | HTTPS URL to receive job results If provided, we POST the result to this URL on completion or failure. You can still poll /job-status as a fallback.
|
Max file size: 25MB per file
name: The filename (e.g., "bank-statement-jan.pdf")url: Public URL to the PDF file, ORdata: Base64-encoded PDF dataNote: Examples use cURL for clarity. Translate to your preferred language (Python, JavaScript, Java, etc.). Standard HTTP requests—nothing custom.
curl -X POST https://broker-standard-api-new.onrender.com/watermark \
-H "Authorization: Bearer aqua-api-watermark-77204041104282" \
-H "Content-Type: application/json" \
-d '{
"user_email": "[email protected]",
"files": [
{
"name": "bank-statement-jan.pdf",
"url": "https://your-portal.com/submissions/jan.pdf"
},
{
"name": "bank-statement-feb.pdf",
"data": "JVBERi0xLjcKJeLjz9MK..."
},
{
"name": "bank-statement-mar.pdf",
"data": "JVBERi0xLjcKJeLjz9MK..."
},
{
"name": "credit-application.pdf",
"url": "https://your-portal.com/submissions/credit-app.pdf"
},
{
"name": "voided-check.pdf",
"data": "JVBERi0xLjcKJeLjz9MK..."
}
]
}'
Note: You can mix files with url and files with data (base64) in the same request. The data field should contain the complete base64-encoded PDF. Convert your PDF files to base64 using any standard library before sending.
{
"job_id": "abc-123-def-456",
"status": "processing",
"file_count": 5,
"webhook_url": null,
"message": "Job created successfully. Poll /job-status/{job_id} for updates."
}
Use the job_id from Step 1 to check status every 10 seconds:
curl https://broker-standard-api-new.onrender.com/job-status/abc-123-def-456
While processing:
{
"job_id": "abc-123-def-456",
"status": "processing",
"progress": "Processing file 2 of 5: bank-statement-feb.pdf",
"created_at": "2025-01-06T10:00:00Z"
}
When complete:
{
"job_id": "abc-123-def-456",
"status": "complete",
"download_url": "https://...broker-job-results/abc-123-def-456.zip?token=eyJhbG...",
"download_expires_at": "2026-02-24T19:45:22.418Z",
"authenticated_download_url": "https://broker-standard-api-new.onrender.com/download/abc-123-def-456",
"message": "Ready for download. Signed link expires in 10 minutes. For logged/authenticated downloads, use the authenticated_download_url with your Bearer token.",
"created_at": "2025-01-06T10:00:00Z",
"completed_at": "2025-01-06T10:01:30Z"
}
On error:
{
"job_id": "abc-123-def-456",
"status": "error",
"error_message": "Job timed out after 10 minutes",
"created_at": "2025-01-06T10:00:00Z",
"completed_at": "2025-01-06T10:10:00Z"
}
Two download methods are available:
Option A: Signed URL (direct)
Use the download_url from Step 3. No auth required, but the link expires in 10 minutes.
curl "https://...broker-job-results/abc-123-def-456.zip?token=eyJhbG..." --output watermarked.zip
Option B: Authenticated download
Use the authenticated_download_url with your Bearer token. Every download is logged with IP, timestamp, and file size.
curl -H "Authorization: Bearer aqua-api-watermark-77204041104282" \
https://broker-standard-api-new.onrender.com/download/abc-123-def-456 \
--output watermarked.zip
Instead of polling, add a webhook_url to your request and we'll POST the results directly to your server when the job finishes.
curl -X POST https://broker-standard-api-new.onrender.com/watermark \
-H "Authorization: Bearer aqua-api-watermark-77204041104282" \
-H "Content-Type: application/json" \
-d '{
"user_email": "[email protected]",
"files": [
{
"name": "bank-statement-jan.pdf",
"url": "https://your-portal.com/submissions/jan.pdf"
}
],
"webhook_url": "https://your-server.com/aquamark-webhook"
}'
{
"job_id": "abc-123-def-456",
"status": "processing",
"file_count": 1,
"webhook_url": "https://your-server.com/aquamark-webhook",
"message": "Job created successfully. You will receive a webhook when processing completes."
}
When processing completes, we POST to your webhook_url:
On success:
POST https://your-server.com/aquamark-webhook
Headers:
Content-Type: application/json
X-Aquamark-Event: job.completed
X-Aquamark-Signature: 2ed0b90b005db9ef29a048f28a1e8acf...
X-Aquamark-Delivery: 7860e1bc-0b42-48e5-ad95-587c04c0efbe
User-Agent: Aquamark-Webhooks/1.0
Body:
{
"event": "job.completed",
"job_id": "abc-123-def-456",
"status": "complete",
"download_url": "https://...broker-job-results/abc-123-def-456.zip?token=eyJhbG...",
"download_expires_at": "2026-02-20T15:40:12.456Z",
"authenticated_download_url": "https://broker-standard-api-new.onrender.com/download/abc-123-def-456",
"file_count": 1,
"elapsed_ms": 2283,
"completed_at": "2026-02-20T15:30:12.456Z"
}
On error:
{
"event": "job.failed",
"job_id": "abc-123-def-456",
"status": "error",
"error_message": "All files failed to process",
"completed_at": "2026-02-20T15:31:00.000Z"
}
Two download options are available:
Option A: Signed URL (direct)
Use the download_url from the webhook payload. No auth required, but the link expires in 10 minutes.
curl "https://...broker-job-results/abc-123-def-456.zip?token=eyJhbG..." --output watermarked.zip
Option B: Authenticated download
Use the authenticated_download_url with your Bearer token. Every download is logged.
curl -H "Authorization: Bearer aqua-api-watermark-77204041104282" \
https://broker-standard-api-new.onrender.com/download/abc-123-def-456 \
--output watermarked.zip
Each webhook includes an X-Aquamark-Signature header — an HMAC-SHA256 hash of the request body signed with your API key. Verify it to confirm the webhook came from Aquamark:
// Node.js example
const crypto = require('crypto');
function verifyWebhook(requestBody, signatureHeader, apiKey) {
const expected = crypto
.createHmac('sha256', apiKey)
.update(requestBody)
.digest('hex');
return expected === signatureHeader;
}
/job-status/:job_id as a backup, even when using webhooks.
watermarked.zip/
├── bank-statement-jan.pdf
├── bank-statement-feb.pdf
├── bank-statement-mar.pdf
├── credit-application.pdf
└── voided-check.pdf
Each file is watermarked with your broker logo and company information.
complete or error/download/:job_id) are deleted immediately after download| Code | Meaning | Example Response |
|---|---|---|
| 400 | Bad request | Validation error (missing params, invalid format) |
| 401 | Invalid API key | Invalid API key |
| 402 | User not authorized | User not found or inactive |
| 404 | Job not found | Job not found |
| 410 | File expired or already downloaded | File has already been downloaded and removed, or has expired |
| 413 | File too large | File exceeds 25MB limit |
| 429 | Rate limit exceeded | Too many requests. You have exceeded 500 requests per hour. |
| 500 | Server error | Internal server error |
The examples above use test credentials with Aquamark branding. To deploy with your own branding:
[email protected] with your Aquamark account email in the user_email parameter
Questions? Contact [email protected]
Privacy Policy