Authentication
Two-layer auth: your app credentials (AppID:AppKey) on every request, plus a user token from login for user-scoped operations.
Auth layers
| Layer | How | When |
|---|---|---|
| App auth | Authorization: AppID:AppKey header | Every request |
| User auth | token in JSON body | User-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 → 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.
Error reference
| Code | Message | Cause |
|---|---|---|
| 401 | Authorization header with appid:appkey is required. | Missing or malformed header |
| 401 | Invalid app credentials. | AppID or AppKey not recognized |
| 401 | Invalid or expired token. | Token overwritten or user deleted |
| 403 | Origin not allowed. | Request from an unauthorized origin |