The Native REST API¶
LM Studio's own API, in two generations. v0 mirrors the OpenAI shapes and adds telemetry; v1 is a different design, with server-stored conversations and model management. The gem uses both.
Path gotcha
Model management lives under /api/v1/models/, not directly under
/api/v1/ — it is POST /api/v1/models/load, not POST /api/v1/load.
Inference stats — :native_v0¶
POST /api/v0/chat/completions is a strict superset of /v1/chat/completions:
the same request — streaming, with_tools, with_schema and the request
extras all included — and the same choices and usage, but it fills in the
stats block that the OpenAI endpoint returns empty, and adds model_info and
runtime.
RubyLLM.configure { |config| config.lms_protocol = :native_v0 }
response = RubyLLM.chat(model: 'qwen/qwen3-4b', provider: :lms).ask('Hello')
response.raw.body['stats']
# => {"tokens_per_second" => 115.19, "time_to_first_token" => 0.0157,
# "generation_time" => 0.172, "stop_reason" => "eosFound"}
response.raw.body['runtime']['name'] # => "llama.cpp-mac-arm64-apple-metal-advsimd"
RubyLLM has no field for any of this, so it arrives through Message#raw.
Everything else behaves identically: this is the default protocol pointed at a
different URL. Reach for it when you want telemetry and the full Chat
Completions feature set.
/v1/chat/completions returns a stats key of its own, but it is {} on an
ordinary request; it carries draft-token counts only when the model was loaded
with a draft_model. The timing figures, model_info and runtime are
v0-only.
Stateful chat — :native_chat¶
POST /api/v1/chat offers capabilities the OpenAI surface cannot express:
chat = RubyLLM.chat(model: 'qwen/qwen3-4b', provider: :lms,
protocol: :native_chat, assume_model_exists: true)
response = chat.ask('Hello')
- Stateful conversations
- LM Studio stores each response server-side and continues from a
response_idinstead of replaying history. Ordinary RubyLLM multi-turn chats just work: each request sends only the new messages and pointsprevious_response_idat the last stored response. The id is onresponse.raw.body['response_id']and onresponse.raw_content, which RubyLLM persists — so a chat reloaded from the database (Railsacts_as_chat) continues where it left off. - Performance stats
response.raw.body['stats']carries tokens per second, time to first token and token counts;response.tokens(input, output, thinking) is filled from it.- Reasoning control
chat.with_thinkingmaps onto the nativereasoningsetting. RubyLLM's:noneeffort is sent as LM Studio'soff. Reasoning comes back asresponse.thinking.text, streamed as thinking chunks. See Reasoning.- Server-side MCP tools
with_provider_options(integrations: [...])has the server itself run MCP plugins frommcp.json({ id: 'mcp/playwright' }) or ephemeral MCP servers declared in the request (server_label/server_url), with optionalallowed_toolsfiltering. Executed tool calls appear inresponse.raw.body['output'].- Per-request context length
with_provider_options(context_length: 8192).- Opting out of storage
with_provider_options(store: false)keeps the conversation off the server. The chat is then single-turn: a secondaskraises, because the endpoint cannot replay history and has nothing stored to continue from.- Sampling settings
top_p,top_k,min_pandrepeat_penaltyare part of the native schema, sowith_provider_options(top_k: 40)works here too.
Limitations¶
- No client-side tools:
with_toolsraises. Use:chat_completions, or MCP integrations. - No structured output:
with_schemaraises. - Image input only as
data_urlparts. - Unknown request keys are rejected, so
ttlanddraft_modelraise aBadRequestErrorhere.
The endpoint reports no stop reason of its own. When a generation runs into
the max_output_tokens the request asked for, the provider reports
finish_reason: :length from the token counts. (Note the spelling: RubyLLM's
stock protocols report truncation as :max_tokens.)
Model listing and management¶
The native listings enrich provider.list_models, and the v1 management
endpoints back the provider's load_model, unload_model and friends. See
Models and Model Management.