> For the complete documentation index, see [llms.txt](https://docs.convai.com/api-docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.convai.com/api-docs/convai-playground/character-customization/external-api/external-api-limitations.md).

# External API limitations

Limits that apply to External API everywhere — supported models, Python runtime, libraries, input schema, and per-character caps.

These limits apply whether you configure External API in the [Playground](/api-docs/convai-playground/character-customization/external-api.md) or through the [API](/api-docs/api-reference/core-api-reference/character-crafting-apis/external-api.md).

## Supported models

External API only runs when the character's model can call tools. That depends on the path you use:

| Path                  | Supported models                                                                                                                                                                                                          |
| --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Live API (WebRTC)** | OpenAI, Claude, and Gemini. Popular open-source models that support tools — including Grok and the DeepSeek family — work here too. Others may work if they support tool calling; check [models.dev](https://models.dev). |
| **gRPC**              | OpenAI, Claude, and Gemini family models only.                                                                                                                                                                            |

If the model doesn't support tools, the character still chats normally — it just won't call your External API functions.

## Runtime

| Rule                 | Detail                                                                           |
| -------------------- | -------------------------------------------------------------------------------- |
| Language             | Python only (`"language": "python"`)                                             |
| Runtime              | Python 3.11                                                                      |
| Standard library     | Allowed (`json`, `datetime`, `math`, `re`, `urllib`, and the rest of the stdlib) |
| Third-party packages | **`requests` only** for now                                                      |
| Source code size     | At most 400 lines                                                                |
| Entry point          | Must define `def handle_event(inputs):` (single argument; name is fixed)         |
| Return value         | JSON-serializable, usually a `dict`                                              |
| State                | No shared mutable state across calls — each run is independent                   |

Anything outside the standard library and `requests` fails at runtime.

## Input description

`input_description` is a **JSON string** (not a nested object in the API body). After parsing, it must look like:

```json
{
  "parameters": {
    "city": {
      "type": "string",
      "description": "Name of the city to look up"
    }
  },
  "required": ["city"]
}
```

| Rule                          | Detail                                            |
| ----------------------------- | ------------------------------------------------- |
| Top-level keys                | `parameters` and `required` are both required     |
| Parameter names               | `^[a-zA-Z_][a-zA-Z0-9_]*$`                        |
| Parameter fields              | Each parameter needs `type` and `description`     |
| Allowed types                 | `string`, `integer`, `boolean`, `object`, `array` |
| Extra keys under `parameters` | Not allowed                                       |

Keep descriptions concrete. The model fills arguments from that text, so vague wording produces bad calls.

## Character limits

| Rule                           | Detail                                                                                                           |
| ------------------------------ | ---------------------------------------------------------------------------------------------------------------- |
| Active functions per character | At most **128**                                                                                                  |
| Unlink vs delete               | `"status": "inactive"` only disconnects a character; delete removes the function from the account and every link |

## Related

* [External API (Playground)](/api-docs/convai-playground/character-customization/external-api.md) — UI setup and examples
* [External API (API reference)](/api-docs/api-reference/core-api-reference/character-crafting-apis/external-api.md) — create, list, link, unlink, delete


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.convai.com/api-docs/convai-playground/character-customization/external-api/external-api-limitations.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
