THINKHX

Runs

A run executes an app: you supply the app's input fields, the API queues the work, and a worker fills in the response. Runs are asynchronous — creating one returns immediately with a new status, and you read the result back once it has finished. A run started through the API shows API as its origin in the workspace history.

Endpoints

MethodPathScope
POST/v1/run/createreasoning:write
GET/v1/run/listreasoning:read
GET/v1/run/detail/<run_id>reasoning:read

<run_id> is a run identifier, prefixed runi_.

Note — The path segment is run but the scope is reasoning:read and reasoning:write, and the object is a reasoning. A key scoped run:* cannot call these endpoints. Use reasoning:*, or *.

The reasoning object

FieldTypeDescription
idstringThe run identifier, prefixed runi_.
objectstringAlways reasoning.
app_idstringThe app that was run.
modelobjectThe model that was resolved for the run, or null.
dataobjectThe inputs the run was launched with, keyed by field name.
instructionobjectThe instructions that were sent, keyed by instruction identifier.
responseobjectThe model's answer, keyed by instruction identifier. Empty until the run finishes.
tokensobjectToken counts as input, output and total, or null when not yet metered.
statusstringSee the statuses below.
durationnumberHow long the run took, in seconds to two decimals, or null.
started_atintegerWhen the worker picked the run up, or null.
finished_atintegerWhen the run completed, or null.
created_atintegerWhen the run was queued, in Unix seconds.
updated_atintegerLast change, in Unix seconds.

The model object carries the resolved build:

FieldTypeDescription
idstringThe model.
model_librarystringThe exact model build the run used.
namestringThe build's name.
parameterstringThe build's parameter size.

Statuses

StatusMeaning
newQueued, not yet picked up.
pullBeing prepared by a worker.
processingRunning against the model.
finishedComplete. response is filled in.
failedEnded in an error.

Poll GET /v1/run/detail/<run_id> until the status is finished or failed. Both are final; every other status will change on its own.

Launch a run

POST /v1/run/create names an app and supplies its inputs.

ParameterTypeRequiredDescription
app_idstringyesThe app to run. Also accepted as app or app_ident.
dataobjectyesOne entry per input field. Key each entry by the field's name, as returned by Apps or Catalog.
curl
curl -X POST https://api.thinkhx.com/v1/run/create \
  -H "Authorization: Bearer sk-project-YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "app_id": "mapp_0ceacb46e5b3a99e91b6",
    "data": { "message": "The checkout page has been down since this morning." }
  }'
json
{
  "code": 200,
  "title": "OK",
  "response": {
    "id": "runi_1b7f4e0c96a2d8531fca",
    "object": "reasoning",
    "data": { "message": "The checkout page has been down since this morning." },
    "instruction": { "1": "Classify the message as low, normal or urgent." },
    "status": "new",
    "created_at": 1754209200
  }
}

Keep the returned id and poll it. The creation response deliberately carries no response field: nothing has run yet.

Sending a document or an image

A field whose type is document or image (see Apps) does not take text: it takes a file your project has already uploaded to its own library. Send the file's identifier, prefixed file_, or its delivery URL — both are accepted and both are stored as the URL:

curl
curl -X POST https://api.thinkhx.com/v1/run/create \
  -H "Authorization: Bearer sk-project-YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "app_id": "mapp_0ceacb46e5b3a99e91b6",
    "data": { "invoice": "file_9c1d4a70e58b23f6ad02" }
  }'

The engine reads the file before the model runs: a document becomes the text it contains, an image is handed to the model as a picture. Accepted document formats are PDF, DOCX, XLSX, CSV and TXT; images are PNG, JPG and WebP.

CodeMessageCause
422Field '<name>' expects an uploaded file: send its cdn file id (file_<20 hex>) or its delivery URL.The value was ordinary text.
422The file sent for '<name>' is not in this project's reasoning image / reasoning document library.The file belongs to another project, was deleted, or was uploaded into another library.
422The file sent for '<name>' cannot be read: accepted document formats are pdf, docx, xlsx, csv, txt.The document is in a format the engine cannot read.
422The model resolved for this app cannot read images. Choose a model that accepts image input.The app has an image field but its model has no image input.

You can run your own apps and any published app of any project. An app that is not activated, or has no usable model, is refused with 422 and the general message.

CodeMessageCause
400Missing required field: app_id.No app was named.
404App not found.The app does not exist, or is deleted, or is private to another project.
422Missing required field: <name>.A required input field was absent or empty.
402Your reasoning quota is exhausted. Please wait until it resets or upgrade your plan.The allowance for the cycle is used up.

The quota is checked before anything else, so an exhausted project cannot queue work. Read the remaining allowance from Quota and token usage.

Tip — A field can also be keyed by its madi_ identifier or by its position, counting from 1. Keying by name is the clearest and is what the app's schema gives you.

Read one run

GET /v1/run/detail/<run_id> returns the whole run, including the response once it exists.

curl
curl https://api.thinkhx.com/v1/run/detail/runi_1b7f4e0c96a2d8531fca \
  -H "Authorization: Bearer sk-project-YOUR_KEY"
json
{
  "code": 200,
  "title": "OK",
  "response": {
    "id": "runi_1b7f4e0c96a2d8531fca",
    "object": "reasoning",
    "app_id": "mapp_0ceacb46e5b3a99e91b6",
    "model": {
      "id": "modi_7b1e4c2a9d05f3618ea4",
      "model_library": "mlyi_2c9a7f45b8e1d06a3427",
      "name": "thinkhx-reason",
      "parameter": "8B"
    },
    "data": { "message": "The checkout page has been down since this morning." },
    "instruction": {
      "miid_9a4c07e5b312df8641ca": "Classify the message as low, normal or urgent."
    },
    "response": {
      "miid_9a4c07e5b312df8641ca": "urgent"
    },
    "tokens": { "input": 412, "output": 3, "total": 415 },
    "status": "finished",
    "duration": 1.84,
    "started_at": 1754209202,
    "finished_at": 1754209204,
    "created_at": 1754209200,
    "updated_at": 1754209204
  }
}

instruction and response share their keys, so you can pair each answer with the instruction that produced it. A run of another project gives 404 and Reasoning not found.

List runs

GET /v1/run/list returns the project's runs, newest first.

ParameterTypeDescription
app_idstringReturn only the runs of one app. Also accepted as app or app_ident.
limitintegerRows to return, 1 to 100. Defaults to 50.
offsetintegerRows to skip. Defaults to 0.
curl
curl "https://api.thinkhx.com/v1/run/list?app_id=mapp_0ceacb46e5b3a99e91b6&limit=2" \
  -H "Authorization: Bearer sk-project-YOUR_KEY"
json
{
  "code": 200,
  "title": "OK",
  "response": {
    "object": "list",
    "data": [
      {
        "id": "runi_1b7f4e0c96a2d8531fca",
        "object": "reasoning",
        "app_id": "mapp_0ceacb46e5b3a99e91b6",
        "status": "finished",
        "duration": 1.84,
        "started_at": 1754209202,
        "finished_at": 1754209204,
        "created_at": 1754209200,
        "updated_at": 1754209204,
        "tokens": { "input": 412, "output": 3, "total": 415 }
      }
    ],
    "total": 1
  }
}

The list omits data, instruction, response and model. Read a run to get them. Listing never touches the quota, so you can poll a history freely.

Need help? Contact Support.