Ellama with a custom OpenAI-compatible endpoint

In short: Ellama reaches models through the llm package, so it takes a provider object rather than a URL, and the constructor whose name ends in compatible is the one that accepts a custom host (the other targets OpenAI's own endpoint and ignores what you set). The default provider and the switchable alist are separate settings, and saved sessions default into the Emacs configuration tree, where a config format the editor also parses can turn them into a startup hang.

Ellama is the Emacs package that talks to language models without leaving the editor, and it does not implement any provider itself. It delegates to the llm Emacs library, which is why the configuration looks less like a list of settings and more like a Lisp expression.

That indirection is the feature, one interface, many backends, and it is also where the only important decision is made. Ellama does not take a URL. It takes a provider object, and the constructor you call decides both the URL and the request shape.

You need a key before the code below runs. Create an account, generate a key, and copy the base URL (https://aicomp.ai/v1). Create one free →
Check current rates → Free to sign up · $1 minimum top-up · No prepayment

Two constructors that differ by one word

The llm library exposes several constructors, and the two that matter here are easy to confuse:

ConstructorWhat it targets
make-llm-openaiOpenAI's own endpoint
make-llm-openai-compatibleany endpoint speaking the OpenAI chat format

The names differ by one word and the resulting behaviour differs entirely. Assign the first one and your requests go to OpenAI's servers no matter what URL you supply, because that constructor's job is to know the provider rather than to accept it. Assign the second and you supply the host, the key and the model explicitly.

The failure is quiet in a specific way: a missing or wrong credential against OpenAI produces an authentication error that reads like a key problem, and the variable you meant to set (the gateway address) is simply not consulted.

The provider object carries all three values

The compatible constructor takes the pieces a gateway needs, and they are all set in one expression:

Reading the key from an auth store is the idiomatic approach and also the one that avoids the class of problem where a key is set, non-empty and wrong because it was written with quoting that survived into the value.

For a private endpoint the key still has to be non-empty, even when the server does not check it. That is a library requirement rather than authentication, and a placeholder is the normal answer.

One default provider, plus an alist of named ones

Ellama separates the default from the set you switch between:

Setting only the default is fine until you want to compare two models, at which point you need the alist and a name for each entry. Adding entries to the alist does not change the default, and that mismatch, a configured provider that never gets used, looks like a configuration that failed to load.

Sessions write to disk, and the default directory can bite

Ellama saves conversations, and the storage location defaults to somewhere inside your Emacs configuration tree. In a distribution that keeps its config in a format Emacs also tries to parse (the common case being an org-based config directory) the session files land in a directory that the editor then reads, and the result is a hang on startup rather than an error message.

Pointing the sessions directory at a cache location outside the config tree removes the problem entirely. It is a one-line change that is much harder to diagnose after the fact, because the symptom appears in the editor rather than in Ellama.

Agent loops read project instructions

Ellama also runs multi-step agent loops: plan, call tools, read project context, continue from the previous turn. Those loops load instructions from a project file and can invoke reusable prompts, and tool calls are subject to a policy layer that can block reads, writes and shell commands.

That matters for cost more than for correctness. An agent loop resends its context each turn and appends tool output, so the input column grows with the length of the task rather than with the size of the prompt.

What a chat-and-agent editor costs

This is a mixed workload: conversational commands, one-shot transformations over a buffer or region, and the occasional multi-step loop.

A working month runs about 150k input and 45k output tokens a day, which is 3M input and 0.9M output over 20 working days. The output share is higher than a pure completion plugin's, because a chat session produces prose rather than a short insertion.

Per 1M input / output tokens and a 20-day month
ModelGateway rate
in / out per 1M tokens
One day20 days
deepseek-v4-pro$0.66 / $1.98$0.19$3.76
claude-sonnet-5$1.00 / $5.00$0.38$7.50
qwen3.8-max$1.00 / $3.00$0.29$5.70
gpt-5.6-terra$1.00 / $6.00$0.42$8.40

One day = 150k input + 45k output on this page's workload. 20 days = 3M input and 0.9M output. Rates checked 2026-10-15, gateway rates move with upstream promotions, so verify the current number in your dashboard before committing to a budget.

Across 221 catalogue models that publish both rates, the median output rate is 4.0× the input rate, and 69% of them (153 models) charge at least 4× more for output than input. The other 624 raw catalogue entries are dropped by cleaning (test entries, dated snapshots and non-chat variants) not for a missing rate. This is why an agent workload is decided on the output column, not the input one everyone quotes.

Mixing a cheap model for buffer transformations with a stronger one for sessions is the usual pattern here. The <a href="/guides/cheapest-models-by-workload/">re-ranked index</a> sorts by workload shape rather than by input price, which is the comparison a mixed client actually needs.

FAQ

FAQ

Does Ellama support any OpenAI-compatible endpoint?

Yes, through the llm library's compatible constructor, which takes an explicit URL, key and chat model. It is not tied to OpenAI or to Ollama, even though those are the two configurations most examples show.

Why does Ellama ignore the URL I set?

Most often the wrong constructor. make-llm-openai targets OpenAI's own endpoint and does not accept a custom host; make-llm-openai-compatible does. The two names differ by one word.

Can I keep several endpoints configured at once?

Yes — ellama-providers is an alist of named providers that the selection command cycles through, while ellama-provider sets the default. Adding to the alist does not change the default.

Does a local endpoint need an API key?

The value has to be non-empty for the client to construct, but a local or unauthenticated server will not check it. A placeholder is expected rather than a misconfiguration.

Why does Emacs hang after I use Ellama?

Check where sessions are written. The default sits inside the configuration tree, and a config directory that Emacs also parses can turn saved session files into a startup hang. Moving the sessions directory out of the config tree resolves it.

Related

Get API access

GPT rate card