Markly API v1
Watermark images programmatically. Add text or logo overlays to single images or process batches of up to 20 at once.
Authentication
Authenticated requests use a Bearer token in the Authorization header. Tokens use the mkly_ prefix.
Anonymous mode - no key required
You can try the text and logo watermark endpoints without an API key. Anonymous requests are rate-limited to 5 per minute and 20 per day per IP, and all output images include a markly.cloud watermark. Batch processing requires an API key.
Authorization: Bearer mkly_your_api_key_here
Getting an API key
Generate a key from the command line on your Markly instance:
php artisan api:token:create "My Agent" --plan=free
AI Agent (MCP) - plug & play
Use Markly from Claude Code, Cursor, or any MCP-compatible agent. Install with npx -y markly-mcp-server and set your API key.
Plans
| Plan | Rate Limit | Daily Limit | Branded Watermark |
|---|---|---|---|
| Anonymous | 5 / min | 20 / day | Yes no key needed |
| Free | 10 / min | 100 / day | Yes "markly.cloud" |
| Pro | 60 / min | 1,000 / day | No |
| Business | 120 / min | 5,000 / day | No |
| Credit Buy credits | 60 / min | 1,000 / day | No while credits remain |
Anonymous and Free plans add a small "markly.cloud" watermark to processed images. Buy credits or upgrade for clean output.
Buy API Credits
One-time credit packs. 1 credit = 1 watermarked image without "markly.cloud" branding. Credits never expire. No account needed - just your email.
Starter
250 credits
€5
Pro
1,000 credits
€15
Bulk
5,000 credits
€49
/api/v1/watermark/text
Add a text watermark to an image. Provide the image as a file upload or a remote URL.
Parameters
| Name | Type | Description | |
|---|---|---|---|
| image | file | conditional | Image file upload. Required if image_url is not provided. |
| image_url | string | conditional | URL of a remote image. Required if image is not provided. |
| text | string | required | The watermark text. Max 200 characters. |
| size | integer | optional | Font size in pixels. Range: 10-200. Default: 48. |
| color | string | optional | Hex color code. Default: #ffffff. |
| opacity | integer | optional | Opacity percentage. Range: 1-100. Default: 50. |
| angle | integer | optional | Rotation angle in degrees. Range: -360 to 360. Default: -25. |
| position | string | optional | One of: center, top-left, top-right, bottom-left, bottom-right. Default: center. |
| tile | boolean | optional | Repeat the watermark across the image. Default: false. |
| font | string | optional | Font name. See available fonts on markly.cloud. |
Example request
curl -X POST https://www.markly.cloud/api/v1/watermark/text \ -H "Authorization: Bearer mkly_your_key" \ -F "[email protected]" \ -F "text=Copyright 2026" \ -F "opacity=60" \ -F "position=bottom-right"
curl -X POST https://www.markly.cloud/api/v1/watermark/text \ -H "Authorization: Bearer mkly_your_key" \ -H "Content-Type: application/json" \ -d '{ "image_url": "https://example.com/photo.jpg", "text": "Copyright 2026", "opacity": 60, "position": "bottom-right" }'
curl -X POST https://www.markly.cloud/api/v1/watermark/text \ -F "[email protected]" \ -F "text=Copyright 2026"
Response
{
"download_url": "https://www.markly.cloud/download/abc123?signature=...",
"filename": "photo_watermarked.jpg",
"expires_at": "2026-03-03T14:30:00Z"
}
/api/v1/watermark/logo
Overlay a logo on an image. Both image and logo can be uploaded or provided as URLs.
Parameters
| Name | Type | Description | |
|---|---|---|---|
| image | file | conditional | Image file upload. Required if image_url is not provided. |
| image_url | string | conditional | URL of a remote image. |
| logo | file | conditional | Logo file upload. Required if logo_url is not provided. |
| logo_url | string | conditional | URL of a remote logo image. |
| position | string | optional | One of: center, top-left, top-right, bottom-left, bottom-right. Default: bottom-right. |
| opacity | integer | optional | Opacity percentage. Range: 1-100. Default: 70. |
| scale | integer | optional | Logo scale percentage. Range: 5-80. Default: 25. |
Example request
curl -X POST https://www.markly.cloud/api/v1/watermark/logo \ -H "Authorization: Bearer mkly_your_key" \ -F "[email protected]" \ -F "[email protected]" \ -F "position=bottom-right" \ -F "opacity=80"
Response
{
"download_url": "https://www.markly.cloud/download/def456?signature=...",
"filename": "photo_watermarked.jpg",
"expires_at": "2026-03-03T14:30:00Z"
}
/api/v1/batch/upload
Upload an image to a batch. Up to 20 images per batch. Each upload call adds one image.
Parameters
| Name | Type | Description | |
|---|---|---|---|
| image | file | conditional | Image file upload. |
| image_url | string | conditional | URL of a remote image. |
| batch_id | string | optional | Existing batch ID. Omit to create a new batch. |
Example request
curl -X POST https://www.markly.cloud/api/v1/batch/upload \ -H "Authorization: Bearer mkly_your_key" \ -F "[email protected]"
Response
{
"batch_id": "b_a1b2c3d4",
"image_id": "img_x1y2z3",
"index": 1,
"total": 1
}
/api/v1/batch/start
Start processing a batch. All uploaded images will be watermarked with the specified settings.
Parameters
| Name | Type | Description | |
|---|---|---|---|
| batch_id | string | required | The batch ID from the upload step. |
| mode | string | required | Either text or logo. |
| text | string | conditional | Watermark text. Required when mode is text. |
| size, color, opacity, angle, position, tile, font | mixed | optional | Same text watermark options as single endpoint. |
| logo / logo_url | file / string | conditional | Logo file or URL. Required when mode is logo. |
| scale | integer | optional | Logo scale. Used when mode is logo. |
Example request
curl -X POST https://www.markly.cloud/api/v1/batch/start \ -H "Authorization: Bearer mkly_your_key" \ -H "Content-Type: application/json" \ -d '{ "batch_id": "b_a1b2c3d4", "mode": "text", "text": "Copyright 2026", "opacity": 50, "position": "center", "tile": true }'
Response
{
"batch_id": "b_a1b2c3d4",
"total": 5,
"status": "processing"
}
/api/v1/batch/{batch_id}/status
Poll the status of a batch. When complete, a download URL for the ZIP file is returned.
Example request
curl https://www.markly.cloud/api/v1/batch/b_a1b2c3d4/status \ -H "Authorization: Bearer mkly_your_key"
Response
{
"batch_id": "b_a1b2c3d4",
"status": "completed",
"processed": 5,
"total": 5,
"failed": 0,
"download_url": "https://www.markly.cloud/download/batch_xyz?signature=..."
}
Status values
pending- Batch created, not started yetprocessing- Watermarking in progresscompleted- All images processed, ZIP readyfailed- Processing failed
/api/v1/batch/image
Remove an image from a batch before processing starts.
Parameters
| Name | Type | Description | |
|---|---|---|---|
| batch_id | string | required | The batch ID. |
| image_id | string | required | The image ID from the upload response. |
Response
{
"success": true,
"total": 4
}
/api/v1/usage
Check your API quota and usage statistics.
Example request
curl https://www.markly.cloud/api/v1/usage \ -H "Authorization: Bearer mkly_your_key"
Response
{
"plan": "free",
"name": "My Agent",
"requests_today": 42,
"daily_limit": 100,
"rate_per_minute": 10,
"requests_total": 1523,
"images_processed": 847,
"branded_watermark": true
}
Rate Limiting
Every API response includes rate limit headers so you can track your usage in real time.
| Header | Description |
|---|---|
| X-RateLimit-Limit | Max requests per minute for your plan |
| X-RateLimit-Remaining | Requests remaining in the current minute window |
| X-Daily-Limit | Max requests per day for your plan |
| X-Daily-Remaining | Requests remaining today |
When you exceed a rate limit, the API returns 429 Too Many Requests with a Retry-After header indicating how many seconds to wait.
Error Codes
Unauthorized
Invalid API key, or endpoint requires authentication (batch). Text and logo endpoints allow anonymous access.
Validation Error
Invalid parameters. The response body contains a errors object with details.
Too Many Requests
Rate limit or daily quota exceeded. Check Retry-After header.
Server Error
Something went wrong on our side. Try again or contact support.
Error response format
{
"message": "The text field is required.",
"errors": {
"text": ["The text field is required."]
}
}
MCP Server
Use Markly directly from AI agents via the Model Context Protocol. The MCP server wraps the API v1 endpoints into tool calls.
Installation
npx -y markly-mcp-server
Claude Code configuration
Add to ~/.claude/settings.json:
{
"mcpServers": {
"markly": {
"command": "npx",
"args": ["-y", "markly-mcp-server"],
"env": {
"MARKLY_API_KEY": "mkly_your_api_key_here"
}
}
}
}
Available tools
| Tool | Description |
|---|---|
| markly_watermark_text | Add a text watermark to an image via URL |
| markly_watermark_logo | Add a logo watermark to an image via URL |
| markly_batch_watermark | Watermark up to 20 images and get a ZIP download |
| markly_check_usage | Check API quota and usage stats |
Example prompt
"Add 'Copyright 2026' as a watermark to this image: https://example.com/photo.jpg"
Environment variables
| MARKLY_API_KEY | optional | Your API key (anonymous free tier without it) |
| MARKLY_API_URL | optional | Default: https://www.markly.cloud/api/v1 |
Markly API v1 - markly.cloud