Asomiru APIv1
Server statistics and vote rewards.
/serverStatus and map
POST/players/resolveLinked players
POST/rewards/claimVote rewards
POST/votes/checkVote status
Make your first request
Open your server page on Asomiru → Asomiru API → Enable API and create key. Server ownership must be verified. Save the key: every request uses it.
Set your key in a terminal:
export ASOMIRU_API_KEY='asmr_42_YOUR_KEY'Copy codeThen fetch your server:
curl 'https://api.asomiru.com/v1/server' \
-H "Authorization: Bearer $ASOMIRU_API_KEY"Copy code{
"id": 42,
"name": "NEVA · Classic Public",
"game": "cs2",
"status": "online",
"address": "play.example.com:27015",
"players": 18,
"maxPlayers": 32,
"map": "de_mirage",
"version": null,
"mode": "defuse",
"activeVotes": 126,
"checkedAt": "2026-10-11T10:00:00.000Z",
"pageUrl": "https://asomiru.com/ru/servers/42"
}Copy codeplayers is the current player count, maxPlayers is the number of slots, and activeVotes is the number of active votes. checkedAt tells you when the monitor last checked the server. An unavailable server has status: "offline". Minecraft returns a version such as 1.21.1 instead of a map. Unknown values are null.
Base URL: https://api.asomiru.com/v1. The key selects your server, so you do not need a server ID in requests. Call the API from a backend, bot or game plugin. Keep the key out of public browser JavaScript.
Get a week's statistics
curl 'https://api.asomiru.com/v1/server/stats?period=week' \
-H "Authorization: Bearer $ASOMIRU_API_KEY"Copy code{
"serverId": 42,
"period": "week",
"since": "2026-10-04T10:00:00.000Z",
"until": "2026-10-11T10:00:00.000Z",
"connectClicks": {"total": 245, "uniqueBrowsers": 173},
"votes": {"received": 64},
"reportedJoins": 312,
"players": {"average": 17.42, "peak": 32},
"monitoring": {"samples": 2016, "onlineSamples": 2008, "availabilityPercent": 99.6},
"generatedAt": "2026-10-11T10:00:00.000Z"
}Copy codeFields you can show on your dashboard:
connectClicks.total: clicks on Connect on Asomiru. These are referrals, not confirmed game joins. Repeated clicks from the same browser within 30 seconds count once.connectClicks.uniqueBrowsers: an estimate of unique referrals during this period.votes.received: votes received during the period.reportedJoins: game joins reported by your plugin. It stays zero until you send data.players.averageandplayers.peak: average and peak player counts from successful checks.monitoring.availabilityPercent: the percentage of checks where the server responded. It isnullwhen no checks are available.
Periods: day is the last 24 hours, week is 7 days, and month is 30 days. The default is week. Statistics are cached for 30 seconds. All response timestamps use UTC.
Build a chart
curl 'https://api.asomiru.com/v1/server/history?period=week' \
-H "Authorization: Bearer $ASOMIRU_API_KEY"Copy code{
"serverId": 42,
"period": "week",
"bucket": "day",
"since": "2026-10-04T10:00:00.000Z",
"until": "2026-10-11T10:00:00.000Z",
"points": [
{"at": "2026-10-04T00:00:00.000Z", "connectClicks": 21, "votes": 4, "reportedJoins": 38, "averagePlayers": 12.5, "peakPlayers": 24, "samples": 168, "onlineSamples": 168},
{"at": "2026-10-05T00:00:00.000Z", "connectClicks": 36, "votes": 8, "reportedJoins": 52, "averagePlayers": 18.7, "peakPlayers": 32, "samples": 288, "onlineSamples": 286}
],
"generatedAt": "2026-10-11T10:00:00.000Z"
}Copy codeThis example is shortened to two points. day returns hourly points; week and month return daily points. at is the start of the hour or day. The first and last points may cover only part of that interval. Empty intervals are included. When no player count was measured, averagePlayers and peakPlayers are null, not zero.
How your plugin identifies a player
An Asomiru ID is a permanent website account ID, such as ASM-1-0000-0042-20. Players can find it in their account. Changing a nickname, email or Steam account does not change it. Send the complete ID, including hyphens. The last two digits help detect typing mistakes. Previously issued IDs also remain valid in the API.
A game ID identifies an account in the game. Your plugin reads it from the game server after the player has authenticated. Players link their game account once. After that, they vote on the website and your plugin finds their votes using the game ID. Players do not need to copy their Asomiru ID on each join.
There are two linking methods.
Steam. The player links Steam in their Asomiru settings and clicks Enable rewards with Steam on your server page. For CS, Team Fortress 2, Rust and Left 4 Dead, your plugin uses the authenticated player’s SteamID64. Send it as a string: JavaScript rounds integers this large. ARK and Valheim support Steam linking too; accounts from other platforms can use a game code.
In-game code. On Minecraft, read the connected player’s UUID and request a code:
curl -X POST 'https://api.asomiru.com/v1/rewards/link' \
-H "Authorization: Bearer $ASOMIRU_API_KEY" \
-H 'Content-Type: application/json' \
--data '{"playerId":"00000000-0000-4000-8000-000000000042"}'Copy code{"code":"aBcD1234_xYz","expiresAt":"2026-10-11T10:10:00.000Z"}Copy codeShow the code only to that player. On your server page, they enter it and click Link and enable rewards. Codes last ten minutes and work once. A new code can be requested after one minute. If the response is lost, wait a minute and request another code.
AsomiruBridge for Minecraft provides /asomiru link. It runs on Paper/Spigot 1.21.1+, Java 21 and online-mode=true. Servers using a proxy or separate login system need an integration that verifies that authentication before linking. A UUID, SteamID or nickname typed into chat does not prove account ownership.
For another platform, use its permanent account ID: 3–64 characters consisting of letters, digits, _, : or -. Keep its format consistent across requests. Do not use a changeable nickname.
Resolve a linked player
Send up to 50 players. The response preserves their order, so you can check players when they join or in a periodic batch.
curl -X POST 'https://api.asomiru.com/v1/players/resolve' \
-H "Authorization: Bearer $ASOMIRU_API_KEY" \
-H 'Content-Type: application/json' \
--data '{"players":[{"kind":"steam","id":"76561198000000001"}]}'Copy code{"players":[{"asomiruId":"ASM-1-0000-0042-20","rewards":true}]}Copy coderewards: true means the link is active. A player without an active link appears as null.
Every endpoint with a player field accepts these references:
| kind | Value for id |
|---|---|
game |
Minecraft UUID or another platform’s permanent account ID. Steam-authenticated games also accept SteamID64. |
steam |
SteamID64 for a game supporting Steam, matching the linked Steam account. |
asomiru |
An already-linked player’s Asomiru ID, useful once stored in your system. |
An Asomiru ID is an identifier, not a password. Your key can only access links for your server. An older link may return asomiruId: null; the player can update it on the server page. Existing reward checks using the game ID continue to work.
Check votes
Use this to show whether a player has voted and how many rewards await collection:
curl -X POST 'https://api.asomiru.com/v1/votes/check' \
-H "Authorization: Bearer $ASOMIRU_API_KEY" \
-H 'Content-Type: application/json' \
--data '{"player":{"kind":"steam","id":"76561198000000001"}}'Copy code{"voted":true,"activeVotes":3,"pendingRewards":1,"lastVotedAt":"2026-10-11T10:00:00.000Z"}Copy codeactiveVotes counts votes still active for this server; each lasts 30 days. pendingRewards counts vote events not yet acknowledged, including events temporarily held by another delivery. This request does not reserve or consume anything.
Use the next section to issue rewards. Do not reward every response with voted: true: that would reward the same vote repeatedly.
Reward a vote
Link the game account first, then ask the player to vote. Only votes made after linking create reward events. An earlier vote can appear in votes/check without a corresponding reward event.
1. Claim events. Generate a UUID requestId and save it in your plugin before sending the request.
curl -X POST 'https://api.asomiru.com/v1/rewards/claim' \
-H "Authorization: Bearer $ASOMIRU_API_KEY" \
-H 'Content-Type: application/json' \
--data '{"player":{"kind":"steam","id":"76561198000000001"},"requestId":"11111111-1111-4111-8111-111111111111"}'Copy code{
"delivery":{"id":"22222222-2222-4222-8222-222222222222","leaseUntil":"2026-10-11T10:02:00.000Z"},
"events":[{"id":"33333333-3333-4333-8333-333333333333","type":"server.vote","votedAt":"2026-10-11T10:00:00.000Z","expiresAt":"2026-11-10T10:00:00.000Z"}]
}Copy codeEach events[].id identifies one vote. A request returns up to 20 events. No new votes and an unavailable link both return:
{"delivery":null,"events":[]}Copy code2. Save the events. Write them into your plugin’s persistent queue. Give events[].id a unique constraint so that receiving it twice cannot create a second reward. After a lost response, repeat claim with the same requestId. While the delivery is valid, the API returns the same batch and excludes these events from other deliveries.
3. Acknowledge receipt. Once the queue is saved, send ack before leaseUntil, normally within two minutes:
curl -X POST 'https://api.asomiru.com/v1/rewards/ack' \
-H "Authorization: Bearer $ASOMIRU_API_KEY" \
-H 'Content-Type: application/json' \
--data '{"deliveryId":"22222222-2222-4222-8222-222222222222"}'Copy code{"acknowledged":true}Copy codeack confirms that you saved the events, not that an item was delivered in the game. Process your saved queue under your reward rules. Keep processed event IDs until expiresAt, and share that ledger between all workers for the same server. Protect the game-side action too: for example, record the event ID and balance change in one game database transaction. If a game command cannot do this, review an ambiguous crash outcome rather than blindly running it again.
For LEASE_EXPIRED, create a new requestId and call claim again. Vote event IDs stay the same, allowing your queue to recognize duplicates. Repeating ack returns acknowledged: true while the delivery record is retained, up to two days. Pending votes remain available for up to 30 days.
Existing integrations using playerId continue to work. Supply either playerId or player, never both.
Count all server joins
For aggregate statistics, count the joins in one minute and send a single request. Player accounts are not needed:
curl -X POST 'https://api.asomiru.com/v1/server/joins' \
-H "Authorization: Bearer $ASOMIRU_API_KEY" \
-H 'Content-Type: application/json' \
--data '{"eventId":"66666666-6666-4666-8666-666666666666","count":7,"occurredAt":"2026-10-11T10:00:00.000Z"}'Copy codeGenerate a new eventId and current timestamp for each batch. After a failure, resend the same data and ID. Each request accepts 1–1000 joins from the last 24 hours, with a limit of ten requests per minute. Results appear as reportedJoins in server statistics. Join reports come from your plugin and do not affect the monitoring ranking.
Node.js example
Download the Asomiru API client and extract asomiru-sdk into your project. Node.js 22.13+; no additional libraries are needed.
import { AsomiruClient } from './asomiru-sdk/index.mjs';
const api = new AsomiruClient(process.env.ASOMIRU_API_KEY);
const player = { kind: 'steam', id: '76561198000000001' };
const server = await api.server();
console.log(`${server.name}: ${server.players}/${server.maxPlayers}`);
const votes = await api.votes(player);
console.log(`Rewards awaiting collection: ${votes.pendingRewards}`);Copy codeThe archive includes examples/rewards.mjs, which saves request IDs and votes in SQLite before acknowledging receipt. Use it as the starting point for your own reward queue. Game-side item delivery belongs in your game plugin.
The client retries safe requests with their original IDs after a connection failure. On a rate limit, it throws AsomiruError with code and retryAfter. Refreshing a bot or website’s online count once a minute is usually enough.
Errors and limits
{"code":"INVALID_API_KEY","message":"Неверный ключ API"}Copy code| Status / code | Action |
|---|---|
| 400 | Check JSON and field names. |
401 / INVALID_API_KEY |
Check the key, API settings and server ownership. |
403 / SERVER_SIDE_ONLY |
Send from a plugin, backend or bot. |
409 / LEASE_EXPIRED |
Create a new claim requestId. |
409 / REQUEST_ID_REUSED |
Do not reuse a request ID for another player or changed data. |
409 / EVENT_ID_REUSED |
Do not change a join batch already sent. |
| 422 | Check identity kind, UUIDs, periods and field values. |
| 429 | Wait the number of seconds in Retry-After. |
| 500 / 503 | Retry later, preserving the ID and body for deliveries and reports. |
Limits are 120 requests per server per minute and 300 per IP. POST bodies are limited to 2 KB, or 24 KB for players/resolve. Statistics are cached for 30 seconds; personal responses are not cached. All timestamps are UTC.
Keep the key on your server. Rotating it disables the previous key. Disabling the API or changing ownership ends access to player links. Unlinking Steam also makes that Steam identity’s linked accounts unavailable.
Full fields and responses: OpenAPI. Minecraft implementation: AsomiruBridge source. Integration questions: support@asomiru.com.