Quickstart
Send a portfolio. Get named factor exposures.
Mint a key, then POST positions. Creo returns beta, size, 12–1 momentum, low volatility and liquidity, plus risk contribution, methodology version, timestamps, coverage and quality flags. You bring prices; Creo sells compute.
Agents: read /llms.txt, /openapi.json
or connect the MCP server at https://itscreo.com/mcp.
Try it without a key
The demo is keyless.
The five SYNTH.* tickers are labeled synthetic series. Score them with no
key and no prices, 20 calls a day per IP.
curl -s https://itscreo.com/v1/demo/exposures
Python
Mint a key once, then reuse it.
Needs pip install httpx. The first run mints a key and prints
export CREO_KEY=…; run that line so later runs reuse the key. Each IP can
mint 5 keys a day. Lost one? Paste a key you have at /account.
# pip install httpx
import os
import httpx
origin = "https://itscreo.com"
key = os.environ.get("CREO_KEY")
if not key: # mint once, then reuse: minting is limited to 5 keys per IP per day
minted = httpx.post(f"{origin}/v1/keys", json={})
minted.raise_for_status()
key = minted.json()["key"]
print(f"export CREO_KEY={key}")
r = httpx.post(
f"{origin}/v1/portfolio/exposures",
headers={"x-api-key": key},
json={
"positions": [
{"ticker": "SYNTH.MOM", "quantity": 10},
{"ticker": "SYNTH.DEF", "quantity": -5},
],
"cash": 2000,
},
)
r.raise_for_status()
for exposure in r.json()["exposures"]:
print(exposure["factor_id"], exposure["value"])
TypeScript
Same contract.
Save it as creo.mjs and run node creo.mjs (Node 18 or newer).
// Save as creo.mjs and run: node creo.mjs (Node 18+; .mjs allows top-level await)
const origin = "https://itscreo.com";
let key = process.env.CREO_KEY;
if (!key) { // mint once, then reuse: minting is limited to 5 keys per IP per day
const minted = await fetch(`${origin}/v1/keys`, {
method: "POST",
headers: { "content-type": "application/json" },
body: "{}",
});
if (!minted.ok) throw new Error(await minted.text());
key = (await minted.json()).key;
console.log(`export CREO_KEY=${key}`);
}
const res = await fetch(`${origin}/v1/portfolio/exposures`, {
method: "POST",
headers: { "content-type": "application/json", "x-api-key": key },
body: JSON.stringify({
positions: [
{ ticker: "SYNTH.MOM", quantity: 10 },
{ ticker: "SYNTH.DEF", quantity: -5 },
],
cash: 2000,
}),
});
if (!res.ok) throw new Error(await res.text());
for (const e of (await res.json()).exposures) console.log(e.factor_id, e.value);
MCP
Connect your agent.
Hosted MCP server at https://itscreo.com/mcp. Send your key as the
x-api-key header. Only successful scoring costs a credit; connecting,
listing tools and errors are free. Clients that browse the
official MCP Registry
can install it as com.itscreo/creo.
Claude Code
claude mcp add --transport http creo https://itscreo.com/mcp --header "x-api-key: $CREO_KEY"
Cursor · ~/.cursor/mcp.json
{
"mcpServers": {
"creo": {
"url": "https://itscreo.com/mcp",
"headers": { "x-api-key": "creo_..." }
}
}
}
Codex · ~/.codex/config.toml
[mcp_servers.creo]
url = "https://itscreo.com/mcp"
http_headers = { "x-api-key" = "creo_..." }
No key yet? Connect without the header: the scoring tools work keyless on
SYNTH.* tickers. mint_api_key returns a key you can pass as
the api_key tool argument for the rest of that session.
Your own book
Real tickers need your prices.
Send daily closes for each position. Add volume for liquidity,
market_cap for size and a benchmark series for beta. Without
them those factors come back null with a reason, never zero. A real ticker without
history is a 422 PRICES_REQUIRED, and it is not charged. Beta and momentum
need 253 daily closes, low volatility 61 and liquidity 64 (with volume); size needs only
market_cap. /llms.txt lists every factor's minimum. Numbers can be JSON numbers or strings.
{
"positions": [
{
"ticker": "AAPL",
"quantity": "100",
"market_cap": "3400000000000",
"history": [{ "date": "2026-11-05", "close": "227.10", "volume": "48100000" }, "..."]
}
],
"benchmark": { "history": [{ "date": "2026-11-05", "close": "6012.4" }, "..."] }
}
Crypto
Crypto gets its own sleeve.
Mark each position "asset_class": "crypto" and send every calendar day
from your own exchange account or feed, with volume in coin units. Beta
and momentum need 181 days, low volatility 21 and liquidity 31. Equity and crypto
exposures are never added together; for clean numbers, score crypto in its own request
with a BTC benchmark. A mixed book with one benchmark gets a
BENCHMARK_SHARED_ACROSS_SLEEVES warning.
{
"positions": [
{ "ticker": "BTC", "asset_class": "crypto", "quantity": 0.5,
"history": [{ "date": "2026-11-07", "close": "76050.12", "volume": "18300" }, "..."] },
{ "ticker": "SOL", "asset_class": "crypto", "quantity": -60, "history": ["..."] }
],
"benchmark": { "ticker": "BTC", "history": [{ "date": "2026-11-07", "close": "76050.12" }, "..."] },
"cash": 20000
}
Fundamentals
Value and quality from SEC filings.
Add any *.sec factor to factors and Creo reads the issuer's
10-K filings on SEC EDGAR for book-to-price, asset growth, gross profitability and
return on assets. You only send a recent close. Only filings made on or before
valid_at count, and every value is traced in sec_sources
with its accession number. Issuers with several share classes, such as GOOGL, need
market_cap for book-to-price.
{
"positions": [
{ "ticker": "AAPL", "quantity": 100, "history": [{ "date": "2026-11-06", "close": "268.47" }] }
],
"factors": ["equity.value.book_to_price.sec", "equity.quality.return_on_assets.sec"]
}