Skip to content

Quoting API

The MoveJoy Quoting API provides a programmatic interface to the same quote engine used by the AI voice agent. Use it to embed real-time estimates on your website, CRM, or any external system.

Base URL

https://api.movejoy.com

All endpoints are prefixed with /api/v1/quotes.

Authentication

All quoting API requests require an API key passed in the Authorization header.

Authorization: Bearer mqk_live_your_api_key_here

API keys are issued per organization and are scoped to either the live or test environment.

Key Format

mqk_{environment}_{random}

Examples: mqk_live_abc123..., mqk_test_abc123...

Generating an API Key

API keys are managed from the dashboard under Settings > API Keys. Generate a live key for production use and a test key for development.

Security

  • Never expose your API key in client-side code or public repositories.
  • Keys are stored as SHA-256 hashes. A lost key cannot be recovered; generate a new one.
  • Keys can be revoked from the dashboard at any time.

Rate Limits

Rate limits are applied per API key. Limits vary by subscription plan and are shown in the Settings > API Keys section of the dashboard.

Rate limit status is returned in response headers on every request:

X-RateLimit-Limit: 30
X-RateLimit-Remaining: 28
X-RateLimit-Reset: 1711900800

When the limit is exceeded, the API returns HTTP 429 with a retryAfter field in the response body (in seconds).

Endpoints

Health Check

GET /api/v1/quotes/health

No authentication required. Returns 200 OK if the API is operational.

Response

json
{ "status": "ok", "version": "1.0.0" }

List Service Types

GET /api/v1/quotes/services

Returns all active service types configured for your organization. Use the code values from this response in estimate requests.

Response

json
{
  "services": [
    {
      "code": "local_move",
      "name": "Local Move",
      "category": "residential",
      "pricing_type": "hourly",
      "description": "Local moves within 50 miles"
    },
    {
      "code": "long_distance",
      "name": "Long Distance Move",
      "category": "residential",
      "pricing_type": "mileage",
      "description": null
    }
  ]
}

Calculate Estimate

POST /api/v1/quotes/estimate
Content-Type: application/json
Authorization: Bearer mqk_live_...

Calculates a quote for a move based on your configured service type pricing.

Request Body

FieldTypeRequiredDescription
service_codestringYesService type code (from /services endpoint)
originstringYesOrigin address or ZIP code
destinationstringYesDestination address or ZIP code
estimated_hoursnumberNoEstimated job duration in hours (0.5 to 48)
move_sizestringNoOne of: studio, 1br, 2br, 3br, 4br, 5br
addonsstring[]NoList of addon type codes to include
addon_quantitiesobjectNoMap of addon code to quantity, e.g. { "stairs": 2 }

Example Request

json
{
  "service_code": "local_move",
  "origin": "33101",
  "destination": "33130",
  "estimated_hours": 4,
  "move_size": "2br",
  "addons": ["packing"],
  "addon_quantities": { "packing": 1 }
}

Response

json
{
  "success": true,
  "quote": {
    "total": 490.00,
    "currency": "USD",
    "summary": "4 hours @ $85.00/hr",
    "minimumFloorApplied": false,
    "distance": {
      "miles": 6.2,
      "travelTimeMinutes": 18,
      "travelTime": "18 min"
    },
    "breakdown": [
      { "label": "Labor (4 hrs)", "amount": 340.00, "type": "hourly" },
      { "label": "Packing Service", "amount": 150.00, "type": "addon" }
    ],
    "service": {
      "name": "Local Move",
      "code": "local_move",
      "pricing_type": "hourly"
    }
  }
}

Response Fields

FieldTypeDescription
quote.totalnumberFinal quote amount in the service type's currency
quote.currencystringISO currency code, e.g. USD
quote.summarystringHuman-readable summary of the calculation
quote.minimumFloorAppliedbooleanWhether the minimum quote amount was enforced
quote.distance.milesnumberDriving distance between origin and destination
quote.distance.travelTimeMinutesnumberEstimated driving time in minutes
quote.distance.travelTimestringHuman-readable travel time, e.g. "18 min"
quote.breakdownLineItem[]Itemized list of charges
quote.service.namestringService type display name
quote.service.codestringService type code
quote.service.pricing_typestringPricing model used

LineItem fields:

FieldTypeDescription
labelstringDisplay label for the line item
amountnumberDollar amount for this line item
typestringOne of: base, hourly, overtime, mileage, travel_time, fuel_surcharge, addon

Error Response

json
{
  "success": false,
  "error": "Service type not found",
  "code": "SERVICE_NOT_FOUND"
}

Pricing Type Behavior

Hourly

Quote is calculated as: base_hourly_rate * max(estimated_hours, minimum_hours).

Overtime applies if estimated_hours > overtime_threshold_hours. Hours above the threshold are multiplied by overtime_rate_multiplier (e.g., 1.5).

Flat

Quote is the configured base_flat_rate regardless of distance or duration.

Mileage

Quote is calculated as: base_flat_rate + (distance_miles * mileage_rate).

Distance is resolved via real-time routing data using the provided origin and destination.

Hybrid

Combines hourly labor and mileage. Quote is: (base_hourly_rate * estimated_hours) + (distance_miles * mileage_rate).

Add-on Pricing Units

UnitDescription
flatFixed price per add-on item
per_hourMultiplied by estimated_hours
per_itemMultiplied by the quantity in addon_quantities
per_flightMultiplied by the quantity (typically flights of stairs)

Integration Examples

JavaScript (fetch)

javascript
const response = await fetch('https://api.movejoy.com/api/v1/quotes/estimate', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'Authorization': 'Bearer mqk_live_your_key_here',
  },
  body: JSON.stringify({
    service_code: 'local_move',
    origin: '33101',
    destination: '33130',
    estimated_hours: 3,
  }),
})

const data = await response.json()
console.log(data.quote.total)

cURL

bash
curl -X POST https://api.movejoy.com/api/v1/quotes/estimate \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer mqk_live_your_key_here" \
  -d '{
    "service_code": "local_move",
    "origin": "33101",
    "destination": "33130",
    "estimated_hours": 3
  }'

Using the Test Environment

Replace mqk_live_ keys with mqk_test_ keys to use the test environment. Test requests do not affect live data and are not counted toward production rate limits.

MoveJoy — Never Miss Another Moving Job