Python API Client
This page provides auto-generated documentation from the client library's docstrings.
crowdcent_challenge.client.ChallengeClient
Bases: DataAPI, SubmissionsAPI, SimulatorAPI, TradingAPI, BaseClient
Client for interacting with a specific CrowdCent Challenge.
Handles authentication and provides methods for accessing challenge data, training datasets, inference data, and managing prediction submissions for a specific challenge identified by its slug — plus meta-model simulation and live trading (staff preview until Trading GA).
Source code in src/crowdcent_challenge/client/__init__.py
__init__(challenge_slug, api_key=None, base_url=None)
Initializes the ChallengeClient for a specific challenge.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
challenge_slug
|
str
|
The unique identifier (slug) for the challenge. |
required |
api_key
|
Optional[str]
|
Your CrowdCent API key. If not provided, it will attempt to load from the CROWDCENT_API_KEY environment variable or a .env file. |
None
|
base_url
|
Optional[str]
|
The base URL of the CrowdCent API. Defaults to https://crowdcent.com/api. |
None
|
Source code in src/crowdcent_challenge/client/base.py
list_all_challenges(api_key=None, base_url=None)
classmethod
Lists all active challenges.
This is a class method that doesn't require a challenge_slug. Use this to discover available challenges before initializing a ChallengeClient.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
api_key
|
Optional[str]
|
Your CrowdCent API key. If not provided, it will attempt to load from the CROWDCENT_API_KEY environment variable or a .env file. |
None
|
base_url
|
Optional[str]
|
The base URL of the CrowdCent API. Defaults to http://crowdcent.com/api. |
None
|
Returns:
| Type | Description |
|---|---|
List[Dict[str, Any]]
|
A list of dictionaries, each representing an active challenge. |
Source code in src/crowdcent_challenge/client/base.py
switch_challenge(new_challenge_slug)
Switch this client to interact with a different challenge.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
new_challenge_slug
|
str
|
The slug identifier for the new challenge. |
required |
Returns:
| Type | Description |
|---|---|
None
|
None. The client is modified in-place. |
Source code in src/crowdcent_challenge/client/base.py
check_auth()
Checks the presenting API key and reports its capabilities.
A cheap validity probe: use it to fail fast at startup, or to decide whether trading features should be surfaced at all.
Returns:
| Type | Description |
|---|---|
Dict[str, Any]
|
A dictionary with:
- |
Raises:
| Type | Description |
|---|---|
AuthenticationError
|
If the key is invalid or revoked. |
Source code in src/crowdcent_challenge/client/base.py
get_trading_accounts()
Lists your Hyperliquid trading accounts (both networks).
Returns only safe fields (status, can_trade, master_address,
agent_expires_at, builder_approved, network) — key material
never traverses the API.
Source code in src/crowdcent_challenge/client/trading.py
get_mandate(network='testnet')
Gets the mandate (execution policy + weighted sleeves) for this challenge on the given network.
Raises:
| Type | Description |
|---|---|
NotFoundError
|
|
Source code in src/crowdcent_challenge/client/trading.py
set_mandate(mandate, network='testnet')
Creates or fully replaces the mandate for this challenge/network.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
mandate
|
Dict[str, Any]
|
|
required |
network
|
str
|
"testnet" (default) or "mainnet". |
'testnet'
|
Returns:
| Type | Description |
|---|---|
Dict[str, Any]
|
The saved mandate, same shape as |
Source code in src/crowdcent_challenge/client/trading.py
get_target_book(network='testnet')
Gets the blended target book the mandate's sleeves currently
resolve to: target holdings, as_of ranking day, and per-sleeve
books.
Source code in src/crowdcent_challenge/client/trading.py
preview_rebalance(network='testnet')
Plans a rebalance WITHOUT executing (dry run, persisted for audit).
Returns the full plan (trades, skipped_trades, gross,
turnover, est_fees) plus run_id and plan_hash — show the
plan to the user, get their explicit confirmation, then pass the
hash to meth:
execute_rebalance within 10 minutes.
Source code in src/crowdcent_challenge/client/trading.py
execute_rebalance(plan_hash, network='testnet')
Executes a LIVE rebalance on your Hyperliquid account.
Real orders; real money on mainnet. Requires a fresh (<10 min)
preview's plan_hash as consent evidence, else the server answers
409 CONFIRMATION_REQUIRED. Execution re-plans fresh, so fills may
differ slightly from the preview; the gross cap, minimum notional,
and stale-book guards always bind server-side.
Raises:
| Type | Description |
|---|---|
ClientError
|
|
Source code in src/crowdcent_challenge/client/trading.py
flatten(plan_hash=None, *, preview=False, network='testnet')
Closes every position (full liquidation) — two-step like rebalancing.
Call with preview=True first to get the flatten plan and its
plan_hash; then call again with that hash to execute. Flatten
hashes are kind-scoped: a rebalance preview's hash never authorizes
a flatten.
Source code in src/crowdcent_challenge/client/trading.py
pause_trading(network='testnet')
Pauses the mandate (scheduled trading off). Works with ANY valid key — killing risk is never blocked by the trading scope.
Source code in src/crowdcent_challenge/client/trading.py
resume_trading(network='testnet')
Resumes the mandate (scheduled trading on). Requires a trade-enabled key — re-enabling risk is a trading action.
Source code in src/crowdcent_challenge/client/trading.py
list_rebalance_runs(limit=10, network='testnet')
Lists recent rebalance runs (the audit trail): kind, status, release_date, result summary, error. The morning-briefing feed.
Source code in src/crowdcent_challenge/client/trading.py
list_orders(status=None, network='testnet')
Lists blotter orders, newest first, optionally filtered by status (resting, filled, twap_running, ...).
Source code in src/crowdcent_challenge/client/trading.py
get_simulator_capabilities()
Gets the simulator knob vocabulary for YOUR tier.
Call this before building simulation configs: it lists the allowed values per knob for the presenting key's points tier, the sweep and blend budgets, the available data range, and which features are sealed behind higher tiers.
Returns:
| Type | Description |
|---|---|
Dict[str, Any]
|
A dictionary with |
Dict[str, Any]
|
knob), |
Dict[str, Any]
|
|
Source code in src/crowdcent_challenge/client/simulator.py
run_simulation(config=None, *, config_token=None, include=None, benchmark_trials=0)
Backtests one portfolio configuration on the live meta-model.
Runs the exact engine behind the site's Simulation tab: the simulator trades the meta-model's published rankings as a long/short portfolio with your chosen construction knobs (cohort sizes, rebalance cadence, weighting scheme, fees, funding, ...).
Knobs above your tier are silently clamped to their accessible
values, identical to the web UI. Check the echoed config and the
locked list in the response to see what was clamped.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
config
|
Optional[Dict[str, Any]]
|
SimulationConfig field names with JSON scalars, e.g.
|
None
|
config_token
|
Optional[str]
|
Alternatively, a compact config token from a
previous response or a site URL — reproduces that exact
config. Mutually exclusive with |
None
|
include
|
Optional[List[str]]
|
Optional extras: any of |
None
|
benchmark_trials
|
int
|
0, 25, or 100 — score the signal against that many random-ranking portfolios with identical construction. |
0
|
Returns:
| Type | Description |
|---|---|
Dict[str, Any]
|
A dictionary with the clamped |
Dict[str, Any]
|
|
Dict[str, Any]
|
config), |
Dict[str, Any]
|
plus any |
Example
Source code in src/crowdcent_challenge/client/simulator.py
run_sweep(config, sweep, *, on_chunk=None)
Grid-searches portfolio configurations on the meta-model.
The server runs one cost-bounded chunk per request; this method
loops offset -> next_offset transparently until the whole grid
has run, so you always get the complete result set back.
How to read a sweep: plateaus, not peaks. A lone bright cell is
luck; a bright region is structure. Prefer configurations whose
neighbors also perform, and weight out-of-sample stats (oos_stats)
over in-sample when picking a candidate.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
config
|
Dict[str, Any]
|
The base configuration (same vocabulary as
|
required |
sweep
|
Dict[str, List[Any]]
|
Mapping of sweepable knob -> list of values, e.g.
|
required |
on_chunk
|
Optional[Callable[[List[Dict[str, Any]], int], None]]
|
Optional callable |
None
|
Returns:
| Type | Description |
|---|---|
Dict[str, Any]
|
A dictionary with |
Dict[str, Any]
|
(in deterministic grid order), each holding |
Dict[str, Any]
|
|
Dict[str, Any]
|
or an |
Raises:
| Type | Description |
|---|---|
ClientError
|
|
Source code in src/crowdcent_challenge/client/simulator.py
run_blend(sleeves)
Blends weighted sleeves into one ensemble book and evaluates it.
Each sleeve runs once and the weighted blend is formed on date-aligned daily returns. Fail-closed: any sleeve error fails the whole blend. Sleeve count is capped by tier (5 at Contender, 3 below).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
sleeves
|
List[Dict[str, Any]]
|
A list of |
required |
Returns:
| Type | Description |
|---|---|
Dict[str, Any]
|
A dictionary with blend |
Dict[str, Any]
|
sleeve |
Dict[str, Any]
|
the aligned window so they are directly comparable). |
Source code in src/crowdcent_challenge/client/simulator.py
list_submissions(period=None)
Lists the authenticated user's submissions for this challenge.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
period
|
Optional[str]
|
Optional filter for submissions by period: - 'current': Only show submissions for the current active period - 'YYYY-MM-DD': Only show submissions for a specific inference period date |
None
|
Returns:
| Type | Description |
|---|---|
List[Dict[str, Any]]
|
A list of dictionaries, each representing a submission. |
Source code in src/crowdcent_challenge/client/submissions.py
get_submission(submission_id)
Gets details for a specific submission by its ID.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
submission_id
|
int
|
The ID of the submission to retrieve. |
required |
Returns:
| Type | Description |
|---|---|
Dict[str, Any]
|
A dictionary representing the specified submission. |
Raises:
| Type | Description |
|---|---|
NotFoundError
|
If the submission with the given ID is not found or doesn't belong to the user. |
Source code in src/crowdcent_challenge/client/submissions.py
submit_predictions(file_path='submission.parquet', df=None, slot=1, queue_next=True, temp=True, max_retries=3, retry_delay=1.0, is_experimental=False, notes='')
Submit predictions for this challenge.
If a submission window is currently open, the prediction is submitted immediately. If no window is open, the prediction is queued and will be automatically submitted when the next window opens.
You can provide either a file path to an existing Parquet file or a DataFrame that will be temporarily saved as Parquet for submission.
The data must contain the required prediction columns specified by the challenge (e.g., id, pred_10d, pred_30d).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
file_path
|
str
|
Optional path to an existing prediction Parquet file. |
'submission.parquet'
|
df
|
Optional[IntoFrameT]
|
Optional DataFrame with the prediction columns. If provided, it will be temporarily saved as Parquet for submission. |
None
|
slot
|
int
|
Submission slot number (1-based). |
1
|
queue_next
|
bool
|
Whether to also queue this submission for the next period (auto-rollover). Defaults to True. When submitting during an open window, this queues a copy for the following period. |
True
|
temp
|
bool
|
Whether to save the DataFrame to a temporary file. |
True
|
max_retries
|
int
|
Maximum number of retry attempts for connection errors (default: 3). |
3
|
retry_delay
|
float
|
Initial delay between retries in seconds (default: 1.0). |
1.0
|
is_experimental
|
bool
|
Mark this submission as experimental. Experimental submissions are scored normally and receive a shadow percentile against the non-experimental competitive field, but are excluded from the leaderboard, the meta-model, and CC Points performance adjustment. Constraint: at least one slot per period must have a non-experimental submission; submitting experimental without a non-experimental sibling in another slot is rejected. Defaults to False. |
False
|
notes
|
str
|
Free-text annotation for this submission, max 2000 characters. Notes are private to the submission owner. Defaults to "". |
''
|
Returns:
| Type | Description |
|---|---|
Dict[str, Any]
|
A dictionary with submission details. The shape depends on context: |
Dict[str, Any]
|
|
Dict[str, Any]
|
|
Raises:
| Type | Description |
|---|---|
ValueError
|
If neither file_path nor df is provided, or if both are provided. |
FileNotFoundError
|
If the specified file_path does not exist. |
ClientError
|
If the submission is invalid (e.g., wrong format, missing columns, experimental constraint violated). |
Examples:
Submit from a DataFrame
client.submit_predictions(df=predictions_df)
Submit from a file
client.submit_predictions(file_path="predictions.parquet")
Submit and opt-out of auto-queueing for next period
client.submit_predictions(df=predictions_df, queue_next=False)
Submit an experimental prediction with a note
client.submit_predictions( df=predictions_df, slot=2, is_experimental=True, notes="2-layer transformer w/ sector embeddings", )
Source code in src/crowdcent_challenge/client/submissions.py
56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 | |
get_performance(user=None, scored_only=True, slot=None)
Get performance history for a user (defaults to authenticated user).
Fetches submissions with their scores and percentiles, flattens the nested score data, and returns a list ready to wrap in pandas/polars.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
user
|
Optional[str]
|
Username to fetch performance for. If None (default), fetches performance for the authenticated user. Note: Fetching other users' performance is not yet supported. |
None
|
scored_only
|
bool
|
If True (default), only include submissions that have been scored. For pending submissions, only the most recent (partially resolved) score is available — daily granularity is not currently exposed by the API. |
True
|
slot
|
Optional[int]
|
Optional slot filter. If provided, only include submissions from this slot. |
None
|
Returns:
| Type | Description |
|---|---|
List[Dict[str, Any]]
|
A list of dictionaries, each containing: |
List[Dict[str, Any]]
|
|
List[Dict[str, Any]]
|
|
List[Dict[str, Any]]
|
|
List[Dict[str, Any]]
|
|
List[Dict[str, Any]]
|
|
List[Dict[str, Any]]
|
|
List[Dict[str, Any]]
|
|
List[Dict[str, Any]]
|
|
List[Dict[str, Any]]
|
|
List[Dict[str, Any]]
|
|
Note
-
For submissions with status="pending", scores reflect the most recent partial evaluation (e.g., day 5 of a 10-day prediction). Daily score progression is tracked server-side but not yet available via the API.
-
Percentile fields (e.g., composite_percentile=0.75) indicate rank relative to all participants — 0.75 means outperforming 75% of submissions for that period.
-
Experimental submissions are included in the result. They are scored against the non-experimental competitive field (shadow percentiles) but excluded from leaderboards, the meta-model, and CC Points performance adjustment. Filter them out client-side if you want only competitive history:
[r for r in rows if not r["is_experimental"]].
Example
client = ChallengeClient("momentum-alpha") history = client.get_performance() import pandas as pd df = pd.DataFrame(history)
Source code in src/crowdcent_challenge/client/submissions.py
206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 | |
get_challenge()
Gets details for this challenge.
Returns:
| Type | Description |
|---|---|
Dict[str, Any]
|
A dictionary representing this challenge. |
Raises:
| Type | Description |
|---|---|
NotFoundError
|
If the challenge with the given slug is not found. |
Source code in src/crowdcent_challenge/client/data.py
list_training_datasets()
Lists all training dataset versions for this challenge.
Returns:
| Type | Description |
|---|---|
List[Dict[str, Any]]
|
A list of dictionaries, each representing a training dataset version. |
Raises:
| Type | Description |
|---|---|
NotFoundError
|
If the challenge is not found. |
Source code in src/crowdcent_challenge/client/data.py
get_training_dataset(version)
Gets details for a specific training dataset version.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
version
|
str
|
The version string of the training dataset (e.g., '1.0', '2.1')
or the special value |
required |
Returns:
| Type | Description |
|---|---|
Dict[str, Any]
|
A dictionary representing the specified training dataset. |
Raises:
| Type | Description |
|---|---|
NotFoundError
|
If the challenge or the specified training dataset is not found. |
Source code in src/crowdcent_challenge/client/data.py
download_training_dataset(version, dest_path)
Downloads the training data file for a specific dataset version.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
version
|
str
|
The version string of the training dataset (e.g., '1.0', '2.1') or 'latest' to get the latest version. |
required |
dest_path
|
str
|
The local file path to save the downloaded dataset. |
required |
Raises:
| Type | Description |
|---|---|
NotFoundError
|
If the challenge, dataset, or its file is not found. |
Source code in src/crowdcent_challenge/client/data.py
list_inference_data()
Lists all inference data periods for this challenge.
Returns:
| Type | Description |
|---|---|
List[Dict[str, Any]]
|
A list of dictionaries, each representing an inference data period. |
Raises:
| Type | Description |
|---|---|
NotFoundError
|
If the challenge is not found. |
Source code in src/crowdcent_challenge/client/data.py
get_inference_data(release_date)
Gets details for a specific inference data period by its release date.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
release_date
|
str
|
The release date of the inference data in 'YYYY-MM-DD' format.
You can also pass the special values:
- |
required |
Returns:
| Type | Description |
|---|---|
Dict[str, Any]
|
A dictionary representing the specified inference data period. |
Raises:
| Type | Description |
|---|---|
NotFoundError
|
If the challenge or the specified inference data is not found. |
ClientError
|
If the date format is invalid. |
Source code in src/crowdcent_challenge/client/data.py
download_inference_data(release_date, dest_path, poll=True, poll_interval=30, timeout=900)
Downloads the inference features file for a specific period.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
release_date
|
str
|
The release date of the inference data in 'YYYY-MM-DD' format
or the special values |
required |
dest_path
|
str
|
The local file path to save the downloaded features file. |
required |
poll
|
bool
|
Whether to wait for the inference data to be available before downloading. |
True
|
poll_interval
|
int
|
Seconds to wait between retries when polling. |
30
|
timeout
|
Optional[int]
|
Maximum seconds to wait before raising :class: |
900
|
Raises:
| Type | Description |
|---|---|
NotFoundError
|
If the challenge, inference data, or its file is not found. |
ClientError
|
If the date format is invalid. |
Source code in src/crowdcent_challenge/client/data.py
wait_for_inference_data(dest_path, poll_interval=30, timeout=900)
Waits for the current inference data release to appear and downloads it.
The internal data-generation pipeline begins around 14:00 UTC, but the
public inference file becomes available only after it passes data-quality
checks. This helper repeatedly calls
meth:
download_inference_data with release_date="current" until
the file is ready (HTTP 404s are silently retried).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
dest_path
|
str
|
Local path where the parquet file will be saved once available. |
required |
poll_interval
|
int
|
Seconds to wait between retries. |
30
|
timeout
|
Optional[int]
|
Maximum seconds to wait before raising :class: |
900
|
Raises:
| Type | Description |
|---|---|
TimeoutError
|
If timeout seconds pass without a successful download. |
CrowdCentAPIError
|
For unrecoverable errors returned by the API. |
Source code in src/crowdcent_challenge/client/data.py
download_meta_model(dest_path)
Downloads the consolidated meta-model file for this challenge.
The meta-model is typically an aggregation (e.g., average) of all valid submissions for past inference periods.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
dest_path
|
str
|
The local file path to save the downloaded meta-model. |
required |
Raises:
| Type | Description |
|---|---|
NotFoundError
|
If the challenge or its meta-model file is not found. |
CrowdCentAPIError
|
For issues during download or file writing. |
PermissionDenied
|
If the meta-model is not public and user lacks permission. |
Source code in src/crowdcent_challenge/client/data.py
get_training_dataset_url(version)
Returns a signed, time-limited download URL for a training dataset.
The URL twin of meth:
download_training_dataset for callers
without a local filesystem (hosted agents): fetch it yourself with
any HTTP client.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
version
|
str
|
The version string, or |
required |
Source code in src/crowdcent_challenge/client/data.py
get_inference_data_url(release_date)
Returns a signed, time-limited download URL for inference features.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
release_date
|
str
|
|
required |
Source code in src/crowdcent_challenge/client/data.py
get_meta_model_url()
Returns a signed, time-limited download URL for the consolidated meta-model file.