API Reference

Juhus Public API · v1

Build on Juhus Market.

A read-only JSON API for categories, events, markets, order books, and trades. Everything shown in the UI is available here — use it to build dashboards, bots, or research tools.

Base URLhttps://juhus.ee/api/v1
FormatJSON
AuthNone (public)
Overview

Conventions

A few conventions apply to every endpoint. Read these once and the rest of the reference will feel familiar.

Pagination

List endpoints return a response envelope with a data array and a meta object. Default limit is 20, maximum is 50 (100 for trades). Requests exceeding the max are capped server-side.

{ data: [...], meta: { total, page, limit, hasMore } }

Category scoping

There are no unbounded list endpoints. Every market and event listing is scoped by a category slug so responses stay small and cacheable.

Rate limiting

All public endpoints are rate-limited per IP. Responses include cache headers (s-maxage from 5 to 60 seconds depending on the resource) so edge caches absorb most traffic.

Errors

Errors use standard HTTP status codes with a JSON body describing the problem. Unknown or soft-deleted resources return 404.

{ "error": "Market not found" }
Resource

Categories

Top-level grouping for events and markets. Use category slugs as the entry point to any list query.

GET/api/v1/categories

Returns every category in the system. Cached aggressively — categories change rarely.

Request· bash
curl https://juhus.ee/api/v1/categories
Response· json
{
  "data": [
    { "slug": "estonian_politics", "name": "Estonian Politics" },
    { "slug": "estonian_sports",   "name": "Estonian Sports"   }
  ]
}
GET/api/v1/categories/:slug/events

Returns events inside a category, newest first. Only events with at least one tradable market are included by default.

Query params

NameTypeRequiredDescription
pageintegeroptionalPage number, starting at 1.
limitintegeroptionalItems per page. Default 20, maximum 50.
Request· bash
curl "https://juhus.ee/api/v1/categories/estonian_politics/events?page=1&limit=20"
Response· json
{
  "data": [
    {
      "id": "8f3a1b2c-9d4e-4f5a-b6c7-d8e9f0a1b2c3",
      "title": "2027 Estonian Parliament Election",
      "category": "estonian_politics",
      "startsAt": "2027-03-01T00:00:00Z"
    }
  ],
  "meta": { "total": 18, "page": 1, "limit": 20, "hasMore": false }
}
GET/api/v1/categories/:slug/markets

Returns markets inside a category. By default only OPEN and UPCOMING markets are returned; pass status=closed to fetch resolved markets.

Query params

NameTypeRequiredDescription
pageintegeroptionalPage number, starting at 1.
limitintegeroptionalItems per page. Default 20, maximum 50.
statusstringoptionalOptional. Pass `closed` to include closed/resolved/disputed markets. Defaults to open and upcoming only.
Request· bash
curl "https://juhus.ee/api/v1/categories/estonian_sports/markets?status=closed"
Response· json
{
  "data": [
    {
      "id": "1a2b3c4d-5e6f-4a7b-8c9d-0e1f2a3b4c5d",
      "title": "Will Estonia win EuroBasket 2027?",
      "category": "estonian_sports",
      "status": "open",
      "lastTradePrice": 35
    }
  ],
  "meta": { "total": 42, "page": 1, "limit": 20, "hasMore": true }
}
Resource

Events

An event bundles several related markets (for example, an election or a tournament).

GET/api/v1/events/:id

Returns a single event with its nested markets. Useful when building an event detail view.

Request· bash
curl https://juhus.ee/api/v1/events/8f3a1b2c-9d4e-4f5a-b6c7-d8e9f0a1b2c3
Response· json
{
  "id": "8f3a1b2c-9d4e-4f5a-b6c7-d8e9f0a1b2c3",
  "title": "2027 Estonian Parliament Election",
  "category": "estonian_politics",
  "startsAt": "2027-03-01T00:00:00Z",
  "markets": [
    { "id": "1a2b3c4d-5e6f-4a7b-8c9d-0e1f2a3b4c5d", "title": "Reform Party wins most seats", "status": "open", "lastTradePrice": 58 },
    { "id": "2b3c4d5e-6f7a-4b8c-9d0e-1f2a3b4c5d6e", "title": "Centre Party wins most seats", "status": "open", "lastTradePrice": 12 }
  ]
}
Resource

Markets

The core trading primitive. Every market resolves to YES, NO, or VOID.

GET/api/v1/markets/:id

Returns a single market with the latest best bid / best ask and last trade price.

Request· bash
curl https://juhus.ee/api/v1/markets/1a2b3c4d-5e6f-4a7b-8c9d-0e1f2a3b4c5d
Response· json
{
  "id": "1a2b3c4d-5e6f-4a7b-8c9d-0e1f2a3b4c5d",
  "title": "Reform Party wins most seats",
  "status": "open",
  "bestBid": 57,
  "bestAsk": 59,
  "lastTradePrice": 58,
  "resolvedOutcome": null
}
GET/api/v1/markets/:id/orderbookCache 5s

Returns the current aggregated order book. Heavily cached — poll on an interval rather than in a tight loop.

Request· bash
curl https://juhus.ee/api/v1/markets/1a2b3c4d-5e6f-4a7b-8c9d-0e1f2a3b4c5d/orderbook
Response· json
{
  "bids": [
    { "price": 57, "quantity": 320 },
    { "price": 56, "quantity": 180 }
  ],
  "asks": [
    { "price": 59, "quantity": 210 },
    { "price": 60, "quantity": 450 }
  ]
}
GET/api/v1/markets/:id/trades

Returns trade history for a market, newest first. Paginated.

Query params

NameTypeRequiredDescription
pageintegeroptionalPage number, starting at 1.
limitintegeroptionalItems per page. Default 20, maximum 50.
Request· bash
curl "https://juhus.ee/api/v1/markets/1a2b3c4d-5e6f-4a7b-8c9d-0e1f2a3b4c5d/trades?limit=50"
Response· json
{
  "data": [
    { "id": "9b8c7d6e-5f4a-4b3c-2d1e-0f9a8b7c6d5e", "price": 58, "quantity": 25, "createdAt": "2026-04-11T08:30:11Z" },
    { "id": "8a7b6c5d-4e3f-4a2b-1c0d-9e8f7a6b5c4d", "price": 57, "quantity": 10, "createdAt": "2026-04-11T08:29:58Z" }
  ],
  "meta": { "total": 1248, "page": 1, "limit": 50, "hasMore": true }
}
Roadmap

Authenticated API

A Bearer-token API for reading your own account and placing orders is planned for a future release.

Coming soon
  • GET/api/v1/me

    Account info and current balance.

  • GET/api/v1/me/orders

    Your open and filled orders.

  • GET/api/v1/me/portfolio

    Your current positions across all markets.

  • POST/api/v1/orders

    Place a YES or NO limit order.

  • DELETE/api/v1/orders/:id

    Cancel an open order.

When released, API keys will be generated from your account settings page and sent as Authorization: Bearer <key>. Keys are stored as a bcrypt hash server-side and can be revoked at any time.