Ingest API reference
ReferenceThe HTTP endpoints the connector calls: pairing, sessions, heartbeats, and confirmed bans.
This is the surface the connector uses. It is documented so you can debug a connector, not so you can build a replacement, and it can change with a connector release.
#Authentication
Every telemetry request carries the connector credential as a bearer token. The token identifies the network and the server, so no request ever names a network id of its own.
The pairing endpoint is the exception: the code is the only credential it takes, and it is rate limited hard for that reason.
Authorization: Bearer mca_live_...
Content-Type: application/json#POST /api/v1/connector/pair
Redeems a pairing code once and returns the credential for that server. An unknown code, an expired code, and an already used code all get the same 401, so the endpoint cannot be used to probe for valid codes.
// request
{ "code": "K3M9-QT4B" }
// 200 response
{
"connectorToken": "mca_live_...",
"networkId": "...",
"serverId": "...",
"serverName": "velocity-proxy",
"platform": "velocity",
"pairedAt": "2026-09-06T10:00:00.000Z"
}#POST /api/v1/telemetry/session
Records one finished session and the player behind it in a single transaction. Answers 201 for a new session and 200 for a replay.
{
"sessionId": "9b1f0c2a-4d3e-4a55-8f21-0c9b7e6a1234",
"username": "Player123",
"identityType": "premium_java",
"uuid": "069a79f4-44e9-4726-a5be-fca90e38aaf5",
"hostname": "tiktok.myserver.net",
"serverName": "velocity-proxy",
"joinedAt": "2026-09-06T10:00:00.000Z",
"authConfirmedAt": "2026-09-06T10:00:03.000Z",
"quitAt": "2026-09-06T10:42:00.000Z",
"durationSeconds": 2520,
"authenticated": true
}#POST /api/v1/telemetry/heartbeat
Reports the health of one server. The server it lands on comes from the credential, not from the body.
{
"serverName": "velocity-proxy",
"tps": 19.98,
"mspt": 3.4,
"memoryUsedMb": 2048,
"memoryMaxMb": 8192,
"onlineCount": 412,
"recordedAt": "2026-09-06T10:00:00.000Z"
}#POST /api/v1/telemetry/anticheat
Records one confirmed ban against a player the network already knows. isConfirmedBan must be true or nothing is stored.
{
"eventId": "3f0a1b2c-5566-4a77-9b88-1c2d3e4f5a6b",
"username": "Player123",
"identityType": "premium_java",
"uuid": "069a79f4-44e9-4726-a5be-fca90e38aaf5",
"serverName": "boxpvp-1",
"checkName": "Simulation",
"violationLevel": 42,
"isConfirmedBan": true,
"recordedAt": "2026-09-06T10:05:00.000Z"
}#Errors and limits
Errors carry a code and a message. A 500 also carries an X-Error-Id header, which is the value to quote when you ask us about it.
| Status | Code | Meaning |
|---|---|---|
| 401 | UNAUTHORIZED | Missing, malformed, or revoked credential |
| 409 | IDEMPOTENCY_CONFLICT | Same id, different contents |
| 422 | VALIDATION_ERROR | The body failed a field or range check |
| 425 | PLAYER_NOT_RESOLVED | The player has no session yet, retry shortly |
| 429 | RATE_LIMITED | Too many requests, honour Retry-After |