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, optional images and video frames. 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 on the data we measure.
  • ImagesConceptsSend up to 16 images and text in the same request. The model reads printed and handwritten text, amounts, dates, objects and layout, and…
  • Batch jobsPatternsSend up to 10,000 requests in one file and collect the answers later, at a lower price than live calls.
  • Pricing and billingYou pay for input tokens only. Output is free because the model generates no text.
↑↓ moveopen7 suggestions
Get API keyGet API key
DecisionNodeDecisionNde

Get started

  • Introduction
  • Quickstart
  • Playground
  • Console and keys
  • With coding agents
  • MCP server
  • Examples

Concepts

  • State
  • Questions
  • Choice
  • Score
  • Truth
  • Number
  • Points and boxes
  • Images
  • Video
  • Boosters
  • Confidence
  • Determinism

Models

  • DecisionNode-1.0
  • DecisionNode-1.0 Flash
  • Limits
  • Versions
  • Dedicated capacity

Fine-tuning

  • Overview
  • Prepare your dataset
  • Upload and validation
  • Start a training run
  • Watch a run
  • The quality gate
  • Use your model
  • Limits and pricing

Patterns

  • Confidence-gated routing
  • Fan-out
  • Guardrails
  • Control loops
  • Batch jobs

API reference

  • Overview
  • POST/v1/decide
  • GET/v1/models
  • POST/v1/uploads
  • Errors
  • Safety check
  • Rate limits

Sessions API

  • Sessions overview
  • POSTOpen a session
  • WSStream frames
  • DELEnd a session

Batch API

  • The batch object
  • POSTCreate a batch
  • POSTAdd requests
  • POSTFinalize a batch
  • GETRetrieve a batch
  • GETGet batch results
  • POSTCancel a batch
  • GETList batches

Pricing and billing

  • Pricing and billing
  • Refer & earn

Policies

  • Responsible use
  • Data and privacy
  • Benchmarks
  • Pricing
  • Playground
Get API key
  • Guides
  • API reference
  • Examples
  • Playground

Get started

  • Introduction
  • Quickstart
  • Playground
  • Console and keys
  • With coding agents
  • MCP server
  • Examples

Concepts

  • State
  • Questions
  • Choice
  • Score
  • Truth
  • Number
  • Points and boxes
  • Images
  • Video
  • Boosters
  • Confidence
  • Determinism

Models

  • DecisionNode-1.0
  • DecisionNode-1.0 Flash
  • Limits
  • Versions
  • Dedicated capacity

Fine-tuning

  • Overview
  • Prepare your dataset
  • Upload and validation
  • Start a training run
  • Watch a run
  • The quality gate
  • Use your model
  • Limits and pricing

Patterns

  • Confidence-gated routing
  • Fan-out
  • Guardrails
  • Control loops
  • Batch jobs

API reference

  • Overview
  • POST/v1/decide
  • GET/v1/models
  • POST/v1/uploads
  • Errors
  • Safety check
  • Rate limits

Sessions API

  • Sessions overview
  • POSTOpen a session
  • WSStream frames
  • DELEnd a session

Batch API

  • The batch object
  • POSTCreate a batch
  • POSTAdd requests
  • POSTFinalize a batch
  • GETRetrieve a batch
  • GETGet batch results
  • POSTCancel a batch
  • GETList batches

Pricing and billing

  • Pricing and billing
  • Refer & earn

Policies

  • Responsible use
  • Data and privacy
  1. docs
  2. /
  3. Get started

POST /v1/uploads

Put an image into your workspace's storage once, then name it by upload_id in any image slot for an hour: on /v1/decide, in a batch line, a session frame or a fine-tuning record. Up to 16 images a call; free.

on this page6 sections
  1. Headers
  2. Request body
  3. Response body
  4. The PUT
  5. Naming an upload
  6. Errors
POSThttps://api.decisionnode.com/v1/uploads

An upload takes two calls: this one, which answers with a storage URL per image, and a PUT of the bytes to that URL. Then any key of the workspace can name the image by its upload_id for one hour. For a one-off decision an https url is simpler; uploads are for an image you ask about several times, for large images, and for the images of a fine-tuning dataset. An uploaded image does not count toward a request's 25 MB body limit; the same image inline as base64 does.

MD5=$(openssl md5 -binary receipt.jpg | base64)
SIZE=$(wc -c < receipt.jpg | tr -d ' ')

curl https://api.decisionnode.com/v1/uploads \
  -H "Authorization: Bearer $DECISIONNODE_API_KEY" \
  -H "Content-Type: application/json" \
  -d "{\"files\": [{\"content_type\": \"image/jpeg\", \"byte_size\": $SIZE, \"checksum\": \"$MD5\"}]}"

# then PUT the bytes to the returned url with exactly the returned headers:
curl -X PUT "$URL" --data-binary @receipt.jpg \
  -H "Content-Type: image/jpeg" -H "Content-MD5: $MD5" -H "If-None-Match: *"

Headers#

Authorizationstringrequired
Bearer dn_live_....
Content-Typestringrequired
application/json; the body is at most 64 KiB.

Request body#

filesarrayrequired
1 to 16 images. All are checked before anything is stored: one bad file refuses the call.
content_typestringrequired
image/jpeg, image/png or image/webp, exactly, lower case.
byte_sizeintegerrequired
The file's size in bytes, 1 to 10,485,760 (10 MB).
checksumstringrequired
The file's MD5, base64 encoded: 24 characters. The storage refuses bytes that do not match it.
sha256string
The file's SHA-256, base64 encoded: 44 characters. When given, the storage checks it too, and a repeated request naming this upload can be answered from the cache of repeated requests; without it, such a request is never cached. The official SDKs always send it.

Response body#

uploadsarray
One entry per file, in request order.
upload_idstring
upl_ and 32 hex digits. Name the image by it.
urlstring
Where to PUT the bytes. Send it as given; never build or edit one.
methodstring
Always PUT.
headersobject
The headers the PUT must carry, exactly: Content-Type, Content-MD5, If-None-Match: *, and the SHA-256 header when you sent sha256.
expires_atstring
When the upload_id stops working: one hour from now, UTC.
expires_ininteger
Seconds the URLs accept the PUT: 300.
  1. Headers
  2. Request body
  3. Response body
  4. The PUT
  5. Naming an upload
  6. Errors
request
{  "files": [    {      "content_type": "image/jpeg",      "byte_size": 482113,      "checksum": "rL0Y20zC+Fzt72VPzMSk2A=="    }  ]}

The PUT#

  • Within 5 minutes, send the file's bytes to url with exactly the headers given. Your API key never goes to that URL.
  • The bytes are checked: a size or an MD5 that differs from what you declared is refused, and the object is written once: a second PUT to the same URL is refused. A retry that is refused because the first attempt landed is a success.
  • After the 5 minutes, call /v1/uploads again for a new URL.

Naming an upload#

JSON
{
  "images": [
    { "id": "receipt", "upload_id": "upl_3f6c1a9e0b2d4c7f8a1e5d9b2c4f6a80" }
  ]
}
  • One of data, url and upload_id per image; media_type is optional and must match the upload when given.
  • Anywhere an image goes: /v1/decide, batch lines, a session frame's image, and fine-tuning records. The image counts toward the 16 images of a request like any other and is billed as the same image sent as data.
  • Any key of the workspace, for one hour from this call, as many times as you like. A batch holds its uploads until it ends, and a validated fine-tuning dataset holds its uploads for the dataset's life.
  • Zero retention: in a workspace with zero retention an upload is deleted right after the first decision that used it.

Errors#

  • 400

    Type
    api_usage_error
    When
    A body that is not a JSON object, or a file outside the rules above; the message names the file and the field
  • 401

    Type
    authentication_error
    When
    The key is missing, unknown or revoked
  • 402

    Type
    insufficient_credit
    When
    The balance is empty: a workspace that may not decide may not upload
  • 403

    Type
    workspace_suspended
    When
    The workspace is paused
  • 413

    Type
    request_too_large_error
    When
    A body over 64 KiB
  • 429

    Type
    rate_limit_error
    When
    Over your key's request rate: each call counts as one request of zero tokens
  • 529

    Type
    overloaded_error
    When
    Storage is busy; wait Retry-After
Errors of this call
StatusTypeWhen
400api_usage_errorA body that is not a JSON object, or a file outside the rules above; the message names the file and the field
401authentication_errorThe key is missing, unknown or revoked
402insufficient_creditThe balance is empty: a workspace that may not decide may not upload
403workspace_suspendedThe workspace is paused
413request_too_large_errorA body over 64 KiB
429rate_limit_errorOver your key's request rate: each call counts as one request of zero tokens
529overloaded_errorStorage is busy; wait Retry-After
  • upload_not_found

    When
    The id is unknown, malformed or another workspace's
  • upload_expired

    When
    More than an hour has passed: upload the image again
  • upload_consumed

    When
    Zero retention: a decision already used it
  • upload_incomplete

    When
    The bytes were never PUT, or not yet
  • upload_mismatch

    When
    The stored size differs from what was declared
  • upload_media_type_mismatch

    When
    A media_type beside the id that differs from the upload's, or bytes that are not of the declared type
Errors of a request that names an upload, all 400
TypeWhen
upload_not_foundThe id is unknown, malformed or another workspace's
upload_expiredMore than an hour has passed: upload the image again
upload_consumedZero retention: a decision already used it
upload_incompleteThe bytes were never PUT, or not yet
upload_mismatchThe stored size differs from what was declared
upload_media_type_mismatchA media_type beside the id that differs from the upload's, or bytes that are not of the declared type

Presigning is free and bills nothing; the image's tokens are billed in the decision that reads it.

nextIntroduction

DecisionNode is built and run by Bynn Intelligence, Inc.

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