GoodMemGoodMem
How-To Guides

Endpoint registration guide

Register embedders, rerankers, and LLMs with provider-specific base URLs and api_path behavior.

Endpoint registration guide

This page shows how to register embedders, rerankers, and LLMs with GoodMem and documents how endpoint_url and api_path are used.

Endpoint fields

GoodMem stores endpoints as two fields:

  • endpoint_url: absolute base URL (scheme + host + optional base path). Example: https://api.openai.com/v1.
  • api_path: provider route appended to the base. Example: /embeddings or /chat/completions.

GoodMem combines them for HTTP calls and the proxy. Example:

  • endpoint_url = https://api.openai.com/v1 + api_path = /embeddings -> https://api.openai.com/v1/embeddings
  • endpoint_url = https://api.jina.ai + api_path = /v1/embeddings -> https://api.jina.ai/v1/embeddings

GoodMem does not move /v1 between fields. Put the base path where the provider expects it.

api_path values and base URLs

If api_path is omitted or blank, GoodMem uses the provider default summarized below. For embedders and LLMs, use the standard api_path values shown here. For rerankers, you can override api_path unless the table says "fixed". DashScope is dialect-specific and is covered in the doctor-first section below. endpoint_url is required; use the suggested base URLs below.

Embedders

Tip: TEI defaults to port 3000 when run as a binary. The official Docker examples often map host port 8080 to container port 80. Use the port you actually run TEI on.

Provider typeSuggested endpoint_url (base)api_path
COHEREhttps://api.cohere.comfixed /v2/embed
JINAhttps://api.jina.aifixed /v1/embeddings
TEIhttp://<host>:<port>fixed /embed
OPENAIhttps://api.openai.com/v1fixed /embeddings
VLLMhttp://<host>:<port>/v1fixed /embeddings
LLAMA_CPPhttp://<host>:<port>/v1fixed /embeddings
VOYAGEhttps://api.voyageai.com/v1fixed /embeddings
GEMINIhttps://generativelanguage.googleapis.com or https://aiplatform.googleapis.combackend-specific; see Gemini below
DASHSCOPERegional DashScope base URLdialect-specific; use goodmem doctor as described below

Rerankers

Provider typeSuggested endpoint_url (base)api_path
COHEREhttps://api.cohere.comdefault /v2/rerank (override via api_path)
JINAhttps://api.jina.aidefault /v1/rerank (override via api_path)
TEIhttp://<host>:<port>fixed /rerank
VLLMhttp://<host>:<port>/v1default /rerank (override via api_path)
LLAMA_CPPhttp://<host>:<port>/v1default /rerank (override via api_path)
VOYAGEhttps://api.voyageai.com/v1default /rerank (override via api_path)
DASHSCOPERegional DashScope base URLdialect-specific; use goodmem doctor as described below

LLMs

Provider typeSuggested endpoint_url (base)api_path
OPENAIhttps://api.openai.com/v1fixed /chat/completions
LITELLM_PROXYhttps://<host>/v1fixed /chat/completions
OPEN_ROUTERhttps://openrouter.ai/api/v1fixed /chat/completions
VLLMhttp://<host>:<port>/v1fixed /chat/completions
OLLAMAhttp://<host>:11434/v1fixed /chat/completions
LLAMA_CPPhttp://<host>:<port>/v1fixed /chat/completions
CUSTOM_OPENAI_COMPATIBLEhttps://<host>/v1fixed /chat/completions
DASHSCOPERegional DashScope base URLdialect-specific; use goodmem doctor as described below

Gemini

GoodMem supports gemini-embedding-2 on the Gemini provider. The current server execution contract is dense, text-only embedding with dimensions from 128 through 3,072 and at most 8,192 input tokens.

geminiEndpointConfig selects one of two API backends:

BackendprojectIdlocationAPI versionCredentials
DEVELOPERMust be omittedMust be omitted/v1betaGemini API key or Google ADC
GOOGLE_CLOUDRequired resource projectOptional; defaults to global/v1Google ADC

The Google Cloud resource project is distinct from the optional ADC quota project. The resource project identifies the inference path; the quota project controls quota and billing attribution. Gemini API-key header and prefix overrides are not accepted because GoodMem owns the native Gemini authentication envelope.

Developer API

goodmem embedder create \
  --display-name "Gemini Developer API" \
  --provider-type GEMINI \
  --endpoint-url "https://generativelanguage.googleapis.com" \
  --api-path "/v1beta" \
  --model-identifier "gemini-embedding-2" \
  --dimensionality 1536 \
  --max-sequence-length 8192 \
  --gemini-api-backend developer \
  --cred-api-key-prompt

The equivalent REST payload uses the provider-specific geminiEndpointConfig object:

{
  "displayName": "Gemini Developer API",
  "providerType": "GEMINI",
  "endpointUrl": "https://generativelanguage.googleapis.com",
  "apiPath": "/v1beta",
  "modelIdentifier": "gemini-embedding-2",
  "dimensionality": 1536,
  "distributionType": "DENSE",
  "maxSequenceLength": 8192,
  "supportedModalities": ["TEXT"],
  "credentials": {
    "kind": "CREDENTIAL_KIND_API_KEY",
    "apiKey": { "inlineSecret": "YOUR_GEMINI_API_KEY" }
  },
  "geminiEndpointConfig": { "backend": "DEVELOPER" }
}

Google Cloud

goodmem embedder create \
  --display-name "Gemini Google Cloud" \
  --provider-type GEMINI \
  --endpoint-url "https://aiplatform.googleapis.com" \
  --api-path "/v1" \
  --model-identifier "gemini-embedding-2" \
  --dimensionality 1536 \
  --max-sequence-length 8192 \
  --gemini-api-backend google-cloud \
  --gemini-project-id "my-resource-project" \
  --cred-gcp \
  --cred-gcp-scope "https://www.googleapis.com/auth/cloud-platform" \
  --cred-gcp-quota "my-billing-project"
{
  "displayName": "Gemini Google Cloud",
  "providerType": "GEMINI",
  "endpointUrl": "https://aiplatform.googleapis.com",
  "apiPath": "/v1",
  "modelIdentifier": "gemini-embedding-2",
  "dimensionality": 1536,
  "distributionType": "DENSE",
  "maxSequenceLength": 8192,
  "supportedModalities": ["TEXT"],
  "credentials": {
    "kind": "CREDENTIAL_KIND_GCP_ADC",
    "gcpAdc": {
      "scopes": ["https://www.googleapis.com/auth/cloud-platform"],
      "quotaProjectId": "my-billing-project"
    }
  },
  "geminiEndpointConfig": {
    "backend": "GOOGLE_CLOUD",
    "projectId": "my-resource-project",
    "location": "global"
  }
}

Registration recipes

The CLI examples use the gRPC API. The cURL examples call the REST API.

export GOODMEM_SERVER="https://localhost:9090"
export GOODMEM_REST_URL="http://localhost:8080"
export GOODMEM_API_KEY="gm_your_key"

REST scripting notes

  • REST JSON uses camelCase fields: endpointUrl, apiPath, dashscopeApiDialect, embedderId, rerankerId, llmId.
  • apiPath is optional; if you omit it, GoodMem applies the provider default. DashScope resolves its default from the selected or inferred dialect described below.
  • For OpenAI-compatible providers, endpointUrl must end with /v1 (not /v1/embeddings or /v1/chat/completions).
  • If you do set apiPath, do not duplicate base paths already present in endpointUrl (for example, https://api.voyageai.com/v1 + /v1/rerank is invalid).
  • Create responses include the resource ID in the JSON body and a Location header (see create embedder, create reranker, and create LLM).
  • For idempotent scripts, pass a client ID (embedderId, rerankerId, llmId). A 409 means the resource already exists; list or look up the existing resource and reuse its ID.
  • If your REST endpoint uses HTTPS with a self-signed certificate, curl needs -k or a trusted CA, and HTTPie needs --verify=no or --verify=/path/to/ca.pem.

DashScope: use doctor first

Alibaba Cloud Model Studio (DashScope) has regional hosts and several request/response dialects on different paths. API keys are region-specific, and a valid model can still fail when its host, path, and request dialect do not agree. For that reason, verify the configuration before registering it:

goodmem doctor llm "https://dashscope-intl.aliyuncs.com" \
  --model "qwen-plus" \
  --probe-dialect \
  --cred-api-key-prompt

Replace llm with embedder or reranker as needed. Active dialect probes send a minimal request, require an API key, and may incur provider usage. Doctor reports the proposed endpoint_url, api_path, and dashscope_api_dialect; checks model and regional-host compatibility where possible; and prints a corresponding goodmem ... create command.

Use the regional base URL assigned to your API key. Common shared endpoints include https://dashscope.aliyuncs.com (China/Beijing), https://dashscope-intl.aliyuncs.com (Singapore), https://dashscope-us.aliyuncs.com (US/Virginia), and https://cn-hongkong.dashscope.aliyuncs.com (China/Hong Kong).

Resourcedashscope_api_dialect / --dashscope-api-dialectCanonical api_path
EmbedderEMBEDDING_NATIVE_TEXT/api/v1/services/embeddings/text-embedding/text-embedding
EmbedderEMBEDDING_NATIVE_CONTENTS/api/v1/services/embeddings/multimodal-embedding/multimodal-embedding
EmbedderOPENAI_COMPATIBLE/compatible-mode/v1/embeddings
RerankerRERANK_NATIVE_NESTED/api/v1/services/rerank/text-rerank/text-rerank
RerankerRERANK_COMPATIBLE_FLAT/compatible-api/v1/reranks
LLMLLM_NATIVE_TEXT/api/v1/services/aigc/text-generation/generation
LLMLLM_NATIVE_MULTIMODAL/api/v1/services/aigc/multimodal-generation/generation
LLMOPENAI_COMPATIBLE/compatible-mode/v1/chat/completions

Workspace-scoped Singapore reranker endpoints may instead use /compatible-mode/v1/reranks; GoodMem recognizes that path as RERANK_COMPATIBLE_FLAT, but does not suggest it for shared hosts.

For REST requests, use the camelCase field dashscopeApiDialect. If you omit the dialect, GoodMem first recognizes an explicit known path. With neither value supplied, embedders and rerankers prefer their native APIs (using the model catalog as an advisory hint), while LLMs default to the OpenAI-compatible API. An explicit dialect is recommended for custom paths so the request envelope is unambiguous.

Replace model identifiers and dimensionality with your actual values.

Embedders

The CLI examples pass provider secrets with --cred-api-key. To keep secrets out of shell history and process listings, export GOODMEM_CRED_API_KEY instead and omit the flag; the CLI reads the environment variable when the flag is absent.

OpenAI (official endpoint):

goodmem embedder create \
  --display-name "OpenAI Embedder" \
  --provider-type OPENAI \
  --endpoint-url "https://api.openai.com/v1" \
  --model-identifier "text-embedding-3-small" \
  --dimensionality 1536 \
  --distribution-type DENSE \
  --cred-api-key "OPENAI_API_KEY"
curl -sS --json @- "$GOODMEM_REST_URL/v1/embedders" \
  --header "x-api-key: $GOODMEM_API_KEY" <<'JSON'
{
  "displayName": "OpenAI Embedder",
  "providerType": "OPENAI",
  "endpointUrl": "https://api.openai.com/v1",
  "modelIdentifier": "text-embedding-3-small",
  "dimensionality": 1536,
  "distributionType": "DENSE",
  "credentials": {
    "kind": "CREDENTIAL_KIND_API_KEY",
    "apiKey": {
      "inlineSecret": "OPENAI_API_KEY"
    }
  }
}
JSON
http POST "$GOODMEM_REST_URL/v1/embedders" \
  x-api-key:"$GOODMEM_API_KEY" \
  displayName="OpenAI Embedder" \
  providerType="OPENAI" \
  endpointUrl="https://api.openai.com/v1" \
  modelIdentifier="text-embedding-3-small" \
  dimensionality:=1536 \
  distributionType="DENSE" \
  credentials:='{
    "kind": "CREDENTIAL_KIND_API_KEY",
    "apiKey": {
      "inlineSecret": "OPENAI_API_KEY"
    }
  }'

vLLM (OpenAI-compatible embeddings):

goodmem embedder create \
  --display-name "vLLM Embedder" \
  --provider-type VLLM \
  --endpoint-url "http://vllm-host:8000/v1" \
  --model-identifier "all-MiniLM-L6-v2" \
  --dimensionality 384 \
  --distribution-type DENSE
curl -sS --json @- "$GOODMEM_REST_URL/v1/embedders" \
  --header "x-api-key: $GOODMEM_API_KEY" <<'JSON'
{
  "displayName": "vLLM Embedder",
  "providerType": "VLLM",
  "endpointUrl": "http://vllm-host:8000/v1",
  "modelIdentifier": "all-MiniLM-L6-v2",
  "dimensionality": 384,
  "distributionType": "DENSE"
}
JSON
http POST "$GOODMEM_REST_URL/v1/embedders" \
  x-api-key:"$GOODMEM_API_KEY" \
  displayName="vLLM Embedder" \
  providerType="VLLM" \
  endpointUrl="http://vllm-host:8000/v1" \
  modelIdentifier="all-MiniLM-L6-v2" \
  dimensionality:=384 \
  distributionType="DENSE"

TEI (Text Embeddings Inference):

goodmem embedder create \
  --display-name "TEI Embedder" \
  --provider-type TEI \
  --endpoint-url "http://tei-host:8080" \
  --model-identifier "Qwen3-Embedding-0.6B" \
  --dimensionality 1024 \
  --distribution-type DENSE
curl -sS --json @- "$GOODMEM_REST_URL/v1/embedders" \
  --header "x-api-key: $GOODMEM_API_KEY" <<'JSON'
{
  "displayName": "TEI Embedder",
  "providerType": "TEI",
  "endpointUrl": "http://tei-host:8080",
  "modelIdentifier": "Qwen3-Embedding-0.6B",
  "dimensionality": 1024,
  "distributionType": "DENSE"
}
JSON
http POST "$GOODMEM_REST_URL/v1/embedders" \
  x-api-key:"$GOODMEM_API_KEY" \
  displayName="TEI Embedder" \
  providerType="TEI" \
  endpointUrl="http://tei-host:8080" \
  modelIdentifier="Qwen3-Embedding-0.6B" \
  dimensionality:=1024 \
  distributionType="DENSE"

Llama.cpp (OpenAI-compatible embeddings):

goodmem embedder create \
  --display-name "Llama.cpp Embedder" \
  --provider-type LLAMA_CPP \
  --endpoint-url "http://llama-cpp-host:8080/v1" \
  --model-identifier "all-MiniLM-L6-v2" \
  --dimensionality 384 \
  --distribution-type DENSE
curl -sS --json @- "$GOODMEM_REST_URL/v1/embedders" \
  --header "x-api-key: $GOODMEM_API_KEY" <<'JSON'
{
  "displayName": "Llama.cpp Embedder",
  "providerType": "LLAMA_CPP",
  "endpointUrl": "http://llama-cpp-host:8080/v1",
  "modelIdentifier": "all-MiniLM-L6-v2",
  "dimensionality": 384,
  "distributionType": "DENSE"
}
JSON
http POST "$GOODMEM_REST_URL/v1/embedders" \
  x-api-key:"$GOODMEM_API_KEY" \
  displayName="Llama.cpp Embedder" \
  providerType="LLAMA_CPP" \
  endpointUrl="http://llama-cpp-host:8080/v1" \
  modelIdentifier="all-MiniLM-L6-v2" \
  dimensionality:=384 \
  distributionType="DENSE"

Voyage AI:

goodmem embedder create \
  --display-name "Voyage Embedder" \
  --provider-type VOYAGE \
  --endpoint-url "https://api.voyageai.com/v1" \
  --model-identifier "voyage-3-large" \
  --dimensionality 1024 \
  --distribution-type DENSE \
  --cred-api-key "VOYAGE_API_KEY"
curl -sS --json @- "$GOODMEM_REST_URL/v1/embedders" \
  --header "x-api-key: $GOODMEM_API_KEY" <<'JSON'
{
  "displayName": "Voyage Embedder",
  "providerType": "VOYAGE",
  "endpointUrl": "https://api.voyageai.com/v1",
  "modelIdentifier": "voyage-3-large",
  "dimensionality": 1024,
  "distributionType": "DENSE",
  "credentials": {
    "kind": "CREDENTIAL_KIND_API_KEY",
    "apiKey": {
      "inlineSecret": "VOYAGE_API_KEY"
    }
  }
}
JSON
http POST "$GOODMEM_REST_URL/v1/embedders" \
  x-api-key:"$GOODMEM_API_KEY" \
  displayName="Voyage Embedder" \
  providerType="VOYAGE" \
  endpointUrl="https://api.voyageai.com/v1" \
  modelIdentifier="voyage-3-large" \
  dimensionality:=1024 \
  distributionType="DENSE" \
  credentials:='{
    "kind": "CREDENTIAL_KIND_API_KEY",
    "apiKey": {
      "inlineSecret": "VOYAGE_API_KEY"
    }
  }'

Cohere:

goodmem embedder create \
  --display-name "Cohere Embedder" \
  --provider-type COHERE \
  --endpoint-url "https://api.cohere.com" \
  --model-identifier "embed-english-v3.0" \
  --dimensionality 1024 \
  --distribution-type DENSE \
  --cred-api-key "COHERE_API_KEY"
curl -sS --json @- "$GOODMEM_REST_URL/v1/embedders" \
  --header "x-api-key: $GOODMEM_API_KEY" <<'JSON'
{
  "displayName": "Cohere Embedder",
  "providerType": "COHERE",
  "endpointUrl": "https://api.cohere.com",
  "modelIdentifier": "embed-english-v3.0",
  "dimensionality": 1024,
  "distributionType": "DENSE",
  "credentials": {
    "kind": "CREDENTIAL_KIND_API_KEY",
    "apiKey": {
      "inlineSecret": "COHERE_API_KEY"
    }
  }
}
JSON
http POST "$GOODMEM_REST_URL/v1/embedders" \
  x-api-key:"$GOODMEM_API_KEY" \
  displayName="Cohere Embedder" \
  providerType="COHERE" \
  endpointUrl="https://api.cohere.com" \
  modelIdentifier="embed-english-v3.0" \
  dimensionality:=1024 \
  distributionType="DENSE" \
  credentials:='{
    "kind": "CREDENTIAL_KIND_API_KEY",
    "apiKey": {
      "inlineSecret": "COHERE_API_KEY"
    }
  }'

Jina:

goodmem embedder create \
  --display-name "Jina Embedder" \
  --provider-type JINA \
  --endpoint-url "https://api.jina.ai" \
  --model-identifier "jina-embeddings-v3" \
  --dimensionality 1024 \
  --distribution-type DENSE \
  --cred-api-key "JINA_API_KEY"
curl -sS --json @- "$GOODMEM_REST_URL/v1/embedders" \
  --header "x-api-key: $GOODMEM_API_KEY" <<'JSON'
{
  "displayName": "Jina Embedder",
  "providerType": "JINA",
  "endpointUrl": "https://api.jina.ai",
  "modelIdentifier": "jina-embeddings-v3",
  "dimensionality": 1024,
  "distributionType": "DENSE",
  "credentials": {
    "kind": "CREDENTIAL_KIND_API_KEY",
    "apiKey": {
      "inlineSecret": "JINA_API_KEY"
    }
  }
}
JSON
http POST "$GOODMEM_REST_URL/v1/embedders" \
  x-api-key:"$GOODMEM_API_KEY" \
  displayName="Jina Embedder" \
  providerType="JINA" \
  endpointUrl="https://api.jina.ai" \
  modelIdentifier="jina-embeddings-v3" \
  dimensionality:=1024 \
  distributionType="DENSE" \
  credentials:='{
    "kind": "CREDENTIAL_KIND_API_KEY",
    "apiKey": {
      "inlineSecret": "JINA_API_KEY"
    }
  }'

Rerankers

TEI (cross-encoder reranking):

goodmem reranker create \
  --display-name "TEI Reranker" \
  --provider-type TEI \
  --endpoint-url "http://tei-host:8080" \
  --model-identifier "cross-encoder/ms-marco-MiniLM-L-6-v2"
curl -sS --json @- "$GOODMEM_REST_URL/v1/rerankers" \
  --header "x-api-key: $GOODMEM_API_KEY" <<'JSON'
{
  "displayName": "TEI Reranker",
  "providerType": "TEI",
  "endpointUrl": "http://tei-host:8080",
  "modelIdentifier": "cross-encoder/ms-marco-MiniLM-L-6-v2"
}
JSON
http POST "$GOODMEM_REST_URL/v1/rerankers" \
  x-api-key:"$GOODMEM_API_KEY" \
  displayName="TEI Reranker" \
  providerType="TEI" \
  endpointUrl="http://tei-host:8080" \
  modelIdentifier="cross-encoder/ms-marco-MiniLM-L-6-v2"

vLLM (Jina-compatible rerank API):

goodmem reranker create \
  --display-name "vLLM Reranker" \
  --provider-type VLLM \
  --endpoint-url "http://vllm-host:8000/v1" \
  --model-identifier "BAAI/bge-reranker-v2-m3"
curl -sS --json @- "$GOODMEM_REST_URL/v1/rerankers" \
  --header "x-api-key: $GOODMEM_API_KEY" <<'JSON'
{
  "displayName": "vLLM Reranker",
  "providerType": "VLLM",
  "endpointUrl": "http://vllm-host:8000/v1",
  "modelIdentifier": "BAAI/bge-reranker-v2-m3"
}
JSON
http POST "$GOODMEM_REST_URL/v1/rerankers" \
  x-api-key:"$GOODMEM_API_KEY" \
  displayName="vLLM Reranker" \
  providerType="VLLM" \
  endpointUrl="http://vllm-host:8000/v1" \
  modelIdentifier="BAAI/bge-reranker-v2-m3"

Llama.cpp (Jina-compatible rerank API):

goodmem reranker create \
  --display-name "Llama.cpp Reranker" \
  --provider-type LLAMA_CPP \
  --endpoint-url "http://llama-cpp-host:8080/v1" \
  --model-identifier "BAAI/bge-reranker-v2-m3"
curl -sS --json @- "$GOODMEM_REST_URL/v1/rerankers" \
  --header "x-api-key: $GOODMEM_API_KEY" <<'JSON'
{
  "displayName": "Llama.cpp Reranker",
  "providerType": "LLAMA_CPP",
  "endpointUrl": "http://llama-cpp-host:8080/v1",
  "modelIdentifier": "BAAI/bge-reranker-v2-m3"
}
JSON
http POST "$GOODMEM_REST_URL/v1/rerankers" \
  x-api-key:"$GOODMEM_API_KEY" \
  displayName="Llama.cpp Reranker" \
  providerType="LLAMA_CPP" \
  endpointUrl="http://llama-cpp-host:8080/v1" \
  modelIdentifier="BAAI/bge-reranker-v2-m3"

Jina:

goodmem reranker create \
  --display-name "Jina Reranker" \
  --provider-type JINA \
  --endpoint-url "https://api.jina.ai" \
  --model-identifier "jina-reranker-v2-base-multilingual" \
  --cred-api-key "JINA_API_KEY"
curl -sS --json @- "$GOODMEM_REST_URL/v1/rerankers" \
  --header "x-api-key: $GOODMEM_API_KEY" <<'JSON'
{
  "displayName": "Jina Reranker",
  "providerType": "JINA",
  "endpointUrl": "https://api.jina.ai",
  "modelIdentifier": "jina-reranker-v2-base-multilingual",
  "credentials": {
    "kind": "CREDENTIAL_KIND_API_KEY",
    "apiKey": {
      "inlineSecret": "JINA_API_KEY"
    }
  }
}
JSON
http POST "$GOODMEM_REST_URL/v1/rerankers" \
  x-api-key:"$GOODMEM_API_KEY" \
  displayName="Jina Reranker" \
  providerType="JINA" \
  endpointUrl="https://api.jina.ai" \
  modelIdentifier="jina-reranker-v2-base-multilingual" \
  credentials:='{
    "kind": "CREDENTIAL_KIND_API_KEY",
    "apiKey": {
      "inlineSecret": "JINA_API_KEY"
    }
  }'

Voyage AI:

goodmem reranker create \
  --display-name "Voyage Reranker" \
  --provider-type VOYAGE \
  --endpoint-url "https://api.voyageai.com/v1" \
  --model-identifier "rerank-2.5" \
  --cred-api-key "VOYAGE_API_KEY"
curl -sS --json @- "$GOODMEM_REST_URL/v1/rerankers" \
  --header "x-api-key: $GOODMEM_API_KEY" <<'JSON'
{
  "displayName": "Voyage Reranker",
  "providerType": "VOYAGE",
  "endpointUrl": "https://api.voyageai.com/v1",
  "modelIdentifier": "rerank-2.5",
  "credentials": {
    "kind": "CREDENTIAL_KIND_API_KEY",
    "apiKey": {
      "inlineSecret": "VOYAGE_API_KEY"
    }
  }
}
JSON
http POST "$GOODMEM_REST_URL/v1/rerankers" \
  x-api-key:"$GOODMEM_API_KEY" \
  displayName="Voyage Reranker" \
  providerType="VOYAGE" \
  endpointUrl="https://api.voyageai.com/v1" \
  modelIdentifier="rerank-2.5" \
  credentials:='{
    "kind": "CREDENTIAL_KIND_API_KEY",
    "apiKey": {
      "inlineSecret": "VOYAGE_API_KEY"
    }
  }'

Cohere:

goodmem reranker create \
  --display-name "Cohere Reranker" \
  --provider-type COHERE \
  --endpoint-url "https://api.cohere.com" \
  --model-identifier "rerank-english-v3.0" \
  --cred-api-key "COHERE_API_KEY"
curl -sS --json @- "$GOODMEM_REST_URL/v1/rerankers" \
  --header "x-api-key: $GOODMEM_API_KEY" <<'JSON'
{
  "displayName": "Cohere Reranker",
  "providerType": "COHERE",
  "endpointUrl": "https://api.cohere.com",
  "modelIdentifier": "rerank-english-v3.0",
  "credentials": {
    "kind": "CREDENTIAL_KIND_API_KEY",
    "apiKey": {
      "inlineSecret": "COHERE_API_KEY"
    }
  }
}
JSON
http POST "$GOODMEM_REST_URL/v1/rerankers" \
  x-api-key:"$GOODMEM_API_KEY" \
  displayName="Cohere Reranker" \
  providerType="COHERE" \
  endpointUrl="https://api.cohere.com" \
  modelIdentifier="rerank-english-v3.0" \
  credentials:='{
    "kind": "CREDENTIAL_KIND_API_KEY",
    "apiKey": {
      "inlineSecret": "COHERE_API_KEY"
    }
  }'

LLMs

The LLM recipes below use OpenAI-compatible providers, whose endpoint_url normally ends in /v1 and whose api_path defaults to /chat/completions. DashScope is the exception; use the doctor-first workflow above to select its regional host, path, and dialect.

OpenAI:

goodmem llm create \
  --display-name "OpenAI LLM" \
  --provider-type OPENAI \
  --endpoint-url "https://api.openai.com/v1" \
  --model-identifier "gpt-4o" \
  --supports-chat \
  --cred-api-key "OPENAI_API_KEY"
curl -sS --json @- "$GOODMEM_REST_URL/v1/llms" \
  --header "x-api-key: $GOODMEM_API_KEY" <<'JSON'
{
  "displayName": "OpenAI LLM",
  "providerType": "OPENAI",
  "endpointUrl": "https://api.openai.com/v1",
  "modelIdentifier": "gpt-4o",
  "capabilities": {
    "supportsChat": true
  },
  "credentials": {
    "kind": "CREDENTIAL_KIND_API_KEY",
    "apiKey": {
      "inlineSecret": "OPENAI_API_KEY"
    }
  }
}
JSON
http POST "$GOODMEM_REST_URL/v1/llms" \
  x-api-key:"$GOODMEM_API_KEY" \
  displayName="OpenAI LLM" \
  providerType="OPENAI" \
  endpointUrl="https://api.openai.com/v1" \
  modelIdentifier="gpt-4o" \
  capabilities:='{"supportsChat": true}' \
  credentials:='{
    "kind": "CREDENTIAL_KIND_API_KEY",
    "apiKey": {
      "inlineSecret": "OPENAI_API_KEY"
    }
  }'

LiteLLM Proxy:

goodmem llm create \
  --display-name "LiteLLM Proxy" \
  --provider-type LITELLM_PROXY \
  --endpoint-url "https://litellm-host/v1" \
  --model-identifier "gpt-4o" \
  --supports-chat \
  --cred-api-key "LITELLM_API_KEY"
curl -sS --json @- "$GOODMEM_REST_URL/v1/llms" \
  --header "x-api-key: $GOODMEM_API_KEY" <<'JSON'
{
  "displayName": "LiteLLM Proxy",
  "providerType": "LITELLM_PROXY",
  "endpointUrl": "https://litellm-host/v1",
  "modelIdentifier": "gpt-4o",
  "capabilities": {
    "supportsChat": true
  },
  "credentials": {
    "kind": "CREDENTIAL_KIND_API_KEY",
    "apiKey": {
      "inlineSecret": "LITELLM_API_KEY"
    }
  }
}
JSON
http POST "$GOODMEM_REST_URL/v1/llms" \
  x-api-key:"$GOODMEM_API_KEY" \
  displayName="LiteLLM Proxy" \
  providerType="LITELLM_PROXY" \
  endpointUrl="https://litellm-host/v1" \
  modelIdentifier="gpt-4o" \
  capabilities:='{"supportsChat": true}' \
  credentials:='{
    "kind": "CREDENTIAL_KIND_API_KEY",
    "apiKey": {
      "inlineSecret": "LITELLM_API_KEY"
    }
  }'

OpenRouter:

goodmem llm create \
  --display-name "OpenRouter" \
  --provider-type OPEN_ROUTER \
  --endpoint-url "https://openrouter.ai/api/v1" \
  --model-identifier "openai/gpt-4o" \
  --supports-chat \
  --cred-api-key "OPENROUTER_API_KEY"
curl -sS --json @- "$GOODMEM_REST_URL/v1/llms" \
  --header "x-api-key: $GOODMEM_API_KEY" <<'JSON'
{
  "displayName": "OpenRouter",
  "providerType": "OPEN_ROUTER",
  "endpointUrl": "https://openrouter.ai/api/v1",
  "modelIdentifier": "openai/gpt-4o",
  "capabilities": {
    "supportsChat": true
  },
  "credentials": {
    "kind": "CREDENTIAL_KIND_API_KEY",
    "apiKey": {
      "inlineSecret": "OPENROUTER_API_KEY"
    }
  }
}
JSON
http POST "$GOODMEM_REST_URL/v1/llms" \
  x-api-key:"$GOODMEM_API_KEY" \
  displayName="OpenRouter" \
  providerType="OPEN_ROUTER" \
  endpointUrl="https://openrouter.ai/api/v1" \
  modelIdentifier="openai/gpt-4o" \
  capabilities:='{"supportsChat": true}' \
  credentials:='{
    "kind": "CREDENTIAL_KIND_API_KEY",
    "apiKey": {
      "inlineSecret": "OPENROUTER_API_KEY"
    }
  }'

vLLM:

goodmem llm create \
  --display-name "vLLM LLM" \
  --provider-type VLLM \
  --endpoint-url "http://vllm-host:8000/v1" \
  --model-identifier "your-llm-model" \
  --supports-chat
curl -sS --json @- "$GOODMEM_REST_URL/v1/llms" \
  --header "x-api-key: $GOODMEM_API_KEY" <<'JSON'
{
  "displayName": "vLLM LLM",
  "providerType": "VLLM",
  "endpointUrl": "http://vllm-host:8000/v1",
  "modelIdentifier": "your-llm-model",
  "capabilities": {
    "supportsChat": true
  }
}
JSON
http POST "$GOODMEM_REST_URL/v1/llms" \
  x-api-key:"$GOODMEM_API_KEY" \
  displayName="vLLM LLM" \
  providerType="VLLM" \
  endpointUrl="http://vllm-host:8000/v1" \
  modelIdentifier="your-llm-model" \
  capabilities:='{"supportsChat": true}'

Ollama:

goodmem llm create \
  --display-name "Ollama LLM" \
  --provider-type OLLAMA \
  --endpoint-url "http://ollama-host:11434/v1" \
  --model-identifier "llama3.1" \
  --supports-chat
curl -sS --json @- "$GOODMEM_REST_URL/v1/llms" \
  --header "x-api-key: $GOODMEM_API_KEY" <<'JSON'
{
  "displayName": "Ollama LLM",
  "providerType": "OLLAMA",
  "endpointUrl": "http://ollama-host:11434/v1",
  "modelIdentifier": "llama3.1",
  "capabilities": {
    "supportsChat": true
  }
}
JSON
http POST "$GOODMEM_REST_URL/v1/llms" \
  x-api-key:"$GOODMEM_API_KEY" \
  displayName="Ollama LLM" \
  providerType="OLLAMA" \
  endpointUrl="http://ollama-host:11434/v1" \
  modelIdentifier="llama3.1" \
  capabilities:='{"supportsChat": true}'

Llama.cpp:

goodmem llm create \
  --display-name "Llama.cpp LLM" \
  --provider-type LLAMA_CPP \
  --endpoint-url "http://llama-cpp-host:8080/v1" \
  --model-identifier "your-llm-model" \
  --supports-chat
curl -sS --json @- "$GOODMEM_REST_URL/v1/llms" \
  --header "x-api-key: $GOODMEM_API_KEY" <<'JSON'
{
  "displayName": "Llama.cpp LLM",
  "providerType": "LLAMA_CPP",
  "endpointUrl": "http://llama-cpp-host:8080/v1",
  "modelIdentifier": "your-llm-model",
  "capabilities": {
    "supportsChat": true
  }
}
JSON
http POST "$GOODMEM_REST_URL/v1/llms" \
  x-api-key:"$GOODMEM_API_KEY" \
  displayName="Llama.cpp LLM" \
  providerType="LLAMA_CPP" \
  endpointUrl="http://llama-cpp-host:8080/v1" \
  modelIdentifier="your-llm-model" \
  capabilities:='{"supportsChat": true}'

Custom OpenAI-compatible endpoint:

If your endpoint does not require authentication, omit --cred-api-key in the CLI and the credentials object in the REST examples.

goodmem llm create \
  --display-name "Custom LLM" \
  --provider-type CUSTOM_OPENAI_COMPATIBLE \
  --endpoint-url "https://your-custom-host/v1" \
  --model-identifier "your-model" \
  --supports-chat \
  --cred-api-key "OPTIONAL_API_KEY"
curl -sS --json @- "$GOODMEM_REST_URL/v1/llms" \
  --header "x-api-key: $GOODMEM_API_KEY" <<'JSON'
{
  "displayName": "Custom LLM",
  "providerType": "CUSTOM_OPENAI_COMPATIBLE",
  "endpointUrl": "https://your-custom-host/v1",
  "modelIdentifier": "your-model",
  "capabilities": {
    "supportsChat": true
  },
  "credentials": {
    "kind": "CREDENTIAL_KIND_API_KEY",
    "apiKey": {
      "inlineSecret": "OPTIONAL_API_KEY"
    }
  }
}
JSON
http POST "$GOODMEM_REST_URL/v1/llms" \
  x-api-key:"$GOODMEM_API_KEY" \
  displayName="Custom LLM" \
  providerType="CUSTOM_OPENAI_COMPATIBLE" \
  endpointUrl="https://your-custom-host/v1" \
  modelIdentifier="your-model" \
  capabilities:='{"supportsChat": true}' \
  credentials:='{
    "kind": "CREDENTIAL_KIND_API_KEY",
    "apiKey": {
      "inlineSecret": "OPTIONAL_API_KEY"
    }
  }'

Does api_path affect inference?

Not always. Some provider integrations use SDKs or generated clients that hardcode the route, so api_path is fixed and ignored at inference time:

  • Embedders: OPENAI, VLLM, LLAMA_CPP, VOYAGE (OpenAI SDK), TEI (TEI client), JINA (Jina4j), COHERE (Cohere SDK)
  • Rerankers: TEI (TEI client)
  • LLMs: OPENAI, LITELLM_PROXY, OPEN_ROUTER, VLLM, OLLAMA, LLAMA_CPP, and CUSTOM_OPENAI_COMPATIBLE (OpenAI SDK)

api_path is used for rerankers that call Jina-compatible HTTP endpoints (JINA, VLLM, LLAMA_CPP, VOYAGE, COHERE) and for every DashScope resource type. In those cases, put only the base host (and any required base path) in endpoint_url, and put the operation route in api_path. DashScope additionally uses dashscope_api_dialect to choose the matching request and response envelope.

When to override api_path

Only override api_path when the provider route differs from the defaults above and the integration uses it at inference time: the Jina-compatible reranker cases and DashScope. For DashScope, keep the path and dialect aligned; goodmem doctor is the easiest way to verify the pair.