Documentation · Appendices
REST Endpoint Reference
This appendix lists the REST API routes registered by the ADP Car Market Hub plugin under the as24ci/v1 namespace.
When to use this document
Use this reference when you need to call a plugin endpoint, when you are diagnosing unexpected 403/404 responses, or when you are documenting an integration. For the conceptual description of each endpoint, see REST API Endpoints.
Overview
All routes registered by the plugin use the WordPress REST API and share the namespace as24ci/v1. The full URL of any endpoint is the WordPress REST root followed by the route, typically https://example.com/wp-json/as24ci/v1/....
The endpoints fall into five groups:
- Public vehicle data (
/vehicles,/vehicles/{id}) — disabled by default; gated byas24ci_rest_api_enabled. - Favorites helper (
/favorites) — used by the front-end favorites page. - Analytics tracking (
/analytics/track) — used by the front-end script. - Cron import trigger (
/cron-import) — token-protected; used by external schedulers. - License refresh signal (
/license-refresh-signal) — used by the API Platform to ask the site to re-validate its license.
Endpoint summary
| Route | Method | Auth | Always registered? |
|---|---|---|---|
/as24ci/v1/vehicles | GET | None (public) | No — only when as24ci_rest_api_enabled is '1'. |
/as24ci/v1/vehicles/{id} | GET | None (public) | No — same gating as above. |
/as24ci/v1/favorites | POST | None (public) | Yes. |
/as24ci/v1/analytics/track | POST | None (public) | Yes. |
/as24ci/v1/cron-import | GET | Bearer token | Yes. Returns 403 until a token is configured. |
/as24ci/v1/license-refresh-signal | POST | Signal-only trust model (handled inside callback) | Yes. |
GET /as24ci/v1/vehicles
Paginated, filterable list of imported vehicles whose post status is publish.
Query parameters:
| Parameter | Type | Default | Notes |
|---|---|---|---|
page | integer ≥ 1 | 1 | Page number. |
per_page | integer 1–100 | 10 | Items per page. |
make | string | — | Exact match against the make meta key. |
model | string | — | Exact match against the model meta key. |
fuel_type | string | — | LIKE match against the fuel type meta key. |
year_min, year_max | integer | — | Numeric range against _as24ci_year. |
price_min, price_max | numeric | — | Numeric range against _as24ci_price. |
orderby | date, price, mileage, title | date | Sort field. |
order | asc, desc | desc | Sort direction (case-insensitive). |
Response (shape):
{
"vehicles": [
{
"id": 0, "title": "", "url": "", "image": "",
"make": "", "model": "", "year": 0, "price": 0,
"currency": "EUR", "mileage": 0, "condition": "",
"fuel_type": "", "transmission": "", "body_type": "",
"color": "", "doors": 0, "horse_power": 0, "vin": "",
"listing_id": ""
}
],
"total": 0,
"pages": 0,
"page": 1,
"per_page": 10
}
The image field is the medium-large size of the featured image (empty string when none). The currency field falls back to as24ci_default_currency when no per-vehicle currency is stored.
GET /as24ci/v1/vehicles/{id}
Full details for a single vehicle.
- Path parameter:
id— positive integer; validated and cast throughabsint. - Auth: none (public). Same gating as the list endpoint.
- Response: all fields from the list response plus
description,images(array of attachment URLs atlargesize, combining manual and imported images and falling back to the featured image),equipment_standard,equipment_optionalandseller. - Errors:
404 as24ci_vehicle_not_foundwhen the post does not exist, is not theas24ci_carCPT, or is not published.
POST /as24ci/v1/favorites
Hydrates the visitor's favorites with current vehicle data for IDs stored in browser local storage.
- Auth: none (public). Always registered.
- Body: JSON object with
ids— an array of post IDs. Sanitised to a unique list of positive integers; capped at 50 IDs per request. - Response:
{ "vehicles": [ ... ] }. - Notes: Only published vehicles are returned. Posts the visitor no longer has access to (deleted, draft, wrong post type) are silently omitted.
POST /as24ci/v1/analytics/track
Receives analytics events from the front-end tracking pixel.
- Auth: none (public). Always registered.
- Body parameters:
post_id— integer ≥ 0. Default0.event_type— one ofview,view_archive,view_compare,view_favorites,filter_search,contact_open,lead_sent.extra_data— optional sanitised string. Forfilter_search, must be a JSON object containing the active filter key/value pairs.- Response:
{ "tracked": true }on success, or{ "tracked": false }with HTTP400when the event requires a vehicle post that does not exist or is unpublished. - Notes: Intentionally permissive so anonymous visitors can send events. Do not rely on it for authoritative business data.
GET /as24ci/v1/cron-import
Token-protected endpoint that runs the shared import routine. Delegates to the same Scheduler::run_import() method used by the WP-Cron hook and the manual "Trigger now" admin button.
- Auth: bearer token. Provide the token via either the HTTP header
Authorization: Bearer <token>(preferred — keeps the token out of access logs) or the?token=<token>query parameter. Comparison useshash_equals()to mitigate timing attacks. - Token storage:
as24ci_cron_tokenoption. Generate or rotate it from Import & Limits in the plugin admin. - Responses:
403when no token is configured or the supplied token does not match.200with{ "success": true, "message": "...", "counts": { ... } }on a successful run.429withsuccess: falsewhen another import is already running and the runner declined to start a second one.500when the runner threw an exception.- Side effect: A successful authentication updates
as24ci_last_external_cron_run, which the System & Help tab uses to confirm that the external cron is reaching the site. Visiting any URL with?as24ci_cron=1also updates this timestamp via the heartbeat hook oninit.
Example external cron invocation (placeholder — substitute your own host and a generated token):
0 * * * * curl -fsS -H "Authorization: Bearer YOUR_TOKEN" \
"https://example.com/wp-json/as24ci/v1/cron-import?as24ci_cron=1"
POST /as24ci/v1/license-refresh-signal
Lightweight signal endpoint that lets the API Platform ask the site to re-validate its license out of band (for example after a plan change). Registered unconditionally so the platform can always reach it; it is not gated behind the public vehicle REST API option.
- Auth: signal-only trust model. Authentication is handled inside the callback rather than by a
permission_callback; the request must be JSON and is validated against the expected signal shape. - Body: JSON object. Safe, non-secret correlation fields (
request_id,event) are echoed back for tracing only. - Responses:
405 method_not_allowedwhen the request is notPOST.400 invalid_content_typewhen the body is not JSON, or400 invalid_jsonwhen the body cannot be parsed.200when the signal is accepted.- Owner:
AS24CI\License_Refresh_Signal.
Operational notes
- The public vehicle endpoints execute standard
WP_Querycalls and honour normal WordPress object caching. Repeated identical requests benefit from the post and post-meta caches. - Numeric filters add to a
meta_query. On large catalogues, ensure the underlying meta keys are indexed at the database level if you expect heavy traffic. Verify the indexing strategy in the current plugin version before publishing. - The list endpoint applies
update_postmeta_cache()on the returned posts to keep response times predictable. - The favorites endpoint hard-caps each request at 50 IDs to prevent abuse.
- The cron import endpoint sets
nocache_headers()so caching proxies do not interfere with scheduled runs. - Pretty permalinks are recommended for path-style REST URLs. With plain permalinks, the endpoints are still reachable via
?rest_route=.
Troubleshooting
/vehiclesreturns404. The public API is disabled. Setas24ci_rest_api_enabledto'1'in Settings → SEO & Integrations (or via WP-CLI /update_option)./cron-importreturns403. Either no token is configured (as24ci_cron_tokenempty — the response message confirms this) or the supplied token does not match. Generate a new token from the admin and retry./cron-importreturns429. Another import is already running and a lock prevents a second concurrent run. Wait for the current run to finish.- Empty
vehiclesarray on the list endpoint with no filters. No vehicles are published, or the catalogue has not been imported yet. Check the Import & Limits screen and the import logs. - HTTP
400on/analytics/track. The event requires a published vehicle post butpost_idreferences a draft, deleted or non-vehicle post.