Models on Your Own Device

Use the models running on your computer from external apps through the API

If you have installed the Onysoft AI Gateway Node app on your computer and connected it to your account, you can use the models running on that computer from external apps such as n8n, Cursor, LangChain, the OpenAI libraries or your own code. The endpoint and the key are the same as for every other model; the only difference is the node/ prefix in the model name.

info

First install the Onysoft AI Gateway Node app on your computer, connect it to your account and turn sharing on in the app. You can follow your devices and the status of their models on the My GPU Sharing page of the dashboard.

POST /v1/chat/completions

When the model name is node/<catalog_id>, the request runs on your own device.

GET /v1/node/models

Lists the models loaded on your devices and whether each one is ready to use right now.

How It Works

Your computer does not open any port to the outside; the connection is always made by the Node app towards the server. A request follows this path:

  1. Your app sends the request to https://api.onysoft.com/v1/chat/completions, as usual.
  2. The server checks that the key is a personal key you created in the dashboard and that the requested model is ready on one of your online devices.
  3. The request is queued as a job owned by you.
  4. The Node app on your computer picks the job up over an outgoing connection that it opens to the server itself and keeps renewing, and runs the model locally on your computer (127.0.0.1).
  5. The answer is sent back to the server and returned to your app in the same format as any other model; for streaming requests, chunks arrive as the device generates them (see “Streaming” below).
  6. Token counts and duration are written to your usage log; the charge is 0.
Your app (n8n, Cursor, your own code)
   │  ▲
   │  │   POST /v1/chat/completions  "model": "node/..."
   │  │   the answer comes back in the same format as other models
   ▼  │
api.onysoft.com   key and device check → queue
   ▲  │
   │  │   outgoing connection: the Node app picks up the job, sends the result back
   │  │   (no port is opened on your computer)
   │  ▼
Your computer     Onysoft AI Gateway Node → local model (127.0.0.1)

Model Name

Add node/ in front of the catalog ID. If the same model is ready on more than one of your devices, the request goes to one of them; to pick a specific device, append @<device_no>.

Model name Meaning
node/qwen3-4b-q4_k_m Any of your online devices on which this model is ready.
node/qwen3-4b-q4_k_m@12 Only your device number 12. If that device is offline or the model is not ready on it, the request is not sent to another device; it returns 503 node_unavailable.

You can find the names and device numbers you can use in the id and device_model_id fields of the GET /v1/node/models response. The catalog ID after node/ is case-insensitive; write the prefix itself in lowercase. If your key has a model restriction, add node/* to its list to allow all device models.

Example Request

The endpoint, the key and the request body are the same as for other models; only the model field changes.

cURL
curl https://api.onysoft.com/v1/chat/completions \
  -H "Authorization: Bearer sk-ony-your-api-key" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "node/qwen3-4b-q4_k_m",
    "messages": [
      {"role": "user", "content": "Merhaba! Kısaca kendini tanıtır mısın?"}
    ],
    "max_tokens": 300
  }'

Example Response

The response has the same format as for other models. id is the request ID (req_...), model contains node/<catalog_id> without the device number, and cost.amount is always 0. If the model produced reasoning text, the message also contains reasoning and reasoning_content; if it called a tool, tool_calls is present and finish_reason is tool_calls.

JSON
{
  "success": true,
  "data": {
    "id": "req_5c1e9a7d2b3f4e6a8c0d1e2f",
    "object": "chat.completion",
    "created": 1758542400,
    "model": "node/qwen3-4b-q4_k_m",
    "choices": [
      {
        "index": 0,
        "message": {
          "role": "assistant",
          "content": "Merhaba! Ben Qwen3, bilgisayarınızda çalışan bir dil modeliyim."
        },
        "finish_reason": "stop",
        "logprobs": null
      }
    ],
    "usage": {
      "prompt_tokens": 18,
      "completion_tokens": 16,
      "total_tokens": 34
    },
    "cost": {
      "amount": 0,
      "currency": "USD"
    }
  }
}

Supported Parameters

Only the following fields are passed to your device:

Streaming

When you send stream:true, the response arrives as SSE chunks, just like with other models. With the current app versions (main app 0.4.5, distributed app 0.6.2 and later), the device sends the model’s reasoning text and the answer to the server as it generates them, so chunks reach your app and the dashboard chat while generation is still running. With these versions, closing the connection also stops generation on the device. Older versions send the answer only once it has been generated in full; the chunks then arrive back to back, in slices of about 40 characters.

As long as no data is flowing, the connection is kept open: the server sends a : ping comment line every 5 seconds. During streaming, long comment lines made of spaces may also arrive to flush intermediate buffers. SSE clients and the OpenAI libraries ignore these lines starting with :. Non-streaming requests have a shorter time limit, so we recommend stream:true for long answers.

SSE
: ping

: ping

data: {"id":"req_5c1e9a7d2b3f4e6a8c0d1e2f","object":"chat.completion.chunk","created":1758542400,"model":"node/qwen3-4b-q4_k_m","choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":null,"logprobs":null}]}

data: {"id":"req_5c1e9a7d2b3f4e6a8c0d1e2f","object":"chat.completion.chunk","created":1758542400,"model":"node/qwen3-4b-q4_k_m","choices":[{"index":0,"delta":{"content":"Merhaba! Ben Qwen3, bilgisayarınızda çal"},"finish_reason":null,"logprobs":null}]}

data: {"id":"req_5c1e9a7d2b3f4e6a8c0d1e2f","object":"chat.completion.chunk","created":1758542400,"model":"node/qwen3-4b-q4_k_m","choices":[{"index":0,"delta":{"content":"ışan bir dil modeliyim."},"finish_reason":null,"logprobs":null}]}

data: {"id":"req_5c1e9a7d2b3f4e6a8c0d1e2f","object":"chat.completion.chunk","created":1758542400,"model":"node/qwen3-4b-q4_k_m","choices":[{"index":0,"delta":{},"finish_reason":"stop","logprobs":null}]}

data: {"id":"req_5c1e9a7d2b3f4e6a8c0d1e2f","object":"chat.completion.chunk","created":1758542401,"model":"node/qwen3-4b-q4_k_m","choices":[],"usage":{"prompt_tokens":18,"completion_tokens":16,"total_tokens":34},"cost":{"amount":0,"currency":"USD"}}

data: [DONE]

Chunk order: role, reasoning text if any (reasoning / reasoning_content), content, tool_calls if any, then finish_reason. If you sent stream_options.include_usage, a usage chunk follows. The last chunk always carries usage and cost, followed by [DONE].

Errors that happen after the stream has started (the device did not pick the request up in time, a timeout, a device error) do not arrive as an HTTP status code but as an error chunk inside the stream, and the stream closes with [DONE]. Errors about the key, the model name or the request body are returned before the stream starts, as a normal JSON error response.

data: {"error":{"code":"node_timeout","message":"..."}}

data: [DONE]

Listing Your Device Models

GET /v1/node/models returns the models loaded on the devices connected to your account. If the same model is loaded on two of your devices, you get two rows (with different node_id values). A model can be used right now only if its ready field is true. This endpoint also works with personal keys only.

cURL
curl https://api.onysoft.com/v1/node/models \
  -H "Authorization: Bearer sk-ony-your-api-key"
JSON
{
  "success": true,
  "object": "list",
  "data": [
    {
      "id": "node/qwen3-4b-q4_k_m",
      "object": "model",
      "created": 1758369600,
      "owned_by": "cihazim",
      "name": "Qwen3 4B",
      "purpose": "genel",
      "context_window": 8192,
      "node_id": 12,
      "node_name": "MacBook Pro",
      "device_model_id": "node/qwen3-4b-q4_k_m@12",
      "online": true,
      "sharing": true,
      "model_status": "hazir",
      "ready": true,
      "last_seen_at": "2026-09-22T14:05:31+03:00",
      "pricing": {
        "input_per_million_tokens": 0,
        "output_per_million_tokens": 0,
        "currency": "USD"
      }
    }
  ],
  "total": 1
}
Field Meaning
idThe name to use as the model in your request; the request goes to one of your devices on which the model is ready.
device_model_idThe name to use to run the model on this device only.
node_id, node_nameThe device number and name.
node_nicknameThe nickname you gave the device in the dashboard; null if none.
readytrue when online and sharing are true and model_status is hazir (ready). Only then does the request run on that device.
onlineTrue if the device has contacted the server within the last 45 seconds.
sharingTrue if sharing is turned on in the Node app.
model_statusThe model's status on the device, returned as a Turkish value: hazir (ready), yukleniyor (loading), hata (error), durdu (stopped) or surum_eski (the app version on the device is no longer supported).
update_requiredIf true, the app version on the device is no longer supported and no requests are sent to this device; in that case model_status is surum_eski and ready is false. Update the app from the download page.
purposeWhat the model is meant for, returned as a Turkish value: genel (general), kod (code), hizli (fast), akil_yurutme (reasoning) or turkce (Turkish).
context_windowThe model's context window (tokens). It is <code>null</code> when unknown, in which case 8192 tokens is assumed.
last_seen_atWhen the device last contacted the server (ISO 8601).
pricingAlways 0, because using your own device is free.

Error Codes

Error responses have the same format as on the other endpoints: {"success": false, "error": {"code": "...", "message": "..."}}. Error messages are in Turkish.

Code code Description
400context_length_exceededThe request exceeds the model's context length. The server checks the estimated prompt length before sending it to the device; the same code is returned if the device reports a context overflow.
400invalid_requestThe request body is invalid: for example n is not 1, messages is not an array, or a parameter has the wrong type.
403node_owner_onlyThe key is not a personal key created in the dashboard (it is a project or partner key). Only personal keys can use device models.
403model_not_allowedYour key's model restriction does not allow this model.
404model_not_foundThe ID after node/ is not in the catalog, or the model name is misspelled.
413payload_too_largeThe messages exceed 256 KB, or the whole request body (messages, tools and format definitions) exceeds 512 KB.
422validation_errorGeneral request validation failed: the model or messages field is missing, or messages is not an array or is empty. The invalid fields are listed in error.fields.
429too_many_node_jobsAt most 4 requests can be processed on your devices at the same time. Returned with a Retry-After: 5 header; try again when earlier requests finish.
502node_errorYour device could not process the request. Check the model's status in the Node app and try again.
503node_unavailableYou have no online device with this model ready, or your device did not pick the request up in time (30 seconds without streaming, 60 seconds with streaming). A request that is not picked up is cancelled.
503node_update_requiredEvery device on which the model is ready runs an app version that is no longer supported. Update the app from the download page; your settings and models are kept.
503node_busyThe server's capacity for waiting device requests is full at the moment. Returned with a Retry-After: 5 header; try again in a few seconds.
504node_timeoutYour device could not produce the answer in time. Try again with a shorter message, a lower max_tokens, or stream:true.

Limits

Privacy and Security

Program Security

Download Onysoft AI Gateway Node only from the download page in your dashboard; do not use copies from other sources. The app accesses your computer and your account only as far as it needs to do its job:

Modifying the app, attempting to decompile it or repackaging it is prohibited by the Acceptable Use Policy (except where mandatory law permits). If you believe you have found a security vulnerability, please report it to info@onysoft.com.

App Updates

The app checks for a new version at startup and at regular intervals while it runs; when a new version is out, it tells you in its window and offers to open the download page. The app never updates itself; you download and install the update. Simply install the new version over the old one: your settings, device connection and downloaded models are kept.

system_update

Only the latest version is currently supported: earlier versions cannot be downloaded and cannot connect to the server. A device running an old version cannot start sharing, and your own requests are not sent to it either.

If every device on which the model is ready runs an unsupported version, the request returns 503 node_update_required. In the GET /v1/node/models response, such a device’s rows show update_required: true and model_status: "surum_eski", and ready is false.

Installing Models on Another Disk

Model files can take tens of GB. If your system disk is full, you can install models on a second or external disk: in the app, click the “Boş disk” (free disk) row on the hardware card and pick a disk from the list (the app’s interface is in Turkish). Models are installed in the OnysoftNode/models folder on the selected disk (OnysoftNodeDagitik/models for the distributed edition); the app itself, its settings and its log file always stay in the application folder.

Distributed Edition: One Model on Two Devices (beta)

Onysoft AI Gateway Node Dağıtık (distributed edition) is a separate app that runs a model which does not fit in a single computer’s memory (for example gpt-oss-20b, which does not fit on an 8 GB graphics card alone) on two of your own devices together. There is no model selection in the distributed app; you only open the device for computing (graphics card or processor). You choose and install the model in the dashboard based on the group’s total capacity, and the model’s layers are split between the two devices. Once the group is ready, the model is used as the main device’s model in the dashboard chat and in the API under the name node/<catalog_id>. The main app continues as it is; if the model fits on a single computer, the main app is faster.

hub

The distributed app is downloaded separately: see the “Distributed edition (beta)” section on the download page. Setup: (1) install the distributed app on both devices and approve the device code shown by the app with this account; (2) in the app, choose the graphics card or the processor and turn on “Hesaplamaya aç” (open for computing); (3) on the Device Groups page in the dashboard, create the group, add both devices, pick a model from the list and press “Install and open”; (4) give the approval each app asks for. After approval, the main device downloads the full model and the helper device downloads only its own share of layers from the model server. The distributed app can be installed next to the main app on the same computer; it keeps its settings and model files in a separate folder and appears as a separate device in the dashboard.

Limits

Group Connection Security

Pricing

Using your own device is free; nothing is deducted from your balance. Requests appear in your usage log with an amount of 0, and token counts and duration are still recorded.

Frequently Asked Questions

Why is there no separate endpoint?

OpenAI-compatible tools such as n8n, Cursor, LangChain and the OpenAI libraries expect /v1/chat/completions for chat. Because we use the same endpoint, you do not have to change the address or the key in these tools; you only change the model name. The node/ prefix makes it explicit that the request goes to your device, not to a catalog model.

What happens if my computer is off?

If none of your devices is online with the model ready, the request returns 503 node_unavailable. If your computer has only just shut down, the server still counts it as online for 45 seconds; in that case the request is queued and the error arrives once the pickup time runs out (30 seconds without streaming, 60 seconds with streaming). In a streaming request, this error arrives inside the stream as an error chunk. The request is never moved to another device or another model.

Can I use it with a project key?

No. Device models only work with the personal keys you create on the API Keys page of the dashboard; project and partner keys get 403 node_owner_only.

Can someone else use my device this way?

No. A request goes to the devices of the owner of the key that sent it. A request sent with your key only runs on your devices, and a request sent with someone else's key only runs on theirs.

Want help finding the right model?