Console
Guide

Authentication

Two-layer auth: your app credentials (AppID:AppKey) on every request, plus a user token from login for user-scoped operations.

Auth layers

LayerHowWhen
App authAuthorization: AppID:AppKey headerEvery request
User authtoken in JSON bodyUser-scoped endpoints

1. Login a user

Call POST /api/vaneltonid/login.php. Returns a session token you store locally.

const res = await fetch('https://vaneltonmedia.com/api/vaneltonid/login.php', {
  method: 'POST',
  headers: {
    'Authorization': 'com.myapp.game:MyAppKey1234567890ABCDE',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({ email: 'user@email.com', password: 'pass123' })
});
const data = await res.json();
const token = data.vaneltonid.token; // store this
interface LoginResponse {
  vaneltonid: {
    logged: number; id: number; userkey: string;
    email: string; username: string; name: string;
    token: string; roles: string; vaneltonpass: boolean;
    itemKeys: string[];
  };
  app: { authorized: number; appname: string; appversion: string; };
}

const res = await fetch('https://vaneltonmedia.com/api/vaneltonid/login.php', {
  method: 'POST',
  headers: {
    'Authorization': 'com.myapp.game:MyAppKey1234567890ABCDE',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({ email: 'user@email.com', password: 'pass123' })
});
const data: LoginResponse = await res.json();
const token: string = data.vaneltonid.token;
$ch = curl_init('https://vaneltonmedia.com/api/vaneltonid/login.php');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_POST => true,
    CURLOPT_HTTPHEADER => [
        'Authorization: com.myapp.game:MyAppKey1234567890ABCDE',
        'Content-Type: application/json',
    ],
    CURLOPT_POSTFIELDS => json_encode([
        'email'    => 'user@email.com',
        'password' => 'pass123',
    ]),
]);
$response = json_decode(curl_exec($ch), true);
curl_close($ch);

$token = $response['vaneltonid']['token'];
import java.net.http.*;
import java.net.URI;

HttpClient client = HttpClient.newHttpClient();
String body = "{\"email\":\"user@email.com\",\"password\":\"pass123\"}";

HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://vaneltonmedia.com/api/vaneltonid/login.php"))
    .header("Authorization", "com.myapp.game:MyAppKey1234567890ABCDE")
    .header("Content-Type", "application/json")
    .POST(HttpRequest.BodyPublishers.ofString(body))
    .build();

HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
// Parse JSON response with your preferred library (Gson, Jackson, etc.)
// String token = parsed.vaneltonid.token;
import requests

res = requests.post(
    'https://vaneltonmedia.com/api/vaneltonid/login.php',
    headers={
        'Authorization': 'com.myapp.game:MyAppKey1234567890ABCDE',
        'Content-Type': 'application/json',
    },
    json={'email': 'user@email.com', 'password': 'pass123'}
)
data = res.json()
token = data['vaneltonid']['token']
// GML — GameMaker Studio 2
var _url  = "https://vaneltonmedia.com/api/vaneltonid/login.php";
var _body = json_stringify({
    email:    "user@email.com",
    password: "pass123"
});
var _headers = ds_map_create();
ds_map_add(_headers, "Authorization", "com.myapp.game:MyAppKey1234567890ABCDE");
ds_map_add(_headers, "Content-Type",  "application/json");

global.login_request_id = http_request(_url, "POST", _headers, _body);
ds_map_destroy(_headers);

// --- In Async HTTP Event ---
if (async_load[? "id"] == global.login_request_id) {
    var _data  = json_parse(async_load[? "result"]);
    global.user_token = _data.vaneltonid.token;
    show_debug_message("Logged in! Token: " + global.user_token);
}
curl -s -X POST "https://vaneltonmedia.com/api/vaneltonid/login.php" \
  -H "Authorization: com.myapp.game:MyAppKey1234567890ABCDE" \
  -H "Content-Type: application/json" \
  -d '{"email":"user@email.com","password":"pass123"}'
using System.Net.Http;
using System.Text;
using System.Text.Json;

using var client = new HttpClient();
client.DefaultRequestHeaders.Add("Authorization", "com.myapp.game:MyAppKey1234567890ABCDE");

var payload = JsonSerializer.Serialize(new { email = "user@email.com", password = "pass123" });
using var res = await client.PostAsync(
    "https://vaneltonmedia.com/api/vaneltonid/login.php",
    new StringContent(payload, Encoding.UTF8, "application/json"));

using var doc = JsonDocument.Parse(await res.Content.ReadAsStringAsync());
var token = doc.RootElement.GetProperty("vaneltonid").GetProperty("token").GetString();
-- Requires: luarocks install luasocket luasec lua-cjson
local http  = require("socket.http")
local ltn12 = require("ltn12")
local json  = require("cjson")

local body   = json.encode({ email = "user@email.com", password = "pass123" })
local chunks = {}
http.request {
    url    = "https://vaneltonmedia.com/api/vaneltonid/login.php",
    method = "POST",
    headers = {
        ["Authorization"]  = "com.myapp.game:MyAppKey1234567890ABCDE",
        ["Content-Type"]   = "application/json",
        ["Content-Length"] = #body,
    },
    source = ltn12.source.string(body),
    sink   = ltn12.sink.table(chunks),
}
local data  = json.decode(table.concat(chunks))
local token = data.vaneltonid.token

2. Handle app authorization

On the first login, app.authorized may be 0. Call the auth endpoint once to link your app to the user.

async function ensureAuthorized(token, appId, appKey) {
  const res = await fetch('https://vaneltonmedia.com/api/vaneltonid/auth.php', {
    method: 'POST',
    headers: {
      'Authorization': `${appId}:${appKey}`,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({ token })
  });
  return res.json();
}

// After login:
if (data.app.authorized === 0) {
  await ensureAuthorized(token, APP_ID, APP_KEY);
}
async function ensureAuthorized(token: string, appId: string, appKey: string): Promise {
  await fetch('https://vaneltonmedia.com/api/vaneltonid/auth.php', {
    method: 'POST',
    headers: { 'Authorization': `${appId}:${appKey}`, 'Content-Type': 'application/json' },
    body: JSON.stringify({ token })
  });
}

if (data.app.authorized === 0) await ensureAuthorized(token, APP_ID, APP_KEY);
if ($response['app']['authorized'] === 0) {
    $ch = curl_init('https://vaneltonmedia.com/api/vaneltonid/auth.php');
    curl_setopt_array($ch, [
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_POST => true,
        CURLOPT_HTTPHEADER => [
            'Authorization: com.myapp.game:MyAppKey1234567890ABCDE',
            'Content-Type: application/json',
        ],
        CURLOPT_POSTFIELDS => json_encode(['token' => $token]),
    ]);
    curl_exec($ch);
    curl_close($ch);
}
if data['app']['authorized'] == 0:
    requests.post(
        'https://vaneltonmedia.com/api/vaneltonid/auth.php',
        headers={'Authorization': 'com.myapp.game:MyAppKey1234567890ABCDE', 'Content-Type': 'application/json'},
        json={'token': token}
    )
// Check after login and call auth if needed
if (_data.app.authorized == 0) {
    var _headers = ds_map_create();
    ds_map_add(_headers, "Authorization", "com.myapp.game:MyAppKey1234567890ABCDE");
    ds_map_add(_headers, "Content-Type",  "application/json");
    http_request(
        "https://vaneltonmedia.com/api/vaneltonid/auth.php",
        "POST", _headers,
        json_stringify({ token: global.user_token })
    );
    ds_map_destroy(_headers);
}
TOKEN="YOUR_SESSION_TOKEN"

curl -s -X POST "https://vaneltonmedia.com/api/vaneltonid/auth.php" \
  -H "Authorization: com.myapp.game:MyAppKey1234567890ABCDE" \
  -H "Content-Type: application/json" \
  -d "{\"token\":\"$TOKEN\"}"
if (loginData.App.Authorized == 0)
{
    var payload = JsonSerializer.Serialize(new { token });
    await client.PostAsync(
        "https://vaneltonmedia.com/api/vaneltonid/auth.php",
        new StringContent(payload, Encoding.UTF8, "application/json"));
}
if data.app.authorized == 0 then
    local body   = json.encode({ token = token })
    local chunks = {}
    http.request {
        url    = "https://vaneltonmedia.com/api/vaneltonid/auth.php",
        method = "POST",
        headers = {
            ["Authorization"]  = "com.myapp.game:MyAppKey1234567890ABCDE",
            ["Content-Type"]   = "application/json",
            ["Content-Length"] = #body,
        },
        source = ltn12.source.string(body),
        sink   = ltn12.sink.table(chunks),
    }
end

3. Use the token

Store the token and pass it in the JSON body of every user-scoped request:

// Helper — wraps every authenticated API call
async function apiCall(path, body = {}) {
  const res = await fetch(`https://vaneltonmedia.com${path}`, {
    method: 'POST',
    headers: {
      'Authorization': `${APP_ID}:${APP_KEY}`,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({ token: localStorage.getItem('vm_token'), ...body })
  });
  return res.json();
}

// Example: save cloud data
await apiCall('/api/cloudstore/set.php', { cloudkey: 'save-1', dataobject: { level: 5 } });
const API_BASE = 'https://vaneltonmedia.com';
const AUTH     = `${APP_ID}:${APP_KEY}`;

async function apiCall<T = unknown>(path: string, body: Record<string, unknown> = {}): Promise<T> {
  const res = await fetch(`${API_BASE}${path}`, {
    method: 'POST',
    headers: { 'Authorization': AUTH, 'Content-Type': 'application/json' },
    body: JSON.stringify({ token: localStorage.getItem('vm_token'), ...body })
  });
  return res.json();
}
function vmApiCall(string $path, array $body = []): array {
    $body['token'] = $_SESSION['vm_token'];
    $ch = curl_init("https://vaneltonmedia.com{$path}");
    curl_setopt_array($ch, [
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_POST => true,
        CURLOPT_HTTPHEADER => [
            'Authorization: ' . APP_ID . ':' . APP_KEY,
            'Content-Type: application/json',
        ],
        CURLOPT_POSTFIELDS => json_encode($body),
    ]);
    $result = json_decode(curl_exec($ch), true);
    curl_close($ch);
    return $result;
}
// Helper macro / function
function vm_api_call(_path, _body) {
    var _headers = ds_map_create();
    ds_map_add(_headers, "Authorization", global.app_id + ":" + global.app_key);
    ds_map_add(_headers, "Content-Type",  "application/json");
    _body.token = global.user_token; // inject token
    var _req_id = http_request(
        "https://vaneltonmedia.com" + _path,
        "POST", _headers, json_stringify(_body)
    );
    ds_map_destroy(_headers);
    return _req_id;
}

// Usage
vm_api_call("/api/cloudstore/set.php", {
    cloudkey:   "save-1",
    dataobject: { level: 5, hp: 80 }
});
TOKEN="YOUR_SESSION_TOKEN"

# Reusable pattern — swap the URL and body as needed
curl -s -X POST "https://vaneltonmedia.com/api/cloudstore/set.php" \
  -H "Authorization: com.myapp.game:MyAppKey1234567890ABCDE" \
  -H "Content-Type: application/json" \
  -d "{\"token\":\"$TOKEN\",\"cloudkey\":\"save-1\",\"dataobject\":{\"level\":5}}"
// Reusable helper
async Task<JsonDocument> ApiCall(string path, object body)
{
    var merged  = new Dictionary<string, object>(body as IDictionary<string, object>
                      ?? JsonSerializer.Deserialize<Dictionary<string, object>>(
                             JsonSerializer.Serialize(body))!)
                      { ["token"] = _savedToken };
    var payload = JsonSerializer.Serialize(merged);
    using var res = await client.PostAsync(
        $"https://vaneltonmedia.com{path}",
        new StringContent(payload, Encoding.UTF8, "application/json"));
    return JsonDocument.Parse(await res.Content.ReadAsStringAsync());
}
-- Reusable helper
local function vm_api_call(path, body)
    body.token = saved_token
    local encoded = json.encode(body)
    local chunks  = {}
    http.request {
        url    = "https://vaneltonmedia.com" .. path,
        method = "POST",
        headers = {
            ["Authorization"]  = APP_ID .. ":" .. APP_KEY,
            ["Content-Type"]   = "application/json",
            ["Content-Length"] = #encoded,
        },
        source = ltn12.source.string(encoded),
        sink   = ltn12.sink.table(chunks),
    }
    return json.decode(table.concat(chunks))
end

4. Recover a session on app launch

After the first login, save the token locally. On every subsequent launch, call POST /api/vaneltonid/session.php with the saved token instead of prompting for credentials again. Only fall back to the login screen if the session call returns an error.

App starts → load saved token → POST /session → OK? → restore user → done
App starts → load saved token → POST /session → error? → show login screen
async function restoreSession() {
  const token = localStorage.getItem('vm_token');
  if (!token) return null; // no saved token — show login

  const res = await fetch('https://vaneltonmedia.com/api/vaneltonid/session.php', {
    method: 'POST',
    headers: {
      'Authorization': `${APP_ID}:${APP_KEY}`,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({ token })
  });
  const data = await res.json();
  if (data.vaneltonid?.logged) return data; // session valid
  localStorage.removeItem('vm_token');
  return null; // token expired — show login
}
async function restoreSession(): Promise<LoginResponse | null> {
  const token = localStorage.getItem('vm_token');
  if (!token) return null;

  const res = await fetch('https://vaneltonmedia.com/api/vaneltonid/session.php', {
    method: 'POST',
    headers: { 'Authorization': `${APP_ID}:${APP_KEY}`, 'Content-Type': 'application/json' },
    body: JSON.stringify({ token })
  });
  const data: LoginResponse = await res.json();
  if (data.vaneltonid?.logged) return data;
  localStorage.removeItem('vm_token');
  return null;
}
function vmRestoreSession(): ?array {
    if (empty($_SESSION['vm_token'])) return null;

    $ch = curl_init('https://vaneltonmedia.com/api/vaneltonid/session.php');
    curl_setopt_array($ch, [
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_POST => true,
        CURLOPT_HTTPHEADER => [
            'Authorization: ' . APP_ID . ':' . APP_KEY,
            'Content-Type: application/json',
        ],
        CURLOPT_POSTFIELDS => json_encode(['token' => $_SESSION['vm_token']]),
    ]);
    $data = json_decode(curl_exec($ch), true);
    curl_close($ch);

    if (!empty($data['vaneltonid']['logged'])) return $data;
    unset($_SESSION['vm_token']);
    return null; // expired — redirect to login
}
def restore_session(saved_token: str) -> dict | None:
    res = requests.post(
        'https://vaneltonmedia.com/api/vaneltonid/session.php',
        headers={'Authorization': f'{APP_ID}:{APP_KEY}', 'Content-Type': 'application/json'},
        json={'token': saved_token}
    )
    data = res.json()
    if data.get('vaneltonid', {}).get('logged'):
        return data
    return None  # token expired — prompt login
// Step / Create event — try to restore before showing login
if (global.user_token != "") {
    var _headers = ds_map_create();
    ds_map_add(_headers, "Authorization", global.app_id + ":" + global.app_key);
    ds_map_add(_headers, "Content-Type",  "application/json");
    global.session_req = http_request(
        "https://vaneltonmedia.com/api/vaneltonid/session.php",
        "POST", _headers,
        json_stringify({ token: global.user_token })
    );
    ds_map_destroy(_headers);
}

// Async HTTP Event
if (async_load[? "id"] == global.session_req) {
    var _d = json_parse(async_load[? "result"]);
    if (_d.vaneltonid.logged == 1) {
        // session OK — enter game
    } else {
        global.user_token = "";
        // show login screen
    }
}
SAVED_TOKEN="YOUR_SAVED_TOKEN"

curl -s -X POST "https://vaneltonmedia.com/api/vaneltonid/session.php" \
  -H "Authorization: com.myapp.game:MyAppKey1234567890ABCDE" \
  -H "Content-Type: application/json" \
  -d "{\"token\":\"$SAVED_TOKEN\"}"
async Task<string?> RestoreSession(string savedToken)
{
    var payload = JsonSerializer.Serialize(new { token = savedToken });
    using var res = await client.PostAsync(
        "https://vaneltonmedia.com/api/vaneltonid/session.php",
        new StringContent(payload, Encoding.UTF8, "application/json"));

    using var doc = JsonDocument.Parse(await res.Content.ReadAsStringAsync());
    var vid = doc.RootElement.GetProperty("vaneltonid");
    if (vid.GetProperty("logged").GetInt32() == 1)
        return savedToken; // still valid

    // Token expired — clear it and show login
    return null;
}
local function restore_session(saved_token)
    local body   = json.encode({ token = saved_token })
    local chunks = {}
    http.request {
        url    = "https://vaneltonmedia.com/api/vaneltonid/session.php",
        method = "POST",
        headers = {
            ["Authorization"]  = "com.myapp.game:MyAppKey1234567890ABCDE",
            ["Content-Type"]   = "application/json",
            ["Content-Length"] = #body,
        },
        source = ltn12.source.string(body),
        sink   = ltn12.sink.table(chunks),
    }
    local data = json.decode(table.concat(chunks))
    if data.vaneltonid and data.vaneltonid.logged == 1 then
        return saved_token -- still valid
    end
    return nil -- expired, show login
end

Multi-session support

Pass a unique masterkey per device during login. Each pair (user, masterKey) holds an independent token — logging in from mobile won't invalidate the desktop session.

// Mobile app
fetch('/api/vaneltonid/login.php', {
  method: 'POST',
  headers: { 'Authorization': `${APP_ID}:${APP_KEY}`, 'Content-Type': 'application/json' },
  body: JSON.stringify({ email, password, masterkey: 'mobile-ios' })
});
var _body = json_stringify({
    email:     "user@email.com",
    password:  "pass123",
    masterkey: "gamemaker-desktop"
});
// ... rest of http_request
curl -s -X POST "https://vaneltonmedia.com/api/vaneltonid/login.php" \
  -H "Authorization: com.myapp.game:MyAppKey1234567890ABCDE" \
  -H "Content-Type: application/json" \
  -d '{"email":"user@email.com","password":"pass123","masterkey":"desktop"}'
var payload = JsonSerializer.Serialize(new {
    email     = "user@email.com",
    password  = "pass123",
    masterkey = "unity-desktop"
});
using var res = await client.PostAsync(
    "https://vaneltonmedia.com/api/vaneltonid/login.php",
    new StringContent(payload, Encoding.UTF8, "application/json"));
local body = json.encode({
    email     = "user@email.com",
    password  = "pass123",
    masterkey = "love2d-desktop",
})
-- ... rest of http.request

Single Sign-On (SSO)

For desktop apps or situations where you prefer not to collect credentials in your UI, use SSO: your app creates a token, opens the Vanelton ID hosted login page in the system browser, and polls for the result. The session token returned is identical to one from login.php.

SSO Guide
Desktop polling flow, web redirect flow, status table, and code examples.

Error reference

CodeMessageCause
401Authorization header with appid:appkey is required.Missing or malformed header
401Invalid app credentials.AppID or AppKey not recognized
401Invalid or expired token.Token overwritten or user deleted
403Origin not allowed.Request from an unauthorized origin