curl --request POST \
--url https://api-uat.dimetrades.com/api/combos \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--header 'X-API-Key: <api-key>' \
--data '
{
"legs": [
{
"marketTicker": "BTC100K",
"side": "yes"
},
{
"marketTicker": "INDWC",
"side": "no"
}
]
}
'{
"data": {
"id": 1,
"marketId": 37,
"eventId": 28,
"eventTicker": "CEV-BTC100KY-INDWCN",
"created": true,
"ticker": "CMB-BTC100KY-INDWCN",
"title": "Will Bitcoin close above $100k on Dec 31? (YES) + Will India win the next World Cup? (NO)",
"status": "active",
"normalizedKey": "1:yes|2:no",
"legs": [
{
"marketId": 1,
"marketTicker": "BTC100K",
"marketTitle": "Will Bitcoin close above $100k on Dec 31?",
"requiredSide": "yes",
"legIndex": 0
},
{
"marketId": 2,
"marketTicker": "INDWC",
"marketTitle": "Will India win the next World Cup?",
"requiredSide": "no",
"legIndex": 1
}
]
},
"errors": []
}Create (or retrieve) a Combo
Composes a Combo from 2 or more existing markets, one required side each.
If a Combo with the exact same legs (in any order) already exists, its
row is returned unchanged — this is a common, expected outcome, not an
error, which is why a successful match also returns 200.
On a genuine new combination: creates a dedicated event, a dedicated
tradable market (its own marketId, registered with the matching engine
the same way any market is), and the Combo’s leg definition — atomically,
or not at all.
Legs are identified by ticker, not id
Each leg names its market by marketTicker — the shape a trading UI
already has on hand (Kalshi’s own combo-style APIs work the same way) —
never by the internal numeric id. eventTicker is optional per leg and
used only as a cross-check: if supplied, it must match the resolved
market’s actual event ticker or the whole request is rejected (a stale
or mismatched ticker pair is far more likely to indicate a client bug
than a market that genuinely changed events). marketTicker alone is
always sufficient to resolve a leg.
Internally, identity is still entirely id-based — normalized_key (the
real economic identity and the DB-level duplicate guard) is built from
the resolved marketIds, sorted ascending, exactly as before. Ticker is
purely an input/output convenience layered on top; it has no bearing on
which Combo two requests resolve to.
Field rules
- 2–6 legs (Phase 1 has no per-collection configuration; this bound is platform-wide).
- Each
marketTickermust resolve to an existing market currentlyopenorhalted. - A
marketTickermay not repeat — neither the same side twice nor conflicting sides (yes+noon the same market is rejected, since a market cannot settle both ways). Matching is case-insensitive.
Using the result
data.marketId is the Combo’s own tradable market — place orders on it,
or request an RFQ against it (POST /rfqs), exactly as you would for any
other market. Both of those existing endpoints are id-based and
unaffected by this endpoint’s ticker-based input. The underlying leg
markets keep trading independently and are never affected by creating a
Combo from them.
curl --request POST \
--url https://api-uat.dimetrades.com/api/combos \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--header 'X-API-Key: <api-key>' \
--data '
{
"legs": [
{
"marketTicker": "BTC100K",
"side": "yes"
},
{
"marketTicker": "INDWC",
"side": "no"
}
]
}
'{
"data": {
"id": 1,
"marketId": 37,
"eventId": 28,
"eventTicker": "CEV-BTC100KY-INDWCN",
"created": true,
"ticker": "CMB-BTC100KY-INDWCN",
"title": "Will Bitcoin close above $100k on Dec 31? (YES) + Will India win the next World Cup? (NO)",
"status": "active",
"normalizedKey": "1:yes|2:no",
"legs": [
{
"marketId": 1,
"marketTicker": "BTC100K",
"marketTitle": "Will Bitcoin close above $100k on Dec 31?",
"requiredSide": "yes",
"legIndex": 0
},
{
"marketId": 2,
"marketTicker": "INDWC",
"marketTitle": "Will India win the next World Cup?",
"requiredSide": "no",
"legIndex": 1
}
]
},
"errors": []
}Authorizations
The end user's JWT access token, sent as Authorization: Bearer <token>.
Obtain one from POST /partner/customers or POST /partner/customers/login
— both return it as token. It identifies which of your users a call
is made for, and is sent alongside your X-API-Key on every authenticated
endpoint.
Event discovery, categories, subcategories and scores are public and need no token.
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.
Body
2 - 6 elementsShow child attributes
Show child attributes
Response
Combo created, or the existing Combo for this exact leg set.
A user-composed Combo market: a real, independently tradable binary market
(own marketId, own order book) whose eventual payout is derived from
several other markets' outcomes together. Phase 1 is AND-only — the Combo
settles YES if and only if every leg resolves to its requiredSide.
marketId is the Combo's own market — trade it, or request an RFQ
against it, exactly like any other market. It is never one of the
underlying leg markets, which keep trading independently and are untouched
by Combo creation or settlement.
Show child attributes
Show child attributes
