API Guide

    Getting Started

    Make your first authenticated request to the MoveitPro+ Public API in under five minutes.

    The MoveitPro+ Public API is a REST API over HTTPS. Every response is JSON, every request is authenticated with an API key, and the base URL is the same for every endpoint:

    https://api.moveitpro.com

    1. Get an API key

    API keys are minted from inside MoveitPro+ by a company Owner, or by an Admin who has been granted the api_keys.manage permission. Each key carries its own label and scope set. A key is either company-scoped (all branches) or branch-scoped (hard-filtered to a single branch at the gateway). Rate limits come from your company's API plan, which is shared by every key the company holds.

    Keys look like this and are shown exactly once, at mint time:

    mip_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

    2. Confirm the key works

    GET /v1/whoami is the cheapest way to verify a key. It returns the key's own identity, its scopes, its company's plan tier, and its effective rate limits.

    curl https://api.moveitpro.com/v1/whoami \
      -H "Authorization: Bearer mip_live_..."

    A healthy response:

    {
      "success": true,
      "data": {
        "key_id": "…",
        "label": "Reporting integration",
        "key_prefix": "mip_live_AbCd1234",
        "key_last_four": "9f2c",
        "company_id": "…",
        "branch_id": null,
        "scopes": ["customers:read", "jobs:read"],
        "tier": "paid",
        "rate_limits": { "requests_per_minute": 300, "requests_per_day": 5000, "requests_per_month": 100000 },
        "requires_hmac": false,
        "hmac": { "result": "skipped_not_required", "enforced": false },
        "created_at": "…",
        "last_used_at": "…"
      }
    }

    3. Read your first resource

    curl "https://api.moveitpro.com/v1/customers?limit=25" \
      -H "Authorization: Bearer mip_live_..."

    Three behaviors to know up front

    • Query parameters are fail-closed. Any parameter a route does not declare — including a typo of one it does — is rejected with 400 unknown_param. A misspelled filter can never silently return an unfiltered result set.
    • By-id routes accept only fields. No filters, no pagination parameters.
    • Every GET also answers HEAD, with identical headers and no body — useful for cheap existence and cache checks.

    Next

    Read Authentication, then browse the full API reference.