KEY="your-key-id"
SECRET="your-secret"
METHOD="POST"
URLPATH="/predictions-service/api/trading/orders"
BODY='{"market_id":"pm_6ae1e3c09e1d4c7a2b5f80e3d6a9c412","side":"yes","quantity":10,"price":0.59,"time_in_force":"FOK","request_id":"3f1c2a9e-5b7d-4e0a-9c1d-8a6b2e4f7d10"}'
TS=$(( $(date +%s) * 1000 ))
SIG=$(printf '%s' "$TS$METHOD$URLPATH$BODY" | openssl dgst -sha256 -hmac "$SECRET" -binary | base64)
curl -X "$METHOD" "https://api.splashsports.com$URLPATH" \
-H "Content-Type: application/json" \
-H "SPLASH-ACCESS-KEY: $KEY" \
-H "SPLASH-ACCESS-TIMESTAMP: $TS" \
-H "SPLASH-ACCESS-SIGNATURE: $SIG" \
--data-binary "$BODY"import base64, hashlib, hmac, json, time
import requests
KEY = "your-key-id"
SECRET = "your-secret"
HOST = "https://api.splashsports.com"
def sign(secret, timestamp, method, path, body):
message = (timestamp + method + path + body).encode("utf-8")
digest = hmac.new(secret.encode("utf-8"), message, hashlib.sha256).digest()
return base64.b64encode(digest).decode("ascii")
def request(method, path, payload=None):
body = json.dumps(payload, separators=(",", ":")) if payload is not None else ""
timestamp = str(int(time.time() * 1000))
headers = {
"Content-Type": "application/json",
"SPLASH-ACCESS-KEY": KEY,
"SPLASH-ACCESS-TIMESTAMP": timestamp,
"SPLASH-ACCESS-SIGNATURE": sign(SECRET, timestamp, method, path, body),
}
return requests.request(method, HOST + path, headers=headers, data=body.encode("utf-8"))
response = request(
"POST",
"/predictions-service/api/trading/orders",
{
"market_id": "pm_6ae1e3c09e1d4c7a2b5f80e3d6a9c412",
"side": "yes",
"quantity": 10,
"price": 0.59,
"time_in_force": "FOK",
"request_id": "3f1c2a9e-5b7d-4e0a-9c1d-8a6b2e4f7d10",
},
)
print(response.status_code, response.json())const options = {
method: 'POST',
headers: {
'SPLASH-ACCESS-KEY': '<api-key>',
'SPLASH-ACCESS-TIMESTAMP': '<api-key>',
'SPLASH-ACCESS-SIGNATURE': '<api-key>',
'Content-Type': 'application/json'
},
body: JSON.stringify({
market_id: 'pm_6ae1e3c09e1d4c7a2b5f80e3d6a9c412',
side: 'yes',
quantity: 10,
price: 0.59,
time_in_force: 'FOK',
request_id: '3f1c2a9e-5b7d-4e0a-9c1d-8a6b2e4f7d10'
})
};
fetch('https://api.splashsports.com/predictions-service/api/trading/orders', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));import { createHmac } from "node:crypto";
const KEY = "your-key-id";
const SECRET = "your-secret";
const HOST = "https://api.splashsports.com";
function sign(secret: string, timestamp: string, method: string, path: string, body: string): string {
return createHmac("sha256", secret).update(timestamp + method + path + body, "utf8").digest("base64");
}
const method = "POST";
const path = "/predictions-service/api/trading/orders";
// Serialize once, sign that exact string, and send that exact string.
const body = JSON.stringify({
market_id: "pm_6ae1e3c09e1d4c7a2b5f80e3d6a9c412",
side: "yes",
quantity: 10,
price: 0.59,
time_in_force: "FOK",
request_id: "3f1c2a9e-5b7d-4e0a-9c1d-8a6b2e4f7d10",
});
const timestamp = Date.now().toString();
const response = await fetch(HOST + path, {
method,
headers: {
"Content-Type": "application/json",
"SPLASH-ACCESS-KEY": KEY,
"SPLASH-ACCESS-TIMESTAMP": timestamp,
"SPLASH-ACCESS-SIGNATURE": sign(SECRET, timestamp, method, path, body),
},
body,
});
console.log(response.status, await response.json());package main
import (
"bytes"
"crypto/hmac"
"crypto/sha256"
"encoding/base64"
"encoding/json"
"fmt"
"io"
"net/http"
"strconv"
"time"
)
const (
key = "your-key-id"
secret = "your-secret"
host = "https://api.splashsports.com"
)
func sign(secret, timestamp, method, path string, body []byte) string {
mac := hmac.New(sha256.New, []byte(secret))
mac.Write([]byte(timestamp + method + path))
mac.Write(body)
return base64.StdEncoding.EncodeToString(mac.Sum(nil))
}
func main() {
method := "POST"
path := "/predictions-service/api/trading/orders"
// Marshal once, sign those exact bytes, and send those exact bytes.
body, err := json.Marshal(map[string]any{
"market_id": "pm_6ae1e3c09e1d4c7a2b5f80e3d6a9c412",
"side": "yes",
"quantity": 10,
"price": 0.59,
"time_in_force": "FOK",
"request_id": "3f1c2a9e-5b7d-4e0a-9c1d-8a6b2e4f7d10",
})
if err != nil {
panic(err)
}
timestamp := strconv.FormatInt(time.Now().UnixMilli(), 10)
req, err := http.NewRequest(method, host+path, bytes.NewReader(body))
if err != nil {
panic(err)
}
req.Header.Set("Content-Type", "application/json")
req.Header.Set("SPLASH-ACCESS-KEY", key)
req.Header.Set("SPLASH-ACCESS-TIMESTAMP", timestamp)
req.Header.Set("SPLASH-ACCESS-SIGNATURE", sign(secret, timestamp, method, path, body))
resp, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
out, _ := io.ReadAll(resp.Body)
fmt.Println(resp.StatusCode, string(out))
}{
"status": "success",
"order_id": "ord_6aedec658f3a61c2d94e07b5a1c6e2d9",
"request_id": "3f1c2a9e-5b7d-4e0a-9c1d-8a6b2e4f7d10",
"order_status": "pending"
}Place an order
Places a fill-or-kill order on one market. Use it to buy YES or NO contracts at your limit price or better. A 200 means the order was accepted, not filled: the order is queued. Poll GET /orders?request_id= (or GET /orders/{id} with the order_id this call returns) until status is executed or cancelled.
Send the raw order only. There is no fee field: Splash computes the fee from your account’s fee settings, adds it to a buy’s debit and takes it from a close’s proceeds. To check before sending that you have enough cash, compute the order’s cost from fee on Get account and compare it with cash_available on Get balance; see Fees and order cost. A buy without enough cash is accepted and then cancelled without filling.
Sign the request with your API key; see Authentication. A request without the SPLASH-ACCESS-KEY header is not treated as an API request and is a 401.
request_id is your idempotency key: one request_id never places more than one order. What to do after each answer:
200withorder_status: "pending": the order is queued. Poll untilexecutedorcancelled.- No response (your client timed out, the connection dropped) or a
504from the gateway: the outcome is unknown, and the order may have gone through. CheckGET /orders?request_id=. If it returns the order, follow it. If it returns nothing, send the request again with the samerequest_id; it can never place the order twice. - Refused before the order was accepted:
401,415,429,400 Invalid request parameters,400 IOC orders are not yet supportedand503 TRADING_API_UNAVAILABLE. Nothing was recorded; fix the cause (after a429, wait theRetry-Afterseconds when that header is present, otherwise about a second) and retry with the samerequest_id. - Any other error: a
400order-check message (Invalid price,Market is not activeand the rest),403,404,409,503 EXCHANGE_UNAVAILABLEorSERVICE_UNAVAILABLE, and500. The order was not placed and thatrequest_idis spent: polling it readscancelledwith the reason inerror, and sending it again returns200withorder_status: "cancelled"without placing anything. Send a newrequest_idto try again.
See Order outcomes and retries. Only time_in_force: "FOK" is accepted today; IOC is coming and is a 400 until then. The market_id is a market’s id from the market endpoints. The order fills completely at your price or better, or is cancelled; it never partially fills.
KEY="your-key-id"
SECRET="your-secret"
METHOD="POST"
URLPATH="/predictions-service/api/trading/orders"
BODY='{"market_id":"pm_6ae1e3c09e1d4c7a2b5f80e3d6a9c412","side":"yes","quantity":10,"price":0.59,"time_in_force":"FOK","request_id":"3f1c2a9e-5b7d-4e0a-9c1d-8a6b2e4f7d10"}'
TS=$(( $(date +%s) * 1000 ))
SIG=$(printf '%s' "$TS$METHOD$URLPATH$BODY" | openssl dgst -sha256 -hmac "$SECRET" -binary | base64)
curl -X "$METHOD" "https://api.splashsports.com$URLPATH" \
-H "Content-Type: application/json" \
-H "SPLASH-ACCESS-KEY: $KEY" \
-H "SPLASH-ACCESS-TIMESTAMP: $TS" \
-H "SPLASH-ACCESS-SIGNATURE: $SIG" \
--data-binary "$BODY"import base64, hashlib, hmac, json, time
import requests
KEY = "your-key-id"
SECRET = "your-secret"
HOST = "https://api.splashsports.com"
def sign(secret, timestamp, method, path, body):
message = (timestamp + method + path + body).encode("utf-8")
digest = hmac.new(secret.encode("utf-8"), message, hashlib.sha256).digest()
return base64.b64encode(digest).decode("ascii")
def request(method, path, payload=None):
body = json.dumps(payload, separators=(",", ":")) if payload is not None else ""
timestamp = str(int(time.time() * 1000))
headers = {
"Content-Type": "application/json",
"SPLASH-ACCESS-KEY": KEY,
"SPLASH-ACCESS-TIMESTAMP": timestamp,
"SPLASH-ACCESS-SIGNATURE": sign(SECRET, timestamp, method, path, body),
}
return requests.request(method, HOST + path, headers=headers, data=body.encode("utf-8"))
response = request(
"POST",
"/predictions-service/api/trading/orders",
{
"market_id": "pm_6ae1e3c09e1d4c7a2b5f80e3d6a9c412",
"side": "yes",
"quantity": 10,
"price": 0.59,
"time_in_force": "FOK",
"request_id": "3f1c2a9e-5b7d-4e0a-9c1d-8a6b2e4f7d10",
},
)
print(response.status_code, response.json())const options = {
method: 'POST',
headers: {
'SPLASH-ACCESS-KEY': '<api-key>',
'SPLASH-ACCESS-TIMESTAMP': '<api-key>',
'SPLASH-ACCESS-SIGNATURE': '<api-key>',
'Content-Type': 'application/json'
},
body: JSON.stringify({
market_id: 'pm_6ae1e3c09e1d4c7a2b5f80e3d6a9c412',
side: 'yes',
quantity: 10,
price: 0.59,
time_in_force: 'FOK',
request_id: '3f1c2a9e-5b7d-4e0a-9c1d-8a6b2e4f7d10'
})
};
fetch('https://api.splashsports.com/predictions-service/api/trading/orders', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));import { createHmac } from "node:crypto";
const KEY = "your-key-id";
const SECRET = "your-secret";
const HOST = "https://api.splashsports.com";
function sign(secret: string, timestamp: string, method: string, path: string, body: string): string {
return createHmac("sha256", secret).update(timestamp + method + path + body, "utf8").digest("base64");
}
const method = "POST";
const path = "/predictions-service/api/trading/orders";
// Serialize once, sign that exact string, and send that exact string.
const body = JSON.stringify({
market_id: "pm_6ae1e3c09e1d4c7a2b5f80e3d6a9c412",
side: "yes",
quantity: 10,
price: 0.59,
time_in_force: "FOK",
request_id: "3f1c2a9e-5b7d-4e0a-9c1d-8a6b2e4f7d10",
});
const timestamp = Date.now().toString();
const response = await fetch(HOST + path, {
method,
headers: {
"Content-Type": "application/json",
"SPLASH-ACCESS-KEY": KEY,
"SPLASH-ACCESS-TIMESTAMP": timestamp,
"SPLASH-ACCESS-SIGNATURE": sign(SECRET, timestamp, method, path, body),
},
body,
});
console.log(response.status, await response.json());package main
import (
"bytes"
"crypto/hmac"
"crypto/sha256"
"encoding/base64"
"encoding/json"
"fmt"
"io"
"net/http"
"strconv"
"time"
)
const (
key = "your-key-id"
secret = "your-secret"
host = "https://api.splashsports.com"
)
func sign(secret, timestamp, method, path string, body []byte) string {
mac := hmac.New(sha256.New, []byte(secret))
mac.Write([]byte(timestamp + method + path))
mac.Write(body)
return base64.StdEncoding.EncodeToString(mac.Sum(nil))
}
func main() {
method := "POST"
path := "/predictions-service/api/trading/orders"
// Marshal once, sign those exact bytes, and send those exact bytes.
body, err := json.Marshal(map[string]any{
"market_id": "pm_6ae1e3c09e1d4c7a2b5f80e3d6a9c412",
"side": "yes",
"quantity": 10,
"price": 0.59,
"time_in_force": "FOK",
"request_id": "3f1c2a9e-5b7d-4e0a-9c1d-8a6b2e4f7d10",
})
if err != nil {
panic(err)
}
timestamp := strconv.FormatInt(time.Now().UnixMilli(), 10)
req, err := http.NewRequest(method, host+path, bytes.NewReader(body))
if err != nil {
panic(err)
}
req.Header.Set("Content-Type", "application/json")
req.Header.Set("SPLASH-ACCESS-KEY", key)
req.Header.Set("SPLASH-ACCESS-TIMESTAMP", timestamp)
req.Header.Set("SPLASH-ACCESS-SIGNATURE", sign(secret, timestamp, method, path, body))
resp, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
out, _ := io.ReadAll(resp.Body)
fmt.Println(resp.StatusCode, string(out))
}{
"status": "success",
"order_id": "ord_6aedec658f3a61c2d94e07b5a1c6e2d9",
"request_id": "3f1c2a9e-5b7d-4e0a-9c1d-8a6b2e4f7d10",
"order_status": "pending"
}Authorizations
Your API key id. Keys are issued by Splash on request, never expire, and stay valid until Splash revokes them, which it does on request. See Authentication.
Unix milliseconds, within 30 seconds of server time.
base64(HMAC-SHA256(secret, timestamp + METHOD + path + body)). See Authentication.
Body
A fill-or-kill order on one market. See Placing an order.
The market to trade: a market id from the market endpoints, including an alternate_lines[].id. An unknown id is 404 Market not found; a market that is not active is 400 Market is not active.
"pm_6ae1e3c09e1d4c7a2b5f80e3d6a9c412"
yes buys YES contracts and no buys NO contracts. The same field closes a position: holding YES, an order for no sells your YES contracts, and holding NO, an order for yes sells your NO contracts. A close must be for exactly the contracts you hold; a partial close or a flip to the other side is a 400. See Order sides.
yes, no "yes"
Whole contracts, at least 1. A contract pays $1 if its side wins. Opening more than the maximum trade in dollars is a 400; closing is never limited.
x >= 110
Your limit in dollars per contract for the side named in side, 0.01 to 0.99. A no order is priced in NO terms, so to sell 10 YES contracts at $0.66 you send side: "no", price: 0.34. The order fills completely at this price or better, or not at all. Fees are added on top of a buy and taken from a sale, not included in the price; see Fees and order cost. A sub-cent price is rounded to the cent in your favour before it reaches the exchange.
0.01 <= x <= 0.990.59
Only FOK (fill or kill) is accepted. IOC is refused with 400 IOC orders are not yet supported. See Time in force.
FOK "FOK"
Your idempotency key: 1 to 64 characters from A-Z a-z 0-9 _ -; a UUID is ideal. One request_id never places more than one order: sending it again returns the order it already names, with its current status. After no response, poll it before sending it again; after an order-check refusal it is spent and you need a new one. A value another account used is 409 DUPLICATE_REQUEST_ID. See Order outcomes and retries.
1 - 64^[A-Za-z0-9_-]+$"3f1c2a9e-5b7d-4e0a-9c1d-8a6b2e4f7d10"
Response
Accepted. order_status is pending on a new order. A request_id you already used returns that order and its current status instead of placing another: cancelled when the first request was refused.
The order was accepted. Poll it until status is executed or cancelled.
Always success on a 200.
"success""success"
The order id (prefix ord_). Read the order with GET /orders/{id} or poll GET /orders?request_id=. A replay returns the original order's id.
"ord_6aedec658f3a61c2d94e07b5a1c6e2d9"
The request_id you sent.
"3f1c2a9e-5b7d-4e0a-9c1d-8a6b2e4f7d10"
pending on a new order: accepted, not filled. A request_id you already used reports that order's current status, and cancelled when the original request was refused (that request_id is spent). See Order statuses.
pending, executed, cancelled "pending"

