---
title: "API Reference"
manual: "AI Cowriter for TYPO3"
version: "main"
permalink: "https://docs.typo3.org/permalink/netresearch/t3-cowriter:api@main"
source: "Api/Index.rst"
rendered: "2026-09-24T09:13:18+00:00"
---

# API Reference {#api}

The Cowriter extension exposes several AJAX endpoints under
`/typo3/ajax/cowriter/`. All endpoints require an authenticated
backend session.

-   [Common response format](https://docs.typo3.org/permalink/netresearch/t3-cowriter:common-response-format@main)
-   [Completion endpoints](https://docs.typo3.org/permalink/netresearch/t3-cowriter:completion-endpoints@main)
-   [Translation](https://docs.typo3.org/permalink/netresearch/t3-cowriter:translation@main)
-   [Vision / Alt text](https://docs.typo3.org/permalink/netresearch/t3-cowriter:vision-alt-text@main)
-   [Templates](https://docs.typo3.org/permalink/netresearch/t3-cowriter:templates@main)
-   [Tool calling](https://docs.typo3.org/permalink/netresearch/t3-cowriter:tool-calling@main)
-   [Configurations](https://docs.typo3.org/permalink/netresearch/t3-cowriter:configurations@main)
-   [Error responses](https://docs.typo3.org/permalink/netresearch/t3-cowriter:error-responses@main)

## Common response format {#common-response-format}

All endpoints return JSON with a `success` boolean. On error,
an `error` string describes the problem.

Rate limit headers are included on every response:

-   `X-RateLimit-Limit` — maximum requests per window
-   `X-RateLimit-Remaining` — requests remaining in current window
-   `Retry-After` — seconds until reset (only on HTTP 429)

## Completion endpoints {#completion-endpoints}

### POST /cowriter/complete {#api-complete}

Generate a completion from a prompt using the default or specified
LLM configuration.

**Request body:**

```json
{
    "prompt": "Write an introduction about TYPO3",
    "configuration": "openai-default"
}
```

**Response (200):**

```json
{
    "success": true,
    "content": "TYPO3 is a powerful...",
    "model": "gpt-5.2",
    "finishReason": "stop",
    "wasTruncated": false,
    "wasFiltered": false,
    "usage": {
        "promptTokens": 50,
        "completionTokens": 120,
        "totalTokens": 170
    }
}
```

### POST /cowriter/stream {#api-stream}

Stream a completion via Server-Sent Events (SSE). Same request format
as `/cowriter/complete`.

Returns `text/event-stream` with JSON chunks:

```text
data: {"content": "TYPO3 "}
data: {"content": "is a "}
data: {"content": "powerful..."}
data: {"done": true, "model": "gpt-5.2"}
```

### POST /cowriter/task-execute {#api-task-execute}

Execute a predefined task with context assembly.

**Request body:**

```json
{
    "taskUid": 12,
    "instruction": "Improve this text",
    "context": "<p>Current editor content</p>",
    "contextType": "content_element",
    "contextScope": "element",
    "configuration": "openai-default",
    "referencePages": [
        {"pid": 42, "relation": "style guide"}
    ]
}
```

`taskUid` is the `tx_nrllm_task` record uid. `contextType` is one of
`selection` or `content_element`; `contextScope` is one of `selection`,
`text`, `element`, `page`, `ancestors_1`, `ancestors_2`.

## Translation {#translation}

### POST /cowriter/translate {#api-translate}

Translate text to a target language.

**Request body:**

```json
{
    "text": "Hello world",
    "targetLanguage": "de",
    "formality": "formal",
    "domain": "technical",
    "configuration": "claude-fast"
}
```

`formality` defaults to `"default"`, `domain` defaults to
`"general"`. `configuration` is optional.

**Response (200):**

```json
{
    "success": true,
    "translation": "Hallo Welt",
    "sourceLanguage": "en",
    "confidence": 0.95,
    "usage": {
        "promptTokens": 30,
        "completionTokens": 10,
        "totalTokens": 40
    }
}
```

## Vision / Alt text {#vision-alt-text}

### POST /cowriter/vision {#api-vision}

Analyze an image and generate descriptive alt text.

**Request body:**

```json
{
    "imageUrl": "https://example.com/photo.jpg",
    "prompt": "Generate a concise, descriptive alt text for this image."
}
```

The `prompt` defaults to a standard alt text generation prompt
if omitted.

**Response (200):**

```json
{
    "success": true,
    "altText": "A red bicycle parked against a brick wall",
    "model": "gpt-5.2",
    "confidence": 0.92,
    "usage": {
        "promptTokens": 200,
        "completionTokens": 15,
        "totalTokens": 215
    }
}
```

## Templates {#templates}

### GET /cowriter/templates {#api-templates}

List available prompt templates (tasks with `category = 'content'`).

**Response (200):**

```json
{
    "success": true,
    "templates": [
        {
            "identifier": "improve-text",
            "name": "Improve Text",
            "description": "Enhance readability and quality",
            "category": "content"
        }
    ]
}
```

## Tool calling {#tool-calling}

### POST /cowriter/tools {#api-tools}

Execute an LLM request with tool calling capabilities.

**Request body:**

```json
{
    "prompt": "Find all headings in the content",
    "tools": ["query_content"]
}
```

`tools` is an optional array of tool names to enable. If omitted,
all available tools are enabled.

**Response (200):**

```json
{
    "success": true,
    "content": "I found 3 headings...",
    "toolCalls": [],
    "finishReason": "stop",
    "usage": {
        "promptTokens": 100,
        "completionTokens": 50,
        "totalTokens": 150
    }
}
```

## Configurations {#configurations}

### GET /cowriter/configurations {#api-configurations}

List active LLM configurations available for selection.

**Response (200):**

```json
{
    "success": true,
    "configurations": [
        {
            "identifier": "openai-default",
            "name": "OpenAI GPT-5.2",
            "isDefault": true
        }
    ]
}
```

## Error responses {#error-responses}

All endpoints use standard HTTP status codes:

-   **400** — Invalid JSON, missing required fields, or fields exceeding
    maximum length (32 KB)
-   **429** — Rate limit exceeded (includes `Retry-After` header)
-   **500** — LLM service error

```json
{
    "success": false,
    "error": "Missing or empty text parameter."
}
```
