veynor 1.0.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- veynor-1.0.0/PKG-INFO +199 -0
- veynor-1.0.0/README.md +174 -0
- veynor-1.0.0/pyproject.toml +36 -0
- veynor-1.0.0/setup.cfg +4 -0
- veynor-1.0.0/veynor/__init__.py +14 -0
- veynor-1.0.0/veynor/client.py +239 -0
- veynor-1.0.0/veynor.egg-info/PKG-INFO +199 -0
- veynor-1.0.0/veynor.egg-info/SOURCES.txt +9 -0
- veynor-1.0.0/veynor.egg-info/dependency_links.txt +1 -0
- veynor-1.0.0/veynor.egg-info/requires.txt +1 -0
- veynor-1.0.0/veynor.egg-info/top_level.txt +1 -0
veynor-1.0.0/PKG-INFO
ADDED
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: veynor
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: Prediction market intelligence for agents and traders — Kalshi + Polymarket
|
|
5
|
+
Author-email: Veynor <hello@veynor.xyz>
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://veynor.xyz
|
|
8
|
+
Project-URL: Repository, https://github.com/veynor/veynor-python
|
|
9
|
+
Project-URL: API Docs, https://veynor.xyz/agents
|
|
10
|
+
Keywords: prediction-markets,kalshi,polymarket,finance,trading,quant
|
|
11
|
+
Classifier: Development Status :: 4 - Beta
|
|
12
|
+
Classifier: Intended Audience :: Developers
|
|
13
|
+
Classifier: Intended Audience :: Financial and Insurance Industry
|
|
14
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
20
|
+
Classifier: Topic :: Office/Business :: Financial
|
|
21
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
22
|
+
Requires-Python: >=3.9
|
|
23
|
+
Description-Content-Type: text/markdown
|
|
24
|
+
Requires-Dist: requests>=2.28
|
|
25
|
+
|
|
26
|
+
# veynor
|
|
27
|
+
|
|
28
|
+
Python client for the [Veynor](https://veynor.xyz) prediction market intelligence API.
|
|
29
|
+
|
|
30
|
+
Cross-venue data across Kalshi and Polymarket: whale trades, smart money signals, arb opportunities, and market search — in a single `import`.
|
|
31
|
+
|
|
32
|
+
```python
|
|
33
|
+
pip install veynor
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
---
|
|
37
|
+
|
|
38
|
+
## Quickstart
|
|
39
|
+
|
|
40
|
+
```python
|
|
41
|
+
import veynor
|
|
42
|
+
|
|
43
|
+
client = veynor.Client(api_key="vey_sk_...")
|
|
44
|
+
|
|
45
|
+
# Whale trades across both venues
|
|
46
|
+
whales = client.whales(venue="all", min_notional=10_000)
|
|
47
|
+
for t in whales["trades"]:
|
|
48
|
+
print(t["platform"], t["market"], t["side"], f"${t['notional']:,.0f}")
|
|
49
|
+
|
|
50
|
+
# Arb opportunities between Kalshi and Polymarket
|
|
51
|
+
arb = client.signals(signal_type="arb_opportunities")
|
|
52
|
+
for opp in arb["arb_opportunities"]:
|
|
53
|
+
print(opp)
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
Get a free API key at [veynor.xyz/agents](https://veynor.xyz/agents).
|
|
57
|
+
|
|
58
|
+
---
|
|
59
|
+
|
|
60
|
+
## Authentication
|
|
61
|
+
|
|
62
|
+
Pass your key directly or via environment variable:
|
|
63
|
+
|
|
64
|
+
```python
|
|
65
|
+
# Option 1: direct
|
|
66
|
+
client = veynor.Client(api_key="vey_sk_...")
|
|
67
|
+
|
|
68
|
+
# Option 2: environment variable
|
|
69
|
+
# export VEYNOR_API_KEY=vey_sk_...
|
|
70
|
+
client = veynor.Client()
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
---
|
|
74
|
+
|
|
75
|
+
## Methods
|
|
76
|
+
|
|
77
|
+
### `client.whales()`
|
|
78
|
+
|
|
79
|
+
Recent large trades across Kalshi and Polymarket.
|
|
80
|
+
|
|
81
|
+
```python
|
|
82
|
+
whales = client.whales(
|
|
83
|
+
venue="all", # "all" | "kalshi" | "polymarket"
|
|
84
|
+
min_notional=8_000, # minimum trade size in USD
|
|
85
|
+
category="Politics", # "All" | "Sports" | "Politics" | "Other"
|
|
86
|
+
limit=20,
|
|
87
|
+
)
|
|
88
|
+
# Returns: { summary, trades: [...], meta }
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
### `client.top_markets()`
|
|
92
|
+
|
|
93
|
+
Top markets by 24-hour volume.
|
|
94
|
+
|
|
95
|
+
```python
|
|
96
|
+
markets = client.top_markets(
|
|
97
|
+
venue="all",
|
|
98
|
+
category="All",
|
|
99
|
+
limit=10,
|
|
100
|
+
)
|
|
101
|
+
# Returns: { summary, kalshi: [...], polymarket: [...], meta }
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
### `client.search()`
|
|
105
|
+
|
|
106
|
+
Search markets by keyword across both venues.
|
|
107
|
+
|
|
108
|
+
```python
|
|
109
|
+
results = client.search("fed rate", venue="all", limit=10)
|
|
110
|
+
# Returns: { summary, polymarket: [...], kalshi: [...], meta }
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
### `client.market()`
|
|
114
|
+
|
|
115
|
+
Full details for a specific market.
|
|
116
|
+
|
|
117
|
+
```python
|
|
118
|
+
# Polymarket: use condition ID
|
|
119
|
+
m = client.market("polymarket", "0x1234...")
|
|
120
|
+
|
|
121
|
+
# Kalshi: use ticker
|
|
122
|
+
m = client.market("kalshi", "KXNBA-25-LAL")
|
|
123
|
+
|
|
124
|
+
# Returns: { summary, market: {...}, meta }
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
### `client.signals()`
|
|
128
|
+
|
|
129
|
+
Alpha signals: wide spreads, price movers, cross-venue arb.
|
|
130
|
+
|
|
131
|
+
```python
|
|
132
|
+
signals = client.signals(
|
|
133
|
+
signal_type="all", # "all" | "wide_spreads" | "price_movers" | "arb_opportunities"
|
|
134
|
+
limit=10,
|
|
135
|
+
)
|
|
136
|
+
# Returns: { summary, wide_spreads, price_movers, arb_opportunities, meta }
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
### `client.usage()`
|
|
140
|
+
|
|
141
|
+
Check your credit balance. Always free.
|
|
142
|
+
|
|
143
|
+
```python
|
|
144
|
+
u = client.usage()
|
|
145
|
+
print(u["tier"], u["credits_remaining"])
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
---
|
|
149
|
+
|
|
150
|
+
## Credit costs
|
|
151
|
+
|
|
152
|
+
| Method | Credits |
|
|
153
|
+
|-----------------|---------|
|
|
154
|
+
| `whales()` | 2 |
|
|
155
|
+
| `top_markets()` | 1 |
|
|
156
|
+
| `search()` | 1 |
|
|
157
|
+
| `market()` | 1 |
|
|
158
|
+
| `signals()` | 3 |
|
|
159
|
+
| `usage()` | 0 |
|
|
160
|
+
|
|
161
|
+
Free tier: 100 credits/month. Upgrade at [veynor.xyz/agents](https://veynor.xyz/agents).
|
|
162
|
+
|
|
163
|
+
---
|
|
164
|
+
|
|
165
|
+
## Exceptions
|
|
166
|
+
|
|
167
|
+
```python
|
|
168
|
+
from veynor import VeynorError, AuthError, RateLimitError
|
|
169
|
+
|
|
170
|
+
try:
|
|
171
|
+
whales = client.whales()
|
|
172
|
+
except AuthError:
|
|
173
|
+
print("Invalid or expired API key")
|
|
174
|
+
except RateLimitError:
|
|
175
|
+
print("Rate limit hit — slow down or upgrade tier")
|
|
176
|
+
except VeynorError as e:
|
|
177
|
+
print(f"API error {e.status_code}: {e}")
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
---
|
|
181
|
+
|
|
182
|
+
## Use in a Jupyter notebook
|
|
183
|
+
|
|
184
|
+
```python
|
|
185
|
+
import veynor, pandas as pd
|
|
186
|
+
|
|
187
|
+
client = veynor.Client()
|
|
188
|
+
data = client.whales(min_notional=15_000, limit=50)
|
|
189
|
+
df = pd.DataFrame(data["trades"])
|
|
190
|
+
df[["market", "side", "notional", "platform"]].sort_values("notional", ascending=False)
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
---
|
|
194
|
+
|
|
195
|
+
## Links
|
|
196
|
+
|
|
197
|
+
- [Register for an API key](https://veynor.xyz/agents)
|
|
198
|
+
- [MCP server](https://mcp.veynor.xyz) — connect directly from Claude Desktop or OpenClaw
|
|
199
|
+
- [Web app](https://veynor.xyz) — whale feed, smart money signals, trade interface
|
veynor-1.0.0/README.md
ADDED
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
# veynor
|
|
2
|
+
|
|
3
|
+
Python client for the [Veynor](https://veynor.xyz) prediction market intelligence API.
|
|
4
|
+
|
|
5
|
+
Cross-venue data across Kalshi and Polymarket: whale trades, smart money signals, arb opportunities, and market search — in a single `import`.
|
|
6
|
+
|
|
7
|
+
```python
|
|
8
|
+
pip install veynor
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## Quickstart
|
|
14
|
+
|
|
15
|
+
```python
|
|
16
|
+
import veynor
|
|
17
|
+
|
|
18
|
+
client = veynor.Client(api_key="vey_sk_...")
|
|
19
|
+
|
|
20
|
+
# Whale trades across both venues
|
|
21
|
+
whales = client.whales(venue="all", min_notional=10_000)
|
|
22
|
+
for t in whales["trades"]:
|
|
23
|
+
print(t["platform"], t["market"], t["side"], f"${t['notional']:,.0f}")
|
|
24
|
+
|
|
25
|
+
# Arb opportunities between Kalshi and Polymarket
|
|
26
|
+
arb = client.signals(signal_type="arb_opportunities")
|
|
27
|
+
for opp in arb["arb_opportunities"]:
|
|
28
|
+
print(opp)
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
Get a free API key at [veynor.xyz/agents](https://veynor.xyz/agents).
|
|
32
|
+
|
|
33
|
+
---
|
|
34
|
+
|
|
35
|
+
## Authentication
|
|
36
|
+
|
|
37
|
+
Pass your key directly or via environment variable:
|
|
38
|
+
|
|
39
|
+
```python
|
|
40
|
+
# Option 1: direct
|
|
41
|
+
client = veynor.Client(api_key="vey_sk_...")
|
|
42
|
+
|
|
43
|
+
# Option 2: environment variable
|
|
44
|
+
# export VEYNOR_API_KEY=vey_sk_...
|
|
45
|
+
client = veynor.Client()
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
---
|
|
49
|
+
|
|
50
|
+
## Methods
|
|
51
|
+
|
|
52
|
+
### `client.whales()`
|
|
53
|
+
|
|
54
|
+
Recent large trades across Kalshi and Polymarket.
|
|
55
|
+
|
|
56
|
+
```python
|
|
57
|
+
whales = client.whales(
|
|
58
|
+
venue="all", # "all" | "kalshi" | "polymarket"
|
|
59
|
+
min_notional=8_000, # minimum trade size in USD
|
|
60
|
+
category="Politics", # "All" | "Sports" | "Politics" | "Other"
|
|
61
|
+
limit=20,
|
|
62
|
+
)
|
|
63
|
+
# Returns: { summary, trades: [...], meta }
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
### `client.top_markets()`
|
|
67
|
+
|
|
68
|
+
Top markets by 24-hour volume.
|
|
69
|
+
|
|
70
|
+
```python
|
|
71
|
+
markets = client.top_markets(
|
|
72
|
+
venue="all",
|
|
73
|
+
category="All",
|
|
74
|
+
limit=10,
|
|
75
|
+
)
|
|
76
|
+
# Returns: { summary, kalshi: [...], polymarket: [...], meta }
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
### `client.search()`
|
|
80
|
+
|
|
81
|
+
Search markets by keyword across both venues.
|
|
82
|
+
|
|
83
|
+
```python
|
|
84
|
+
results = client.search("fed rate", venue="all", limit=10)
|
|
85
|
+
# Returns: { summary, polymarket: [...], kalshi: [...], meta }
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
### `client.market()`
|
|
89
|
+
|
|
90
|
+
Full details for a specific market.
|
|
91
|
+
|
|
92
|
+
```python
|
|
93
|
+
# Polymarket: use condition ID
|
|
94
|
+
m = client.market("polymarket", "0x1234...")
|
|
95
|
+
|
|
96
|
+
# Kalshi: use ticker
|
|
97
|
+
m = client.market("kalshi", "KXNBA-25-LAL")
|
|
98
|
+
|
|
99
|
+
# Returns: { summary, market: {...}, meta }
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
### `client.signals()`
|
|
103
|
+
|
|
104
|
+
Alpha signals: wide spreads, price movers, cross-venue arb.
|
|
105
|
+
|
|
106
|
+
```python
|
|
107
|
+
signals = client.signals(
|
|
108
|
+
signal_type="all", # "all" | "wide_spreads" | "price_movers" | "arb_opportunities"
|
|
109
|
+
limit=10,
|
|
110
|
+
)
|
|
111
|
+
# Returns: { summary, wide_spreads, price_movers, arb_opportunities, meta }
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
### `client.usage()`
|
|
115
|
+
|
|
116
|
+
Check your credit balance. Always free.
|
|
117
|
+
|
|
118
|
+
```python
|
|
119
|
+
u = client.usage()
|
|
120
|
+
print(u["tier"], u["credits_remaining"])
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
---
|
|
124
|
+
|
|
125
|
+
## Credit costs
|
|
126
|
+
|
|
127
|
+
| Method | Credits |
|
|
128
|
+
|-----------------|---------|
|
|
129
|
+
| `whales()` | 2 |
|
|
130
|
+
| `top_markets()` | 1 |
|
|
131
|
+
| `search()` | 1 |
|
|
132
|
+
| `market()` | 1 |
|
|
133
|
+
| `signals()` | 3 |
|
|
134
|
+
| `usage()` | 0 |
|
|
135
|
+
|
|
136
|
+
Free tier: 100 credits/month. Upgrade at [veynor.xyz/agents](https://veynor.xyz/agents).
|
|
137
|
+
|
|
138
|
+
---
|
|
139
|
+
|
|
140
|
+
## Exceptions
|
|
141
|
+
|
|
142
|
+
```python
|
|
143
|
+
from veynor import VeynorError, AuthError, RateLimitError
|
|
144
|
+
|
|
145
|
+
try:
|
|
146
|
+
whales = client.whales()
|
|
147
|
+
except AuthError:
|
|
148
|
+
print("Invalid or expired API key")
|
|
149
|
+
except RateLimitError:
|
|
150
|
+
print("Rate limit hit — slow down or upgrade tier")
|
|
151
|
+
except VeynorError as e:
|
|
152
|
+
print(f"API error {e.status_code}: {e}")
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
---
|
|
156
|
+
|
|
157
|
+
## Use in a Jupyter notebook
|
|
158
|
+
|
|
159
|
+
```python
|
|
160
|
+
import veynor, pandas as pd
|
|
161
|
+
|
|
162
|
+
client = veynor.Client()
|
|
163
|
+
data = client.whales(min_notional=15_000, limit=50)
|
|
164
|
+
df = pd.DataFrame(data["trades"])
|
|
165
|
+
df[["market", "side", "notional", "platform"]].sort_values("notional", ascending=False)
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
---
|
|
169
|
+
|
|
170
|
+
## Links
|
|
171
|
+
|
|
172
|
+
- [Register for an API key](https://veynor.xyz/agents)
|
|
173
|
+
- [MCP server](https://mcp.veynor.xyz) — connect directly from Claude Desktop or OpenClaw
|
|
174
|
+
- [Web app](https://veynor.xyz) — whale feed, smart money signals, trade interface
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=68", "wheel"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "veynor"
|
|
7
|
+
version = "1.0.0"
|
|
8
|
+
description = "Prediction market intelligence for agents and traders — Kalshi + Polymarket"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
license = { text = "MIT" }
|
|
11
|
+
authors = [{ name = "Veynor", email = "hello@veynor.xyz" }]
|
|
12
|
+
requires-python = ">=3.9"
|
|
13
|
+
keywords = ["prediction-markets", "kalshi", "polymarket", "finance", "trading", "quant"]
|
|
14
|
+
classifiers = [
|
|
15
|
+
"Development Status :: 4 - Beta",
|
|
16
|
+
"Intended Audience :: Developers",
|
|
17
|
+
"Intended Audience :: Financial and Insurance Industry",
|
|
18
|
+
"License :: OSI Approved :: MIT License",
|
|
19
|
+
"Programming Language :: Python :: 3",
|
|
20
|
+
"Programming Language :: Python :: 3.9",
|
|
21
|
+
"Programming Language :: Python :: 3.10",
|
|
22
|
+
"Programming Language :: Python :: 3.11",
|
|
23
|
+
"Programming Language :: Python :: 3.12",
|
|
24
|
+
"Topic :: Office/Business :: Financial",
|
|
25
|
+
"Topic :: Software Development :: Libraries :: Python Modules",
|
|
26
|
+
]
|
|
27
|
+
dependencies = ["requests>=2.28"]
|
|
28
|
+
|
|
29
|
+
[project.urls]
|
|
30
|
+
Homepage = "https://veynor.xyz"
|
|
31
|
+
Repository = "https://github.com/veynor/veynor-python"
|
|
32
|
+
"API Docs" = "https://veynor.xyz/agents"
|
|
33
|
+
|
|
34
|
+
[tool.setuptools.packages.find]
|
|
35
|
+
where = ["."]
|
|
36
|
+
include = ["veynor*"]
|
veynor-1.0.0/setup.cfg
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Veynor — prediction market intelligence for agents and traders.
|
|
3
|
+
|
|
4
|
+
pip install veynor
|
|
5
|
+
|
|
6
|
+
import veynor
|
|
7
|
+
client = veynor.Client(api_key="vey_sk_...")
|
|
8
|
+
whales = client.whales(venue="all", min_notional=10_000)
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
from .client import Client, VeynorError, AuthError, RateLimitError
|
|
12
|
+
|
|
13
|
+
__all__ = ["Client", "VeynorError", "AuthError", "RateLimitError"]
|
|
14
|
+
__version__ = "1.0.0"
|
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Veynor Python Client — prediction market intelligence for agents and traders.
|
|
3
|
+
|
|
4
|
+
pip install veynor
|
|
5
|
+
|
|
6
|
+
Usage:
|
|
7
|
+
import veynor
|
|
8
|
+
client = veynor.Client(api_key="vey_sk_...")
|
|
9
|
+
|
|
10
|
+
whales = client.whales(venue="all", min_notional=10_000)
|
|
11
|
+
markets = client.top_markets(limit=10)
|
|
12
|
+
arb = client.signals(signal_type="arb_opportunities")
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
from __future__ import annotations
|
|
16
|
+
|
|
17
|
+
import os
|
|
18
|
+
from typing import Any, Optional
|
|
19
|
+
|
|
20
|
+
import requests
|
|
21
|
+
from requests import Response
|
|
22
|
+
|
|
23
|
+
__all__ = ["Client", "VeynorError", "AuthError", "RateLimitError"]
|
|
24
|
+
|
|
25
|
+
_DEFAULT_BASE_URL = "https://api.veynor.xyz"
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
# ── Exceptions ─────────────────────────────────────────────────────────────────
|
|
29
|
+
|
|
30
|
+
class VeynorError(Exception):
|
|
31
|
+
"""Base exception for all Veynor errors."""
|
|
32
|
+
def __init__(self, message: str, status_code: Optional[int] = None):
|
|
33
|
+
super().__init__(message)
|
|
34
|
+
self.status_code = status_code
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
class AuthError(VeynorError):
|
|
38
|
+
"""Raised when the API key is missing, invalid, or over quota."""
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
class RateLimitError(VeynorError):
|
|
42
|
+
"""Raised when the per-minute request rate limit is exceeded."""
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
# ── Client ─────────────────────────────────────────────────────────────────────
|
|
46
|
+
|
|
47
|
+
class Client:
|
|
48
|
+
"""
|
|
49
|
+
Veynor REST API client.
|
|
50
|
+
|
|
51
|
+
Parameters
|
|
52
|
+
----------
|
|
53
|
+
api_key : str, optional
|
|
54
|
+
Your Veynor API key (``vey_sk_...``).
|
|
55
|
+
Falls back to the ``VEYNOR_API_KEY`` environment variable.
|
|
56
|
+
base_url : str, optional
|
|
57
|
+
Override the API base URL. Defaults to ``https://api.veynor.xyz``.
|
|
58
|
+
timeout : int, optional
|
|
59
|
+
Request timeout in seconds. Default: 20.
|
|
60
|
+
"""
|
|
61
|
+
|
|
62
|
+
def __init__(
|
|
63
|
+
self,
|
|
64
|
+
api_key: Optional[str] = None,
|
|
65
|
+
base_url: str = _DEFAULT_BASE_URL,
|
|
66
|
+
timeout: int = 20,
|
|
67
|
+
) -> None:
|
|
68
|
+
key = api_key or os.environ.get("VEYNOR_API_KEY")
|
|
69
|
+
if not key:
|
|
70
|
+
raise AuthError(
|
|
71
|
+
"No API key provided. Pass api_key= or set the VEYNOR_API_KEY "
|
|
72
|
+
"environment variable. Register at https://veynor.xyz/agents"
|
|
73
|
+
)
|
|
74
|
+
self._base_url = base_url.rstrip("/")
|
|
75
|
+
self._timeout = timeout
|
|
76
|
+
self._session = requests.Session()
|
|
77
|
+
self._session.headers.update({
|
|
78
|
+
"X-API-Key": key,
|
|
79
|
+
"Accept": "application/json",
|
|
80
|
+
"User-Agent": "veynor-python/1.0.0",
|
|
81
|
+
})
|
|
82
|
+
|
|
83
|
+
# ── Internal ───────────────────────────────────────────────────────────────
|
|
84
|
+
|
|
85
|
+
def _get(self, path: str, **params: Any) -> Any:
|
|
86
|
+
"""Make a GET request; raise typed exceptions on error."""
|
|
87
|
+
# Drop None values so optional params don't pollute the query string
|
|
88
|
+
clean = {k: v for k, v in params.items() if v is not None}
|
|
89
|
+
url = f"{self._base_url}{path}"
|
|
90
|
+
resp: Response = self._session.get(url, params=clean, timeout=self._timeout)
|
|
91
|
+
return self._handle(resp)
|
|
92
|
+
|
|
93
|
+
@staticmethod
|
|
94
|
+
def _handle(resp: Response) -> Any:
|
|
95
|
+
if resp.status_code == 200:
|
|
96
|
+
return resp.json()
|
|
97
|
+
try:
|
|
98
|
+
body = resp.json()
|
|
99
|
+
msg = body.get("error", resp.text)
|
|
100
|
+
except Exception:
|
|
101
|
+
msg = resp.text or f"HTTP {resp.status_code}"
|
|
102
|
+
|
|
103
|
+
if resp.status_code in (401, 403):
|
|
104
|
+
raise AuthError(msg, resp.status_code)
|
|
105
|
+
if resp.status_code == 429:
|
|
106
|
+
raise RateLimitError(msg, resp.status_code)
|
|
107
|
+
raise VeynorError(msg, resp.status_code)
|
|
108
|
+
|
|
109
|
+
# ── Public API ─────────────────────────────────────────────────────────────
|
|
110
|
+
|
|
111
|
+
def whales(
|
|
112
|
+
self,
|
|
113
|
+
*,
|
|
114
|
+
venue: str = "all",
|
|
115
|
+
min_notional: float = 8_000,
|
|
116
|
+
category: Optional[str] = None,
|
|
117
|
+
limit: int = 20,
|
|
118
|
+
) -> dict:
|
|
119
|
+
"""
|
|
120
|
+
Recent large trades across Kalshi and Polymarket.
|
|
121
|
+
|
|
122
|
+
Parameters
|
|
123
|
+
----------
|
|
124
|
+
venue : "all" | "kalshi" | "polymarket"
|
|
125
|
+
min_notional : float
|
|
126
|
+
Minimum trade size in USD (default 8000).
|
|
127
|
+
category : "All" | "Sports" | "Politics" | "Other", optional
|
|
128
|
+
limit : int
|
|
129
|
+
Max trades to return (1–60, default 20).
|
|
130
|
+
|
|
131
|
+
Returns
|
|
132
|
+
-------
|
|
133
|
+
dict with keys: summary, trades (list), meta
|
|
134
|
+
"""
|
|
135
|
+
return self._get(
|
|
136
|
+
"/v1/whale-trades",
|
|
137
|
+
platform=venue,
|
|
138
|
+
min_notional=min_notional,
|
|
139
|
+
category=category,
|
|
140
|
+
limit=limit,
|
|
141
|
+
)
|
|
142
|
+
|
|
143
|
+
def top_markets(
|
|
144
|
+
self,
|
|
145
|
+
*,
|
|
146
|
+
venue: str = "all",
|
|
147
|
+
category: Optional[str] = None,
|
|
148
|
+
limit: int = 10,
|
|
149
|
+
) -> dict:
|
|
150
|
+
"""
|
|
151
|
+
Top prediction markets by 24-hour volume.
|
|
152
|
+
|
|
153
|
+
Parameters
|
|
154
|
+
----------
|
|
155
|
+
venue : "all" | "kalshi" | "polymarket"
|
|
156
|
+
category : "All" | "Sports" | "Politics" | "Other", optional
|
|
157
|
+
limit : int
|
|
158
|
+
Max markets per platform (1–20, default 10).
|
|
159
|
+
|
|
160
|
+
Returns
|
|
161
|
+
-------
|
|
162
|
+
dict with keys: summary, kalshi (list), polymarket (list), meta
|
|
163
|
+
"""
|
|
164
|
+
return self._get(
|
|
165
|
+
"/v1/markets/top",
|
|
166
|
+
platform=venue,
|
|
167
|
+
category=category,
|
|
168
|
+
limit=limit,
|
|
169
|
+
)
|
|
170
|
+
|
|
171
|
+
def search(
|
|
172
|
+
self,
|
|
173
|
+
query: str,
|
|
174
|
+
*,
|
|
175
|
+
venue: str = "all",
|
|
176
|
+
limit: int = 10,
|
|
177
|
+
) -> dict:
|
|
178
|
+
"""
|
|
179
|
+
Search prediction markets by keyword across both venues.
|
|
180
|
+
|
|
181
|
+
Parameters
|
|
182
|
+
----------
|
|
183
|
+
query : str
|
|
184
|
+
E.g. "fed rate", "NBA finals", "Iran"
|
|
185
|
+
venue : "all" | "kalshi" | "polymarket"
|
|
186
|
+
limit : int
|
|
187
|
+
|
|
188
|
+
Returns
|
|
189
|
+
-------
|
|
190
|
+
dict with keys: summary, polymarket (list), kalshi (list), meta
|
|
191
|
+
"""
|
|
192
|
+
return self._get("/v1/markets/search", q=query, platform=venue, limit=limit)
|
|
193
|
+
|
|
194
|
+
def market(self, venue: str, market_id: str) -> dict:
|
|
195
|
+
"""
|
|
196
|
+
Full details for a specific market.
|
|
197
|
+
|
|
198
|
+
Parameters
|
|
199
|
+
----------
|
|
200
|
+
venue : "polymarket" | "kalshi"
|
|
201
|
+
market_id : str
|
|
202
|
+
Polymarket condition ID (0x...) or Kalshi ticker (e.g. KXNBA-...).
|
|
203
|
+
|
|
204
|
+
Returns
|
|
205
|
+
-------
|
|
206
|
+
dict with keys: summary, market (full object), meta
|
|
207
|
+
"""
|
|
208
|
+
return self._get(f"/v1/markets/{venue}/{market_id}")
|
|
209
|
+
|
|
210
|
+
def signals(
|
|
211
|
+
self,
|
|
212
|
+
*,
|
|
213
|
+
signal_type: str = "all",
|
|
214
|
+
limit: int = 10,
|
|
215
|
+
) -> dict:
|
|
216
|
+
"""
|
|
217
|
+
Alpha-generating signals: wide spreads, price movers, arb opportunities.
|
|
218
|
+
|
|
219
|
+
Parameters
|
|
220
|
+
----------
|
|
221
|
+
signal_type : "all" | "wide_spreads" | "price_movers" | "arb_opportunities"
|
|
222
|
+
limit : int
|
|
223
|
+
Max results per signal type (1–20, default 10).
|
|
224
|
+
|
|
225
|
+
Returns
|
|
226
|
+
-------
|
|
227
|
+
dict with keys: summary, wide_spreads, price_movers, arb_opportunities, meta
|
|
228
|
+
"""
|
|
229
|
+
return self._get("/v1/signals", signal_type=signal_type, limit=limit)
|
|
230
|
+
|
|
231
|
+
def usage(self) -> dict:
|
|
232
|
+
"""
|
|
233
|
+
Current credit usage, tier, and quota. Always free.
|
|
234
|
+
|
|
235
|
+
Returns
|
|
236
|
+
-------
|
|
237
|
+
dict with keys: summary, tier, credits_used, credits_remaining, total_calls, tool_costs
|
|
238
|
+
"""
|
|
239
|
+
return self._get("/v1/usage")
|
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: veynor
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: Prediction market intelligence for agents and traders — Kalshi + Polymarket
|
|
5
|
+
Author-email: Veynor <hello@veynor.xyz>
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://veynor.xyz
|
|
8
|
+
Project-URL: Repository, https://github.com/veynor/veynor-python
|
|
9
|
+
Project-URL: API Docs, https://veynor.xyz/agents
|
|
10
|
+
Keywords: prediction-markets,kalshi,polymarket,finance,trading,quant
|
|
11
|
+
Classifier: Development Status :: 4 - Beta
|
|
12
|
+
Classifier: Intended Audience :: Developers
|
|
13
|
+
Classifier: Intended Audience :: Financial and Insurance Industry
|
|
14
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
20
|
+
Classifier: Topic :: Office/Business :: Financial
|
|
21
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
22
|
+
Requires-Python: >=3.9
|
|
23
|
+
Description-Content-Type: text/markdown
|
|
24
|
+
Requires-Dist: requests>=2.28
|
|
25
|
+
|
|
26
|
+
# veynor
|
|
27
|
+
|
|
28
|
+
Python client for the [Veynor](https://veynor.xyz) prediction market intelligence API.
|
|
29
|
+
|
|
30
|
+
Cross-venue data across Kalshi and Polymarket: whale trades, smart money signals, arb opportunities, and market search — in a single `import`.
|
|
31
|
+
|
|
32
|
+
```python
|
|
33
|
+
pip install veynor
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
---
|
|
37
|
+
|
|
38
|
+
## Quickstart
|
|
39
|
+
|
|
40
|
+
```python
|
|
41
|
+
import veynor
|
|
42
|
+
|
|
43
|
+
client = veynor.Client(api_key="vey_sk_...")
|
|
44
|
+
|
|
45
|
+
# Whale trades across both venues
|
|
46
|
+
whales = client.whales(venue="all", min_notional=10_000)
|
|
47
|
+
for t in whales["trades"]:
|
|
48
|
+
print(t["platform"], t["market"], t["side"], f"${t['notional']:,.0f}")
|
|
49
|
+
|
|
50
|
+
# Arb opportunities between Kalshi and Polymarket
|
|
51
|
+
arb = client.signals(signal_type="arb_opportunities")
|
|
52
|
+
for opp in arb["arb_opportunities"]:
|
|
53
|
+
print(opp)
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
Get a free API key at [veynor.xyz/agents](https://veynor.xyz/agents).
|
|
57
|
+
|
|
58
|
+
---
|
|
59
|
+
|
|
60
|
+
## Authentication
|
|
61
|
+
|
|
62
|
+
Pass your key directly or via environment variable:
|
|
63
|
+
|
|
64
|
+
```python
|
|
65
|
+
# Option 1: direct
|
|
66
|
+
client = veynor.Client(api_key="vey_sk_...")
|
|
67
|
+
|
|
68
|
+
# Option 2: environment variable
|
|
69
|
+
# export VEYNOR_API_KEY=vey_sk_...
|
|
70
|
+
client = veynor.Client()
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
---
|
|
74
|
+
|
|
75
|
+
## Methods
|
|
76
|
+
|
|
77
|
+
### `client.whales()`
|
|
78
|
+
|
|
79
|
+
Recent large trades across Kalshi and Polymarket.
|
|
80
|
+
|
|
81
|
+
```python
|
|
82
|
+
whales = client.whales(
|
|
83
|
+
venue="all", # "all" | "kalshi" | "polymarket"
|
|
84
|
+
min_notional=8_000, # minimum trade size in USD
|
|
85
|
+
category="Politics", # "All" | "Sports" | "Politics" | "Other"
|
|
86
|
+
limit=20,
|
|
87
|
+
)
|
|
88
|
+
# Returns: { summary, trades: [...], meta }
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
### `client.top_markets()`
|
|
92
|
+
|
|
93
|
+
Top markets by 24-hour volume.
|
|
94
|
+
|
|
95
|
+
```python
|
|
96
|
+
markets = client.top_markets(
|
|
97
|
+
venue="all",
|
|
98
|
+
category="All",
|
|
99
|
+
limit=10,
|
|
100
|
+
)
|
|
101
|
+
# Returns: { summary, kalshi: [...], polymarket: [...], meta }
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
### `client.search()`
|
|
105
|
+
|
|
106
|
+
Search markets by keyword across both venues.
|
|
107
|
+
|
|
108
|
+
```python
|
|
109
|
+
results = client.search("fed rate", venue="all", limit=10)
|
|
110
|
+
# Returns: { summary, polymarket: [...], kalshi: [...], meta }
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
### `client.market()`
|
|
114
|
+
|
|
115
|
+
Full details for a specific market.
|
|
116
|
+
|
|
117
|
+
```python
|
|
118
|
+
# Polymarket: use condition ID
|
|
119
|
+
m = client.market("polymarket", "0x1234...")
|
|
120
|
+
|
|
121
|
+
# Kalshi: use ticker
|
|
122
|
+
m = client.market("kalshi", "KXNBA-25-LAL")
|
|
123
|
+
|
|
124
|
+
# Returns: { summary, market: {...}, meta }
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
### `client.signals()`
|
|
128
|
+
|
|
129
|
+
Alpha signals: wide spreads, price movers, cross-venue arb.
|
|
130
|
+
|
|
131
|
+
```python
|
|
132
|
+
signals = client.signals(
|
|
133
|
+
signal_type="all", # "all" | "wide_spreads" | "price_movers" | "arb_opportunities"
|
|
134
|
+
limit=10,
|
|
135
|
+
)
|
|
136
|
+
# Returns: { summary, wide_spreads, price_movers, arb_opportunities, meta }
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
### `client.usage()`
|
|
140
|
+
|
|
141
|
+
Check your credit balance. Always free.
|
|
142
|
+
|
|
143
|
+
```python
|
|
144
|
+
u = client.usage()
|
|
145
|
+
print(u["tier"], u["credits_remaining"])
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
---
|
|
149
|
+
|
|
150
|
+
## Credit costs
|
|
151
|
+
|
|
152
|
+
| Method | Credits |
|
|
153
|
+
|-----------------|---------|
|
|
154
|
+
| `whales()` | 2 |
|
|
155
|
+
| `top_markets()` | 1 |
|
|
156
|
+
| `search()` | 1 |
|
|
157
|
+
| `market()` | 1 |
|
|
158
|
+
| `signals()` | 3 |
|
|
159
|
+
| `usage()` | 0 |
|
|
160
|
+
|
|
161
|
+
Free tier: 100 credits/month. Upgrade at [veynor.xyz/agents](https://veynor.xyz/agents).
|
|
162
|
+
|
|
163
|
+
---
|
|
164
|
+
|
|
165
|
+
## Exceptions
|
|
166
|
+
|
|
167
|
+
```python
|
|
168
|
+
from veynor import VeynorError, AuthError, RateLimitError
|
|
169
|
+
|
|
170
|
+
try:
|
|
171
|
+
whales = client.whales()
|
|
172
|
+
except AuthError:
|
|
173
|
+
print("Invalid or expired API key")
|
|
174
|
+
except RateLimitError:
|
|
175
|
+
print("Rate limit hit — slow down or upgrade tier")
|
|
176
|
+
except VeynorError as e:
|
|
177
|
+
print(f"API error {e.status_code}: {e}")
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
---
|
|
181
|
+
|
|
182
|
+
## Use in a Jupyter notebook
|
|
183
|
+
|
|
184
|
+
```python
|
|
185
|
+
import veynor, pandas as pd
|
|
186
|
+
|
|
187
|
+
client = veynor.Client()
|
|
188
|
+
data = client.whales(min_notional=15_000, limit=50)
|
|
189
|
+
df = pd.DataFrame(data["trades"])
|
|
190
|
+
df[["market", "side", "notional", "platform"]].sort_values("notional", ascending=False)
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
---
|
|
194
|
+
|
|
195
|
+
## Links
|
|
196
|
+
|
|
197
|
+
- [Register for an API key](https://veynor.xyz/agents)
|
|
198
|
+
- [MCP server](https://mcp.veynor.xyz) — connect directly from Claude Desktop or OpenClaw
|
|
199
|
+
- [Web app](https://veynor.xyz) — whale feed, smart money signals, trade interface
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
requests>=2.28
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
veynor
|