Install the public Python SDK or copy an HTTP example for JavaScript, Go, Ruby, Java, PHP, C#, or Rust. The HTTP examples are standalone reference code: you do not need to download a separate ParlayAPI client file.
First, get a free API key and set PARLAY_API_KEY in your terminal. Keep your key on your server; do not put it in browser code or commit it to Git. For a request without an account, start with the live demo.
export PARLAY_API_KEY='paste_your_key_here'
On Windows PowerShell, use $env:PARLAY_API_KEY = "paste_your_key_here". The examples request MLB moneylines. Coverage varies by sport, market, and time; an empty response is possible.
Python 3.10+ · public SDK · no required runtime dependencies.
PyPI release 0.3.2 · Public source and examples. This SDK uses the /v4 compatibility endpoints and passes the key as apiKey; redact query strings from request logs.
python -m pip install parlay-api==0.3.2Save the example as quickstart.py.
import os
from parlay_api import ParlayAPI
api_key = os.environ["PARLAY_API_KEY"]
if not api_key.strip():
raise ValueError("Set PARLAY_API_KEY first")
client = ParlayAPI(api_key=api_key, timeout=30)
events = client.odds("baseball_mlb", regions="us", markets="h2h")
print(events[0] if events else "No events match this request right now.")
python quickstart.py
Node 18+ · standalone HTTP reference · built-in fetch.
The JavaScript/TypeScript SDK source is public. The example below uses native HTTP and does not depend on an npm release.
No package install needed. Save the example as quickstart.mjs so Node can run the top-level await.
const apiKey = process.env.PARLAY_API_KEY;
if (!apiKey?.trim()) throw new Error("Set PARLAY_API_KEY first");
const response = await fetch(
"https://parlay-api.com/v1/sports/baseball_mlb/odds?regions=us&markets=h2h",
{
headers: { "X-API-Key": apiKey },
signal: AbortSignal.timeout(30_000),
}
);
if (!response.ok) {
throw new Error(`HTTP ${response.status}: ${await response.text()}`);
}
const events = await response.json();
if (!Array.isArray(events)) throw new Error("Expected an event array");
console.log(events[0] ?? "No events match this request right now.");
node quickstart.mjs
Go 1.21+ · standalone HTTP reference · standard library.
Save the example as main.go. No third-party dependencies.
package main
import (
"encoding/json"
"fmt"
"io"
"net/http"
"os"
"strings"
"time"
)
func main() {
key := os.Getenv("PARLAY_API_KEY")
if strings.TrimSpace(key) == "" { panic("Set PARLAY_API_KEY first") }
req, err := http.NewRequest("GET", "https://parlay-api.com/v1/sports/baseball_mlb/odds?regions=us&markets=h2h", nil)
if err != nil { panic(err) }
req.Header.Set("X-API-Key", key)
client := &http.Client{Timeout: 30 * time.Second}
resp, err := client.Do(req)
if err != nil { panic(err) }
defer resp.Body.Close()
body, err := io.ReadAll(resp.Body)
if err != nil { panic(err) }
if resp.StatusCode != http.StatusOK {
panic(fmt.Sprintf("HTTP %d: %s", resp.StatusCode, body))
}
var events []json.RawMessage
if err := json.Unmarshal(body, &events); err != nil { panic(err) }
if len(events) == 0 {
fmt.Println("No events match this request right now.")
return
}
fmt.Println(string(events[0]))
}
go run main.go
Ruby 3.0+ · standalone HTTP reference · net/http and json.
Save the example as quickstart.rb. No gem install needed.
require 'net/http'
require 'json'
key = ENV.fetch('PARLAY_API_KEY')
raise 'Set PARLAY_API_KEY first' if key.strip.empty?
uri = URI('https://parlay-api.com/v1/sports/baseball_mlb/odds?regions=us&markets=h2h')
request = Net::HTTP::Get.new(uri)
request['X-API-Key'] = key
response = Net::HTTP.start(uri.host, uri.port,
use_ssl: true, open_timeout: 10, read_timeout: 30) do |http|
http.request(request)
end
unless response.is_a?(Net::HTTPSuccess)
raise "HTTP #{response.code}: #{response.body}"
end
events = JSON.parse(response.body)
raise 'Expected an event array' unless events.is_a?(Array)
puts(events.empty? ? 'No events match this request right now.' : JSON.pretty_generate(events.first))
ruby quickstart.rb
Java 17+ · standalone HTTP reference · java.net.http.
Save the example as Main.java. It prints the JSON response as text, so no JSON library is required.
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.time.Duration;
public class Main {
public static void main(String[] args) throws Exception {
String key = System.getenv("PARLAY_API_KEY");
if (key == null || key.isBlank()) {
throw new IllegalStateException("Set PARLAY_API_KEY first");
}
var client = HttpClient.newBuilder()
.connectTimeout(Duration.ofSeconds(10)).build();
var request = HttpRequest.newBuilder(URI.create(
"https://parlay-api.com/v1/sports/baseball_mlb/odds?regions=us&markets=h2h"))
.header("X-API-Key", key)
.timeout(Duration.ofSeconds(30)).GET().build();
var response = client.send(request, HttpResponse.BodyHandlers.ofString());
if (response.statusCode() != 200) {
throw new IllegalStateException("HTTP " + response.statusCode() + ": " + response.body());
}
String json = response.body().trim();
System.out.println(json.matches("\\[\\s*\\]")
? "No events match this request right now." : json);
}
}
java Main.java
PHP 8.1+ · standalone HTTP reference · cURL extension.
Enable the PHP cURL extension and save the example as quickstart.php. No Composer package needed.
<?php
$key = getenv('PARLAY_API_KEY');
if ($key === false || trim($key) === '') {
throw new RuntimeException('Set PARLAY_API_KEY first');
}
$curl = curl_init('https://parlay-api.com/v1/sports/baseball_mlb/odds?regions=us&markets=h2h');
curl_setopt_array($curl, [
CURLOPT_HTTPHEADER => ['X-API-Key: ' . $key],
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CONNECTTIMEOUT => 10,
CURLOPT_TIMEOUT => 30,
]);
$body = curl_exec($curl);
$status = curl_getinfo($curl, CURLINFO_HTTP_CODE);
$error = curl_error($curl);
curl_close($curl);
if ($body === false) { throw new RuntimeException($error); }
if ($status !== 200) { throw new RuntimeException("HTTP $status: $body"); }
$events = json_decode($body, true, 512, JSON_THROW_ON_ERROR);
if (!is_array($events) || !array_is_list($events)) {
throw new RuntimeException('Expected an event array');
}
if (count($events) === 0) {
echo "No events match this request right now.\n";
} else {
print_r($events[0]);
}
php quickstart.php
.NET 6+ · standalone HTTP reference · built-in HTTP and JSON libraries.
dotnet new console -o parlay-quickstart
cd parlay-quickstartReplace Program.cs with the example.
using System;
using System.Net.Http;
using System.Text.Json;
var key = Environment.GetEnvironmentVariable("PARLAY_API_KEY");
if (string.IsNullOrWhiteSpace(key))
throw new InvalidOperationException("Set PARLAY_API_KEY first");
using var client = new HttpClient { Timeout = TimeSpan.FromSeconds(30) };
client.DefaultRequestHeaders.Add("X-API-Key", key);
using var response = await client.GetAsync(
"https://parlay-api.com/v1/sports/baseball_mlb/odds?regions=us&markets=h2h");
var body = await response.Content.ReadAsStringAsync();
if (!response.IsSuccessStatusCode)
throw new HttpRequestException($"HTTP {(int)response.StatusCode}: {body}");
using var document = JsonDocument.Parse(body);
var events = document.RootElement;
if (events.ValueKind != JsonValueKind.Array)
throw new InvalidOperationException("Expected an event array");
Console.WriteLine(events.GetArrayLength() == 0
? "No events match this request right now." : events[0].GetRawText());
dotnet run
Rust with Cargo · standalone HTTP reference · reqwest and serde_json.
cargo new parlay-quickstart
cd parlay-quickstartAdd these entries under [dependencies] in Cargo.toml, then replace src/main.rs with the example.
reqwest = { version = "0.12", default-features = false, features = ["blocking", "rustls-tls"] }
serde_json = "1"
use std::{env, error::Error, time::Duration};
use serde_json::Value;
fn main() -> Result<(), Box<dyn Error>> {
let key = env::var("PARLAY_API_KEY")?;
if key.trim().is_empty() { return Err("Set PARLAY_API_KEY first".into()); }
let client = reqwest::blocking::Client::builder()
.timeout(Duration::from_secs(30)).build()?;
let response = client.get(
"https://parlay-api.com/v1/sports/baseball_mlb/odds?regions=us&markets=h2h")
.header("X-API-Key", key).send()?;
let status = response.status();
let body = response.text()?;
if !status.is_success() {
return Err(format!("HTTP {status}: {body}").into());
}
let value: Value = serde_json::from_str(&body)?;
let events = value.as_array().ok_or("Expected an event array")?;
match events.first() {
Some(event) => println!("{event}"),
None => println!("No events match this request right now."),
}
Ok(())
}
cargo run
A successful odds call returns a JSON array. [] means no events were returned for that request. Check the sport key, filters, and current availability using the sports catalogue and the live demo. Do not assume that every event contains every sportsbook or market.
The Python 0.3.2 SDK and these HTTP examples do not automatically retry requests. For production reads, add bounded retries for HTTP 429 and transient 5xx errors, honoring Retry-After when present. Check the status and error body before retrying: authentication and plan errors need a configuration or account change. See production best practices and limits.
The Python SDK raises ParlayAPIError subclasses and exposes credit headers through client.last_quota. The HTTP examples check the response status directly. When debugging an HTTP request, save its X-Request-ID response header if present and include it when contacting support. Do not share your API key.
Use the OpenAPI specification with your preferred client generator, or start from the curl cookbook. These are REST examples; live streaming requires Business tier or above. See current plans.
Report SDK issues in the public Python issue tracker or JavaScript issue tracker.