API Documentation

REST API for automation, integrations, and AI agents

Introduction

The Moj Web API provides programmatic access to manage your businesses, websites, media, calendar, menu items, and inquiries. It is designed for:

  • Automation - Sync availability calendars, update menus automatically
  • Integrations - Connect with booking platforms, POS systems, CRMs
  • AI Agents - Enable AI assistants to manage your web presence

The base URL for all API requests is:

https://your-domain.com

Authentication

All API requests require authentication using a Bearer token. You can create and manage API keys from your dashboard.

Getting an API Key

  1. Log in to your dashboard
  2. Navigate to Settings > API Keys
  3. Click "Create API Key"
  4. Select the scopes (permissions) you need
  5. Copy and securely store the generated key

Using Your API Key

Include the API key in the Authorization header of every request:

curl -H "Authorization: Bearer mw_live_your_api_key_here" \
  https://your-domain.com/api/v1/businesses

Key Prefixes

PrefixEnvironmentDescription
mw_live_ProductionUse for production applications
mw_test_TestingUse for development and testing

Scopes

API keys have scopes that define what operations they can perform. Request only the scopes your application needs for better security.

ScopeDescription
business:readRead business information
business:writeCreate and update businesses
business:deleteDelete businesses
website:readRead website content
website:writeUpdate website content and theme
website:publishPublish and unpublish websites
media:readList media files
media:writeUpload media files
media:deleteDelete media files
calendar:readRead availability calendar
calendar:writeManage blocked dates
menu:readRead menu items
menu:writeCreate and update menu items
menu:deleteDelete menu items
inquiry:readRead inquiries
inquiry:writeCreate inquiries and update status

You can also use wildcard scopes: business:* grants all business permissions, and * grants all permissions.

Endpoints Reference

Businesses

GET/api/v1/businesses
List all businessesbusiness:read
POST/api/v1/businesses
Create a new businessbusiness:write
GET/api/v1/businesses/:id
Get business detailsbusiness:read
PATCH/api/v1/businesses/:id
Update a businessbusiness:write
DELETE/api/v1/businesses/:id
Delete a businessbusiness:delete

Websites

GET/api/v1/websites
List all websiteswebsite:readQuery: isPublished
GET/api/v1/websites/:id
Get website with contentwebsite:read
PATCH/api/v1/websites/:id
Update content/themewebsite:write
POST/api/v1/websites/:id/publish
Publish websitewebsite:publish
DELETE/api/v1/websites/:id/publish
Unpublish websitewebsite:publish

Media

GET/api/v1/media
List media filesmedia:readQuery: businessId
POST/api/v1/media
Upload media (multipart/form-data)media:write
GET/api/v1/media/:id
Get media detailsmedia:read
DELETE/api/v1/media/:id
Delete mediamedia:delete

Calendar

GET/api/v1/calendar
List blocked datescalendar:readQuery: unitId (required)
POST/api/v1/calendar
Create blocked datecalendar:write
GET/api/v1/calendar/:id
Get blocked datecalendar:read
PATCH/api/v1/calendar/:id
Update blocked datecalendar:write
DELETE/api/v1/calendar/:id
Delete blocked datecalendar:write

Inquiries

GET/api/v1/inquiries
List inquiriesinquiry:readQuery: websiteId, status
POST/api/v1/inquiries
Create inquiry with metadatainquiry:write
GET/api/v1/inquiries/:id
Get inquiry detailsinquiry:read
PATCH/api/v1/inquiries/:id
Update inquiry statusinquiry:write

Example Requests

List your businesses

curl -X GET "https://your-domain.com/api/v1/businesses" \
  -H "Authorization: Bearer mw_live_your_api_key"

Response:

{
  "businesses": [
    {
      "id": "clx1234567890",
      "type": "APARTMENT",
      "name": "Apartments Sunset",
      "description": "Beautiful seaside apartments",
      "address": "Obala 123",
      "city": "Split",
      "country": "Croatia",
      "phone": "+385 21 123 456",
      "website": {
        "id": "clx0987654321",
        "subdomain": "apartments-sunset",
        "isPublished": true
      }
    }
  ],
  "pagination": {
    "total": 1,
    "limit": 50,
    "offset": 0,
    "hasMore": false
  }
}

Create a business

curl -X POST "https://your-domain.com/api/v1/businesses" \
  -H "Authorization: Bearer mw_live_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "RESTAURANT",
    "name": "Konoba Mare",
    "description": "Traditional Dalmatian cuisine",
    "address": "Riva 45",
    "city": "Dubrovnik",
    "country": "Croatia",
    "phone": "+385 20 321 654"
  }'

Get calendar availability

curl -X GET "https://your-domain.com/api/v1/calendar?unitId=clx_unit_id&startDate=2024-06-01&endDate=2024-08-31" \
  -H "Authorization: Bearer mw_live_your_api_key"

Block dates in calendar

curl -X POST "https://your-domain.com/api/v1/calendar" \
  -H "Authorization: Bearer mw_live_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "unitId": "clx_unit_id",
    "startDate": "2024-07-15",
    "endDate": "2024-07-22",
    "reason": "BOOKING",
    "guestName": "John Smith"
  }'

Upload media

curl -X POST "https://your-domain.com/api/v1/media" \
  -H "Authorization: Bearer mw_live_your_api_key" \
  -F "businessId=clx1234567890" \
  -F "file=@/path/to/image.jpg"

Add menu item

curl -X POST "https://your-domain.com/api/v1/menu" \
  -H "Authorization: Bearer mw_live_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "businessId": "clx1234567890",
    "name": "Grilled Sea Bass",
    "description": "Fresh daily catch with seasonal vegetables",
    "price": 25.00,
    "category": "Main Courses",
    "isAvailable": true
  }'

Create inquiry with metadata

curl -X POST "https://your-domain.com/api/v1/inquiries" \
  -H "Authorization: Bearer mw_live_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "websiteId": "clx_website_id",
    "name": "Vila Sunset",
    "email": "info@vila-sunset.hr",
    "phone": "+385 91 123 4567",
    "message": "Lead from Booking.com scraper",
    "metadata": {
      "source": "booking-scraper",
      "booking_url": "https://booking.com/hotel/...",
      "rating": 9.2,
      "lead_score": 85
    }
  }'

Update inquiry status

curl -X PATCH "https://your-domain.com/api/v1/inquiries/clx_inquiry_id" \
  -H "Authorization: Bearer mw_live_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{"status": "CONTACTED"}'

Publish a website

curl -X POST "https://your-domain.com/api/v1/websites/clx_website_id/publish" \
  -H "Authorization: Bearer mw_live_your_api_key"

List only published websites

curl -X GET "https://your-domain.com/api/v1/websites?isPublished=true" \
  -H "Authorization: Bearer mw_live_your_api_key"

Error Handling

The API uses standard HTTP status codes to indicate success or failure:

Status CodeMeaning
200Success
201Created - Resource created successfully
400Bad Request - Invalid parameters or request body
401Unauthorized - Missing or invalid API key
403Forbidden - Insufficient scope permissions
404Not Found - Resource does not exist
500Internal Server Error - Something went wrong

Error responses include a JSON body with an error field:

{
  "error": "Missing Authorization header"
}
{
  "error": "Insufficient permissions. Required: business:write"
}
{
  "error": "Business not found"
}

Rate Limiting

API requests are rate limited to ensure fair usage and maintain service quality. Rate limits are configurable per API key.

Default limits:

  • Standard keys: 100 requests per minute
  • Premium keys: 1000 requests per minute

When you exceed the rate limit, you will receive a 429 Too Many Requests response. Wait before retrying or contact support to increase your limits.

Rate limit headers are included in responses:

X-RateLimit-Limit: 100
X-RateLimit-Remaining: 95
X-RateLimit-Reset: 1699876543

Need help? Contact support or check our guides in the dashboard.