How to Configure API Keys for Different LLM Engines in SymbolicAI
SymbolicAI stores all API credentials in a JSON file named symai.config.json located inside a .symai directory, supporting environment variable overrides for secure, production-ready deployments.
Configuring API keys for multiple LLM backends in SymbolicAI requires understanding its hierarchical configuration system. The framework, maintained in the extensityai/symbolicai repository, uses a centralized settings manager to resolve credentials at runtime and inject them into specialized engines for neuro-symbolic reasoning, search, embeddings, and more.
Configuration File Location and Priority
SymbolicAI resolves the symai.config.json file using a three-layer priority system defined in symai/backend/settings.py. The framework searches for a .symai folder in the following order:
- Debug mode – Current working directory (
./.symai/) - Environment-specific – Python prefix directory (
<python-prefix>/.symai/) - Global (home) – User home directory (
~/.symai/)
The first location found wins. This allows developers to keep project-specific keys in a local folder while falling back to global settings for shared credentials.
The symai.config.json Schema for LLM Engines
Each engine expects a specific key suffix pattern ending with _ENGINE_API_KEY. The configuration manager in symai/__init__.py populates the global SYMAI_CONFIG dictionary with these values, which engines then access via self.config.
| JSON Key | Target Engine |
|---|---|
NEUROSYMBOLIC_ENGINE_API_KEY |
Neuro-symbolic LLMs (OpenAI, Anthropic, Google, Groq, DeepSeek, Cerebras) |
SEARCH_ENGINE_API_KEY |
Search backends (OpenAI, Perplexity, SerpAPI, Firecrawl) |
EMBEDDING_ENGINE_API_KEY |
Embedding providers (OpenAI, Azure, Cohere) |
DRAWING_ENGINE_API_KEY |
Image generation (OpenAI DALL-E, Stable Diffusion) |
TEXT_TO_SPEECH_ENGINE_API_KEY |
TTS services (OpenAI, ElevenLabs) |
OCR_ENGINE_API_KEY |
OCR services (Apilayer, Google Vision) |
INDEXING_ENGINE_API_KEY |
Vector databases (Qdrant, Pinecone) |
FASTAPI_API_KEY |
Optional authentication for the built-in FastAPI server |
A minimal configuration file targeting OpenAI models looks like this:
{
"NEUROSYMBOLIC_ENGINE_MODEL": "gpt-4o-mini",
"NEUROSYMBOLIC_ENGINE_API_KEY": "sk-your-openai-key",
"SEARCH_ENGINE_MODEL": "gpt-4o-mini",
"SEARCH_ENGINE_API_KEY": "sk-your-openai-key",
"EMBEDDING_ENGINE_MODEL": "text-embedding-3-large",
"EMBEDDING_ENGINE_API_KEY": "sk-your-openai-key",
"DRAWING_ENGINE_MODEL": "dall-e-3",
"DRAWING_ENGINE_API_KEY": "sk-your-openai-key",
"TEXT_TO_SPEECH_ENGINE_MODEL": "tts-1",
"TEXT_TO_SPEECH_ENGINE_API_KEY": "sk-your-openai-key"
}
Setting API Keys via Environment Variables
SymbolicAI supports environment variable overrides to avoid persisting secrets on disk. The bootstrap function _start_symai() in symai/__init__.py loads the JSON configuration first, then overlays any matching environment variables, with environment values taking precedence.
Set variables using the same key names defined in the JSON schema:
export NEUROSYMBOLIC_ENGINE_API_KEY="sk-your-openai-key"
export SEARCH_ENGINE_API_KEY="sk-your-openai-key"
export EMBEDDING_ENGINE_API_KEY="sk-your-openai-key"
This pattern is recommended for CI/CD pipelines and production deployments where committing credentials poses a security risk.
How Engines Consume Configuration at Runtime
The configuration flow follows a strict path from file to execution context. The SymAIConfig class in symai/backend/settings.py resolves the file location, while _start_symai() initializes three global dictionaries: SYMAI_CONFIG, SYMSH_CONFIG, and SYMSERVER_CONFIG.
Individual engines receive these values through the shared configuration dictionary. For example, the OpenAI search engine in symai/backend/engines/search/engine_openai.py retrieves its credentials as follows:
# symai/backend/engines/search/engine_openai.py
class GPTXSearchEngine(Engine):
def __init__(self, api_key: str | None = None, model: str | None = None):
# If caller passes a key, store it; otherwise read from config.
if api_key is not None and model is not None:
self.config["SEARCH_ENGINE_API_KEY"] = api_key
self.api_key = self.config.get("SEARCH_ENGINE_API_KEY")
self.client = OpenAI(api_key=self.api_key)
This pattern ensures that engines automatically pick up keys from symai.config.json or environment variables without manual wiring in user code.
Verifying Your Configuration
You can inspect the active configuration at runtime to confirm that keys are loaded correctly. Access the global SYMAI_CONFIG dictionary directly:
from symai import SYMAI_CONFIG
print("Neuro-symbolic key:", SYMAI_CONFIG.get("NEUROSYMBOLIC_ENGINE_API_KEY"))
print("Search key:", SYMAI_CONFIG.get("SEARCH_ENGINE_API_KEY"))
print("Embedding key:", SYMAI_CONFIG.get("EMBEDDING_ENGINE_API_KEY"))
Alternatively, use the built-in CLI helper:
symconfig
This command prints the resolved configuration path and loaded values, helping debug path resolution issues when multiple .symai directories exist.
Complete End-to-End Example
The following script demonstrates the full workflow: setting environment variables, initializing the framework, and verifying that an engine receives the correct API key.
# demo_config.py
import os
from symai import SYMAI_CONFIG, _start_symai
# 1. Set keys via environment variables (recommended for production)
os.environ["NEUROSYMBOLIC_ENGINE_API_KEY"] = "sk-openai-demo-key"
os.environ["SEARCH_ENGINE_API_KEY"] = "sk-openai-demo-key"
# 2. Initialise the framework (loads config, populates SYMAI_CONFIG)
_start_symai()
# 3. Verify configuration
print("Loaded neuro-symbolic key:", SYMAI_CONFIG.get("NEUROSYMBOLIC_ENGINE_API_KEY"))
# 4. Use an LLM-backed engine – the key is automatically injected
from symai.backend.engines.search.engine_openai import GPTXSearchEngine
search_engine = GPTXSearchEngine()
print("Engine instance API key:", search_engine.api_key)
Run this after installing SymbolicAI (pip install symbolicai or uv sync --all-extras --dev) to confirm your setup works without manual credential passing.
Summary
- SymbolicAI uses a JSON file named
symai.config.jsonstored in a.symaidirectory to manage API keys for all LLM engines. - The framework searches for
.symaiin three locations: current working directory (debug), Python prefix (environment), and home directory (global), in that order of priority. - Each engine expects a specific key ending in
_ENGINE_API_KEY(e.g.,NEUROSYMBOLIC_ENGINE_API_KEY,SEARCH_ENGINE_API_KEY). - Environment variables override JSON values, allowing secure CI/CD usage without committing secrets.
- The
SymAIConfigclass insymai/backend/settings.pyand the_start_symai()function insymai/__init__.pyhandle loading and global distribution of these settings.
Frequently Asked Questions
What file name and format does SymbolicAI use for API keys?
SymbolicAI expects a JSON file named exactly symai.config.json. This file must reside inside a folder named .symai (hidden on Unix systems). The JSON structure contains key-value pairs where keys follow the pattern <ENGINE_TYPE>_ENGINE_API_KEY, such as NEUROSYMBOLIC_ENGINE_API_KEY or EMBEDDING_ENGINE_API_KEY.
Can I use environment variables instead of the JSON config file?
Yes. SymbolicAI checks for environment variables using the same key names defined in the JSON schema (e.g., NEUROSYMBOLIC_ENGINE_API_KEY). The bootstrap process in symai/__init__.py loads the JSON file first, then overlays environment variables, with environment values taking precedence. This is the recommended approach for production and CI/CD pipelines.
Where should I place the .symai folder in a production deployment?
For production, use the environment-specific location (<python-prefix>/.symai/) or rely on environment variables exclusively. Avoid committing the .symai folder in your project root to prevent accidental secret leakage. If you must use the global location (~/.symai/), ensure the file permissions are restrictive (e.g., chmod 600) so only the owner can read the API keys.
How do I check if my API key is loaded correctly?
You can verify the active configuration by importing the global SYMAI_CONFIG dictionary from the symai module and printing the specific key. Alternatively, run the symconfig command in your terminal, which outputs the resolved configuration path and loaded values, helping you debug path resolution issues when multiple .symai directories exist.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →