Skip to content

REST API

DMS ships a read/write REST API under the dms/v1 namespace. It powers the Dealer.ms mobile app and is available to any custom integration (scripts, middleware, Zapier-style automations) that authenticates with an API key.

  • Base URL: https://your-site.com/wp-json/dms/v1/
  • Auth: per-user API key sent as a Bearer token - see Authentication.
  • Format: JSON in, JSON out. All responses use a consistent envelope (see Responses).
  • Licensing: requires a Pro license, or the App Access add-on (see below).

The API is versioned in the path (/dms/v1/). Breaking changes ship under a new version; v1 stays stable.


Endpoint reference

Each resource group has its own page:

Page Endpoints
Authentication authenticate
Types types, type_data/{id}
Categories & Terms categories/{id}, category/{id}, terms/{id}, term/{id}, icons
Inventory inventory/{id}, search_all, clear_trash/{id}
Listings listing/{id} (GET/POST/PATCH/DELETE)
Leads leads, leads/type/{id}, leads/{id}
Media upload_image, upload_file
VIN vin/{id}, import_vin/{id}
Stats & Cache stats/{id}, options, cache/flush

Licensing requirement

Every request is gated at the point of use. An install must be activated with a Pro license, or have the App Access add-on, for any endpoint to respond. The App Access add-on unlocks the API (and the mobile app) without requiring a Pro license. If neither applies, every route returns:

{ "code": "dms_not_licensed", "message": "API access requires a Pro license or the App Access add-on.", "data": { "status": 403 } }

This is enforced on the request itself, not just on key creation - a key issued while entitled stops working if the license lapses or is downgraded (and the add-on isn't active), and works again once re-entitled. Keys are never deleted by a lapse.


Responses

Success envelope

Every successful response is wrapped in:

{
  "success": true,
  "message": "Human-readable message.",
  "data": { }
}

data is an object or array specific to the endpoint.

Collection envelope

List endpoints add a pagination block inside data, and mirror the totals in WP headers:

{
  "success": true,
  "message": "Successfully grabbed vehicles",
  "data": {
    "items": [ /* ... */ ],
    "pagination": {
      "current_page": 1,
      "per_page": 25,
      "total": 132,
      "total_pages": 6
    }
  }
}
Response header Meaning
X-WP-Total Total items across all pages.
X-WP-TotalPages Total number of pages.

Error envelope

Errors use the standard WordPress REST error shape:

{
  "code": "dms_listing_not_found",
  "message": "Listing not found.",
  "data": { "status": 404 }
}

Pagination parameters

List endpoints accept:

Query param Type Default Notes
page int 1 1-indexed page number.
per_page int 25 Items per page. Capped at 100.
status string - Comma-separated post statuses (publish, draft, trash).

The listing payload

Endpoints that return a listing use a consistent shape:

{
  "id": 123,
  "permalink": "https://your-site.com/vehicles/2021-example/",
  "title": "2021 Example Model",
  "content": "Full description...",
  "price": 24995,
  "status": "publish",
  "categories": {
    "42": "Blue",
    "51": ["Bluetooth", "Backup Camera"]
  },
  "images": [ { "id": 9, "src": "...", "width": 1600, "height": 1067 } ],
  "is_sold": false,
  "is_sale_pending": false
}

categories is keyed by numeric category ID. Values are a single string, an array of terms (checkbox / multi-select categories), or an attachment reference (file categories). Resolve category IDs under Dealer.ms → (type) → Categories.


Capabilities

The Bearer key resolves to a WordPress user, and DMS capability checks run against that user. A route with a capability requirement returns 403 dms_forbidden if the user lacks it. Call GET /authenticate to see the caller's write capabilities up front.

Capability Grants
add_inventory Create listings, run VIN imports.
edit_all_inventory Update any listing, upload files.
delete_inventory Trash listings, clear trash.
modify_gallery Upload gallery images.
view_all_leads Read leads.
manage_settings Flush cache and other settings-level actions.

To scope an integration, create a dedicated WordPress user with only the roles/capabilities it needs, and issue that user its own labeled key.


See also