curl command and the equivalent Python snippet using the
requests library.
What you’ll build
- Authenticate and smoke-test the connection.
- Browse premade strategies and your own strategies.
- Look up companies by ticker.
- Create a strategy from an objective, submit it, and poll until it’s ready.
- Fetch the strategy’s companies and a constructed portfolio with weights.
- Backtest those holdings against a benchmark (e.g.
SPY).
Prerequisites
| Requirement | Value |
|---|---|
| REST base URL | https://api.noonum.ai/v1 |
| Auth header | Authorization: Bearer <token> |
<token> | Your Noonum API key |
| Tools | curl for the shell examples; Python 3.9+ with requests for the code |
<token> is your Noonum API key. See
Authentication for how to obtain and send it.
Install the Python dependency if you plan to follow the code snippets:
Authenticate and smoke-test
Confirm the service is reachable and your token works.Hit the unauthenticated health check to verify connectivity:A The equivalent set-up in Python. Every later snippet reuses this
200 OK with {"status":"OK","message":"Service is running"} means the API is up.Now make your first authenticated call. Listing your strategies validates the token: it
returns 200 (even if the list is empty) when the token is good, and 401 Unauthorized
when it isn’t. Replace YOUR_API_KEY with your key:BASE_URL and headers:Explore the catalog
Noonum ships a library of read-only premade strategies. Inspect them to see the data
shape before you build your own. List them:Each item is a The response is a
Strategy object with an id, name, objective, and status. Fetch
the companies inside any premade strategy with
GET /premade-strategies/{strategyId}/companies, the way you will for your own strategies
in Step 5. Premade strategies also expose read-only per-company evidence and historical
snapshots, covered in Working with premade strategies
below.To find the closest existing premade strategy for a plain-English objective, use semantic
search:matches array ordered by descending similarity, each wrapping a full
Strategy.Look up companies by ticker
Most Noonum endpoints identify companies by a UUID, not a ticker. Resolve a ticker, name,
ISIN, or FIGI fragment to a company id with the helper search endpoint:Results are ranked with exact matches first, then prefix matches, capped at the top 10.
Each result lists its active
securities (primary listing first). Any endpoint that takes
a company id, including the backtest later in this tutorial, can use an id resolved here.Create and build a strategy
This is the create → submit → poll loop from
Build a strategy, in code: create the strategy (synchronous),
submit to start the async theme analysis, then poll until it’s done.A A
4a. Create
POST /strategies requires a name and an objective; exclusions is optional.201 Created returns the new Strategy object. Save its id.4b. Submit for processing
Submitting kicks off the async build:423 Locked here means a previous submission of the same strategy is still running.
Wait for it to finish before resubmitting.4c. Poll until complete
PollGET /strategies/{strategyId} and watch status, the percent-complete field; 100
means the build has finished.Fetch holdings
With the strategy built, retrieve its companies. Pass Each entry is a The response carries a
includeReasoning=true to also get
the human-readable explanation for each inclusion.Company with id, symbol, name, sector, marketCap,
linguisticBeta, marketBuzz, and a convictionScore in (0, 1). The
convictionScore is the default ranking metric, an overall thematic-strength score
independent of company size. See Signals and scores for
what each field means.Turn the list into a weighted portfolio
The raw company list is unweighted. To get an investable portfolio with per-holding weights, use the construction endpoint.POST /strategies/{strategyId}/optimize tilts the
weights by a signal score (default convictionScore):metadata block (number of holdings, weighted signal score, and
expected return/volatility/Sharpe stats) plus a portfolio array where every company also
has a weight. A 202 Accepted here means the strategy framework hasn’t finished yet.
Keep polling Step 4c.Backtest the holdings
Validate the portfolio against history. The same call with The response includes:
POST /backtest takes a list of holdings (each
a companyId + weight), resolves each to a tradeable security, and computes a
buy-and-hold NAV with risk statistics versus a benchmark.Build the request from the constructed portfolio you fetched:curl (using two holdings for brevity):metadata: totalreturns,annualizedReturn(CAGR),variance,sharpeRatio,maxDrawdown, plusstockCount,weekCount, and anywarnings.timeSeries:[timestamp, navValue]pairs rebased to 10,000.benchmarkMetadataandbenchmarkTimeSeries: the same stats for the benchmark, aligned to the portfolio’s dates so you can chart them together.
years accepts 1–20 (default 5) and benchmark accepts any symbol such as SPY or
QQQ (default SPY). A 400 Bad Request means there was insufficient price data or no
companies could be resolved.Handling errors
Every endpoint shares the same auth and error conventions:| Status | Meaning | What to do |
|---|---|---|
401 Unauthorized | Missing/invalid token, or an inactive account | Recheck the Authorization header; revisit Authentication |
400 Bad Request | Malformed body or invalid identifier (e.g. a non-UUID company id) | Read the error field in the JSON body and fix the input |
404 Not Found | The strategy, company, or portfolio doesn’t exist or isn’t visible to you | Verify the id |
423 Locked | A previous submit of this strategy is still running | Wait, then resubmit |
202 Accepted | An async result isn’t ready yet | Poll until status == 100, then retry |
Working with premade strategies
Noonum maintains a library of read-only premade strategies that expose more data than your own strategies. Beyond listing them and fetching their companies (Step 2), you can inspect the evidence behind each holding and pull historical snapshots. Every endpoint below lives under the/premade-strategies path and takes a premade strategy id: the
premade_id you captured from the catalog in Step 2, not the strategy_id of the strategy
you built.
Get evidence for a specific company
This endpoint explains why a company is in the premade strategy: a human-readablereasoning plus supporting summaries (evidence excerpts). It takes the premade_id
and a company id from that strategy’s holdings:
provider (the source), pubDate (a Unix timestamp), and text
(the evidence content).
Get evidence for every company at once
Fetch reasoning and evidence for all companies in the premade strategy in a single call:List the dates with historical data
Premade strategies keep dated snapshots of their holdings. Check which dates are available before requesting one:{"available_dates": ["2024-01-31", "2024-02-29", ...]}. Only dates with
completed results appear.
Download the holdings for a historical date
Retrieve the full company list as it stood on a specific date:409 Conflict means the snapshot for that date is still processing or failed. Pick
another date from available_dates.
Next steps
You now have the full loop: authenticate → build → fetch holdings → optimize → backtest. From here:- Refine results with exclusions in the Iterate a strategy guide.
- Browse every endpoint, with request/response schemas and an interactive try-it console, in the API Reference.
- Drive Noonum from an AI agent with the same token via the MCP overview.