REST API · v1

API Reference

Manage blog posts and images programmatically. All endpoints are authenticated with an API key and return JSON.

Overview

Base URL

https://www.mailexel.com

Format

JSON

Auth

X-API-Key header

All endpoints

POST
/api/v1/images

Upload an image file

GET
/api/v1/images

List all uploaded images

DELETE
/api/v1/images/:filename

Delete an image by filename

GET
/api/v1/blogs

List blog posts with filtering & pagination

POST
/api/v1/blogs

Create a new blog post

GET
/api/v1/blogs/:id

Get a single blog post

PUT
/api/v1/blogs/:id

Update a blog post

DELETE
/api/v1/blogs/:id

Delete a blog post

Authentication

Every request must include your API key in the X-API-Key header. Contact your administrator to obtain an API key or set the EXTERNAL_API_KEY environment variable on the server.

curl -X GET "https://www.mailexel.com/api/v1/images" \
  -H "X-API-Key: your_api_key_here"
Keep your key secret. Never expose it in client-side JavaScript or commit it to source control. Use environment variables.

Images

Upload, list, and delete images hosted on MailExel's CDN. Uploaded images are publicly accessible via /uploads/filename.

POST/api/v1/images

Upload an image file. The request body must be multipart/form-data.

Request fields

FieldTypeDescription
imagerequiredFileImage file. Max 5 MB. Allowed: jpeg, png, gif, webp.

cURL

curl -X POST "https://www.mailexel.com/api/v1/images" \
  -H "X-API-Key: your_api_key_here" \
  -F "image=@/path/to/screenshot.png"

JavaScript (fetch)

const form = new FormData();
form.append("image", fileInput.files[0]);

const res = await fetch("https://www.mailexel.com/api/v1/images", {
  method: "POST",
  headers: { "X-API-Key": "your_api_key_here" },
  body: form,
});
const data = await res.json();
console.log(data.data.url); // "/uploads/screenshot.png"

Python (requests)

import requests

with open("screenshot.png", "rb") as f:
    res = requests.post(
        "https://www.mailexel.com/api/v1/images",
        headers={"X-API-Key": "your_api_key_here"},
        files={"image": f},
    )
print(res.json()["data"]["url"])  # /uploads/screenshot.png

Response — 201 Created

{
  "success": true,
  "data": {
    "filename": "screenshot.png",
    "url": "/uploads/screenshot.png",
    "publicUrl": "https://bmt4alccllpf5daq.public.blob.vercel-storage.com/uploads/screenshot.png",
    "size": 248320,
    "type": "image/png"
  }
}
GET/api/v1/images

Returns all uploaded images sorted by upload date (newest first).

cURL

curl "https://www.mailexel.com/api/v1/images" \
  -H "X-API-Key: your_api_key_here"

Response — 200 OK

{
  "success": true,
  "total": 2,
  "data": [
    {
      "filename": "hero-image.png",
      "url": "/uploads/hero-image.png",
      "publicUrl": "https://bmt4alccllpf5daq.public.blob.vercel-storage.com/uploads/hero-image.png",
      "size": 512000,
      "createdAt": "2026-05-31T10:00:00.000Z"
    }
  ]
}
DELETE/api/v1/images/:filename

Permanently deletes an image. Use the filename value returned by the upload or list endpoints.

cURL

curl -X DELETE "https://www.mailexel.com/api/v1/images/screenshot.png" \
  -H "X-API-Key: your_api_key_here"

Response — 200 OK

{
  "success": true,
  "message": "Image 'screenshot.png' deleted successfully."
}

Blogs

Create, read, update, and delete blog posts. All endpoints require API key authentication.

GET/api/v1/blogs

List blog posts with optional filtering and pagination.

Query parameters

ParamDefaultDescription
statusallFilter by status: published | draft | all
page1Page number
limit20Results per page (max 100)
searchSearch in title and excerpt
categoryFilter by category name
tagFilter by tag
curl "https://www.mailexel.com/api/v1/blogs?status=published&limit=10&page=1" \
  -H "X-API-Key: your_api_key_here"
POST/api/v1/blogs

Create a new blog post. Slug is auto-generated from the title.

curl -X POST "https://www.mailexel.com/api/v1/blogs" \
  -H "X-API-Key: your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "How to Convert PST to MBOX",
    "excerpt": "A step-by-step guide to converting PST files.",
    "content": "<h2>Introduction</h2><p>...</p>",
    "status": "published",
    "category": "Email Conversion",
    "tags": ["pst", "mbox", "conversion"],
    "featuredImage": "/uploads/hero-image.png"
  }'

Errors

All errors return a JSON body with success: false and a human-readable message.

StatusMeaning
400Bad request — missing or invalid fields
401Invalid or missing X-API-Key header
404Resource not found
500Server error — check message for details
503API disabled — EXTERNAL_API_KEY not configured

Error response example

{
  "success": false,
  "message": "Invalid or missing API key. Pass it via the X-API-Key header."
}