🌹 Wild Rose Trucking — VTC API

Integrate your VTC website with Wild Rose Trucking. Authenticate users, pull stats, and display live data.

Overview

The Wild Rose VTC API allows external VTC websites to:

Base URL: https://wild-rose-gaming.com

Getting Started

1. Create an OAuth Client

Go to your Manage VTC tab and scroll to the API / OAuth section. Fill in:

You'll receive a client_id and client_secret. Store the secret securely — it's only shown once.

⚠️ Important: Keep your client_secret private. Never expose it in client-side JavaScript or public repositories.

OAuth Flow

Wild Rose uses a standard OAuth 2.0 Authorization Code flow:

Step 1: Redirect User to Authorize

Send the user to the Wild Rose authorization page:

GET https://wild-rose-gaming.com/oauth/authorize
    ?client_id=YOUR_CLIENT_ID
    &redirect_uri=https://yoursite.com/auth/callback
    &state=RANDOM_STRING
ParameterRequiredDescription
client_idYesYour OAuth client ID
redirect_uriYesMust exactly match the URI registered with your client
stateRecommendedRandom string to prevent CSRF. Returned unchanged in the callback.

The user will see a branded "Login with Wild Rose" page. If not logged in, they'll be prompted to sign in. They then approve or deny access.

Step 2: Handle the Callback

After approval, the user is redirected back to your redirect_uri with:

https://yoursite.com/auth/callback?code=AUTHORIZATION_CODE&state=YOUR_STATE

If denied:

https://yoursite.com/auth/callback?error=access_denied&state=YOUR_STATE
⚠️ Security: Always verify that state matches what you sent. The authorization code expires in 5 minutes and can only be used once.

Step 3: Exchange Code for Access Token

Make a server-side POST request to exchange the code:

POST https://wild-rose-gaming.com/oauth/token

Content-Type: application/json

{
    "client_id": "YOUR_CLIENT_ID",
    "client_secret": "YOUR_CLIENT_SECRET",
    "code": "AUTHORIZATION_CODE",
    "redirect_uri": "https://yoursite.com/auth/callback"
}

Response:

{
    "access_token": "abc123...",
    "token_type": "Bearer",
    "expires_in": 604800,
    "user": {
        "id": 1,
        "username": "trucker_joe",
        "display_name": "Trucker Joe",
        "avatar": "https://wild-rose-gaming.com/uploads/staff/user_1_abc.jpg",
        "company_id": 1,
        "company_name": "Wild Rose Trucking",
        "company_role": "driver"
    }
}

Step 4: Use the Access Token

Include the token in subsequent API requests:

Authorization: Bearer YOUR_ACCESS_TOKEN

Tokens are valid for 7 days.

Authorization Endpoints

GET /oauth/authorize

Authorization page — redirect users here to begin the OAuth flow.

ParameterTypeDescription
client_idstringYour OAuth client ID
redirect_uristringCallback URL (must match registered URI)
statestringAnti-CSRF token (returned in callback)
POST /oauth/token

Exchange authorization code for an access token.

ParameterTypeDescription
client_idstringYour OAuth client ID
client_secretstringYour OAuth client secret
codestringAuthorization code from callback
redirect_uristringSame redirect URI used in authorize request

User Data Endpoints

GET /oauth/token?action=user&access_token=TOKEN

Get the authenticated user's full profile, stats, recent jobs, and company driver leaderboard.

⚠️ Cloudflare: Use ?access_token=TOKEN query parameter. The Authorization header gets stripped.

Response

{
    "id": 1,
    "username": "trucker_joe",
    "display_name": "Trucker Joe",
    "avatar": "https://wild-rose-gaming.com/uploads/staff/user_1_abc.jpg",
    "email": "joe@example.com",
    "company": {
        "id": 1,
        "name": "Wild Rose Trucking",
        "tag": "WRT",
        "color": "#FF6A2A",
        "logo": "https://wild-rose-gaming.com/uploads/trucking/co_logo_1_abc.png",
        "slug": "wild-rose-trucking"
    },
    "company_role": "driver",
    "stats": {
        "total_jobs": 142,
        "total_distance": 85420,
        "total_revenue": 4250000,
        "total_xp": 28500
    },
    "recent_jobs": [
        {
            "cargo": "Electronics",
            "source_city": "Las Vegas",
            "source_company": "Tech Corp",
            "destination_city": "Los Angeles",
            "destination_company": "Retail Hub",
            "distance": 420,
            "planned_distance": 415,
            "revenue": 32000,
            "xp": 850,
            "cargo_mass": 18500,
            "cargo_damage": 0.001,
            "truck_damage": 0.003,
            "truck": "Kenworth W900",
            "fuel_used": 145,
            "duration": 1800,
            "created_at": "2025-07-10 14:30:00"
        }
    ],
    "jobs_total": 142,
    "jobs_page": 1,
    "jobs_pages": 15,
    "company_drivers": [
        {
            "id": 1,
            "username": "trucker_joe",
            "display_name": "Trucker Joe",
            "avatar": "https://wild-rose-gaming.com/uploads/staff/user_1_abc.jpg",
            "role": "driver",
            "total_jobs": 142,
            "total_distance": 85420,
            "total_revenue": 4250000
        }
    ],
    "member_since": "2024-01-15 10:30:00"
}
ParameterTypeDescription
access_tokenstringOAuth access token (query param)
job_pageintPage number for recent_jobs (optional, default 1, 10 per page)
GET /oauth/token?action=live_drivers&access_token=TOKEN

Get live driver positions for the authenticated user's company.

Response

{
    "ok": true,
    "drivers": [
        {
            "username": "trucker_joe",
            "display_name": "Trucker Joe",
            "avatar": "https://wild-rose-gaming.com/uploads/staff/user_1_abc.jpg",
            "speed": 88.5,
            "has_load": true,
            "cargo": "Electronics",
            "source_city": "Las Vegas",
            "destination_city": "Los Angeles",
            "game": "ats"
        }
    ]
}
GET /oauth/token?action=driver_jobs&driver_id=ID&access_token=TOKEN

Get paginated delivery history for a specific driver in your company. Requires user token.

ParameterTypeDescription
driver_idintThe driver's user ID (from company_drivers array)
pageintPage number (optional, default 1, 10 per page)
access_tokenstringOAuth access token

Response

{
    "driver": { "id": 1, "name": "Trucker Joe" },
    "jobs": [
        {
            "cargo": "Electronics",
            "source_city": "Las Vegas",
            "source_company": "Tech Corp",
            "destination_city": "Los Angeles",
            "destination_company": "Retail Hub",
            "distance": 420,
            "planned_distance": 415,
            "revenue": 32000,
            "xp": 850,
            "cargo_mass": 18500,
            "cargo_damage": 0.001,
            "truck_damage": 0.003,
            "truck": "Kenworth W900",
            "fuel_used": 145,
            "duration": 1800,
            "created_at": "2025-07-10 14:30:00"
        }
    ],
    "total": 142,
    "page": 1,
    "pages": 15
}
GET /oauth/token?action=driver_jobs_public&client_id=ID&client_secret=SECRET&driver_id=ID

Get paginated delivery history using client credentials. No user login needed — perfect for public driver profile pages.

ParameterTypeDescription
client_idstringYour OAuth client ID
client_secretstringYour OAuth client secret
driver_idintThe driver's user ID
pageintPage number (optional, default 1, 10 per page)

Response is identical to driver_jobs. Only returns drivers in your company.

💡 Tip: Use this server-side to build public driver profile pages without requiring visitors to log in. Keep your client_secret in server-side code only.

Company Data Endpoints

GET /oauth/token?action=company_stats

Get public company stats using client credentials. No user token needed.

ParameterTypeDescription
client_idstringYour OAuth client ID
client_secretstringYour OAuth client secret

Response

{
    "ok": true,
    "company": {
        "id": 1,
        "name": "Wild Rose Trucking",
        "tag": "WRT",
        "color": "#FF6A2A",
        "logo": "https://wild-rose-gaming.com/uploads/trucking/co_logo_1_abc.png",
        "slug": "wild-rose-trucking"
    },
    "stats": {
        "total_drivers": 12,
        "total_jobs": 847,
        "total_distance": 412000,
        "total_revenue": 18200000,
        "total_xp": 95000
    },
    "top_drivers": [
        {
            "id": 1,
            "username": "trucker_joe",
            "display_name": "Trucker Joe",
            "avatar": "https://wild-rose-gaming.com/uploads/staff/user_1_abc.jpg",
            "total_jobs": 142,
            "total_distance": 85420,
            "total_revenue": 4250000
        }
    ]
}
💡 Tip: Use this endpoint to display company stats on your public homepage without requiring users to log in. The stats are for the company owned by the OAuth client creator.
POST /api/trucking.php

Get live driver positions for your company.

{
    "action": "get_positions",
    "api_key": "YOUR_TRUCKING_API_KEY",
    "company_id": 1
}

Response

{
    "ok": true,
    "drivers": [
        {
            "username": "trucker_joe",
            "display_name": "Trucker Joe",
            "avatar": "/uploads/staff/user_1_abc.jpg",
            "pos_x": -95432.5,
            "pos_y": 0,
            "pos_z": 23456.7,
            "heading": 1.57,
            "speed": 88.5,
            "has_load": true,
            "cargo": "Electronics",
            "source_city": "Las Vegas",
            "destination_city": "Los Angeles",
            "game": "ats",
            "active": true
        }
    ]
}

Company Management Endpoints

These endpoints require an OAuth token from a user with owner or manager role in their company. All use ?access_token=TOKEN for authentication.

⚠️ Permissions: Most management endpoints require owner or manager role. Application review also allows recruiter role.
GET /oauth/token?action=update_company&access_token=TOKEN

Update company details. Requires owner or manager role.

ParameterTypeDescription
namestringCompany name (required)
tagstringShort tag (e.g. "WRT")
descriptionstringCompany description
join_typestring"open", "application", or "invite"
webhookstringDiscord webhook URL
colorstringHex color (e.g. "#FF6A2A")
app_formstringApplication form slug

Response

{ "ok": true }
GET /oauth/token?action=company_forms&access_token=TOKEN

Get available application forms that can be linked to your company. Requires owner or manager role.

Response

{
    "ok": true,
    "forms": [
        { "slug": "vtc-application", "name": "VTC Application Form" }
    ]
}
GET /oauth/token?action=update_role&access_token=TOKEN

Change a company member's role. Requires owner or manager role. Only owners can promote to manager.

ParameterTypeDescription
member_idintUser ID of the member to update
rolestring"driver", "recruiter", or "manager"

Response

{ "ok": true, "role": "manager" }
GET /oauth/token?action=applications&access_token=TOKEN

Get pending company applications. Requires owner, manager, or recruiter role.

Response

{
    "ok": true,
    "applications": [
        {
            "id": 12,
            "username": "new_driver",
            "display_name": "New Driver",
            "avatar": "https://wild-rose-gaming.com/uploads/staff/user_5_abc.jpg",
            "message": "I'd love to join your company!",
            "created_at": "2025-07-10 09:00:00"
        }
    ]
}
GET /oauth/token?action=approve_app&access_token=TOKEN

Approve a pending application. The user will be added to your company as a driver. Requires owner, manager, or recruiter role.

ParameterTypeDescription
app_idintApplication ID (from applications list)

Response

{ "ok": true, "status": "approved" }
GET /oauth/token?action=decline_app&access_token=TOKEN

Decline a pending application. Requires owner, manager, or recruiter role.

ParameterTypeDescription
app_idintApplication ID (from applications list)

Response

{ "ok": true, "status": "declined" }
GET /oauth/token?action=kick_member&access_token=TOKEN

Remove a member from your company. Requires owner or manager role. Cannot kick the owner.

ParameterTypeDescription
member_idintUser ID of the member to remove

Response

{ "ok": true }

Error Responses (Management)

ErrorCause
unauthorizedMissing or invalid access token
forbiddenUser doesn't have required role (owner/manager/recruiter)
invalid_roleRole must be "driver", "recruiter", or "manager"
cannot_change_ownCannot change your own role
cannot_change_ownerCannot modify the company owner's role
cannot_kick_selfCannot kick yourself
cannot_kick_ownerCannot kick the company owner
member_not_foundMember ID not found in your company
not_foundApplication or member not found
name_requiredCompany name is required for update_company

Error Handling

All error responses follow this format:

{
    "error": "error_code",
    "message": "Human-readable description"
}
Error CodeHTTP StatusDescription
invalid_request400Missing or invalid parameters
invalid_client401Invalid client_id or client_secret
invalid_grant400Authorization code is invalid, expired, or already used
access_deniedUser denied the authorization request
unauthorized401Missing or invalid access token
invalid_token401Access token has expired
server_error500Internal server error

Cloudflare & Authorization Headers

Wild Rose Gaming sits behind Cloudflare. In some configurations, Cloudflare will strip the Authorization header from requests before they reach the origin server. This affects both server-side curl calls and client-side fetch requests.

⚠️ Important: If you receive {"error":"unauthorized","message":"Access token required"} despite sending a valid Bearer token, Cloudflare is likely stripping the header.

Solution: Use the Query Parameter

All endpoints that accept Authorization: Bearer TOKEN also accept the token as a query parameter:

GET /oauth/token?action=user&access_token=YOUR_TOKEN

This bypasses the header stripping entirely. Use this method when:

When Headers Work Fine

The Authorization header works without issues when:

Example: Client-Side Fetch

// ❌ May fail — Cloudflare strips the header
fetch('https://wild-rose-gaming.com/oauth/token?action=user', {
    headers: { 'Authorization': 'Bearer ' + token }
});

// ✅ Always works — token in query string
fetch('https://wild-rose-gaming.com/oauth/token?action=user&access_token=' + token);

Example: Server-Side PHP

// ❌ May fail from external servers
$ch = curl_init('https://wild-rose-gaming.com/oauth/token?action=user');
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Authorization: Bearer ' . $token]);

// ✅ Always works
$ch = curl_init('https://wild-rose-gaming.com/oauth/token?action=user&access_token=' . urlencode($token));
💡 Tip: The POST /oauth/token exchange (Step 3 of the OAuth flow) is unaffected — credentials go in the JSON body, not headers. Only GET requests with Bearer tokens are impacted.

Rate Limits

Please be respectful with API usage:

Rate Limit Response

When you exceed the limit, you'll receive a 429 Too Many Requests response:

{
    "error": "rate_limited",
    "message": "Too many requests. Please wait before trying again.",
    "retry_after": 30
}
FieldTypeDescription
retry_afterintSeconds to wait before making another request
💡 Tip: Cache user data on your side for a few minutes rather than hitting the API on every page load. Use company_stats with a 5-minute cache for public pages.

Try It

Test the API directly from this page. Paste your access token below to make live requests.

🔑 Token Tester

⚠️ Note: Your token is never sent to any server other than wild-rose-gaming.com. This runs entirely in your browser.

Full Example (PHP)

Here's a complete example of implementing "Login with Wild Rose" on your VTC site:

login.php — Redirect to Wild Rose

<?php
session_start();

$clientId = 'YOUR_CLIENT_ID';
$redirectUri = 'https://yoursite.com/auth/callback.php';

// Generate random state for CSRF protection
$state = bin2hex(random_bytes(16));
$_SESSION['oauth_state'] = $state;

// Redirect to Wild Rose
$url = 'https://wild-rose-gaming.com/oauth/authorize?' . http_build_query([
    'client_id' => $clientId,
    'redirect_uri' => $redirectUri,
    'state' => $state,
]);

header('Location: ' . $url);
exit;

callback.php — Handle the response

<?php
session_start();

$clientId = 'YOUR_CLIENT_ID';
$clientSecret = 'YOUR_CLIENT_SECRET';
$redirectUri = 'https://yoursite.com/auth/callback.php';

// Verify state
if (($_GET['state'] ?? '') !== ($_SESSION['oauth_state'] ?? '')) {
    die('Invalid state — possible CSRF attack');
}
unset($_SESSION['oauth_state']);

// Check for errors
if (isset($_GET['error'])) {
    die('Authorization denied: ' . htmlspecialchars($_GET['error']));
}

// Exchange code for token
$code = $_GET['code'] ?? '';
$response = file_get_contents('https://wild-rose-gaming.com/oauth/token', false,
    stream_context_create([
        'http' => [
            'method' => 'POST',
            'header' => 'Content-Type: application/json',
            'content' => json_encode([
                'client_id' => $clientId,
                'client_secret' => $clientSecret,
                'code' => $code,
                'redirect_uri' => $redirectUri,
            ]),
        ],
    ])
);

$data = json_decode($response, true);

if (!isset($data['access_token'])) {
    die('Token exchange failed: ' . ($data['message'] ?? 'Unknown error'));
}

// Store in session
$_SESSION['access_token'] = $data['access_token'];
$_SESSION['user'] = $data['user'];

header('Location: /dashboard');
exit;

Fetching user data later

<?php
session_start();

$token = $_SESSION['access_token'] ?? '';
if (!$token) { header('Location: /login.php'); exit; }

// Use access_token query param (Cloudflare strips Authorization headers)
$response = file_get_contents(
    'https://wild-rose-gaming.com/oauth/token?action=user&access_token=' . urlencode($token)
);

$user = json_decode($response, true);

echo 'Welcome, ' . htmlspecialchars($user['display_name']);
echo '<br>Total distance: ' . number_format($user['stats']['total_distance']) . ' km';
echo '<br>Company: ' . htmlspecialchars($user['company']['name'] ?? 'None');

Fetching company stats (no user login needed)

<?php
// Public company stats using client credentials
$response = file_get_contents(
    'https://wild-rose-gaming.com/oauth/token?action=company_stats'
    . '&client_id=' . urlencode($clientId)
    . '&client_secret=' . urlencode($clientSecret)
);

$data = json_decode($response, true);

if ($data['ok']) {
    echo $data['company']['name'] . ' — ' . $data['stats']['total_drivers'] . ' drivers';
    echo '<br>' . number_format($data['stats']['total_jobs']) . ' deliveries';
    echo '<br>' . number_format($data['stats']['total_distance']) . ' km driven';
}
💡 Live Demo: See a full working integration at test.wild-rose-gaming.com

Changelog

📝 Version History

v1.2 — July 2025
• Added action=company_stats — public stats via client credentials
• Added action=live_drivers — live positions via OAuth
• Added action=driver_jobs — paginated delivery history
• Added company management endpoints (update_company, update_role, applications, kick_member)
• Documented Cloudflare header stripping — use ?access_token= query param
• Added /docs/api.txt machine-readable endpoint
action=user now returns company_drivers, recent_jobs, and pagination
v1.1 — June 2025
• Added company_drivers array to user endpoint
• Added recent_jobs with full delivery details
• Token response now includes user object
v1.0 — May 2025
• Initial release
• OAuth 2.0 Authorization Code flow
• User profile + stats endpoint
• Trucking API positions endpoint

Machine-Readable Docs (for AI / curl)

Need a quick summary an LLM or script can parse? Hit the plaintext endpoint:

GET /api.txt

Returns a plain-text summary of the entire API — perfect for piping into an AI assistant or quick reference via curl.

curl https://api.wild-rose-gaming.com/api.txt
💡 Tip: Feed the output straight into your LLM context:
curl -s https://api.wild-rose-gaming.com/api.txt | llm "write me a PHP integration"

Live Map Embed

Embed the Wild Rose live map directly on your VTC site using an iframe. Authenticates with your client_id — no user token needed.

GET /livemap?embed&client_id=YOUR_CLIENT_ID

Embeddable live map showing your company's drivers in real-time.

Usage

<iframe
    src="https://wild-rose-gaming.com/livemap?embed&client_id=YOUR_CLIENT_ID"
    style="width:100%;height:600px;border:none;border-radius:12px;"
    allow="fullscreen"
></iframe>
💡 Tip: The embed mode hides the site header/footer and only shows the map. It automatically filters to your company's drivers based on the client_id.

Full-Page Example

<!-- Full-height map page -->
<div style="position:fixed;inset:0;">
    <iframe
        src="https://wild-rose-gaming.com/livemap?embed&client_id=YOUR_CLIENT_ID"
        style="width:100%;height:100%;border:none;"
        allow="fullscreen"
    ></iframe>
</div>

Support

Having issues with the API? Reach out on our Discord server.