curl --request GET \
--url https://api.limitless.exchange/parlay/packs/searchimport requests
url = "https://api.limitless.exchange/parlay/packs/search"
response = requests.get(url)
print(response.text)const options = {method: 'GET'};
fetch('https://api.limitless.exchange/parlay/packs/search', 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.limitless.exchange/parlay/packs/search",
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.limitless.exchange/parlay/packs/search"
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.limitless.exchange/parlay/packs/search")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.limitless.exchange/parlay/packs/search")
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_body[
{
"id": "<string>",
"name": "<string>",
"parlayType": "CLOB",
"status": "ACTIVE",
"wasteStrategy": "HOLD",
"earliestDeadline": "<string>",
"legs": [
{
"marketId": 123,
"marketSlug": "<string>",
"marketTitle": "<string>",
"outcome": "YES",
"livePrice": 123,
"priceSnapshot": 123,
"resolvedOutcome": "YES",
"esportsPropType": "map_winner",
"outcomeLabels": [
"<string>"
],
"outcomeImageUrls": [
"<string>"
],
"marketType": "CLOB",
"group": {
"id": 123,
"slug": "<string>",
"title": "<string>",
"leagueName": "<string>",
"homeTeam": "<string>",
"awayTeam": "<string>",
"homeScore": 123,
"awayScore": 123,
"startMatchTimestamp": 123
},
"leagueName": "<string>",
"marketImageUrl": "<string>",
"startMatchTimestamp": 123
}
],
"payout": {
"stake": "10",
"parlayMultiplier": 123,
"parlayPayout": "76.80",
"singlesMultiplier": 123,
"singlesPayout": "<string>",
"savingsPct": 123
},
"properties": [
{
"id": "<string>",
"propertyKeyId": "<string>",
"propertyKeySlug": "<string>",
"propertyKeyName": "<string>",
"value": "<unknown>"
}
],
"inDeadlineWindow": true,
"packOutcome": "WON",
"eligible": true,
"ineligibleReason": "<string>"
}
]Search Active Packs
Free-text search over the packs the active-pack listing returns. The search applies the same ACTIVE, trade-window, and eligibility gating as the listing, so it never surfaces a pack the listing hides. Matches the pack name, each leg’s team names, match titles, market titles, and league names. Matching is case- and accent-insensitive and tokenized: every word in the query must appear somewhere in the fields being tested, but words can match in any order and across different fields. Results are ranked by relevance: packs matched on their name first, then packs where a single leg’s teams or match title carries the whole query, then matches spread across other fields. When packs are paused platform-wide, the search returns an empty array.
curl --request GET \
--url https://api.limitless.exchange/parlay/packs/searchimport requests
url = "https://api.limitless.exchange/parlay/packs/search"
response = requests.get(url)
print(response.text)const options = {method: 'GET'};
fetch('https://api.limitless.exchange/parlay/packs/search', 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.limitless.exchange/parlay/packs/search",
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.limitless.exchange/parlay/packs/search"
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.limitless.exchange/parlay/packs/search")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.limitless.exchange/parlay/packs/search")
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_body[
{
"id": "<string>",
"name": "<string>",
"parlayType": "CLOB",
"status": "ACTIVE",
"wasteStrategy": "HOLD",
"earliestDeadline": "<string>",
"legs": [
{
"marketId": 123,
"marketSlug": "<string>",
"marketTitle": "<string>",
"outcome": "YES",
"livePrice": 123,
"priceSnapshot": 123,
"resolvedOutcome": "YES",
"esportsPropType": "map_winner",
"outcomeLabels": [
"<string>"
],
"outcomeImageUrls": [
"<string>"
],
"marketType": "CLOB",
"group": {
"id": 123,
"slug": "<string>",
"title": "<string>",
"leagueName": "<string>",
"homeTeam": "<string>",
"awayTeam": "<string>",
"homeScore": 123,
"awayScore": 123,
"startMatchTimestamp": 123
},
"leagueName": "<string>",
"marketImageUrl": "<string>",
"startMatchTimestamp": 123
}
],
"payout": {
"stake": "10",
"parlayMultiplier": 123,
"parlayPayout": "76.80",
"singlesMultiplier": 123,
"singlesPayout": "<string>",
"savingsPct": 123
},
"properties": [
{
"id": "<string>",
"propertyKeyId": "<string>",
"propertyKeySlug": "<string>",
"propertyKeyName": "<string>",
"value": "<unknown>"
}
],
"inDeadlineWindow": true,
"packOutcome": "WON",
"eligible": true,
"ineligibleReason": "<string>"
}
]ACTIVE, trade-window, and eligibility gating, so it never surfaces a pack the listing hides.
When to use
Use this endpoint to power a pack search box. Pack names are often editorial and say nothing about their contents, so the search also matches what is inside each pack: leg team names, match titles, market titles, and league names. A user searching for a team or league finds every active pack that carries it, even when the pack name mentions neither.Matching
- Matching is case- and accent-insensitive:
kolnmatches1. FC Köln,fenerbahcematchesFenerbahçe. - The search tokenizes the query, so word order does not matter and words can match across different fields:
man cityfinds a Manchester City pack, andvitality 9zfinds a pack holding both teams in different legs. - Every word in the query must appear somewhere for a pack to match.
querymust be 2-100 characters. A query shorter than 2 characters after trimming returns an empty array rather than an error, matching/markets/search.
Ranking
Results come back in three relevance tiers:- Packs whose name matches the query.
- Packs where a single leg’s team names or match title carries the whole query. A query spread across different legs does not earn this tier.
- Packs matched across any other fields, such as market titles or league names.
Limits and availability
limitcaps the number of results at 1-50. The default is 20.- When packs are paused platform-wide, the search returns an empty array, matching the listing.
Caching
Responses carryCache-Control: public, max-age=30, stale-while-revalidate=60, so results can trail the live listing by up to a minute.Query Parameters
Free-text query, matched case- and accent-insensitively against the pack name, its legs' team names, match titles, market titles, and league names. A query shorter than 2 characters after trimming returns an empty array.
2 - 100"liverpool"
Maximum number of results to return.
1 <= x <= 50Response
Matching active packs, ranked by relevance
CLOB, NEGRISK ACTIVE, CLOSED, DRAFT, HIDDEN Waste-disposition strategy for parlays bought from this pack
HOLD, SELL ISO timestamp of the earliest leg deadline
Show child attributes
Show child attributes
Always computed with stake = "10"
Show child attributes
Show child attributes
Property-key tags attached to this pack (used by filter pages)
Show child attributes
Show child attributes
Mirrors the deadline gate the active-pack listing applies. False packs are hidden from users even when ACTIVE.
LOST the moment any resolved leg mismatches, WON only when every leg resolves matching, PENDING otherwise
WON, LOST, PENDING True when the pack would be accepted by a quote against current orderbook state. False signals clients to disable the buy CTA and surface ineligibleReason.
Single-line reason from the most recent quote attempt when eligible=false. Null when eligible.