Search series
curl --request GET \
--url https://api.oddpool.com/search/seriesimport requests
url = "https://api.oddpool.com/search/series"
response = requests.get(url)
print(response.text)const options = {method: 'GET'};
fetch('https://api.oddpool.com/search/series', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.oddpool.com/search/series",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.oddpool.com/search/series"
req, _ := http.NewRequest("GET", url, nil)
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api.oddpool.com/search/series")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.oddpool.com/search/series")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
response = http.request(request)
puts response.read_bodySearch
Search series
Discover Kalshi and Polymarket series.
GET
/
search
/
series
Search series
curl --request GET \
--url https://api.oddpool.com/search/seriesimport requests
url = "https://api.oddpool.com/search/series"
response = requests.get(url)
print(response.text)const options = {method: 'GET'};
fetch('https://api.oddpool.com/search/series', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.oddpool.com/search/series",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.oddpool.com/search/series"
req, _ := http.NewRequest("GET", url, nil)
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api.oddpool.com/search/series")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.oddpool.com/search/series")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
response = http.request(request)
puts response.read_bodyA series groups recurring or related events under one identifier.
KXBTC15M is the Kalshi 15-minute Bitcoin up/down series — one event opens every 15 minutes and a new market is created for it. btc-up-or-down-15m is the Polymarket equivalent. KXFEDDECISION is the series for Kalshi Fed rate-decision events.
Use this endpoint to find a series_id, then pass it to Search markets or Search events to drill in.
Parameters
string
Matches the series title (full-text) or the
series_id (case-insensitive substring). q=KXBTC returns every Kalshi BTC series; q=15m returns every 15-minute series across both venues; q=bitcoin returns series whose title contains “Bitcoin”.string
kalshi or polymarket.string
Exact match on
category. Common values: Crypto, Sports, Politics, Up or Down.string
default:"active"
active or closed.string
default:"title"
title (alphabetical) or newest (by discovered_at).integer
default:"30"
1-100.
integer
default:"0"
Pagination offset.
Examples
Find all 15-minute crypto series across both venues
A single call surfaces the matching Kalshi and Polymarket series side by side.curl -H "X-API-Key: your_api_key" \
"https://api.oddpool.com/search/series?q=15m"
import requests
response = requests.get(
"https://api.oddpool.com/search/series",
headers={"X-API-Key": "your_api_key"},
params={"q": "15m"},
)
series = response.json()
Browse Polymarket sports series
curl -H "X-API-Key: your_api_key" \
"https://api.oddpool.com/search/series?exchange=polymarket&category=Sports&limit=50"
import requests
response = requests.get(
"https://api.oddpool.com/search/series",
headers={"X-API-Key": "your_api_key"},
params={"exchange": "polymarket", "category": "Sports", "limit": 50},
)
series = response.json()
Response
[
{
"series_id": "KXBTC15M",
"exchange": "kalshi",
"title": "Bitcoin price up down",
"category": "Crypto",
"status": "active",
"n_events_total": 4285,
"n_events_active": 88,
"earliest_event_at": "2026-03-13T19:00:00Z",
"latest_event_at": "2026-05-04T00:05:52Z"
},
{
"series_id": "btc-up-or-down-15m",
"exchange": "polymarket",
"title": "BTC Up or Down 15 Min",
"category": "Up or Down",
"status": "active",
"n_events_total": 4310,
"n_events_active": 96,
"earliest_event_at": "2026-03-15T07:00:00Z",
"latest_event_at": "2026-05-04T01:23:19Z"
}
]
Field reference
| Field | Description |
|---|---|
series_id | Pass this to ?series_id= on Search markets and Search events. |
n_events_total | Total events in this series. |
n_events_active | Events currently open for trading. |
earliest_event_at | Earliest event in this series. |
latest_event_at | Most recent event in this series. |
Not every event belongs to a series — about 15% are one-off markets (news markets, single-instance political markets) that aren’t part of any recurring group. Find those via Search events text search instead.