# Understanding the Interface Section of plugin.json in OpenAI Plugins

> Explore the interface section of plugin.json, the contract between your plugin and the Codex runtime. Learn how it controls UI theming, capabilities, and prompts for seamless integration.

- Repository: [OpenAI/plugins](https://github.com/openai/plugins)
- Tags: documentation
- Published: 2026-09-10

---

**The `interface` section in [`plugin.json`](https://github.com/openai/plugins/blob/main/plugin.json) serves as the contract between a plugin's metadata and the Codex runtime, controlling UI theming, capability declarations, and starter prompts while enabling the Composer to render plugin tiles and enforce security permissions.**

The OpenAI Plugins repository defines the `interface` object within each [`plugin.json`](https://github.com/openai/plugins/blob/main/plugin.json) manifest as the single source of truth for how a plugin appears to users and what operations it advertises. This section bridges static plugin description with dynamic runtime behavior, driving everything from color schemes to capability gating.

## What Is the Interface Section?

The `interface` object lives inside the [`plugin.json`](https://github.com/openai/plugins/blob/main/plugin.json) file located at `plugins/<name>/.codex-plugin/plugin.json`. It acts as the declarative contract that connects plugin metadata with both the Codex-Plugin runtime and the Composer UI components. According to the specification in [`.agents/skills/plugin-creator/references/plugin-json-spec.md`](https://github.com/openai/plugins/blob/main/.agents/skills/plugin-creator/references/plugin-json-spec.md), this section determines visual presentation, legal disclosures, and operational permissions.

## Key Fields in the plugin.json Interface

### Visual Branding and Icons

The **branding fields** control how the plugin appears in the Composer UI and Plugin Store:

- **`brandColor`** and **`brandColorDark`**: Hex color values theming the plugin tile
- **`composerIcon`**: Path to SVG/PNG assets displayed on the Composer toolbar
- **`logo`** and **`logoDark`**: Larger assets shown in plugin detail views
- **`screenshots`**: Paths to PNG/SVG assets displayed in the store carousel

### Capability Declarations

The **`capabilities`** array declares what operations the plugin can perform. Valid values include `Read`, `Write`, and `Interactive`. The runtime validates all incoming requests against these flags in [`plugins/plugin-eval/src/evaluators/plugin.js`](https://github.com/openai/plugins/blob/main/plugins/plugin-eval/src/evaluators/plugin.js), preventing write operations on plugins that only declare `Read` access.

### Starter Prompts and Descriptions

- **`defaultPrompt`**: An array of starter messages (maximum 3 prompts, each ≤128 characters) displayed when users create new conversations with the plugin
- **`shortDescription`** and **`longDescription`**: Text rendered in store listings and Composer detail panes
- **`category`**: Human-readable grouping (e.g., *Communication*, *Productivity*) for store organization

### Legal and External Links

- **`privacyPolicyURL`**, **`termsOfServiceURL`**, and **`websiteURL`**: Required legal endpoints displayed to end-users before installation

## How the Runtime Consumes the Interface Section

### Manifest Loading and Validation

When a plugin installs, the Codex runtime loads `plugins/<name>/.codex-plugin/plugin.json` and executes validation logic in [`plugins/plugin-eval/src/evaluators/plugin.js`](https://github.com/openai/plugins/blob/main/plugins/plugin-eval/src/evaluators/plugin.js). This validator checks that required fields exist and enforces the `defaultPrompt` constraints:

```javascript
// Validation logic mirrors this implementation
function validateDefaultPrompt(iface) {
  if (!Array.isArray(iface.defaultPrompt)) return false;
  if (iface.defaultPrompt.length > 3) return false;
  return iface.defaultPrompt.every(p => p.length <= 128);
}

```

### Token Budget Estimation

The runtime uses `defaultPrompt` to reserve context window space. In [`plugins/plugin-eval/src/core/budget.js`](https://github.com/openai/plugins/blob/main/plugins/plugin-eval/src/core/budget.js), the system concatenates the starter prompts and calls `estimateTokenCount` to calculate required allocations for new Composer conversations.

### UI Rendering Pipeline

The Composer UI reads `manifest.interface.*` to:
- Paint plugin tiles using `brandColor` and `composerIcon`
- Display legal links and descriptions in detail views
- Render `defaultPrompt` strings as clickable quick-start buttons

### Capability Gating

Before executing any plugin action, the runtime checks `manifest.interface.capabilities`. A plugin declaring only `"Read"` receives an error when attempting write-oriented operations, enforcing the principle of least privilege.

## Working with the Interface Section

### Loading a Plugin Interface in JavaScript

```javascript
import fs from 'fs';
import path from 'path';

function loadInterface(pluginName) {
  const manifestPath = path.join(
    __dirname,
    'plugins',
    pluginName,
    '.codex-plugin',
    'plugin.json'
  );
  const manifest = JSON.parse(fs.readFileSync(manifestPath, 'utf-8'));
  return manifest.interface;
}

// Example usage
const zoomInterface = loadInterface('zoom');
console.log(zoomInterface.brandColor);     // → "#0B5CFF"
console.log(zoomInterface.capabilities);   // → ["Read", "Interactive"]

```

### Enforcing defaultPrompt Constraints

```javascript
function validateDefaultPrompt(iface) {
  if (!Array.isArray(iface.defaultPrompt)) return false;
  if (iface.defaultPrompt.length > 3) return false;
  return iface.defaultPrompt.every(p => p.length <= 128);
}

if (!validateDefaultPrompt(zoomInterface)) {
  throw new Error('defaultPrompt does not meet Codex requirements');
}

```

### Rendering Starter Prompts in the UI

```javascript
// React pseudo-code demonstrating Composer integration
function renderStarterPrompts(interface) {
  return interface.defaultPrompt.map((prompt, i) => (
    <button key={i} onClick={() => sendMessage(prompt)}>
      {prompt}
    </button>
  ));
}

```

## Summary

- The **`interface` section** in [`plugin.json`](https://github.com/openai/plugins/blob/main/plugin.json) controls both visual presentation and functional capabilities of OpenAI Plugins
- **Validation occurs** in [`plugins/plugin-eval/src/evaluators/plugin.js`](https://github.com/openai/plugins/blob/main/plugins/plugin-eval/src/evaluators/plugin.js), enforcing `defaultPrompt` limits (3 prompts max, 128 characters each) and verifying capability declarations
- **Token budgeting** uses `defaultPrompt` content via [`plugins/plugin-eval/src/core/budget.js`](https://github.com/openai/plugins/blob/main/plugins/plugin-eval/src/core/budget.js) to manage context window allocation
- **Capability gating** prevents unauthorized operations by matching runtime requests against declared `capabilities` (Read/Write/Interactive)
- **UI components** consume `brandColor`, `composerIcon`, and description fields to render plugin tiles and detail views

## Frequently Asked Questions

### What happens if defaultPrompt exceeds 3 items or 128 characters?

The validator in [`plugins/plugin-eval/src/evaluators/plugin.js`](https://github.com/openai/plugins/blob/main/plugins/plugin-eval/src/evaluators/plugin.js) rejects the manifest during plugin installation. The runtime enforces these limits strictly to prevent token budget overflow and maintain UI consistency in the Composer's quick-start suggestions.

### Can a plugin change its capabilities after installation?

No. The `capabilities` array is static and defined at build time in [`plugin.json`](https://github.com/openai/plugins/blob/main/plugin.json). The runtime checks these flags before every operation, and modifying them requires repackaging and reinstalling the plugin with updated declarations.

### Where does the Composer read the brand colors and icons?

The Composer UI reads `manifest.interface.brandColor`, `manifest.interface.composerIcon`, and related fields directly from the loaded manifest object. These values style the plugin tile in the toolbar and the detailed view in the Plugin Store.

### How does the interface section relate to the rest of plugin.json?

While other sections of [`plugin.json`](https://github.com/openai/plugins/blob/main/plugin.json) define technical endpoints and authentication, the `interface` section specifically handles user-facing metadata. It remains the only portion read by both the UI rendering layer and the runtime security validator, making it the bridge between user experience and system enforcement.