API & Callback Integration
Drop the vote button in your game, get notified when a player votes, grant rewards automatically.
1. Public vote URL
Link to this URL from your game's "Vote on VibeTopList" button. The ?ref= parameter is the player's username — round-tripped back to you.
https://vibetoplist.com/vote/<your-listing-slug>?ref=PLAYER_USERNAME
Aliases also accepted: ?u=, ?username=, ?incentive=, ?postback=, ?id=. Any of them works.
2. Vote rules
- One vote per IP per listing every 12 hours.
- Votes accumulate into a monthly counter; resets on the 1st of every month at 00:00 UTC. All-time totals are preserved.
- Banned IPs and detected bots are silently rejected.
3. Webhook callback
After every successful vote, VibeTopList fires both a POST and a GET to your configured callback URL with these parameters:
secret | Your callback secret (verify this!) |
|---|---|
voted | 1 on success, 0 if rejected post-validation |
userip | Voter's IP (for your own anti-abuse) |
userid | The ref parameter you passed in (the player username) |
reset | Unix timestamp when the same IP can vote again |
vote_id | VibeTopList's internal vote id (use for idempotent reward grants) |
We don't validate your response — fire-and-forget. Return any 2xx and we'll log it as success.
PHP receiver
<?php
$secret = "YOUR_CALLBACK_SECRET";
if (($_REQUEST['secret'] ?? '') !== $secret) { http_response_code(403); exit; }
if (($_REQUEST['voted'] ?? '0') === '1') {
$player = $_REQUEST['userid'] ?? '';
$vote_id = $_REQUEST['vote_id'] ?? '';
// grant reward to $player, idempotent on $vote_id
}
http_response_code(200);
Node.js (Express) receiver
app.all('/vote-callback', (req, res) => {
const p = { ...req.query, ...req.body };
if (p.secret !== process.env.VTL_SECRET) return res.status(403).end();
if (p.voted === '1') {
grantReward(p.userid, p.vote_id);
}
res.json({ ok: true });
});
Python (Flask) receiver
@app.route('/vote-callback', methods=['GET', 'POST'])
def vote_callback():
p = {**request.args, **request.form}
if p.get('secret') != app.config['VTL_SECRET']:
abort(403)
if p.get('voted') == '1':
grant_reward(p.get('userid'), p.get('vote_id'))
return 'ok'
4. Pull API (alternative)
If you can't accept incoming requests, poll us instead.
GET https://vibetoplist.com/api/v1/check-vote?key=YOUR_API_KEY&username=PLAYER
→ {"voted": true, "voted_at": "2026-05-09T13:42:11Z",
"vote_id": 42, "claimed": false}
5. Claim API
Mark a vote as rewarded so you don't double-grant on retries.
POST https://vibetoplist.com/api/v1/claim-vote
Content-Type: application/json
{"key": "YOUR_API_KEY", "vote_id": 42}
→ 200 {"ok": true, "claimed_at": "..."}
→ 409 {"error": "already_claimed"}
6. Public listing JSON
Embed live vote counts on your own site.
GET https://vibetoplist.com/api/v1/listing/<your-slug>
→ {"slug": "...", "name": "...", "rank": 5, "votes_this_month": 1432, ...}
Where do I find my API key and callback secret? → Dashboard → your listing → API & Callbacks.