← Back to Blog
Tutorial · 10 min read

Chat API v3: From a Simple Query to Streaming and Vision

·
Chat API v3: From a Simple Query to Streaming and Vision

Basic Information

Property Value
Endpoint POST /api/v3/chat
Authentication API Key with scope ayeto.chat
Response Model BasicLLMMessageView
Rate Limit Default limits

๐Ÿ” Authentication

API Key

The endpoint requires an API key with permission (scope) ayeto.chat.

Authentication Header

uni-api-key: <YOUR_API_KEY>

API Key Format

The API key has the following format:

ayeto-{64_random_hex_characters}

Example:

ayeto-a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2

Scopes

To use the chat endpoint, the API key must have one of the following scopes: - ayeto.chat - specific scope for chat - * - wildcard scope (access to all endpoints)

Authentication Error Responses

Error Description
API key not provided The uni-api-key header is missing or empty.
API key is invalid The API key does not exist, is deactivated, or does not have the required scope.

๐Ÿ”’ Security: When an invalid API key is used, a security delay is applied to protect against brute-force attacks.


๐Ÿ“ฅ Request Body - ChatRequest

Field Type Required Default Description
conversation_id UUID No Auto-generated Conversation identifier. If not provided, a new one is created.
assistant_id UUID No* null ID of the assistant to be used.
organization_id UUID No null Organization ID for conversation context.
model string No* null Model ID for generating the response.
message string Yes - User message text.
max_tokens integer No null Maximum number of tokens in the response.
image boolean No false Use image generation instead of text.
documents EncodedData[] No null Attachments (documents, images).
relevant_history boolean No false Use relevant conversation history.
dynamic_tools boolean No false Enable dynamic tools.
stream boolean No false Stream the response (SSE).
remove_tool_calls boolean No false Remove tool calls from the response.

โš ๏ธ Important: Either assistant_id OR model must be provided. One of these fields is required.


๐Ÿ“Ž Attachments - EncodedData

To attach documents or images, use the documents field:

Field Type Required Description
filename string Yes File name including extension.
data string Yes Base64 encoded file content (with prefix data:{mime};base64,).
size integer Yes File size in bytes.
mime_type string Yes File MIME type (e.g. image/png, application/pdf).
vision boolean No true = image for vision analysis.

โš ๏ธ Limitation: Only one image with vision: true is allowed in a single request.


๐Ÿ“ค Response - BasicLLMMessageView

Field Type Description
id UUID Unique message identifier.
timestamp integer Unix timestamp of message creation (in milliseconds).
role string Message role: system, user, assistant, tool, internal.
content string \| null Text content of the response.
reasoning_content string \| null Reasoning content (if supported by the model).
model string \| null ID of the model used.
img_gen ImgGenMessage \| null Generated image data (if image: true).

Example response

{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "timestamp": 1735815581000,
  "role": "assistant",
  "content": "Hello! Iโ€™m doing well, thank you for asking. How can I help?",
  "reasoning_content": null,
  "model": "gpt-4o",
  "img_gen": null
}

๐Ÿ–ผ๏ธ Image Generation Response - ImgGenMessage

If image: true, the response contains an img_gen object:

Field Type Description
id UUID ID of the generated image.
timestamp integer Unix timestamp (in milliseconds).
model string Model used for generation.
format string Image format (e.g. 1024x1024, 1792x1024, 1024x1792).
hd boolean HD quality.
prompt string Prompt used for generation.
content string Response content.
response_id string Provider response ID.
image_url string URL of the generated image.
image_file_id UUID \| null ID of the stored file.

๐Ÿ“ก Streaming Response (SSE)

If stream: true, the endpoint returns a Server-Sent Events (SSE) stream.

Streaming Response Headers

Content-Type: text/event-stream
Transfer-Encoding: chunked

Stream Chunk Format - StreamChunk

Each chunk is a JSON object on a separate line:

Field Type Description
timestamp integer Unix timestamp when the chunk was created (in milliseconds).
data string \| null Part of the text response (token/word).
error StreamError \| null Error object if an error occurred.

Stream Error Format - StreamError

If an error occurs during streaming:

Field Type Description
status integer HTTP status code of the error.
text string Name/type of the error.
detail any Detailed description of the error.

Example streaming response

{"timestamp": 1735815581000, "data": "Hello", "error": null}
{"timestamp": 1735815581050, "data": ",", "error": null}
{"timestamp": 1735815582100, "data": " how", "error": null}
{"timestamp": 1735815582150, "data": " are", "error": null}
{"timestamp": 1735815582200, "data": " you", "error": null}
{"timestamp": 1735815583000, "data": "?", "error": null}

Example streaming error

{"timestamp": 1735815590000, "data": null, "error": {"status": 500, "text": "Internal Server Error", "detail": "Model timeout"}}

๐Ÿ”ง cURL Examples

1. Basic chat with a model

curl -X POST "https://beta.ayeto.ai/api/v3/chat" \
  -H "uni-api-key: ayeto-a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "gpt-4o",
    "message": "Hello, how are you?"
  }'

2. Chat with an existing conversation

curl -X POST "https://beta.ayeto.ai/api/v3/chat" \
  -H "uni-api-key: ayeto-a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2" \
  -H "Content-Type: application/json" \
  -d '{
    "conversation_id": "550e8400-e29b-41d4-a716-446655440000",
    "model": "gpt-4o",
    "message": "Continue the previous topic."
  }'

3. Chat with an assistant

curl -X POST "https://beta.ayeto.ai/api/v3/chat" \
  -H "uni-api-key: ayeto-a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2" \
  -H "Content-Type: application/json" \
  -d '{
    "assistant_id": "123e4567-e89b-12d3-a456-426614174000",
    "message": "Help me with data analysis."
  }'

4. Chat with an attachment (document)

curl -X POST "https://beta.ayeto.ai/api/v3/chat" \
  -H "uni-api-key: ayeto-a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "gpt-4o",
    "message": "Analyze this document.",
    "documents": [
      {
        "filename": "report.txt",
        "data": "data:text/plain;base64,VGhpcyBpcyBhIHRlc3QgZG9jdW1lbnQu",
        "size": 25,
        "mime_type": "text/plain",
        "vision": false
      }
    ]
  }'

5. Chat with an image (Vision)

# First encode the image to base64
IMAGE_BASE64=$(base64 -w 0 photo.jpg)  # Linux
# or: IMAGE_BASE64=$(base64 -i photo.jpg)  # macOS

curl -X POST "https://beta.ayeto.ai/api/v3/chat" \
  -H "uni-api-key: ayeto-a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2" \
  -H "Content-Type: application/json" \
  -d "{
    \"model\": \"gpt-4o\",
    \"message\": \"What do you see in this image?\",
    \"documents\": [
      {
        \"filename\": \"photo.jpg\",
        \"data\": \"data:image/jpeg;base64,${IMAGE_BASE64}\",
        \"size\": $(stat -f%z photo.jpg 2>/dev/null || stat -c%s photo.jpg),
        \"mime_type\": \"image/jpeg\",
        \"vision\": true
      }
    ]
  }"

6. Image generation

curl -X POST "https://beta.ayeto.ai/api/v3/chat" \
  -H "uni-api-key: ayeto-a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "dall-e-3",
    "message": "Draw a sunset over mountains in the style of Impressionism.",
    "image": true
  }'

7. Streaming response

curl -X POST "https://beta.ayeto.ai/api/v3/chat" \
  -H "uni-api-key: ayeto-a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2" \
  -H "Content-Type: application/json" \
  -N \
  -d '{
    "model": "gpt-4o",
    "message": "Write a short story about a robot.",
    "stream": true
  }'

๐Ÿ’ก Tip: The -N (or --no-buffer) flag disables buffering for real-time stream display.

8. Streaming with chunk processing (Bash + jq)

curl -X POST "https://beta.ayeto.ai/api/v3/chat" \
  -H "uni-api-key: ayeto-a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2" \
  -H "Content-Type: application/json" \
  -N -s \
  -d '{
    "model": "gpt-4o",
    "message": "Explain quantum physics.",
    "stream": true
  }' | while IFS= read -r line; do
    echo "$line" | jq -r '.data // empty' | tr -d '\n'
  done
echo ""

9. Chat in organization context

curl -X POST "https://beta.ayeto.ai/api/v3/chat" \
  -H "uni-api-key: ayeto-a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2" \
  -H "Content-Type: application/json" \
  -d '{
    "organization_id": "550e8400-e29b-41d4-a716-446655440000",
    "model": "gpt-4o",
    "message": "What are our company goals?"
  }'

10. Chat with token limit

curl -X POST "https://beta.ayeto.ai/api/v3/chat" \
  -H "uni-api-key: ayeto-a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "gpt-4o",
    "message": "Summarize the history of computers.",
    "max_tokens": 500
  }'

11. Chat with dynamic tools and relevant history

curl -X POST "https://beta.ayeto.ai/api/v3/chat" \
  -H "uni-api-key: ayeto-a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2" \
  -H "Content-Type: application/json" \
  -d '{
    "assistant_id": "123e4567-e89b-12d3-a456-426614174000",
    "message": "Find weather information in Prague.",
    "relevant_history": true,
    "dynamic_tools": true
  }'

12. Chat with tool calls removed from the response

curl -X POST "https://beta.ayeto.ai/api/v3/chat" \
  -H "uni-api-key: ayeto-a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2" \
  -H "Content-Type: application/json" \
  -d '{
    "assistant_id": "123e4567-e89b-12d3-a456-426614174000",
    "message": "Calculate 2+2 using a calculator.",
    "remove_tool_calls": true
  }'

13. Complete example with multiple parameters

curl -X POST "https://beta.ayeto.ai/api/v3/chat" \
  -H "uni-api-key: ayeto-a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2" \
  -H "Content-Type: application/json" \
  -d '{
    "conversation_id": "550e8400-e29b-41d4-a716-446655440000",
    "organization_id": "123e4567-e89b-12d3-a456-426614174000",
    "assistant_id": "abcd1234-e89b-12d3-a456-426614174000",
    "message": "Analyze the attached document and create a summary.",
    "max_tokens": 1000,
    "relevant_history": true,
    "dynamic_tools": true,
    "stream": false,
    "remove_tool_calls": true,
    "documents": [
      {
        "filename": "report.pdf",
        "data": "data:application/pdf;base64,JVBERi0xLjQK...",
        "size": 102400,
        "mime_type": "application/pdf",
        "vision": false
      }
    ]
  }'

14. Verbose curl for debugging

curl -v -X POST "https://beta.ayeto.ai/api/v3/chat" \
  -H "uni-api-key: ayeto-a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "gpt-4o",
    "message": "Test message"
  }'

โš ๏ธ Error States

HTTP Status Description
400 Bad request (missing model or assistant_id, invalid data).
401 Invalid or missing API key (uni-api-key header).
403 Insufficient permissions (user does not have access to the conversation/assistant/organization).
404 Assistant or organization not found.
500 Internal server error.

Example error response

{
  "detail": "API key is invalid"
}

๐Ÿ”„ Validation Rules

  1. Model vs Assistant: assistant_id OR model must be provided (not both empty).
  2. Vision limit: Maximum of one document with vision: true per request.
  3. Max tokens: If provided, it must be within the modelโ€™s limits.
  4. Conversation: If a conversation with the given ID exists, it must belong to the current user.
  5. API Key scope: The API key must have scope ayeto.chat or *.