---
title: "Global Configuration"
description: "Set up AI providers, API keys, and project-wide defaults in your config.php – applies across every Panel view and section."
canonical_url: "https://kirby.tools/docs/copilot/configuration/global"
---

# Global Configuration

> Set up AI providers, API keys, and project-wide defaults in your config.php – applies across every Panel view and section.

## AI Provider Configuration

Kirby Copilot supports multiple AI providers. You must configure at least one provider with valid credentials for the plugin to function.

<card-group>
<card icon="i-simple-icons-openai" title="OpenAI" to="https://platform.openai.com">

The latest GPT-5 family models for content generation.

</card>

<card icon="i-simple-icons-google" title="Google" to="https://aistudio.google.com/api-keys">

Gemini models. Recommended for blocks and layout generation. Free tier available!

</card>

<card icon="i-simple-icons-anthropic" title="Anthropic" to="https://console.anthropic.com">

Claude models for nuanced content generation.

</card>

<card icon="i-simple-icons-mistralai" title="Mistral" to="https://console.mistral.ai">

European AI models with custom base URL support.

</card>
</card-group>

<note>

For generating [Blocks and Layouts](/docs/copilot/advanced/blocks-and-layouts) or other structured data, we recommend Google Gemini models. Create a new [Google API key](https://aistudio.google.com/api-keys) and add it to the configuration along with the AI model such as Gemini 3.1 Pro. Usage is currently free!

</note>

### Basic Provider Setup

All provider configurations are nested under the `johannschopplich.copilot` key:

```php [config.php]
return [
    'johannschopplich.copilot' => [
        'provider' => 'google', // Choose your primary provider
        'providers' => [
            'google' => [
                'apiKey' => 'YOUR_API_KEY',
                // Model for content generation
                'model' => 'gemini-3.1-pro-preview',
                // Model for writer field inline suggestions
                'completionModel' => 'gemini-3.5-flash'
            ]
        ]
    ]
];
```

Each provider supports two model configurations:

- **model**: Used for content generation (text, blocks, layouts).
- **completionModel**: Used for inline suggestions in writer fields (should be fast and lightweight).

### Provider Examples

<code-group>

```php [OpenAI]
return [
    'johannschopplich.copilot' => [
        'provider' => 'openai',
        'providers' => [
            'openai' => [
                'apiKey' => env('OPENAI_API_KEY'),
                'model' => 'gpt-5.6-terra'
            ]
        ]
    ]
];
```

```php [Google Gemini]
return [
    'johannschopplich.copilot' => [
        'provider' => 'google',
        'providers' => [
            'google' => [
                'apiKey' => env('GOOGLE_API_KEY'),
                'model' => 'gemini-3.1-pro-preview'
            ]
        ]
    ]
];
```

```php [Anthropic Claude]
return [
    'johannschopplich.copilot' => [
        'provider' => 'anthropic',
        'providers' => [
            'anthropic' => [
                'apiKey' => env('ANTHROPIC_API_KEY'),
                'model' => 'claude-sonnet-5'
            ]
        ]
    ]
];
```

```php [Mistral]
return [
    'johannschopplich.copilot' => [
        'provider' => 'mistral',
        'providers' => [
            'mistral' => [
                'apiKey' => env('MISTRAL_API_KEY'),
                'model' => 'mistral-medium-latest',
                // Optional: custom base URL
                'baseUrl' => 'https://api.mistral.ai'
            ]
        ]
    ]
];
```

</code-group>

### Default Models

If you do not specify a `model` or `completionModel`, Kirby Copilot uses sensible defaults for each provider:

<table>
<thead>
  <tr>
    <th>
      Provider
    </th>
    
    <th>
      Generation Model (<code>
        model
      </code>
      
      )
    </th>
    
    <th>
      Completion Model (<code>
        completionModel
      </code>
      
      )
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      OpenAI
    </td>
    
    <td>
      <code>
        gpt-5.6-terra
      </code>
    </td>
    
    <td>
      <code>
        gpt-5.4-nano
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      Google
    </td>
    
    <td>
      <code>
        gemini-3.1-pro-preview
      </code>
    </td>
    
    <td>
      <code>
        gemini-3.5-flash
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      Anthropic
    </td>
    
    <td>
      <code>
        claude-sonnet-5
      </code>
    </td>
    
    <td>
      <code>
        claude-haiku-4-5
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      Mistral
    </td>
    
    <td>
      <code>
        mistral-medium-latest
      </code>
    </td>
    
    <td>
      <code>
        mistral-small-latest
      </code>
    </td>
  </tr>
</tbody>
</table>

<tip>

The `completionModel` is used for [inline suggestions](/docs/copilot/usage/inline-suggestions) in writer fields. It should be a fast, lightweight model optimized for quick inline suggestions.

</tip>

<warning>

Behind an AI gateway, set `completionModel` yourself whenever your `model` carries a prefix from another provider – `google-ai-studio/gemini-3.5-flash` under `provider: 'openai'`, for example. Copilot won't guess one across gateways, so inline suggestions fail until you set it. See [Routing Multiple Providers Through One Gateway](#routing-multiple-providers-through-one-gateway).

</warning>

## AI Generation Settings

### `systemPrompt` <u-badge className="align-middle,ml-2,rounded-full!" label="String" variant="subtle"></u-badge>

Global system prompt that defines how the AI should structure and approach content generation. This can be overridden by view button props or section configuration.

The default prompt formats the response per field type and preserves formatting in a selection – override it only when your project needs different rules.

<callout color="info" icon="i-ri-ai-generate" to="/docs/copilot/configuration/system-prompt">

Learn more about the default system prompt and when to customize it.

</callout>

### `excludedBlocks` <u-badge className="align-middle,ml-2,rounded-full!" label="Array" variant="subtle"></u-badge>

Specify block types to exclude from structured data generation in [blocks and layout fields](/docs/copilot/advanced/blocks-and-layouts). This is useful for custom block types for which AI generation is not desired.

**Default:** `[]` (no blocks excluded)

```php [config.php]
return [
    'johannschopplich.copilot' => [
        'excludedBlocks' => ['custom-form', 'widget', 'advertisement'],
    ]
];
```

### `reasoningEffort` <u-badge className="align-middle,ml-2,rounded-full!" label="String" variant="subtle"></u-badge>

Controls the depth of reasoning applied during content generation. Configure the effort once – it is translated to each provider's native reasoning controls automatically. Models without reasoning support simply ignore the setting.

**Default:** `low`<br />

**Options:** `provider-default`, `none`, `minimal`, `low`, `medium`, `high`, `xhigh`

```php [config.php]
return [
    'johannschopplich.copilot' => [
        'reasoningEffort' => 'medium'
    ]
];
```

Use `provider-default` to let the provider pick its own reasoning depth – equivalent to not sending a reasoning setting at all. Not every model supports every level; providers clamp unsupported values to the nearest supported one.

<note>

Modern AI models are designed as reasoning models with different underlying architectures. The model manages creativity internally based on the reasoning effort level, making manual `temperature` configuration obsolete.

</note>

### `completion` <u-badge className="align-middle,ml-2,rounded-full!" label="Array | Boolean" variant="subtle"></u-badge>

Controls inline suggestions in writer fields. Inline suggestions are enabled by default for all writer fields.

**Default:** `['debounce' => 1000]`

Set it to `false` to stop ghost text from appearing on its own. The manual trigger, <kbd value="meta">



</kbd>

 <kbd value=",">



</kbd>

, keeps working:

```php [config.php]
return [
    'johannschopplich.copilot' => [
        'completion' => false
    ]
];
```

To customize the debounce timing (minimum 500ms):

```php [config.php]
return [
    'johannschopplich.copilot' => [
        'completion' => [
            'debounce' => 1500 // Wait 1.5 seconds after typing stops
        ]
    ]
];
```

<callout color="info" icon="i-ri-ai-generate" to="/docs/copilot/usage/inline-suggestions">

Learn more about inline suggestions behavior and keyboard shortcuts.

</callout>

### `promptTemplates` <u-badge className="align-middle,ml-2,rounded-full!" label="Array" variant="subtle"></u-badge>

Define prompt templates that appear for all Panel users. Config-defined templates are read-only and displayed alongside user-created templates.

**Default:** `[]` (uses built-in defaults)

<tabs>
<tabs-item label="Basic">

```php [config.php]
return [
    'johannschopplich.copilot' => [
        'promptTemplates' => [
            [
                'label' => 'Apply House Style',
                'prompt' => 'Format the text according to our editorial style: artist names in bold, album titles in italics, use curly quotation marks.'
            ],
            [
                'label' => 'Add Spotify Links',
                'prompt' => 'Find all album titles in the text and wrap them in Markdown links to their Spotify pages.'
            ]
        ]
    ]
];
```

</tabs-item>

<tabs-item label="Multilingual">

```php [config.php]
return [
    'johannschopplich.copilot' => [
        'promptTemplates' => [
            [
                'label' => [
                    'en' => 'Apply House Style',
                    'de' => 'Redaktionsstil anwenden'
                ],
                'prompt' => [
                    'en' => 'Format the text according to our editorial style: artist names in bold, album titles in italics, use curly quotation marks.',
                    'de' => 'Formatiere den Text nach unserem Redaktionsstil: Künstlernamen fett, Albumtitel kursiv, typografische Anführungszeichen verwenden.'
                ]
            ]
        ]
    ]
];
```

</tabs-item>
</tabs>

<note>

When config templates are defined, they replace the built-in default templates. Existing user templates saved in local storage are preserved and remain editable.

</note>

<callout color="info" icon="i-ri-bookmark-line" to="/docs/copilot/prompt-dialog/templates#config-defined-templates">

Learn more about prompt templates and how they appear in the Panel.

</callout>

### `skills` <u-badge className="align-middle,ml-2,rounded-full!" label="Array" variant="subtle"></u-badge> <u-badge className="align-middle,rounded-full" label="since v3.7.0" variant="subtle"></u-badge>

Define reusable prompt instructions – tone, style, or house rules – that editors invoke via `@skill://` mentions in the prompt editor.

**Default:** `[]`

<tabs>
<tabs-item label="Basic">

```php [config.php]
return [
    'johannschopplich.copilot' => [
        'skills' => [
            [
                'id' => 'brand-voice',
                'label' => 'Brand Voice',
                'instructions' => 'Write in a warm, conversational tone. Avoid corporate jargon. Prefer short sentences.'
            ]
        ]
    ]
];
```

</tabs-item>

<tabs-item label="Multilingual">

```php [config.php]
return [
    'johannschopplich.copilot' => [
        'skills' => [
            [
                'id' => 'brand-voice',
                'label' => [
                    'en' => 'Brand Voice',
                    'de' => 'Markenstimme'
                ],
                'instructions' => [
                    'en' => 'Write in a warm, conversational tone. Avoid corporate jargon. Prefer short sentences.',
                    'de' => 'Schreibe in einem warmen, gesprächigen Ton. Vermeide Fachjargon. Bevorzuge kurze Sätze.'
                ]
            ]
        ]
    ]
];
```

</tabs-item>
</tabs>

<callout color="info" icon="i-ri-sparkling-line" to="/docs/copilot/prompt-dialog/skills">

Learn more about how editors invoke skills in the Panel.

</callout>

### `baseUrl` <u-badge className="align-middle,ml-2,rounded-full!" label="String" variant="subtle"></u-badge>

Custom base URL for the AI provider API. This property is configured per provider alongside `apiKey` and `model`. Useful when using proxy services, custom API endpoints, or self-hosted AI services like llama.cpp.

**Default:** Provider-specific default URL

```php [config.php]
return [
    'johannschopplich.copilot' => [
        'provider' => 'openai',
        'providers' => [
            'openai' => [
                'apiKey' => env('OPENAI_API_KEY'),
                'model' => 'llama-3.2-3b-instruct',
                'baseUrl' => 'https://llama.example.com/v1'
            ]
        ]
    ]
];
```

### `api` <u-badge className="align-middle,ml-2,rounded-full!" label="String" variant="subtle"></u-badge> <u-badge className="align-middle,mb-1,rounded-full" label="since v3.6.0" variant="subtle"></u-badge>

Selects the OpenAI API variant the Panel calls. Defaults to the Responses API (`/v1/responses`). Set to `chat` when your endpoint only exposes `/v1/chat/completions`. PHP runs through [`OpenAIProvider`](/docs/copilot/php-classes/providers/openai) always use Chat Completions and ignore this option.

**Default:** `responses`<br />

**Options:** `chat`, `responses`

```php [config.php]
return [
    'johannschopplich.copilot' => [
        'provider' => 'openai',
        'providers' => [
            'openai' => [
                'apiKey' => env('OPENAI_API_KEY'),
                'baseUrl' => 'https://gateway.ai.cloudflare.com/v1/{account_id}/{gateway_id}/compat',
                'model' => 'openai/gpt-5.6-terra',
                'api' => 'chat'
            ]
        ]
    ]
];
```

#### Compatibility

<table>
<thead>
  <tr>
    <th>
      Endpoint
    </th>
    
    <th>
      Responses API
    </th>
    
    <th>
      <code>
        api
      </code>
      
       flag
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      Direct OpenAI (<code>
        api.openai.com/v1
      </code>
      
      )
    </td>
    
    <td>
      Yes
    </td>
    
    <td>
      —
    </td>
  </tr>
  
  <tr>
    <td>
      <a href="https://vercel.com/docs/ai-gateway" rel="nofollow">
        Vercel AI Gateway
      </a>
      
       (<code>
        ai-gateway.vercel.sh/v1
      </code>
      
      )
    </td>
    
    <td>
      Yes
    </td>
    
    <td>
      —
    </td>
  </tr>
  
  <tr>
    <td>
      <a href="https://developers.cloudflare.com/ai-gateway/usage/providers/openai/" rel="nofollow">
        Cloudflare AI Gateway – <code>
          …/openai
        </code>
      </a>
      
       (OpenAI only)
    </td>
    
    <td>
      Yes
    </td>
    
    <td>
      —
    </td>
  </tr>
  
  <tr>
    <td>
      <a href="https://developers.cloudflare.com/ai-gateway/usage/chat-completion/" rel="nofollow">
        Cloudflare AI Gateway – <code>
          …/compat
        </code>
      </a>
      
       (many providers)
    </td>
    
    <td>
      No
    </td>
    
    <td>
      <strong>
        <code>
          chat
        </code>
      </strong>
    </td>
  </tr>
  
  <tr>
    <td>
      <a href="https://openrouter.ai/" rel="nofollow">
        OpenRouter
      </a>
      
       (<code>
        openrouter.ai/api/v1
      </code>
      
      )
    </td>
    
    <td>
      Yes
    </td>
    
    <td>
      —
    </td>
  </tr>
  
  <tr>
    <td>
      Self-hosted (llama.cpp, vLLM, LiteLLM default)
    </td>
    
    <td>
      Typically no
    </td>
    
    <td>
      <strong>
        <code>
          chat
        </code>
      </strong>
    </td>
  </tr>
</tbody>
</table>

Not listed? Check your gateway's docs for `/v1/responses` support – if absent, set `api: 'chat'`.

<note>

`reasoningEffort` continues to work with both API variants.

</note>

#### Routing Multiple Providers Through One Gateway

Cloudflare AI Gateway's [Unified API](https://developers.cloudflare.com/ai-gateway/usage/chat-completion/) (`…/compat`) routes many providers through the OpenAI SDK shape using `{provider}/{model}` model IDs. This lets you access Gemini, Claude, OpenAI, and more through a single endpoint – handy for unified observability, caching, and rate limiting across providers.

Because `/compat` is Chat Completions only, `api: 'chat'` is required.

```php [config.php]
return [
    'johannschopplich.copilot' => [
        'provider' => 'openai',
        'providers' => [
            'openai' => [
                'apiKey' => env('GOOGLE_AI_STUDIO_API_KEY'),
                'baseUrl' => 'https://gateway.ai.cloudflare.com/v1/{account_id}/{gateway_id}/compat',
                'model' => 'google-ai-studio/gemini-3.5-flash',
                // Required when the gateway prefix doesn't match the provider
                'completionModel' => 'google-ai-studio/gemini-2.5-flash-lite',
                'api' => 'chat'
            ]
        ]
    ]
];
```

<callout color="info" icon="i-ri-external-link-line" to="https://developers.cloudflare.com/ai-gateway/usage/chat-completion/">

See Cloudflare's Unified API documentation for the full provider list and model ID formats.

</callout>

#### Limitations

<warning>

- **Structured output (blocks, layouts, field schemas)** through OpenAI-compatible gateways depends on the gateway's `json_schema` translation. Test before relying on blocks or layout generation through this path.
- **reasoningEffort may not apply across cross-provider gateway prefixes.** The OpenAI-compatible path cannot reliably map reasoning settings onto other vendors' models. For full reasoning control on Anthropic or Google models, use `provider: "anthropic"` or `provider: "google"` directly.

</warning>

## Global Defaults

You can set global defaults that apply to both view buttons and sections. These can be overridden in individual blueprints.

### Available Global Defaults

For detailed descriptions of each property, see the [View Button & Field Configuration](/docs/copilot/configuration/local#available-properties) page. The following properties can be set globally:

#### `systemPrompt` <u-badge className="align-middle,ml-2,rounded-full!" label="String" variant="subtle"></u-badge>

Default system prompt that controls how the AI structures and formats generated content across all view buttons and fields.

#### `logLevel` <u-badge className="align-middle,ml-2,rounded-full!" label="String" variant="subtle"></u-badge>

Default logging level for debugging AI generation.

**Default:** `warn`<br />

**Options:** `error`, `warn`, `info`, `debug`

### Basic Global Configuration

```php [config.php]
return [
    'johannschopplich.copilot' => [
        'provider' => 'google', // Primary provider
        'providers' => [
            'google' => [
                'apiKey' => env('GOOGLE_API_KEY'),
                'model' => 'gemini-3.1-pro-preview'
            ]
        ],

        // Global Defaults
        'logLevel' => 'info',
        'excludedBlocks' => ['custom-form']
    ]
];
```

## Security

All AI provider requests are routed through a server-side proxy. API keys are never exposed in browser network requests and stay hidden from Panel users. No additional configuration required – the proxy is enabled automatically.

### Dynamic API Keys <u-badge className="align-middle,mb-1,ml-2,rounded-full" label="since v3.1.0" variant="subtle"></u-badge>

For advanced use cases, you can provide a closure that resolves the API key dynamically at runtime. The closure receives the Kirby instance as its first argument, allowing user-specific or context-dependent API keys.

```php [config.php]
return [
    'johannschopplich.copilot' => [
        'providers' => [
            'openai' => [
                'apiKey' => function (\Kirby\Cms\App $kirby) {
                    // Example: Return different keys based on user role
                    $user = $kirby->user();

                    if ($user?->role()->name() === 'admin') {
                        return env('OPENAI_API_KEY_ADMIN');
                    }

                    return env('OPENAI_API_KEY_USER');
                }
            ]
        ]
    ]
];
```

This is useful for scenarios like:

- Different API keys or rate limits per user role.
- Fetching keys from external services or databases.
- Multi-tenant setups with client-specific credentials.

<callout color="info" icon="i-ri-arrow-right-line" to="/docs/copilot/configuration/local#configuration-precedence">

For configuration precedence and blueprint overrides, see the **View Button & Field Configuration** docs.

</callout>

---

Every page of this site as Markdown: <https://kirby.tools/sitemap.md>
