API DOCUMENTATION
Platoonix API allows you to post and manage loads programmatically. Perfect for integrating with your Transport Management System (TMS) or automating bulk operations.
Step 1: Generate API Key
Step 2: Authentication
Include your API key in all requests:
Header: Authorization: Bearer YOUR_API_KEY
Content-Type: application/json
Open-load discovery (Find Backhaul) uses the same core logic as GET /api/matches/find-for-vehicle: results are sorted on the server so better vehicle/load fit comes first, then road distance to the pickup (ascending). Distances use road routing where configured — not straight-line “as the crow flies”.
If a load specifies a required vehicle type (artic/rigid/van), only that type is returned — mismatches are filtered out, not shown as “near match”. Remaining candidates are scored “perfect” vs near match (trailer preference, equipment flags), then:
# Order of results returned to the client
pairs.sort(key=lambda x: (not x.is_perfect_match, x.distance_miles))
Loads that fail hard requirements (wrong vehicle type, weight over capacity, missing required tail lift / temp / ADR) are omitted entirely.
GET /api/matches/find-for-vehicle
Query parameters:
Example: GET /api/matches/find-for-vehicle?vehicle_id=123&origin_postcode=M1%201AA&radius_miles=25
Each item is a LoadMatchResult: the nested load plus distance_miles. Match quality is reflected in the order of the array (best matches first). The dashboard may show extra flags (e.g. perfect vs near); ask us if you need those fields exposed in JSON for integrations.
[
{
"load": {
"id": 456,
"pickup_postcode": "M2 5DB",
"delivery_postcode": "B1 1AA",
"budget_gbp": 300,
"status": "open",
"weight_kg": 5000,
"requirements": { "vehicle_type": "rigid", "trailer_type": "curtain_sider" }
},
"distance_miles": 8.3
},
{
"load": {
"id": 789,
"pickup_postcode": "M15 6AZ",
"delivery_postcode": "L1 8JQ",
"budget_gbp": 250,
"status": "open"
},
"distance_miles": 12.1
}
]
When you use Find Backhaul in the web app with both origin and destination, we also blend corridor matches (loads near your return route) with origin-radius matches — still sorted by match quality then distance. There is no separate public JSON endpoint documented here for corridor; behaviour is described in Terms (section 11).
For the philosophy behind ranking (no pay-to-rank, no random ordering), see Terms — Smart Matching Algorithm.
Base URL: https://platoonix.co.uk/api/v1
Create a new load
Request body:
{
"pickup_postcode": "M1 1AD",
"delivery_postcode": "LS1 1UR",
"budget_gbp": 300,
"vehicle_type": "artic",
"trailer_type": "curtain",
"pallets": 10,
"cubic_metres": 12,
"pickup_window_start": "2026-04-08T09:00:00Z",
"pickup_window_end": "2026-04-08T17:00:00Z",
"delivery_window_start": "2026-04-09T09:00:00Z",
"delivery_window_end": "2026-04-09T17:00:00Z",
"notes": "Fragile items, handle with care"
}
Required fields: pickup_postcode, delivery_postcode, budget_gbp, vehicle_type
Optional fields: All others
Response (201 Created):
{
"id": 123,
"status": "active",
"pickup_postcode": "M1 1AD",
"delivery_postcode": "LS1 1UR",
"budget_gbp": 300,
"platform_fee_gbp": 6.00,
"created_at": "2026-04-07T14:30:00Z"
}
List your loads
Query parameters (all optional):
Example: GET /api/v1/loads?status=active&limit=20
Response (200 OK):
{
"loads": [
{
"id": 123,
"pickup_postcode": "M1 1AD",
"delivery_postcode": "LS1 1UR",
"budget_gbp": 300,
"status": "active",
"created_at": "2026-04-07T14:30:00Z"
}
],
"total": 45,
"limit": 20,
"offset": 0
}
Get single load details
Response (200 OK):
{
"id": 123,
"pickup_postcode": "M1 1AD",
"delivery_postcode": "LS1 1UR",
"budget_gbp": 300,
"platform_fee_gbp": 6.00,
"vehicle_type": "artic",
"trailer_type": "curtain",
"status": "active",
"created_at": "2026-04-07T14:30:00Z",
"matched_at": null,
"completed_at": null
}
Update load details (only for active loads)
Request body: Same as POST (all fields optional)
Response (200 OK):
{
"id": 123,
"status": "active",
"updated_at": "2026-04-07T15:30:00Z"
}
Cancel load (only for active or matched loads)
Response (200 OK):
{
"id": 123,
"status": "cancelled",
"cancelled_at": "2026-04-07T16:00:00Z"
}
400 Bad Request - Invalid parameters
{
"error": "validation_error",
"message": "Invalid postcode format",
"field": "pickup_postcode"
}
401 Unauthorized - Invalid or missing API key
{
"error": "unauthorized",
"message": "Invalid API key"
}
404 Not Found - Load doesn't exist
{
"error": "not_found",
"message": "Load not found"
}
429 Too Many Requests - Rate limit exceeded
{
"error": "rate_limit_exceeded",
"message": "Rate limit exceeded. Try again in 60 seconds."
}
Standard rate limit: 100 requests per hour per API key
Need higher limits? Contact us about our Enterprise API plan.
API access is included at no additional cost!
Standard platform fees apply:
Same pricing whether you use web, CSV, or API.
Python:
import requests
headers = {
'Authorization': 'Bearer YOUR_API_KEY',
'Content-Type': 'application/json'
}
# Create load
data = {
'pickup_postcode': 'M1 1AD',
'delivery_postcode': 'LS1 1UR',
'budget_gbp': 300,
'vehicle_type': 'artic'
}
response = requests.post(
'https://platoonix.co.uk/api/v1/loads',
headers=headers,
json=data
)
print(response.json())
JavaScript/Node.js:
const axios = require('axios');
const headers = {
'Authorization': 'Bearer YOUR_API_KEY',
'Content-Type': 'application/json'
};
// Create load
const data = {
pickup_postcode: 'M1 1AD',
delivery_postcode: 'LS1 1UR',
budget_gbp: 300,
vehicle_type: 'artic'
};
axios.post('https://platoonix.co.uk/api/v1/loads', data, { headers })
.then(response => console.log(response.data))
.catch(error => console.error(error));
cURL:
curl -X POST https://platoonix.co.uk/api/v1/loads \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"pickup_postcode": "M1 1AD",
"delivery_postcode": "LS1 1UR",
"budget_gbp": 300,
"vehicle_type": "artic"
}'
Standard Support (Included):
Need faster support, custom features, or higher rate limits?
Ask about our Enterprise API plan:
Contact: support@platoonix.co.uk (subject: Enterprise API)