Last reviewed: November 9, 2026 (Asia/Shanghai); sources fetched November 8 UTC.
Direct answer
For a gptel CometAPI setup, register a named backend with gptel-make-openai, set :host to api.cometapi.com, and set :endpoint to /v1/chat/completions. Supply a function that reads your CometAPI key privately, and list an exact model ID whose documentation supports that route. Select the backend and model in a fresh text buffer before sending.
The gptel backend constructor
combines protocol, host, and endpoint. Its :host field takes a hostname, whereas the CometAPI quickstart
gives SDK clients a base URL ending in /v1. Translate those fields deliberately so the final request uses the documented Chat Completions path.
Inspect the request before the first live send. The gptel manual explains that ordinary sending uses the active region or buffer text up to point, and separately added context can also accompany a request. A small visible prompt does not, by itself, describe the complete payload.
Who this is for
This guide is for Emacs users who already have gptel installed and want a separate CometAPI text-chat configuration. Use the installation instructions for your chosen gptel release, including its Transient dependency, and compare that release’s function help with the references below. These references include the project’s moving development branch; record your installed package version rather than assuming every release behaves identically.
You need a CometAPI key and a verified Chat Completions model ID. The procedure below is based on current primary documentation and source inspection. No Emacs executable or authenticated generation was available in the preparation environment, so the configuration and acceptance checks were not executed here.
Key takeaways
- Give the backend a distinct name and supply the host separately from the operation path.
- Keep the credential value out of your init file and share only nonsecret setup details.
- Use an exact model ID from the current public catalog and check its endpoint documentation.
- Apply the initial settings to a new buffer, with streaming, tools, and added context disabled.
- Inspect the JSON payload before sending, then record the observed result of one small request.
Contract details to verify
Start with the CometAPI model catalog reference
. It documents public GET /api/models access without an Authorization header. Review the candidate’s exact id, model type, endpoint hints, and upcoming flag. Follow its model documentation when available. Catalog metadata helps choose a model; it does not prove your account’s access or that a particular request succeeds.
Endpoint hints may be strings, arrays, objects, or null; a string can contain encoded JSON. A familiar display name is therefore insufficient evidence for choosing the Chat Completions route. Do not interpret missing context or output limits as unlimited capacity.
| Setting | Initial value | Reason |
|---|---|---|
| Backend name | CometAPI text | Identifies this local configuration |
| Protocol | https | Matches the documented API transport |
| Host | api.cometapi.com | Contains neither scheme nor path |
| Endpoint | /v1/chat/completions | Supplies the complete operation path |
| Model | Exact reviewed catalog ID | Matches the API’s routing identifier |
| Key | Function reading COMETAPI_KEY | Avoids a credential literal in configuration |
| Initial request | Non-streaming text, no tools | Gives the first check a small scope |
Make COMETAPI_KEY available through your normal private process-launch configuration. Set the nonsecret COMETAPI_MODEL variable to the ID you reviewed. A GUI-launched Emacs or an existing Emacs daemon needs those values in its own process environment. Changing a terminal’s environment does not establish what an already running editor inherited.
Use the repository practices in keeping CometAPI keys out of tutorial repositories when saving this configuration. Avoid printing the environment or evaluating a key-returning function interactively without discarding its result.
Register the backend and create a dedicated buffer
Load this after gptel is installed. It registers the backend and defines a command for a fresh text buffer. The model variable is read when this configuration is evaluated; the key is read when requested by the backend.
(require 'gptel)
(require 'gptel-openai)
(defun my-cometapi-key ()
(let ((key (getenv "COMETAPI_KEY")))
(unless (and key (string-match-p "\\S-" key))
(user-error "COMETAPI_KEY is missing"))
key))
(let ((model (getenv "COMETAPI_MODEL")))
(unless (and model
(> (length model) 0)
(not (string-match-p "[[:space:]]" model)))
(user-error "Set COMETAPI_MODEL to a verified model ID"))
(gptel-make-openai "CometAPI text"
:protocol "https"
:host "api.cometapi.com"
:endpoint "/v1/chat/completions"
:key #'my-cometapi-key
:stream nil
:models (list (intern model))))
(defun my-cometapi-chat ()
(interactive)
(let ((backend (gptel-get-backend "CometAPI text")))
(switch-to-buffer
(generate-new-buffer "*CometAPI text check*"))
(text-mode)
(gptel-mode 1)
(setq-local
gptel-backend backend
gptel-model (car (gptel-backend-models backend))
gptel-stream nil
gptel-use-tools nil
gptel-tools nil
gptel-use-context nil
gptel-track-media nil
gptel-temperature nil
gptel-max-tokens nil
gptel-system-prompt "Reply concisely in plain text."
gptel-expert-commands t)
(message "CometAPI buffer ready; inspect before sending")))
The constructor’s default header function supplies Bearer authentication using the configured key. An explicit :key function avoids depending on another backend’s credential variable. The gptel request implementation
supports function-based key resolution and defines the context, media, and tool options used here.
The command sets its options locally in the new buffer. It does not select CometAPI as the global default. Existing presets, prompt transformations, and extensions can still alter request construction in a customized installation; inspect the resulting payload before relying on the intended settings.
This example leaves the output limit unset. In the inspected compatible backend, a non-nil gptel-max-tokens becomes the API field max_tokens. The CometAPI Chat Completions reference
describes that as a legacy field and documents max_completion_tokens for its GPT-6 Astra examples. Match any output-limit configuration to the selected model and verify the emitted JSON. A concise system prompt is a writing instruction, not an enforced token ceiling.
Inspect and send the first request
Run M-x my-cometapi-chat, then insert a harmless prompt:
Reply with EMACS_ROUTE_OK and one short sentence about text editing.
Put point at the end of that prompt and deactivate any region. Open M-x gptel-menu. With expert commands enabled, the manual documents dry-run inspection options that produce the request payload without sending it. Choose Inspect query (JSON) and inspect the generated buffer locally.
Require the reviewed model ID, the intended short user message, the concise system message, and non-streaming behavior. Confirm that no tool definitions or unrelated file contents appear. Because this setup disables added context, a previously registered context file should not be injected through the normal context mechanism. Custom prompt transformations still need their own review.
Do not assume a JSON body preview proves the destination or credential header. Check the backend’s host and endpoint independently. Where approved diagnostics expose the request URL, confirm those components without exporting authorization data. Avoid copying generated curl commands into shared notes: inspect them for credential material first.
Close the preview without sending from it, return to the original chat buffer, and use M-x gptel-send once. Keep the buffer contents and settings unchanged between inspection and send. gptel also supports sending from an inspected payload; this procedure uses the original buffer so the baseline remains easy to repeat.
Record whether a nonempty answer completes. The requested marker is a convenient fixture, not a guarantee of deterministic output. Retain the observation time, Emacs and gptel versions, backend name, model ID, configured route, and observed outcome. Include an HTTP status only when actually exposed. A successful short reply establishes that request, leaving tools, media, and streaming for separate checks.
Check the local failure path
You can exercise the missing-key guard without changing the running editor’s environment permanently or making a model request. Evaluate this expression after loading the configuration:
(let ((process-environment (copy-sequence process-environment)))
(setenv "COMETAPI_KEY" nil)
(condition-case nil
(progn (my-cometapi-key) 'unexpected-key)
(user-error 'missing-key-guard-ok)))
The expected value is missing-key-guard-ok. This checks only the local helper; it does not test transport dispatch or remote authentication. The expression discards any successful key return, so it does not display a credential.
For an actual request failure, stop after the first error and identify its stage. Check configuration loading, credential availability, endpoint selection, and model parameters in that order. Change one relevant setting and repeat the smallest necessary check. A timeout leaves remote execution uncertain; avoid repeatedly generating while diagnosing it.
Failure modes
| Symptom | Likely boundary to inspect | Useful next action |
|---|---|---|
| Backend command cannot load | Installed package and function availability | Check the installed release’s help and dependencies |
| Model variable error | Launch environment | Supply a nonempty exact model ID, then reload the registration |
| Missing-key error | Emacs process environment | Restore the credential privately; do not print its value |
Wrong route or duplicated /v1 | Host/path composition | Restore the hostname and full endpoint as separate fields |
| Unsupported output parameter | Model-specific request contract | Inspect the emitted limit field before changing token counts |
| Unexpected text in the preview | Buffer selection, context, presets, or hooks | Remove unintended input and repeat the dry run |
| No incremental text | Initial non-streaming configuration | Expect insertion after completion; test streaming separately |
An active region changes the ordinary prompt scope; point changes how much buffer text precedes the request. Added context is another mechanism. Disabling tools does not remove text already present in the prompt. These distinctions matter when moving from a disposable buffer to real project material.
FAQ
Should :host contain the SDK base URL?
Use only api.cometapi.com in this field. The constructor adds the protocol and endpoint, while the SDK base URL in CometAPI’s quickstart includes /v1.
Does the model appear automatically from CometAPI’s catalog?
This setup supplies one model explicitly through :models. Refresh the public catalog yourself when choosing another model, check its route, reload the backend registration, and open a new test buffer.
Does gptel-use-context set to nil send an empty request?
It disables the additional-context mechanism. The active region or buffer text up to point still supplies the ordinary prompt. Inspect both the user and system messages before sending.
Can I turn on streaming or tools after text works?
Treat each as a separate capability change. Streaming needs compatible service and client behavior; tools also require suitable model support and locally configured functions. Repeat focused acceptance checks for the capability you add.
Reader next step
Choose one current Chat Completions model, register the backend, and create the dedicated buffer. Complete the local missing-key check, inspect the short request, and send it once. Keep the sanitized configuration and observed result as your baseline.
For Neovim, the CodeCompanion connection guide covers a different adapter contract. Its URL fields and context controls should be translated deliberately.
Need an account or credential first? Start with CometAPI , then return to the same small request check.
Sources checked
- gptel manual — installation, sending scope, additional context, expert commands, and request inspection.
- gptel compatible-backend implementation — constructor arguments, URL composition, Bearer header construction, model registration, and emitted Chat Completions fields.
- gptel request implementation — key lookup, backend lookup, model representation, and context, streaming, media, and tool options.
- CometAPI OpenAI-compatible quickstart — API host, v1 base URL, Bearer authentication, and Chat Completions route.
- CometAPI model catalog reference — public catalog access, exact IDs, endpoint metadata, capability fields, and missing-limit meanings.
- CometAPI Chat Completions reference — streaming and model-specific output-limit parameters.
All six primary references were fetched successfully on November 8, 2026 UTC. They support an evergreen integration task. The isolated buffer, conservative capability settings, and acceptance sequence are recommendations derived from those references; they are not recorded editor-test results.