> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.reka.ai/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.reka.ai/_mcp/server.

The [Chat API](/chat/api-reference/) supports conversations that include images, short videos, and audio.

> **Info**
>
> Our Chat API performs best with **videos shorter than 30 seconds**.
>
> For longer videos, use our [Vision API](/vision/video-qa) instead. After uploading your video, we run a sophisticated pipeline to process your video so that it is optimized for our models to query your video content.
>
> For one-shot flows, see below on [Working with video](#working-with-video).

You can insert multimodal content in the conversation by using media content types. The supported types are: `image_url`, `video_url`, `audio_url`, and `pdf_url`.

Below is an example of sending an image of a cat by URL:

![Image of a cat on a keyboard](https://v0.docs.reka.ai/_images/000000245576.jpg)

**`OpenAI SDK`**

```python title="OpenAI SDK"
from openai import OpenAI

client = OpenAI(
    base_url="https://api.reka.ai/v1",
    api_key="YOUR_API_KEY",
)

response = client.chat.completions.create(
    model="reka-flash",
    messages=[
        {
            "role": "user",
            "content": [
                {"type": "image_url", "image_url": {"url": "https://v0.docs.reka.ai/_images/000000245576.jpg"}},
                {"type": "text", "text": "What animal is this? Answer briefly"}
            ],
        }
    ],
)
print(response.choices[0].message.content)
```

**`Python`**

```python title="Python"
import requests

response = requests.post(
    "https://api.reka.ai/v1/chat/completions",
    headers={
        "X-Api-Key": "YOUR_API_KEY",
        "Content-Type": "application/json",
    },
    json={
        "model": "reka-flash",
        "messages": [
            {
                "role": "user",
                "content": [
                    {"type": "image_url", "image_url": {"url": "https://v0.docs.reka.ai/_images/000000245576.jpg"}},
                    {"type": "text", "text": "What animal is this? Answer briefly"}
                ],
            }
        ],
    },
)
data = response.json()
print(data["choices"][0]["message"]["content"])
```

**`JavaScript`**

```javascript title="JavaScript"
const response = await fetch('https://api.reka.ai/v1/chat/completions', {
    method: 'POST',
    headers: {
        'X-Api-Key': 'YOUR_API_KEY',
        'Content-Type': 'application/json',
    },
    body: JSON.stringify({
        model: 'reka-flash',
        messages: [
            {
                role: 'user',
                content: [
                    { type: 'image_url', image_url: { url: 'https://v0.docs.reka.ai/_images/000000245576.jpg' } },
                    { type: 'text', text: 'What animal is this? Answer briefly' }
                ],
            }
        ],
    }),
});

const data = await response.json();
console.log(data.choices[0].message.content);
```

**`Go`**

```go title="Go"
package main

import (
	"bytes"
	"encoding/json"
	"fmt"
	"io"
	"net/http"
)

func main() {
	reqBody, _ := json.Marshal(map[string]interface{}{
		"model": "reka-flash",
		"messages": []map[string]interface{}{
			{
				"role": "user",
				"content": []map[string]interface{}{
					{"type": "image_url", "image_url": map[string]string{"url": "https://v0.docs.reka.ai/_images/000000245576.jpg"}},
					{"type": "text", "text": "What animal is this? Answer briefly"},
				},
			},
		},
	})

	req, _ := http.NewRequest("POST", "https://api.reka.ai/v1/chat/completions", bytes.NewBuffer(reqBody))
	req.Header.Set("X-Api-Key", "YOUR_API_KEY")
	req.Header.Set("Content-Type", "application/json")

	resp, _ := http.DefaultClient.Do(req)
	defer resp.Body.Close()

	body, _ := io.ReadAll(resp.Body)
	fmt.Println(string(body))
}
```

**`Java`**

```java title="Java"
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

HttpClient client = HttpClient.newHttpClient();
String jsonBody = """
        {
            "model": "reka-flash",
            "messages": [
                {
                    "role": "user",
                    "content": [
                        {"type": "image_url", "image_url": {"url": "https://v0.docs.reka.ai/_images/000000245576.jpg"}},
                        {"type": "text", "text": "What animal is this? Answer briefly"}
                    ]
                }
            ]
        }
        """;

HttpRequest request = HttpRequest.newBuilder()
        .uri(URI.create("https://api.reka.ai/v1/chat/completions"))
        .header("X-Api-Key", "YOUR_API_KEY")
        .header("Content-Type", "application/json")
        .POST(HttpRequest.BodyPublishers.ofString(jsonBody))
        .build();

HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
```

**`REST`**

```shell title="REST"
curl -X POST https://api.reka.ai/v1/chat/completions \
    -H "X-Api-Key: YOUR_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
        "model": "reka-flash",
        "messages": [
            {
                "role": "user",
                "content": [
                    {"type": "image_url", "image_url": {"url": "https://v0.docs.reka.ai/_images/000000245576.jpg"}},
                    {"type": "text", "text": "What animal is this? Answer briefly"}
                ]
            }
        ]
    }'
```

This will output a response like:

> The animal in the image is a domestic cat. Specifically, it appears to be a ginger or orange tabby cat, which is characterized by its reddish-brown fur with darker stripes or patches. The cat is engaging in a common feline behavior of sniffing or licking objects, which in this case is a computer keyboard. Cats are known for their curiosity and often explore their environment by using their sense of smell, which is highly developed. The act of licking or sniffing can also be a way for cats to mark their territory with pheromones from their saliva.

## Data URLs

The API supports sending media via data URLs, for example you could URL-encode a jpeg image and then set `image_url` to a value like `"data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAASABIAAD/4QmoRXhpZgAATU0AKgAAAAgADQEPAAIAA..."`.

## Multiple media

You can send multiple media files in your request by appending them to the `content` array for a `user` message:

**`OpenAI SDK`**

```python title="OpenAI SDK"
response = client.chat.completions.create(
    model="reka-flash",
    messages=[
        {
            "role": "user",
            "content": [
                {"type": "image_url", "image_url": {"url": "https://example.com/image_1.jpg"}},
                {"type": "image_url", "image_url": {"url": "https://example.com/image_2.jpg"}},
                {"type": "text", "text": "What colours and shapes are present in both images?"}
            ],
        }
    ],
)
```

**`Python`**

```python title="Python"
import requests

response = requests.post(
    "https://api.reka.ai/v1/chat/completions",
    headers={
        "X-Api-Key": "YOUR_API_KEY",
        "Content-Type": "application/json",
    },
    json={
        "model": "reka-flash",
        "messages": [
            {
                "role": "user",
                "content": [
                    {"type": "image_url", "image_url": {"url": "https://example.com/image_1.jpg"}},
                    {"type": "image_url", "image_url": {"url": "https://example.com/image_2.jpg"}},
                    {"type": "text", "text": "What colours and shapes are present in both images?"}
                ],
            }
        ],
    },
)
```

**`JavaScript`**

```javascript title="JavaScript"
const response = await fetch('https://api.reka.ai/v1/chat/completions', {
    method: 'POST',
    headers: {
        'X-Api-Key': 'YOUR_API_KEY',
        'Content-Type': 'application/json',
    },
    body: JSON.stringify({
        model: 'reka-flash',
        messages: [
            {
                role: 'user',
                content: [
                    { type: 'image_url', image_url: { url: 'https://example.com/image_1.jpg' } },
                    { type: 'image_url', image_url: { url: 'https://example.com/image_2.jpg' } },
                    { type: 'text', text: 'What colours and shapes are present in both images?' }
                ],
            }
        ],
    }),
});

const data = await response.json();
console.log(data.choices[0].message.content);
```

**`Go`**

```go title="Go"
package main

import (
	"bytes"
	"encoding/json"
	"fmt"
	"io"
	"net/http"
)

func main() {
	reqBody, _ := json.Marshal(map[string]interface{}{
		"model": "reka-flash",
		"messages": []map[string]interface{}{
			{
				"role": "user",
				"content": []map[string]interface{}{
					{"type": "image_url", "image_url": map[string]string{"url": "https://example.com/image_1.jpg"}},
					{"type": "image_url", "image_url": map[string]string{"url": "https://example.com/image_2.jpg"}},
					{"type": "text", "text": "What colours and shapes are present in both images?"},
				},
			},
		},
	})

	req, _ := http.NewRequest("POST", "https://api.reka.ai/v1/chat/completions", bytes.NewBuffer(reqBody))
	req.Header.Set("X-Api-Key", "YOUR_API_KEY")
	req.Header.Set("Content-Type", "application/json")

	resp, _ := http.DefaultClient.Do(req)
	defer resp.Body.Close()

	body, _ := io.ReadAll(resp.Body)
	fmt.Println(string(body))
}
```

**`Java`**

```java title="Java"
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

HttpClient client = HttpClient.newHttpClient();
String jsonBody = """
        {
            "model": "reka-flash",
            "messages": [
                {
                    "role": "user",
                    "content": [
                        {"type": "image_url", "image_url": {"url": "https://example.com/image_1.jpg"}},
                        {"type": "image_url", "image_url": {"url": "https://example.com/image_2.jpg"}},
                        {"type": "text", "text": "What colours and shapes are present in both images?"}
                    ]
                }
            ]
        }
        """;

HttpRequest request = HttpRequest.newBuilder()
        .uri(URI.create("https://api.reka.ai/v1/chat/completions"))
        .header("X-Api-Key", "YOUR_API_KEY")
        .header("Content-Type", "application/json")
        .POST(HttpRequest.BodyPublishers.ofString(jsonBody))
        .build();

HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
```

**`REST`**

```shell title="REST"
curl -X POST https://api.reka.ai/v1/chat/completions \
    -H "X-Api-Key: YOUR_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
        "model": "reka-flash",
        "messages": [
            {
                "role": "user",
                "content": [
                    {"type": "image_url", "image_url": {"url": "https://example.com/image_1.jpg"}},
                    {"type": "image_url", "image_url": {"url": "https://example.com/image_2.jpg"}},
                    {"type": "text", "text": "What colours and shapes are present in both images?"}
                ]
            }
        ]
    }'
```

## Working with video

### Using the Chat API with a video URL

> **Info**
>
> Note that this method only works if the video URL is unprotected - providers like Youtube employ defensive measures to prevent video download.
>
> Our [Vision API](/vision) provides a managed service which helps you download and process videos from Youtube.

If you have a short video (less than 30 seconds), you can pass it into the Chat API using the `video_url` content type:

**`OpenAI SDK`**

```python title="OpenAI SDK"
from openai import OpenAI

client = OpenAI(
    base_url="https://api.reka.ai/v1",
    api_key="YOUR_API_KEY",
)

response = client.chat.completions.create(
    model="reka-flash",
    messages=[
        {
            "role": "user",
            "content": [
                {"type": "video_url", "video_url": "https://example.com/short_video.mp4"},
                {"type": "text", "text": "Describe what happens in this video."}
            ],
        }
    ],
)
print(response.choices[0].message.content)
```

**`Python`**

```python title="Python"
import requests

response = requests.post(
    "https://api.reka.ai/v1/chat/completions",
    headers={
        "X-Api-Key": "YOUR_API_KEY",
        "Content-Type": "application/json",
    },
    json={
        "model": "reka-flash",
        "messages": [
            {
                "role": "user",
                "content": [
                    {"type": "video_url", "video_url": "https://example.com/short_video.mp4"},
                    {"type": "text", "text": "Describe what happens in this video."}
                ],
            }
        ],
    },
)
data = response.json()
print(data["choices"][0]["message"]["content"])
```

**`JavaScript`**

```javascript title="JavaScript"
const response = await fetch('https://api.reka.ai/v1/chat/completions', {
    method: 'POST',
    headers: {
        'X-Api-Key': 'YOUR_API_KEY',
        'Content-Type': 'application/json',
    },
    body: JSON.stringify({
        model: 'reka-flash',
        messages: [
            {
                role: 'user',
                content: [
                    { type: 'video_url', video_url: 'https://example.com/short_video.mp4' },
                    { type: 'text', text: 'Describe what happens in this video.' }
                ],
            }
        ],
    }),
});

const data = await response.json();
console.log(data.choices[0].message.content);
```

**`Go`**

```go title="Go"
package main

import (
	"bytes"
	"encoding/json"
	"fmt"
	"io"
	"net/http"
)

func main() {
	reqBody, _ := json.Marshal(map[string]interface{}{
		"model": "reka-flash",
		"messages": []map[string]interface{}{
			{
				"role": "user",
				"content": []map[string]interface{}{
					{"type": "video_url", "video_url": "https://example.com/short_video.mp4"},
					{"type": "text", "text": "Describe what happens in this video."},
				},
			},
		},
	})

	req, _ := http.NewRequest("POST", "https://api.reka.ai/v1/chat/completions", bytes.NewBuffer(reqBody))
	req.Header.Set("X-Api-Key", "YOUR_API_KEY")
	req.Header.Set("Content-Type", "application/json")

	resp, _ := http.DefaultClient.Do(req)
	defer resp.Body.Close()

	body, _ := io.ReadAll(resp.Body)
	fmt.Println(string(body))
}
```

**`Java`**

```java title="Java"
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

HttpClient client = HttpClient.newHttpClient();
String jsonBody = """
        {
            "model": "reka-flash",
            "messages": [
                {
                    "role": "user",
                    "content": [
                        {"type": "video_url", "video_url": "https://example.com/short_video.mp4"},
                        {"type": "text", "text": "Describe what happens in this video."}
                    ]
                }
            ]
        }
        """;

HttpRequest request = HttpRequest.newBuilder()
        .uri(URI.create("https://api.reka.ai/v1/chat/completions"))
        .header("X-Api-Key", "YOUR_API_KEY")
        .header("Content-Type", "application/json")
        .POST(HttpRequest.BodyPublishers.ofString(jsonBody))
        .build();

HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
```

**`REST`**

```shell title="REST"
curl -X POST https://api.reka.ai/v1/chat/completions \
    -H "X-Api-Key: YOUR_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
        "model": "reka-flash",
        "messages": [
            {
                "role": "user",
                "content": [
                    {"type": "video_url", "video_url": "https://example.com/short_video.mp4"},
                    {"type": "text", "text": "Describe what happens in this video."}
                ]
            }
        ]
    }'
```

### Longer videos using the Vision API (recommended)

For longer videos, use our [Vision API](/vision/video-qa). After uploading your video, we run a sophisticated pipeline to process and extract information from your video so that it is optimized for our models to query your video content. The Vision API supports downloads from Youtube so all you need to do is specify a video URL.

### Longer videos using the Chat API - processing videos yourself

If you prefer to handle video processing yourself (for e.g. to control frame sampling or reduce upload size), you can extract frames from your video and send them as multiple `image_url` content entries.

First, extract frames from your video using ffmpeg. This command extracts one frame per second:

```bash
ffmpeg -i input.mp4 -vf "fps=1" -q:v 2 frame_%03d.jpg
```

Then encode each frame as a base64 data URL and send them as separate `image_url` entries:

> **Note**
>
> Error handling is omitted from these examples for brevity. In production code, you should handle file I/O errors and HTTP response errors appropriately.

**`OpenAI SDK`**

```python title="OpenAI SDK"
import base64
import glob
from openai import OpenAI

# Read and encode frames extracted by ffmpeg
image_content = []
for frame_path in sorted(glob.glob("frame_*.jpg")):
    with open(frame_path, "rb") as f:
        base64_frame = base64.b64encode(f.read()).decode("utf-8")
        image_content.append({
            "type": "image_url",
            "image_url": {"url": f"data:image/jpeg;base64,{base64_frame}"}
        })

client = OpenAI(
    base_url="https://api.reka.ai/v1",
    api_key="YOUR_API_KEY",
)
response = client.chat.completions.create(
    model="reka-flash",
    messages=[
        {
            "role": "user",
            "content": [
                *image_content,
                {"type": "text", "text": "Describe what happens in this video."}
            ],
        }
    ],
)
print(response.choices[0].message.content)
```

**`Python`**

```python title="Python"
import base64
import glob
import requests

# Read and encode frames extracted by ffmpeg
image_content = []
for frame_path in sorted(glob.glob("frame_*.jpg")):
    with open(frame_path, "rb") as f:
        base64_frame = base64.b64encode(f.read()).decode("utf-8")
        image_content.append({
            "type": "image_url",
            "image_url": {"url": f"data:image/jpeg;base64,{base64_frame}"}
        })

response = requests.post(
    "https://api.reka.ai/v1/chat/completions",
    headers={
        "X-Api-Key": "YOUR_API_KEY",
        "Content-Type": "application/json",
    },
    json={
        "model": "reka-flash",
        "messages": [
            {
                "role": "user",
                "content": [
                    *image_content,
                    {"type": "text", "text": "Describe what happens in this video."}
                ],
            }
        ],
    },
)
data = response.json()
print(data["choices"][0]["message"]["content"])
```

**`JavaScript`**

```javascript title="JavaScript"
import fs from 'fs';

// Read and encode frames extracted by ffmpeg
const frameFiles = fs.readdirSync('.')
    .filter(f => f.match(/^frame_\d+\.jpg$/))
    .sort();

const imageContent = frameFiles.map(file => {
    const data = fs.readFileSync(file);
    return { type: 'image_url', image_url: { url: `data:image/jpeg;base64,${data.toString('base64')}` } };
});

const response = await fetch('https://api.reka.ai/v1/chat/completions', {
    method: 'POST',
    headers: {
        'X-Api-Key': 'YOUR_API_KEY',
        'Content-Type': 'application/json',
    },
    body: JSON.stringify({
        model: 'reka-flash',
        messages: [
            {
                role: 'user',
                content: [
                    ...imageContent,
                    { type: 'text', text: 'Describe what happens in this video.' }
                ],
            }
        ],
    }),
});

const data = await response.json();
console.log(data.choices[0].message.content);
```

**`Go`**

```go title="Go"
package main

import (
	"bytes"
	"encoding/base64"
	"encoding/json"
	"fmt"
	"io"
	"net/http"
	"os"
	"path/filepath"
	"sort"
)

func main() {
	// Read and encode frames extracted by ffmpeg
	files, _ := filepath.Glob("frame_*.jpg")
	sort.Strings(files)

	var content []map[string]interface{}
	for _, file := range files {
		data, _ := os.ReadFile(file)
		content = append(content, map[string]interface{}{
			"type":      "image_url",
			"image_url": map[string]string{"url": "data:image/jpeg;base64," + base64.StdEncoding.EncodeToString(data)},
		})
	}
	content = append(content, map[string]interface{}{
		"type": "text",
		"text": "Describe what happens in this video.",
	})

	reqBody, _ := json.Marshal(map[string]interface{}{
		"model": "reka-flash",
		"messages": []map[string]interface{}{
			{
				"role":    "user",
				"content": content,
			},
		},
	})

	req, _ := http.NewRequest("POST", "https://api.reka.ai/v1/chat/completions", bytes.NewBuffer(reqBody))
	req.Header.Set("X-Api-Key", "YOUR_API_KEY")
	req.Header.Set("Content-Type", "application/json")

	resp, _ := http.DefaultClient.Do(req)
	defer resp.Body.Close()

	body, _ := io.ReadAll(resp.Body)
	fmt.Println(string(body))
}
```

**`Java`**

```java title="Java"
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Base64;
import java.util.stream.Collectors;

// Build an image_url entry for each frame extracted by ffmpeg
String imageEntries = Files.list(Paths.get("."))
        .filter(p -> p.getFileName().toString().matches("frame_\\d+\\.jpg"))
        .sorted()
        .map(p -> {
            try {
                String b64 = Base64.getEncoder().encodeToString(Files.readAllBytes(p));
                return String.format(
                    "{\"type\": \"image_url\", \"image_url\": {\"url\": \"data:image/jpeg;base64,%s\"}}", b64);
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        })
        .collect(Collectors.joining(",\n                        "));

HttpClient client = HttpClient.newHttpClient();
String jsonBody = String.format("""
        {
            "model": "reka-flash",
            "messages": [
                {
                    "role": "user",
                    "content": [
                        %s,
                        {"type": "text", "text": "Describe what happens in this video."}
                    ]
                }
            ]
        }
        """, imageEntries);

HttpRequest request = HttpRequest.newBuilder()
        .uri(URI.create("https://api.reka.ai/v1/chat/completions"))
        .header("X-Api-Key", "YOUR_API_KEY")
        .header("Content-Type", "application/json")
        .POST(HttpRequest.BodyPublishers.ofString(jsonBody))
        .build();

HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
```

**`REST`**

```shell title="REST"
# After extracting frames with ffmpeg, build an image_url entry for each frame
IMAGE_ENTRIES=""
for f in frame_*.jpg; do
    B64=$(base64 < "$f" | tr -d '\n')
    [ -n "$IMAGE_ENTRIES" ] && IMAGE_ENTRIES="$IMAGE_ENTRIES,"
    IMAGE_ENTRIES="$IMAGE_ENTRIES{\"type\":\"image_url\",\"image_url\":{\"url\":\"data:image/jpeg;base64,$B64\"}}"
done

curl -X POST https://api.reka.ai/v1/chat/completions \
    -H "X-Api-Key: YOUR_API_KEY" \
    -H "Content-Type: application/json" \
    -d "{
        \"model\": \"reka-flash\",
        \"messages\": [
            {
                \"role\": \"user\",
                \"content\": [
                    $IMAGE_ENTRIES,
                    {\"type\": \"text\", \"text\": \"Describe what happens in this video.\"}
                ]
            }
        ]
    }"
```

This uses the same `image_url` content type shown in the [Multiple media](#multiple-media) section above, with each video frame sent as a separate base64-encoded image.

## Streaming, Async, and other advanced usage

Please see the [guide for text-only chat](/chat) for more guidance on the advanced features of the Chat API, which also work for multimodal inputs.