Ora
All guides All guides

Getting started

Your first decision in the Playground Call the API from your code Save, share and reuse queries

Financial decisions

Decide on a stock with just its symbol Write your own rule Read probabilities and choose thresholds

Rule playground

From English to rule Combining conditions Offsets and windows Reading beliefs Rules plus forecasts in one request Turning a rule into an alert or workflow

Automation

Send a Slack alert when a rule fires Send decisions to your own system Run a watchlist every day after the close

Production

Handle errors, rate limits and retries

Cookbooks

All cookbooks Rank a watchlist by probability Send a pre-open digest Trend filter plus entry trigger Breakout confirmation with volume RSI and Bollinger mean-reversion checks Gap-fill playbook to your order system Confidence-gated actions Detect two-way risk Size positions by volatility regime Risk guardrail before an order Ask many questions in one request Self-consistency: three wordings Route support tickets Is a headline relevant to a symbol?

Use cases

Tag financial news for trading signalsGuardrails for LLM appsSupport ticket triage and routingFilter retrieved passages before your LLM answersVerify claims and citations against a source

Guides / Cookbooks

Cookbooks · Screening and digests · Beginner · about 10 min

Send a pre-open digest

Before the open every weekday, ask the same questions about a short list of index ETFs and post one message with all of them to Slack.

You'll need
  1. When to use it

    You want one morning read in the channel the desk already watches, not one message per symbol. A workflow asks the questions for every symbol on its list at a set New York time and sends a single digest.

  2. The workflow

    Here is the definition. 08:30 runs before the open on the previous session's numbers; 16:45 would use the session that just closed.

    {
      "name": "Pre-open read with trend",
      "symbols": "SPY QQQ IWM DIA",
      "days": [
        1,
        2,
        3,
        4,
        5
      ],
      "at_time": "08:30",
      "model": "ora-fin1",
      "questions": {
        "up_week": {
          "type": "yes_no",
          "instructions": "Will the stock be higher in a week?"
        },
        "move2": {
          "type": "yes_no",
          "instructions": "Will the stock move more than 2% in either direction in 5 trading days?"
        },
        "above_50d": {
          "type": "yes_no",
          "ask": "C > sma(C,50)"
        }
      },
      "actions": [],
      "digest": {
        "do": "slack",
        "connection": "trading-desk",
        "when": "always"
      }
    }

    Each symbol is an ordinary request, the same one you can send yourself:

    {
      "model": "ora-fin1",
      "state": {
        "symbol": "SPY"
      },
      "questions": {
        "up_week": {
          "type": "yes_no",
          "instructions": "Will the stock be higher in a week?"
        },
        "move2": {
          "type": "yes_no",
          "instructions": "Will the stock move more than 2% in either direction in 5 trading days?"
        },
        "above_50d": {
          "type": "yes_no",
          "ask": "C > sma(C,50)"
        }
      }
    }
    Open this in the Playground
  3. The real response

    The four per-symbol answers for the session of 2026-10-30:

    Symbolup_weekmove2above_50d (rule)
    SPY0.5980.3940.1128
    QQQ0.5610.360.0653
    IWM0.5260.3220.2176
    DIA0.5670.3670.2849

    And the digest those four answers make, in the layout a workflow posts (assembled here from the responses above):

    Pre-open read with trend · data as of 2026-10-30 · 0 of 4 symbols fired:
    • SPY: up_week 60%, move2 39%, above_50d 11%
    • QQQ: up_week 56%, move2 36%, above_50d 7%
    • IWM: up_week 53%, move2 32%, above_50d 22%
    • DIA: up_week 57%, move2 37%, above_50d 28%

    The read is mixed: all four lean slightly up on the week, while the rule C > sma(C,50) says each one closed under its 50-day average (beliefs from 0.0653 to 0.2849). One message shows the desk both.

  4. The code

    You don't need code for a workflow. To build the same read yourself (for example inside your own scheduler), loop over the symbols and format the line:

    Requires curl 7.76+. Save as run.sh, then: bash run.sh
    curl -sS https://oramodel.com/v1/systemone \
      -H "Authorization: Bearer $JEV_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{
      "model": "ora-fin1",
      "state": {
        "symbol": "SPY"
      },
      "questions": {
        "up_week": {
          "type": "yes_no",
          "instructions": "Will the stock be higher in a week?"
        },
        "move2": {
          "type": "yes_no",
          "instructions": "Will the stock move more than 2% in either direction in 5 trading days?"
        },
        "above_50d": {
          "type": "yes_no",
          "ask": "C > sma(C,50)"
        }
      }
    }'
    import os
    import requests
    
    URL = "https://oramodel.com/v1/systemone"
    HEADERS = {"Authorization": f"Bearer {os.environ['JEV_API_KEY']}"}
    
    SYMBOLS = ["SPY", "QQQ", "IWM", "DIA"]
    QUESTIONS = {
        "up_week": {
            "type": "yes_no",
            "instructions": "Will the stock be higher in a week?"
        },
        "move2": {
            "type": "yes_no",
            "instructions": "Will the stock move more than 2% in either direction in 5 trading days?"
        },
        "above_50d": {
            "type": "yes_no",
            "ask": "C > sma(C,50)"
        }
    }
    
    lines = []
    for s in SYMBOLS:
        r = requests.post(URL, headers=HEADERS, timeout=30,
                          json={"model": "ora-fin1", "state": {"symbol": s}, "questions": QUESTIONS})
        r.raise_for_status()
        a = r.json()["answers"]
        lines.append(f"• {s}: " + ", ".join(f"{k} {v['yes_no']:.0%}" for k, v in a.items()))
    print("\n".join(lines))
  5. Act on it

    1. Go to Workflows → New workflow, or start from the Pre-open market read template under Examples → Workflows.
    2. Set the symbols, weekdays and 08:30, paste the questions, and set the digest to Slack → trading-desk, always.
    3. Save (it checks everything with a dry run), then Test run: you see each symbol's answers and the digest, and nothing is sent.
    4. Untick dry run. Holidays and late data are skipped, so the digest never repeats an old session.
  6. Variations

    • Add a per-symbol action (for example up_week >= 0.62) and set the digest to fired, so the message lists only the names that crossed the line.
    • Send the digest to a webhook instead: the body is {event: "jev.workflow", workflow, run_id, as_of, symbols, answered, fired_symbols, rows} (Workflows reference).
    • Run after the close at 16:45 on the session that just ended.

Information, not investment advice. Every number on this page is a real response for the session shown; answers change with each session.

What's next

Create an account Open the Playground Everything here also lives in the console, next to your keys and usage.