Skip to content
DecisionNodeDecisionNdedocs
  • Guides
  • API reference
  • Examples
  • Playground

start here

  • QuickstartGet startedGet an API key, send one request with three questions, and branch your code on the typed answers. Plain HTTPS, no SDK to install.
  • POST /v1/decideAPI referenceAnswer typed questions about a state and optional images. One request, one buffered JSON response, one answer per question.
  • QuestionsConceptsQuestions say what to decide. Each one has a type that fixes the shape of its answer: a choice from your options, a score on your scale, a…
  • ConfidenceConceptsProbabilities are calibrated per question type, so a threshold means what it says.
  • ImagesConceptsSend images and text in the same request. The model reads printed and handwritten text, amounts, dates, objects and layout, and answers…
  • Pricing and billingYou pay for input tokens only. Output is free because the model generates no text.
↑↓ moveopen6 suggestions
Get API keyGet API key
DecisionNodeDecisionNde

Get started

  • Introduction
  • Quickstart
  • With coding agents
  • Examples

Concepts

  • State
  • Questions
  • Choice
  • Score
  • Truth
  • Number
  • Images
  • Confidence
  • Determinism

Models

  • DecisionNode-1.0
  • DecisionNode-1.0 Flash
  • Limits

Patterns

  • Confidence-gated routing
  • Fan-out
  • Guardrails
  • Control loopscomingcoming soon

API reference

  • POST/v1/decide
  • POST/v1/sessionscomingcoming soon
  • GET/v1/models
  • Errors
  • Rate limits

Pricing and billing

  • Pricing and billing

Policies

  • Responsible use

Migrate

  • Coming from a Jev-shaped API
  • Benchmarks
  • Pricing
  • Playground
Get API key
  • Guides
  • API reference
  • Examples
  • Playground

Get started

  • Introduction
  • Quickstart
  • With coding agents
  • Examples

Concepts

  • State
  • Questions
  • Choice
  • Score
  • Truth
  • Number
  • Images
  • Confidence
  • Determinism

Models

  • DecisionNode-1.0
  • DecisionNode-1.0 Flash
  • Limits

Patterns

  • Confidence-gated routing
  • Fan-out
  • Guardrails
  • Control loopscomingcoming soon

API reference

  • POST/v1/decide
  • POST/v1/sessionscomingcoming soon
  • GET/v1/models
  • Errors
  • Rate limits

Pricing and billing

  • Pricing and billing

Policies

  • Responsible use

Migrate

  • Coming from a Jev-shaped API
  1. docs
  2. /
  3. API reference

Sessionscomingcoming soon

Streaming decisions. Open a session once with the fixed part of your request, then stream frames over a WebSocket and get a typed decision for each one. More than 10 decisions a second? Use a session.

on this page9 sections
  1. Open a session
  2. Stream frames
  3. Replies
  4. How a session behaves
  5. End a session
  6. Limits
  7. Billing
  8. Clients
  9. Published at release

Coming: sessions are announced, not yet served

This page documents the shapes sessions will use. What it does not state yet (the full open response, close codes, error bodies) is published at release, together with measured per-frame latency for both models.

A call to /v1/decide sends everything every time: the instructions, the context and the questions. A session sends that fixed part once. The model keeps your context loaded for the life of the session, so each frame you stream costs only its own tokens, and each reply carries the same typed, calibrated answers as a normal call. Control loops covers when to use one.

POST /v1/sessionscomingcoming sooninstructions, state, questions, window 8

sent once, billed once

frames, each only what changedseq

  1. 7
  2. 8
  3. 9
  4. 10
  5. 11
  6. 12
  7. 13
  8. 14
  9. 15
  10. 16
  11. 17
  12. 18
  13. 19
window, last 8

replies, newest wins

    your controller

    mode

    continuereturn

    Takes the mode when the answer clears your threshold. It flies the vehicle, keeps its own limits and runs its own failsafe.

    A session opened once with instructions, state, questions and a window of 8 frames. Frames 15 to 19 stream in; each is answered on the fixed part plus the last 8 frames. Frames 17 and 18 arrive while 16 is being answered, so 18, the newest, is answered and the reply reports 17 as skipped. The reply to frame 19 says mode return with confidence 0.79 and abort 0.07, and your controller takes that mode.

    Open a session#

    POSThttps://api.decisionnode.com/v1/sessions
    Request body
    {
      "model": "decisionnode-latest",
      "instructions": "You are the mission supervisor of a survey drone.",
      "state": {
        "mission": "Survey the north field in parallel lines, 40 m altitude",
        "geofence": "Stay inside the field boundary and below 120 m",
        "rules": "Return home when battery is under 30% at the far end of a line"
      },
      "questions": {
        "mode": {
          "type": "choice",
          "instructions": "Which flight mode now?",
          "criteria": {
            "continue": "keep flying the survey pattern",
            "hold": "hover in place until conditions change",
            "return": "fly back to the home point",
            "land": "land at the nearest safe spot now"
          }
        },
        "abort": {
          "type": "truth",
          "instructions": "Should the mission be aborted now?"
        }
      },
      "window": 8
    }
    # the body above, saved as session.json
    curl https://api.decisionnode.com/v1/sessions \
      -H "Authorization: Bearer $DECISIONNODE_API_KEY" \
      -H "Content-Type: application/json" \
      -d @session.json
    modelstringrequired
    Either model, or a pinned version, as on /v1/decide.
    instructionsstring
    Who the model is deciding as, for every frame of the session.
    statestring | object | array
    The static context: a mission brief, a rulebook, a map legend. Read once, within the 64k request limit.
    questionsobjectrequired
    The questions every frame is answered on, in the same shape as on /v1/decide: choice, score, truth or number.
    windownumber
    How many recent frames stay in context. Default 8.
    ttl_secondsnumber
    How long the session lives. Default 300, at most 3,600.

    What comes back

    session_idstring
    The session's id. Use it to open the stream and to end the session.

    The response also carries the stream URL (wss://api.decisionnode.com/v1/sessions/{id}/stream) and the limits that apply to each frame. Their exact field names are published at release.

    Stream frames#

    WSwss://api.decisionnode.com/v1/sessions/{id}/stream

    Connect from your server with your key in the Authorization header (Bearer dn_live_...), as on every call. Each message you send is one frame; each message you receive is the reply to one frame.

    {
      "seq": 17,
      "frame": {
        "battery": 0.31,
        "wind_mps": 11.4,
        "distance_home_m": 820,
        "obstacle": "none"
      }
    }

    Frame

    seqnumberrequired
    Your sequence number for the frame. The reply carries it back.
    framestring | object | imagerequired
    What changed: text, a JSON value or one image, at most 4,096 tokens. How an image frame is encoded is published at release.
    questionsstring[]
    The question names to answer this time. All of them when left out.
    resetboolean
    true drops the recent frames from context before this one is answered.

    Replies#

    Reply
    {
      "seq": 17,
      "answers": {
        "mode": {
          "type": "choice",
          "choice": "return",
          "confidence": 0.79,
          "probabilities": {
            "continue": 0.09,
            "hold": 0.05,
            "land": 0.02,
            "return": 0.84
          }
        },
        "abort": { "type": "truth", "truth": 0.07 }
      }
    }

    Reply

    seqnumber
    The sequence number of the frame this answers.
    answersobject
    One answer per question asked, exactly as /v1/decide shapes it, with the same calibration.
    latency_msnumber
    Time spent on our side for this frame, in milliseconds.
    safetyobject
    The safety check's probabilities for this frame. Every frame passes the same check as every call.

    How a session behaves#

    • Rolling window. Each frame is answered on the fixed part plus the last window frames (8 by default), so the model sees what just happened. Older frames leave the context. Send "reset": true to start the window over.
    • Latest wins. If frames arrive faster than they are answered, the newest frame is answered and the skipped sequence numbers are reported to you. A client that falls behind gets the newest answer, never a backlog. If you need every frame answered, send the next one after its reply.
    • Lifetime. A session ends at ttl_seconds (300 by default, at most 3,600), when the socket closes, or when you end it. If it ends early, the socket closes with a code your client can read: open a new session with the same body and carry on.
    • One session per socket. Run several sessions on several sockets, within the sessions your key may hold.

    End a session#

    DELETEhttps://api.decisionnode.com/v1/sessions/{id}
    curl
    curl -X DELETE https://api.decisionnode.com/v1/sessions/$SESSION_ID \
      -H "Authorization: Bearer $DECISIONNODE_API_KEY"

    Ending a session frees its context at once. Closing the socket ends it too.

    Limits#

    • Frame

      Value
      At most 4,096 tokens, or one image
    • Fixed part

      Value
      Within the 64k request limit, as on Limits
    • Window

      Value
      8 recent frames by default
    • Lifetime

      Value
      300 seconds by default, at most 3,600
    • Sessions per key

      Value
      Published at /v1/models
    Session limits
    LimitValue
    FrameAt most 4,096 tokens, or one image
    Fixed partWithin the 64k request limit, as on Limits
    Window8 recent frames by default
    Lifetime300 seconds by default, at most 3,600
    Sessions per keyPublished at /v1/models

    Billing#

    session = opening tokens × price

    + sum(frame tokens × price)

    opening tokens
    the instructions, the state and the questions, billed once when the session opens
    frame tokens
    each frame's own tokens plus the questions it asks
    price
    the live price per input token of the session's model, today $0.042 per million on DecisionNode-1.0

    Output stays free. The context is never billed again per frame, which is what makes a long session cheap. See Pricing and billing.

    Clients#

    Open the session over HTTPS, then stream. One task sends frames at your sensor's rate; another reads replies and hands each typed answer to your own controller, which keeps flying, driving or running while it waits.

    import asyncio, json, os
    import websockets  # pip install websockets
    
    KEY = os.environ["DECISIONNODE_API_KEY"]
    MODE_AT, ABORT_AT = 0.7, 0.9   # your thresholds, in config
    
    async def supervise(session_id, telemetry, autopilot):
        url = f"wss://api.decisionnode.com/v1/sessions/{session_id}/stream"
        headers = {"Authorization": f"Bearer {KEY}"}
        async with websockets.connect(url, additional_headers=headers) as ws:
    
            async def send_frames():
                seq = 0
                async for reading in telemetry:          # your sensor loop, at its own rate
                    seq += 1
                    await ws.send(json.dumps({"seq": seq, "frame": reading}))
    
            async def read_replies():
                async for message in ws:
                    reply = json.loads(message)
                    # under latest wins a reply may also list the seqs it skipped
                    # (the field is published at release); the newest answer is what counts
                    mode = reply["answers"]["mode"]
                    abort = reply["answers"]["abort"]
                    # the autopilot flies; the session only proposes a mode
                    if abort["truth"] >= ABORT_AT:
                        autopilot.request_mode("return", seq=reply["seq"])
                    elif mode["confidence"] >= MODE_AT:
                        autopilot.request_mode(mode["choice"], seq=reply["seq"])
                    # below both bars the autopilot keeps its current mode
    
            await asyncio.gather(send_frames(), read_replies())

    Published at release#

    • Measured per-frame latency for both models.
    • The full open response, beyond session_id and the stream URL.
    • How an image frame is encoded, and how skipped frames are listed in a reply.
    • Close codes and error bodies.
    • The sessions each key may hold, at /v1/models.
    previousPOST /v1/decidenextGET /v1/models

    DecisionNode is built and run by Bynn Intelligence, Inc.

    • Home
    • Playground
    • Examples
    • Console
    • Responsible use
    • Terms
    • Acceptable use
    • Privacy
    • Data processing
    • Defence addendum
    • Cookies

    on this page

    1. Open a session
    2. Stream frames
    3. Replies
    4. How a session behaves
    5. End a session
    6. Limits
    7. Billing
    8. Clients
    9. Published at release