L'intégration API est réservée au propriétaire du serveur de jeux.
Si votre jeu n'a pas de plugin dédié, vous pouvez intégrer QuantumLogs via l'API REST directement. Cette méthode fonctionne avec n'importe quel langage de programmation.
Endpoint
POST /logs
Authentification
Envoyez votre clé API dans le header Authorization :
Authorization: votre-cle-api-ici
La clé est envoyée directement dans le header, sans préfixe Bearer. C'est le format attendu par QuantumLogs.
Format de la requête
Le body est un tableau JSON de logs. Chaque élément du tableau est un objet log :
[{"measurement":"player_kill","timestamp":"2025-01-15T14:30:45.123Z","tags":{"player_name":"John","player_id":"12345","player_global_id":"76561198000000000","target_name":"Jane","target_id":"67890","target_global_id":"76561198000000001","server":"serveur-1"},"fields":{"value":"John a tué Jane avec AK-47 à 50m (headshot)"},"metadata":{"weapon":"AK-47","distance":50,"bodypart":"head"}}]
Champs détaillés
Champs obligatoires
Champ
Type
Description
measurement
string
Type/catégorie du log (ex: kill, chat, connect)
timestamp
string (ISO 8601)
Horodatage du log (ex: 2025-01-15T14:30:45.123Z)
fields
object
Objet contenant le champ value
fields.value
string
Contenu textuel du log (c'est ce qui s'affiche dans la colonne "Valeur")
tags
object
Objet contenant les tags d'indexation (peut être vide {})
Tous ces champs sont obligatoires. L'objet tags doit être présent même s'il est vide ({}). Le timestamp doit être au format ISO 8601 — il n'y a pas de valeur par défaut côté serveur.
Tags reconnus par le backend
Seuls les noms de tags listés ci-dessous sont reconnus. Tout tag avec un nom différent sera silencieusement ignoré et n'apparaîtra pas dans vos logs. C'est la cause la plus fréquente de "logs qui ne fonctionnent pas".
Tag
Type
Description
player_name
string
Nom du joueur
player_id
string
ID du joueur (spécifique au serveur, ex: ID de personnage)
player_global_id
string
Identifiant unique global du joueur (Steam ID 64, UUID, etc.)
player_steamid
string
Steam ID (déprécié, utilisez player_global_id)
target_name
string
Nom de la cible
target_id
string
ID de la cible
target_global_id
string
Identifiant unique global de la cible
target_steamid
string
Steam ID de la cible (déprécié)
server
string
Identifiant du serveur source
Tous les tags sont optionnels, mais server est fortement recommandé — il est utilisé pour le comptage de serveurs actifs et le contrôle des limites de votre plan.
Exemples de tags invalides (seront ignorés) :
weapon, distance, map → Mettez ces infos dans fields.value ou dans metadata
attacker_name, victim_name → Utilisez player_name et target_name
admin_name → Utilisez player_name
Champs optionnels
Champ
Type
Description
metadata
object
Données JSON supplémentaires libres (visible dans le détail du log, non filtrable)
Codes de réponse
Succès
Code
Body
Description
201
OK
Logs reçus et insérés avec succès
Erreurs
Code
Description
Détail
401
Clé API invalide ou manquante
{ "statusCode": 401, "message": "Missing authorization header" } ou { "statusCode": 401, "message": "Invalid API key" }
413
Body trop volumineux
La taille maximale du body est de 50 Mo
429
Limite de serveurs dépassée
Voir détail ci-dessous
500
Erreur serveur
Injection bloquée (plan expiré/suspendu) ou erreur de base de données
Détail de la réponse 429
Si vous dépassez le nombre de serveurs autorisés par votre plan, la réponse contient des informations utiles :
Les serveurs actifs sont suivis pendant 24 heures. Un serveur qui n'envoie plus de logs pendant 24h libère automatiquement une place.
Bonnes pratiques
Envoi par lots
Envoyez vos logs par lots plutôt qu'un par un. Un intervalle de 10 secondes est recommandé :
Accumulez les logs dans une file d'attente en mémoire
Toutes les 10 secondes, envoyez le lot complet en une seule requête
Videz la file après un envoi réussi
Tout dans fields.value
Le champ value est le contenu principal de votre log. Mettez-y toutes les informations lisibles. Les tags ne servent qu'à l'indexation (recherche par joueur, serveur, etc.).
Metadata pour les données structurées
Si vous avez besoin de stocker des données structurées en plus du texte, utilisez metadata :
Les métadonnées sont stockées en JSON et visibles dans le détail du log, mais ne sont pas filtrables via les filtres classiques.
Gestion des erreurs
En cas d'erreur réseau, conservez les logs en mémoire et réessayez
Implémentez un retry avec backoff exponentiel
Envoyez les logs restants à l'arrêt du serveur (flush)
{
"statusCode": 429,
"error": "Server Limit Exceeded",
"message": "You have reached your server limit (5). Upgrade your plan to add more servers.",
"upgradeUrl": "https://quantumlogs.com/pricing",
"activeServers": ["rp-1", "rp-2", "pvp-1", "event-1", "test"],
"maxServers": 5
}
// CORRECT - toutes les infos dans value
{
"measurement": "player_kill",
"timestamp": "2025-01-15T14:30:45.123Z",
"fields": { "value": "John a tué Jane avec AK-47 à 50m (headshot)" },
"tags": { "player_name": "John", "target_name": "Jane", "server": "rp-1" }
}
// INCORRECT - les données custom dans les tags sont ignorées
{
"measurement": "player_kill",
"timestamp": "2025-01-15T14:30:45.123Z",
"tags": { "weapon": "AK-47", "distance": "50", "bodypart": "head" },
"fields": { "value": "" }
}
using System.Net.Http;
using System.Text;
using System.Text.Json;
var client = new HttpClient();
client.DefaultRequestHeaders.Add("Authorization", "votre-cle-api");
var logs = new[] {
new {
measurement = "player_connection",
timestamp = DateTime.UtcNow.ToString("o"),
tags = new { player_name = "John", server = "serveur-1" },
fields = new { value = "John s'est connecté" }
}
};
var content = new StringContent(
JsonSerializer.Serialize(logs),
Encoding.UTF8,
"application/json"
);
var response = await client.PostAsync(
"https://votre-instance.quantumlogs.cloud/logs",
content
);
Console.WriteLine($"Status: {(int)response.StatusCode}"); // 201 = succès
local API_URL = "https://votre-instance.quantumlogs.cloud/logs"
local API_KEY = "votre-cle-api"
local logs = {
{
measurement = "player_chat",
timestamp = os.date("!%Y-%m-%dT%H:%M:%S.000Z"),
tags = {
player_name = "John",
player_global_id = "76561198000000000",
server = "darkrp-1"
},
fields = {
value = "John: Bonjour tout le monde !"
}
}
}
HTTP({
url = API_URL,
method = "POST",
headers = {
["Content-Type"] = "application/json",
["Authorization"] = API_KEY
},
body = util.TableToJSON(logs),
success = function(code, body)
print("QuantumLogs: " .. code) -- 201 = succès
end,
failed = function(reason)
print("QuantumLogs Error: " .. reason)
end
})