RankingsNew ServersVote Rewards API
RankingsNew ServersVote Rewards API
Login
Submit
METIN2.GG
Login
Submit

Categories

  • Metin2 PvP Servers
  • Metin2 PvM Servers
  • Metin2 Oldschool Servers
  • Metin2 Newschool Servers
  • Metin2 Low Rate Servers
  • Metin2 Mid Rate Servers
  • Metin2 High Rate Servers
  • Metin2 Middleschool Servers
  • Metin2 Easy Servers
  • Metin2 Hard Servers

Top Lists

  • Best Metin2 Private Servers in 2026
  • Metin2 PServer 2026
  • Metin2 PServer List 2026
  • Metin2 Toplist 2026
  • Metin2 Server List 2026
  • Metin2 Private Server Rankings 2026
  • New Metin2 Private Servers in 2026
  • Top Voted Metin2 Servers in 2026
  • Metin2 Servers Opening Today
  • Metin2 Servers Opening This Week
  • Metin2 Servers 2026
  • Metin2 PvP Server 2026
  • Metin2 Middleschool Server 2026
  • MT2 PServer 2026

Quick Links

  • Server Rankings
  • Submit Your Server
  • Vote Rewards API
  • PvP Servers
  • Oldschool Servers
  • New Servers 2026
  • Blog
  • Metin2 Sapphire Servers: The Complete Guide to Premium One-Time Access
  • How to Farm Gold (Yang) Fast in Metin2 Private Servers
  • Metin2 Server Rates Explained: Low Rate, Mid Rate & High Rate
METIN2.GG

© 2026 Metin2.gg — Not affiliated with Webzen Inc.

AboutPrivacyContactTerms
Home/Vote Rewards/Integration Guide

Vote Rewards API Integration Guide

Everything you need to connect your Metin2 server to the metin2.gg Vote Rewards system — with copy-paste code for every common setup.

How It Works

The metin2.gg Vote Rewards API lets your Metin2 server automatically detect when players vote and grant in-game rewards. The flow is simple: players vote on metin2.gg with their character name, and your server queries our API to check and claim those votes.

There are two integration modes — choose whichever fits your setup:

Player
Votes on metin2.gg
metin2.gg
Records vote
Your Server
Grants reward

Polling (Recommended)

Your server periodically calls our API to check for new votes. Simplest to implement — works with any Metin2 server setup. Just add one HTTP request to your game server code.

Webhooks (Advanced)

metin2.gg pushes a notification to your server the instant a player votes. Real-time, but requires a publicly accessible HTTPS endpoint on your side.

Authentication

All API requests require an API key sent via the X-API-Key header. Keys follow the format mg_live_... and are generated from your server panel.

HTTP
X-API-Key: mg_live_5bef...1a70

Your API key is tied to one server and shown only once when generated. If you lose it, regenerate a new one from the panel (the old key is immediately invalidated).

How to Get Your API Key

  1. 1Go to My Panel → My Servers. Click the name of your server to open its management page.
  2. 2On the management page, verify ownership (DNS TXT record or meta tag) if you haven't already.
  3. 3Add a backlink to metin2.gg on your server's website to unlock Partner status.
  4. 4On your server's management page, click the "API Settings" button. Then click "Generate API Key" and copy it — it's shown only once.
Go to PanelDon't have a server yet? Submit one

Check Vote Status

Check whether a specific player has an unclaimed vote. If a pending vote exists, it is automatically claimed (marked as used) so the same vote cannot be claimed twice.

HTTP
GET /api/v1/vote/check?player_id=PlayerName HTTP/1.1
Host: metin2.gg
X-API-Key: mg_live_YOUR_KEY_HERE

Query Parameters

ParameterTypeRequiredDescription
player_idstringYesThe character name the player used when voting. Case-insensitive.

Response

Player has an unclaimed vote (now claimed)

JSON
{
  "voted": true,
  "player_id": "PlayerName",
  "vote_id": "550e8400-e29b-41d4-a716-446655440000",
  "voted_at": "2026-03-02T14:30:00Z"
}

No pending vote for this player

JSON
{
  "voted": false
}

List Unclaimed Votes

Retrieve all unclaimed votes for your server. Useful for batch processing — for example, a cron job that runs every 5 minutes and grants rewards for all pending votes at once.

HTTP
GET /api/v1/vote/unclaimed?limit=50 HTTP/1.1
Host: metin2.gg
X-API-Key: mg_live_YOUR_KEY_HERE

Query Parameters

ParameterTypeRequiredDescription
limitintegerNoMaximum number of votes to return (1–100, default 50).

Response

JSON
{
  "votes": [
    {
      "vote_id": "550e8400-e29b-41d4-a716-446655440000",
      "player_id": "PlayerName",
      "voted_at": "2026-03-02T14:30:00Z"
    },
    {
      "vote_id": "660e8400-e29b-41d4-a716-446655440001",
      "player_id": "AnotherPlayer",
      "voted_at": "2026-03-02T14:32:00Z"
    }
  ],
  "total": 2
}

Batch Claim Votes

Mark multiple votes as claimed in one request. Use this after processing votes from the unclaimed endpoint.

HTTP
POST /api/v1/vote/claim HTTP/1.1
Host: metin2.gg
Content-Type: application/json
X-API-Key: mg_live_YOUR_KEY_HERE

{
  "vote_ids": [
    "550e8400-e29b-41d4-a716-446655440000",
    "660e8400-e29b-41d4-a716-446655440001"
  ]
}

Request Body (JSON)

ParameterTypeRequiredDescription
vote_idsstring[]YesArray of vote UUIDs to claim. Maximum 100 per request.

Response

JSON
{
  "claimed": 2,
  "failed": 0
}

Webhooks

Instead of polling, you can receive real-time push notifications when a player votes. Configure your webhook URL in the server panel under API Settings.

Webhook Payload

HTTP
POST https://your-server.com/api/vote-webhook HTTP/1.1
Content-Type: application/json
X-Metin2GG-Signature: a1b2c3d4e5f6...

{
  "event": "vote.created",
  "vote_id": "550e8400-e29b-41d4-a716-446655440000",
  "server_id": "your-server-uuid",
  "player_id": "PlayerName",
  "voted_at": "2026-03-02T14:30:00Z",
  "timestamp": "2026-03-02T14:30:01Z"
}

Verifying the Signature

Every webhook request includes an X-Metin2GG-Signature header containing an HMAC-SHA256 hex digest of the raw request body, signed with your API secret. Always verify this signature before trusting the payload.

Pythonverify_webhook.py
import hmac
import hashlib

def verify_webhook(request_body: bytes, signature: str, secret: str) -> bool:
    """Verify the X-Metin2GG-Signature header."""
    expected = hmac.new(
        secret.encode("utf-8"),
        request_body,
        hashlib.sha256,
    ).hexdigest()
    return hmac.compare_digest(expected, signature)

# Usage in your webhook handler:
# body = request.body  (raw bytes)
# sig  = request.headers["X-Metin2GG-Signature"]
# if not verify_webhook(body, sig, "your_api_secret"):
#     return HttpResponse(status=403)
PHPverify_webhook.php
<?php
function verifyWebhook(string $body, string $signature, string $secret): bool {
    $expected = hash_hmac('sha256', $body, $secret);
    return hash_equals($expected, $signature);
}

// Usage in your webhook handler:
// $body = file_get_contents('php://input');
// $sig  = $_SERVER['HTTP_X_METIN2GG_SIGNATURE'] ?? '';
// if (!verifyWebhook($body, $sig, 'your_api_secret')) {
//     http_response_code(403);
//     exit('Invalid signature');
// }

Metin2 Integration: Python Command

Drop this script into your game server's Python command system. When a player types /reward in-game, it checks metin2.gg for a pending vote and grants the reward.

Pythonvote_reward.py
# vote_reward.py — Drop into your game server's command scripts
# Works with Python 2.7+ (common in Metin2 servers)
import json
import os

METIN2GG_API_KEY = "mg_live_YOUR_KEY_HERE"
METIN2GG_API_URL = "https://metin2.gg/api/v1/vote/check"

def check_vote(player_name):
    """Check if player has a pending vote and auto-claim it."""
    url = "%s?player_id=%s" % (METIN2GG_API_URL, player_name)

    # Method 1: Use urllib2 (Python 2) or urllib.request (Python 3)
    try:
        try:
            import urllib2
            req = urllib2.Request(url)
            req.add_header("X-API-Key", METIN2GG_API_KEY)
            resp = urllib2.urlopen(req, timeout=5)
            data = json.loads(resp.read())
        except ImportError:
            import urllib.request
            req = urllib.request.Request(url)
            req.add_header("X-API-Key", METIN2GG_API_KEY)
            resp = urllib.request.urlopen(req, timeout=5)
            data = json.loads(resp.read().decode("utf-8"))

        return data.get("voted", False)
    except Exception:
        pass

    # Method 2: Fallback to curl (works even with broken SSL)
    try:
        cmd = 'curl -s -H "X-API-Key: %s" "%s"' % (METIN2GG_API_KEY, url)
        raw = os.popen(cmd).read()
        data = json.loads(raw)
        return data.get("voted", False)
    except Exception:
        return None

# Example usage in your game command handler:
# def cmd_reward(player):
#     result = check_vote(player.GetName())
#     if result is True:
#         player.GiveItem(50011, 10)  # Example: 10x Dragon God Coins
#         player.ChatInfoMessage("Vote reward claimed!")
#     elif result is False:
#         player.ChatInfoMessage("No pending vote. Vote at metin2.gg!")
#     else:
#         player.ChatInfoMessage("Could not reach metin2.gg. Try again.")

Metin2 Integration: Quest File (Lua)

This quest file creates an NPC interaction where players can check their vote status. It calls a server-side command that triggers the Python vote check.

Luavote_reward.quest
quest vote_reward begin
    state start begin
        when login or letter begin
            send_letter("Vote Reward")
        end

        when button or info begin
            say_title("Vote Reward")
            say("")
            say("Vote for our server on metin2.gg")
            say("and claim your reward here!")
            say("")

            local s = select("Check My Vote", "How to Vote", "Close")

            if s == 1 then
                -- Triggers the Python command that checks the API
                cmdchat("checkvote "..pc.get_name())
            elseif s == 2 then
                say_title("How to Vote")
                say("")
                say("1. Open metin2.gg in your browser")
                say("2. Find our server page")
                say("3. Enter your character name")
                say("4. Click the Vote button")
                say("5. Come back here to claim your reward!")
                say("")
            end
        end
    end
end

Metin2 Integration: PHP Web Panel

If your server has a web panel (PHP-based), use this snippet to check and claim votes from the panel. Works with any PHP 7+ environment with cURL.

PHPcheck_vote.php
<?php
/**
 * check_vote.php — Vote check for PHP-based web panels
 * Requires PHP 7.0+ with cURL extension
 */

$apiKey    = "mg_live_YOUR_KEY_HERE";
$playerName = $_GET["player"] ?? "";

if (empty($playerName)) {
    echo json_encode(["error" => "Missing player name"]);
    exit;
}

// Check vote status
$ch = curl_init(
    "https://metin2.gg/api/v1/vote/check?player_id=" . urlencode($playerName)
);
curl_setopt_array($ch, [
    CURLOPT_HTTPHEADER     => ["X-API-Key: $apiKey"],
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_TIMEOUT        => 10,
    CURLOPT_SSL_VERIFYPEER => true,
]);
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);

if ($httpCode !== 200) {
    echo json_encode(["error" => "API returned HTTP $httpCode"]);
    exit;
}

$data = json_decode($response, true);

if ($data["voted"] ?? false) {
    // Player has voted — grant reward via your game DB
    // Example: INSERT INTO player.reward_queue (player, item_vnum, count) ...
    echo json_encode([
        "success" => true,
        "message" => "Vote reward granted!",
        "vote_id" => $data["vote_id"],
    ]);
} else {
    echo json_encode([
        "success" => false,
        "message" => "No pending vote found.",
    ]);
}

Rate Limits & Error Codes

The API enforces rate limits to ensure fair usage. Current limits:

  • 60 requests per minute per API key
  • 1,000 requests per hour per API key
StatusDescription
200 OKRequest succeeded.
400 Bad RequestMissing or invalid parameters. Check the player_id or vote_ids format.
401 UnauthorizedMissing or invalid API key. Make sure you include the X-API-Key header.
403 ForbiddenAPI access is disabled — usually because the backlink was removed. Re-add the backlink and check again.
404 Not FoundThe endpoint doesn't exist. Double-check the URL path.
429 Too Many RequestsRate limit exceeded. Wait and retry after the Retry-After header value (in seconds).
500 Internal Server ErrorSomething went wrong on our end. Retry after a few seconds.

Retry Strategy

On 429 errors, read the Retry-After header (value in seconds) and wait before retrying. For 500 errors, retry with exponential backoff (1s, 2s, 4s).

Troubleshooting FAQ

I get 401 Unauthorized on every request

Make sure you're sending the API key in the X-API-Key header (not as a query parameter or in the body). The key must start with mg_live_.

The API says voted: false but the player claims they voted

The player may have voted without entering their character name, or used a different name. Check the vote link URL — it must include ?player_id=EXACT_NAME. Names are case-insensitive.

I get 403 Forbidden

Your API access is paused, likely because the backlink to metin2.gg was removed from your website. Re-add it and click 'Check Now' in the panel to re-verify.

Can I test the API without real votes?

Currently there's no sandbox mode. Vote on your own server listing with a test character name to verify the integration end-to-end.

My Python script can't connect (timeout or SSL error)

Most Metin2 servers run Python 2.7 which has outdated SSL certificates. Use the os.popen('curl ...') fallback shown in the Python example, or upgrade your server's Python CA bundle.

How often should I poll the API?

For the /check endpoint (per-player): call it when the player requests their reward (e.g. /reward command). For /unclaimed (bulk): every 3–5 minutes via cron is ideal. Don't poll more than once per minute.

Can multiple servers share one API key?

No. Each API key is tied to one server listing. If you run multiple servers, generate a separate key for each from their respective panel pages.

What happens if my webhook endpoint is down?

metin2.gg retries failed webhook deliveries up to 5 times with exponential backoff. If all retries fail, the vote remains unclaimed and can still be picked up via the polling endpoints.

Ready to Integrate?

Add your server to metin2.gg, generate an API key, and start rewarding voters in minutes.

Submit Your ServerGo to Panel

Table of Contents

  • How It Works
  • Authentication
  • Check Vote Status
  • List Unclaimed Votes
  • Batch Claim Votes
  • Webhooks
  • Metin2 Integration: Python Command
  • Metin2 Integration: Quest File (Lua)
  • Metin2 Integration: PHP Web Panel
  • Rate Limits & Error Codes
  • Troubleshooting FAQ