Overview

How it works

This service aggregates EVE Online killmails from multiple sources and provides real-time access through two methods: websocket streaming and HTTP long polling. Both endpoints require a queueID parameter that acts as your session identifier.

This service is committed to having no breaking changes. If the underlying sources such as RedisQ change, this service will adapt its implementation so you don't have to.

Note The queueID allows you to resume from where you left off within 24 hours. Use any string up to 128 characters.
Endpoints

Consuming the stream

Websocket /websocket/{queueID}

Real-time streaming connection that pushes killmails as they arrive. Best for applications that need immediate updates. Add ?stream=fast to receive killmails earlier without the zkb object, see Fast stream.

Python
import asyncio
import websockets
import json

async def consume_killmails():
    # Prefer secure websocket (wss://) but plain websocket (ws://) is available
    uri = "wss://killmail.stream/websocket/my-queue-id"

    async with websockets.connect(uri) as websocket:
        while True:
            message = await websocket.recv()
            killmail = json.loads(message)
            print(f"Killmail: {killmail['killmail_id']}")

asyncio.run(consume_killmails())

GET /poll/{queueID}

HTTP long polling endpoint that waits up to 60 seconds for new killmails. Returns up to 100 killmails per request. Best for simple integrations or environments where websockets are not available. Add ?stream=fast to receive killmails earlier without the zkb object, see Fast stream.

Python
import requests
import time

def poll_killmails():
    while True:
        try:
            response = requests.get('https://killmail.stream/poll/my-queue-id')
            killmails = response.json()

            for killmail in killmails:
                print(f"Killmail: {killmail['killmail_id']}")

        except Exception as e:
            print(f"Error: {e}")
            time.sleep(5)  # Retry after 5s

poll_killmails()

GET /listen.php?queueID={queueID} RedisQ compatible

RedisQ compatible HTTP long polling endpoint that waits up to 10 seconds for new killmails. Returns zero or one killmail per request in the RedisQ package format. Best for minimum effort changes to existing applications, all you need to do is change the domain. The RedisQ package is only the kill ID and the zkb object, so this endpoint does not support ?stream=fast.

Python
import requests
import time

def poll_killmails():
    while True:
        try:
            response = requests.get('https://killmail.stream/listen.php?queueID=my-queue-id')

            data = response.json()
            if not data['package']:
                continue

            print(f"Killmail: {data['killID']}")

        except Exception as e:
            print(f"Error: {e}")
            time.sleep(5)  # Retry after 5s

poll_killmails()
Data

Response format

All endpoints return killmail data in the same RedisQ format, but only the /listen.php endpoint is fully compatible with RedisQ since the other endpoints can return multiple killmails. Each killmail combines ESI killmail data with zKillboard metadata.

Latency

Fast stream

The zKillboard API only publishes the zkb object some time after a killmail happens, so waiting for it delays every killmail we hand out. The /websocket/{queueID} and /poll/{queueID} endpoints accept a stream parameter that lets you choose which side of that trade you want:

stream=full The default. ESI killmail plus the zkb object.
stream=fast The ESI killmail on its own, published as soon as we have it. There are no zkb specific values.

Every killmail is delivered on both streams, so you can consume the fast one for latency and the full one for the values if you want. The two keep independent positions, so the same queue ID can safely be used for both.

Guidelines

Best practices

  • Use a unique queueID for each consumer to track position independently
  • Handle reconnections gracefully, your position is preserved for 24 hours
  • Websocket connections automatically resume from the last received killmail
  • Polling returns up to 100 killmails per request with a 60 second timeout
  • Implement exponential backoff for error scenarios