# How to Configure API Keys for Different LLM Engines in SymbolicAI

> Learn how to configure API keys for various LLM engines in SymbolicAI. Securely manage credentials using symai.config.json and environment variables for seamless integration.

- Repository: [ExtensityAI/symbolicai](https://github.com/extensityai/symbolicai)
- Tags: how-to-guide
- Published: 2026-03-01

---

**SymbolicAI stores all API credentials in a JSON file named [`symai.config.json`](https://github.com/extensityai/symbolicai/blob/main/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`](https://github.com/extensityai/symbolicai/blob/main/symai.config.json) file using a three-layer priority system defined in [`symai/backend/settings.py`](https://github.com/extensityai/symbolicai/blob/main/symai/backend/settings.py). The framework searches for a `.symai` folder in the following order:

1. **Debug mode** – Current working directory (`./.symai/`)
2. **Environment-specific** – Python prefix directory (`<python-prefix>/.symai/`)
3. **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`](https://github.com/extensityai/symbolicai/blob/main/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`](https://github.com/extensityai/symbolicai/blob/main/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:

```json
{
  "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`](https://github.com/extensityai/symbolicai/blob/main/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:

```bash
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`](https://github.com/extensityai/symbolicai/blob/main/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`](https://github.com/extensityai/symbolicai/blob/main/symai/backend/engines/search/engine_openai.py) retrieves its credentials as follows:

```python

# 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`](https://github.com/extensityai/symbolicai/blob/main/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:

```python
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:

```bash
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.

```python

# 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.json`](https://github.com/extensityai/symbolicai/blob/main/symai.config.json) stored in a `.symai` directory to manage API keys for all LLM engines.
- The framework searches for `.symai` in 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 `SymAIConfig` class in [`symai/backend/settings.py`](https://github.com/extensityai/symbolicai/blob/main/symai/backend/settings.py) and the `_start_symai()` function in [`symai/__init__.py`](https://github.com/extensityai/symbolicai/blob/main/symai/__init__.py) handle 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`](https://github.com/extensityai/symbolicai/blob/main/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`](https://github.com/extensityai/symbolicai/blob/main/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.