curl --request GET \
--url https://api-uat.dimetrades.com/api/events \
--header 'X-API-Key: <api-key>'import requests
url = "https://api-uat.dimetrades.com/api/events"
headers = {"X-API-Key": "<api-key>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {'X-API-Key': '<api-key>'}};
fetch('https://api-uat.dimetrades.com/api/events', 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-uat.dimetrades.com/api/events",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"X-API-Key: <api-key>"
],
]);
$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-uat.dimetrades.com/api/events"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("X-API-Key", "<api-key>")
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-uat.dimetrades.com/api/events")
.header("X-API-Key", "<api-key>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api-uat.dimetrades.com/api/events")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["X-API-Key"] = '<api-key>'
response = http.request(request)
puts response.read_body{
"data": {
"events": [
{
"id": 1525674,
"ticker": "202610031F02C72E",
"title": "New York Islanders vs New Jersey Devils",
"subtitle": null,
"totalMarketCount": 34,
"activeMarketCount": 34,
"status": "open",
"isFuture": false,
"closeAt": "2026-10-03T23:30:00.000Z",
"openAt": null,
"volume": 0,
"totalVolume": null,
"isBookmarked": false,
"score": null,
"currentPeriod": null,
"metaData": {
"opticOdds": {
"fixtureId": "202610031F02C72E",
"sportName": "Hockey",
"leagueName": "NHL",
"venue": "UBS Arena",
"venueLocation": "Elmont, NY",
"tournamentName": null,
"tournamentStage": null,
"homeCompetitorId": "5E16D8AA2B86",
"awayCompetitorId": "0502F7C6398C39E5",
"homeCompetitorName": "New York Islanders",
"awayCompetitorName": "New Jersey Devils",
"teamLogos": {
"New York Islanders": "https://cdn.opticodds.com/team-logos/hockey/11223.png",
"New Jersey Devils": "https://cdn.opticodds.com/team-logos/hockey/11224.png"
},
"homeRecord": "4-2",
"awayRecord": "3-3"
}
},
"category": {
"id": 32,
"name": "Sports",
"imageUrl": "https://.../sports.png"
},
"subcategory": {
"id": 24862,
"categoryId": 32,
"name": "NHL",
"imageUrl": null,
"parent": {
"id": 137,
"categoryId": 32,
"name": "Ice Hockey",
"imageUrl": "https://.../ice-hockey.png",
"parentId": null
}
},
"series": null,
"markets": [
{
"marketDisplayName": "Moneyline 3-Way",
"outcomes": [
{
"id": 32872605,
"eventId": 1525674,
"ticker": "202610031F02C72E-moneyline_3-way-new_jersey_devils-na-na",
"title": "New Jersey Devils",
"marketDisplayName": "Moneyline 3-Way",
"yesBid": null,
"yesAsk": null,
"noBid": null,
"noAsk": null,
"currentPrice": null,
"status": "open",
"result": null,
"isFuture": false,
"ruleSummary": null,
"metaData": {
"opticOdds": {
"fixtureId": "202610031F02C72E",
"marketId": "moneyline_3-way",
"marketName": "Moneyline 3-Way",
"selection": "New Jersey Devils",
"normalizedSelection": "new_jersey_devils",
"selectionLine": null,
"points": null,
"sportsbook": "DraftKings"
}
}
},
{
"id": 32872606,
"eventId": 1525674,
"ticker": "202610031F02C72E-moneyline_3-way-draw-na-na",
"title": "Draw",
"marketDisplayName": "Moneyline 3-Way",
"currentPrice": null,
"status": "open",
"result": null,
"metaData": {
"opticOdds": {
"fixtureId": "202610031F02C72E",
"marketId": "moneyline_3-way",
"selection": "Draw",
"normalizedSelection": "draw",
"selectionLine": null,
"points": null,
"sportsbook": "DraftKings"
}
}
}
]
},
{
"marketDisplayName": "Puck Line",
"outcomes": [
{
"id": 32870146,
"eventId": 1525674,
"ticker": "202610031F02C72E-puck_line-new_york_islanders-na--1.5",
"title": "New York Islanders -1.5",
"marketDisplayName": "Puck Line",
"currentPrice": null,
"status": "open",
"result": null,
"metaData": {
"opticOdds": {
"fixtureId": "202610031F02C72E",
"marketId": "puck_line",
"selection": "New York Islanders -1.5",
"normalizedSelection": "new_york_islanders",
"selectionLine": null,
"points": -1.5,
"sportsbook": "DraftKings"
}
}
}
]
}
]
}
],
"pagination": {
"count": 1,
"totalCount": 108,
"hasPreviousPage": false,
"hasNextPage": true
}
},
"errors": []
}List / browse events
Returns a paginated list of events, each with its markets nested inside. This is the main discovery endpoint — the one you build a browse screen on.
X-API-Key is required; a user Bearer token is optional. With one, each event’s
isBookmarked reflects the caller; without one it is always false.
Three things to get right before you start
- Sports events group their markets by betting line. Each entry in
marketsis a group — “Moneyline 3-Way”, “Puck Line” — holding its selectable outcomes inoutcomes, and that is how it is meant to be displayed. Non-sports events have no betting lines, so theirmarketsarrive flat. Branch on the presence ofoutcomes; full rule on theEvent.marketsfield. - Future events are hidden by default.
isFuturedefaults tofalseserver-side, so events awaiting reveal never appear unless you ask for them explicitly withisFuture=true. - Titles and rule texts arrive rendered — display them as they are.
Send a
user-timezoneheader to have the closing time rendered on your viewer’s own clock instead of our US Eastern default. Rule copy also carries$BINANCE$-style source tokens worth turning into links. Both in the Events guide — §3.
Unknown query parameters are rejected
The query string is validated strictly: any parameter not listed below
returns 400 rather than being ignored. A typo like catgoryId fails
loudly, which is deliberate — but it also means you cannot pass your own
tracking parameters through this endpoint.
Reading every status in one call
status takes a comma-separated list and isFuture accepts all, so a
single request can return every event a player could see — instead of one
request per status plus a separate one for future events:
GET /events?status=open,pending,live,halted&isFuture=all&page=1&limit=200
Events come back interleaved, each carrying its own status and
isFuture, and one pagination block covers the whole set — no merging or
de-duplicating across reads. Page it with hasNextPage as usual.
Paging
page and limit are integers. Drive “load more” from
pagination.hasNextPage rather than comparing count to limit, which
breaks on the final page.
curl --request GET \
--url https://api-uat.dimetrades.com/api/events \
--header 'X-API-Key: <api-key>'import requests
url = "https://api-uat.dimetrades.com/api/events"
headers = {"X-API-Key": "<api-key>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {'X-API-Key': '<api-key>'}};
fetch('https://api-uat.dimetrades.com/api/events', 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-uat.dimetrades.com/api/events",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"X-API-Key: <api-key>"
],
]);
$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-uat.dimetrades.com/api/events"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("X-API-Key", "<api-key>")
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-uat.dimetrades.com/api/events")
.header("X-API-Key", "<api-key>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api-uat.dimetrades.com/api/events")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["X-API-Key"] = '<api-key>'
response = http.request(request)
puts response.read_body{
"data": {
"events": [
{
"id": 1525674,
"ticker": "202610031F02C72E",
"title": "New York Islanders vs New Jersey Devils",
"subtitle": null,
"totalMarketCount": 34,
"activeMarketCount": 34,
"status": "open",
"isFuture": false,
"closeAt": "2026-10-03T23:30:00.000Z",
"openAt": null,
"volume": 0,
"totalVolume": null,
"isBookmarked": false,
"score": null,
"currentPeriod": null,
"metaData": {
"opticOdds": {
"fixtureId": "202610031F02C72E",
"sportName": "Hockey",
"leagueName": "NHL",
"venue": "UBS Arena",
"venueLocation": "Elmont, NY",
"tournamentName": null,
"tournamentStage": null,
"homeCompetitorId": "5E16D8AA2B86",
"awayCompetitorId": "0502F7C6398C39E5",
"homeCompetitorName": "New York Islanders",
"awayCompetitorName": "New Jersey Devils",
"teamLogos": {
"New York Islanders": "https://cdn.opticodds.com/team-logos/hockey/11223.png",
"New Jersey Devils": "https://cdn.opticodds.com/team-logos/hockey/11224.png"
},
"homeRecord": "4-2",
"awayRecord": "3-3"
}
},
"category": {
"id": 32,
"name": "Sports",
"imageUrl": "https://.../sports.png"
},
"subcategory": {
"id": 24862,
"categoryId": 32,
"name": "NHL",
"imageUrl": null,
"parent": {
"id": 137,
"categoryId": 32,
"name": "Ice Hockey",
"imageUrl": "https://.../ice-hockey.png",
"parentId": null
}
},
"series": null,
"markets": [
{
"marketDisplayName": "Moneyline 3-Way",
"outcomes": [
{
"id": 32872605,
"eventId": 1525674,
"ticker": "202610031F02C72E-moneyline_3-way-new_jersey_devils-na-na",
"title": "New Jersey Devils",
"marketDisplayName": "Moneyline 3-Way",
"yesBid": null,
"yesAsk": null,
"noBid": null,
"noAsk": null,
"currentPrice": null,
"status": "open",
"result": null,
"isFuture": false,
"ruleSummary": null,
"metaData": {
"opticOdds": {
"fixtureId": "202610031F02C72E",
"marketId": "moneyline_3-way",
"marketName": "Moneyline 3-Way",
"selection": "New Jersey Devils",
"normalizedSelection": "new_jersey_devils",
"selectionLine": null,
"points": null,
"sportsbook": "DraftKings"
}
}
},
{
"id": 32872606,
"eventId": 1525674,
"ticker": "202610031F02C72E-moneyline_3-way-draw-na-na",
"title": "Draw",
"marketDisplayName": "Moneyline 3-Way",
"currentPrice": null,
"status": "open",
"result": null,
"metaData": {
"opticOdds": {
"fixtureId": "202610031F02C72E",
"marketId": "moneyline_3-way",
"selection": "Draw",
"normalizedSelection": "draw",
"selectionLine": null,
"points": null,
"sportsbook": "DraftKings"
}
}
}
]
},
{
"marketDisplayName": "Puck Line",
"outcomes": [
{
"id": 32870146,
"eventId": 1525674,
"ticker": "202610031F02C72E-puck_line-new_york_islanders-na--1.5",
"title": "New York Islanders -1.5",
"marketDisplayName": "Puck Line",
"currentPrice": null,
"status": "open",
"result": null,
"metaData": {
"opticOdds": {
"fixtureId": "202610031F02C72E",
"marketId": "puck_line",
"selection": "New York Islanders -1.5",
"normalizedSelection": "new_york_islanders",
"selectionLine": null,
"points": -1.5,
"sportsbook": "DraftKings"
}
}
}
]
}
]
}
],
"pagination": {
"count": 1,
"totalCount": 108,
"hasPreviousPage": false,
"hasNextPage": true
}
},
"errors": []
}Authorizations
ISV / partner credential — public half. Required on every request.
Identifies the integration partner (ISV) making the call. Issued by Dime
Trades when the ISV is onboarded and sent on every /partner/* endpoint:
X-API-Key: dt_pk_live_7f3c9a2e5b18
- On the two partner endpoints that create accounts or issue tokens (
POST /partner/customers,POST /partner/customers/login), it is accompanied byX-API-Secretand is the only authentication — there is no user token yet. - On every other partner endpoint it is sent alongside the user's
Authorization: Bearer <token>: the API key says which platform is calling, the bearer token says which user it is calling for.
Credentials are scoped to one or more brands; using a key with a brandId outside that scope returns 403. Staging and production keys are separate.
The key identifies your platform — treat it as a backend credential.
Query Parameters
Restrict to one category (e.g. Sports, Crypto). Digits only, as a string.
^[0-9]+$"32"
Restrict to one subcategory. Includes descendants — passing a parent subcategory id (e.g. Metals) also returns events filed under its children (Gold, Silver). The expansion is one level deep. Passing a leaf id returns only that leaf.
Crypto subcategories are per-asset (BTC, ETH, … each have their own id), so this is also the correct way to scope a request to a single asset.
^[0-9]+$Restrict each returned event's markets to one sport-scoped category/tab (e.g. "Player Props") — the id from GET /market-groups. This filters markets only, never which events appear — every event in the page still shows up regardless of category, only the contents of its markets array change. An event with no markets in the requested group (which is every non-sports event, since their marketGroupId is always null and can never match) comes back with markets: [] rather than being dropped from the page.
^[0-9]+$"48"
Only events flagged as trending.
Only events flagged as new.
Whether to return future events. Which kind of future depends on the category the call is scoped to: under Sports it means season-long outrights (Championship Winner, MVP), and everywhere else it means a round published in advance whose target is revealed at open. Defaults to false when omitted, so ordinary calls see neither. Unscoped calls with true return both sets. Prefer the unambiguous isFutureTradable for the pre-reveal rounds.
Send all to drop the future/non-future split entirely: the response mixes regular and future events in one listing, and each event's own isFuture / isFutureTradable flags tell you which is which. Use it with a multi-value status to read everything in one call.
true, false, all Whether to return pre-reveal rounds — published in advance and tradable before their window, with the target still TBD until open. Unlike isFuture this never means a sports outright, whatever the call is scoped to, and it takes precedence when both are sent. Defaults to false when omitted. Also accepts all, with the same meaning as for isFuture.
true, false, all Only events pinned to the top by an administrator.
Filter by event lifecycle status. open is the only status whose markets accept orders.
Takes one status or a comma-separated list — status=open,pending,live,halted returns events in any of them. Use exact lowercase values with no spaces around the commas; an unknown value, an empty item (open,) or a space (open, live) returns 400. Omit it to apply no status filter.
Two things change when you send a list that includes live: events are ordered live first and then by openAt ascending, and sortBy / sortOrder are not applied. And open events are still held to the usual open window (not yet closed, or flagged future) even in a mixed list — it is the other statuses that pass straight through.
^(pending|open|live|halted|closed|settled|expired|terminated)(,(pending|open|live|halted|closed|settled|expired|terminated))*$"open"
"open,pending,live,halted"
Sort field. volume sorts by live traded volume (the volume response field, not totalVolume); openAt sorts by scheduled open time, which is what you usually want alongside isFuture=true; closeAt sorts by scheduled close time. The date sorts honour sortOrder and default to ascending.
volume, openAt, closeAt Sort direction, applied to sortBy.
asc, desc Restrict to events issued on a given cadence. Cadence is a property of the event (metaData.cadence), not of its category or subcategory — one subcategory typically runs several cadences at once, so pair this with subcategoryId to isolate a single recurring series.
The enum below is the canonical set: every value this endpoint accepts is one an event can carry, and vice versa. The /subcategories cadence menu offers the same values.
A cadence describes a recurring window. Markets that happen once — a sports fixture, an IPO announcement, a company's KPI report — carry no metaData.cadence at all and cannot be reached through this filter. See EventMetaData.cadence.
5min, 10min, 15min, 1hr, daily, weekly, monthly, quarterly, yearly, season, per_meeting, annual_release, per_release, election Filter by event classification. Supported values are standard, leaderboard, and short_market. short_market means a market with a duration of 15 minutes or less. The filter combines with every other filter, for example marketType=leaderboard&cadence=15min.
standard, leaderboard, short_market Exclude events whose volume is below this threshold.
Only takes effect when sortBy=volume is also sent. Without it the parameter is accepted and then silently ignored — minVolume=999999 alone still returns the full catalogue. Always pair the two: ?sortBy=volume&minVolume=1.
^[0-9]+$1-based page number (integer). Standardized across all endpoints.
Page size (integer). Standardized across all endpoints. There is no server-side maximum — the value is passed straight through, so a large limit returns a correspondingly large payload (the whole catalogue in one response if you ask for it). Keep it to a sane page size. limit=0 is accepted and falls back to the default of 10 rather than returning an empty page.
