Start an agent chat

October 16, 2026

Table of contents

  1. Request Headers
  2. Request Body
  3. Responses
  4. Model
  5. Callback
  6. Examples
  7. Try It

Start a chat with Google Flow Agent and send its first message. The answer is a chatId for every later call. See the Agent Overview for how chats, approvals and credits work.

The request answers 202 as soon as Google has accepted the turn. That usually takes a few seconds to about 40 seconds and can take up to about 100 seconds, so set your HTTP client’s timeout to about 150 seconds. The turn then keeps running on Google’s side whether or not you are connected. Follow it live with GET /agent/chats/chatId/stream, read it with GET /agent/chats/chatId, or get it posted to your replyUrl when it ends.

A 504 means Google has not confirmed the turn yet, and it may still start. Read the chat with GET /agent/chats/chatId before you send it again.

Each turn uses one captcha, solved by the API with your captcha providers or the free captcha credits of your first account.

https://api.useapi.net/v1/google-flow/agent/chats

Request Headers
Authorization: Bearer {API token}
Content-Type: application/json
# Alternatively you can use multipart/form-data
# Content-Type: multipart/form-data
Request Body
{
  "message": "Make one 8 second video with Veo 3.1 - Lite of a paper boat floating on a calm pond.",
  "email": "[email protected]",
  "replyUrl": "https://example.com/flow-agent-hook",
  "replyRef": "my-ref-42"
}
  • message is required, what you say to the agent.
    Maximum length: 20000 characters.
  • email is optional, the Google Flow account to chat on. When omitted, the account the references belong to is used, or without references the API picks one of your accounts the same way it does for POST /images.
  • projectId is optional, the Flow project the chat lives in, from GET /assets/projects/email.
    Default: the account’s own agent project, created on its first chat and named like My Agents Work Fri, Oct 16.

  • referenceImage_1 to referenceImage_7 are optional, images to attach: an id from POST /assets/email, an image made by POST /images, or the referenceId of an image the agent made.
  • referenceVideo_1 is optional, a video to attach: an uploaded video from POST /assets/email, a video made by POST /videos, or the referenceId of a video the agent made.
  • referenceAudio_1 to referenceAudio_5 are optional, voices to attach. Each one is a built-in voice name such as Aoede or Achernar (case-insensitive, the 30 names listed on POST /voices), or a custom voice from POST /voices or GET /voices.
  • character_1 to character_7 are optional, characters from POST /characters or GET /characters.

All references must belong to the account the chat runs on. They can come from any project of that account.

Point at a reference inside the message with an @-mention, the same syntax as POST /videos: @referenceImage_1, @referenceVideo_1, @referenceAudio_1, @character_1. Each @-mention needs its matching parameter. A mentioned reference appears inside the sentence, the way a chip does in the Flow web app. A reference you pass without mentioning it is attached to the message as well.

{
  "message": "Make @character_1 walk into @referenceImage_1 and say hello in the @referenceAudio_1 voice",
  "character_1": "user:12345-email:6a6f...-character:860b2818-...-imgs:2",
  "referenceImage_1": "user:12345-email:6a6f...-image:6bb4a078-...",
  "referenceAudio_1": "Aoede"
}
  • replyUrl is optional, a public https URL that receives one POST with the turn’s result when it ends. When omitted, the replyUrl of your useapi.net account is used, if you set one. See Callback.
  • replyRef is optional, your own reference sent back in the callback body.
    Maximum length: 1024 characters.
  • captchaToken, captchaRetry, captchaOrder are optional, the same captcha parameters as every Flow generation request. See Captcha Parameters.
Responses
  • 202 Accepted

    Google accepted the turn and the agent is working on it. Follow it with GET /agent/chats/chatId/stream.

    {
      "chatId": "c-u12345-email:[email protected]:f166200a-ea22-461a-bc68-47ff6d3ee500-chat:2a0f1973-d554-4fbc-aa6b-0c372edf182e-bot:google-flow",
      "email": "[email protected]",
      "turn": 1,
      "status": "running"
    }
    
  • 400 Bad Request

    A parameter is missing or invalid, an @-mention has no matching parameter, or a reference belongs to another account.

    {
      "error": "message mentions @referenceImage_1 but referenceImage_1 was not given",
      "code": 400
    }
    
  • 401 Unauthorized

    Invalid API token.

    {
      "error": "Unauthorized",
      "code": 401
    }
    
  • 404 Not Found

    The account named by email is not added.

    {
      "error": "Google Flow account [email protected] not found",
      "code": 404
    }
    
  • 429 Too Many Requests

    429 has two causes. When the API picked the account itself (no email), retry or pass another account’s email.

    The account already runs 3 agent turns, the most the API runs at once per account. Wait for one to finish, or use another account. The answer carries a Retry-After header (seconds) and a retryAfter time in the body.

    {
      "error": "Account [email protected] already runs 3 agent turns (our limit per account). Wait for one to finish or use another account",
      "code": 429,
      "retryAfter": "2026-10-16T22:26:47.819Z"
    }
    

    The account reached Google’s daily limit on agent messages. Google does not publish the limit. The message Google refused answers with reason AGENT_QUOTA, and after that the API answers at once until midnight UTC, with Retry-After and retryAfter set to that time. Use another account until then.

    {
      "error": "Google's daily Flow agent limit is reached for [email protected]. Try again after 2026-10-17T00:00:00.000Z or use another account",
      "code": 429,
      "retryAfter": "2026-10-17T00:00:00.000Z"
    }
    
  • 502 Bad Gateway

    Google answered with an error or without a readable reply (reason GOOGLE_ERROR or UNREADABLE_ANSWER). The turn may have run. Look at GET /agent/chats before you send it again.

    {
      "error": "Google answered without a readable reply and may already have run this turn. Check GET /agent/chats/{chatId} before retrying",
      "code": 502,
      "reason": "UNREADABLE_ANSWER"
    }
    
  • 503 Service Unavailable

    Nothing ran and nothing was charged. Google refused every captcha for the turn (reason CAPTCHA_FAILED), so send the message again. When error starts with Captcha service failed:, the problem is your captcha provider: check its key and balance.

    {
      "error": "Google refused every captcha token for this turn. Nothing ran and nothing was charged. Retry",
      "code": 503,
      "reason": "CAPTCHA_FAILED"
    }
    
  • 504 Gateway Timeout

    Google has not confirmed the turn yet, and it may still start. Read the chat with GET /agent/chats/chatId before you send it again.

    {
      "error": "Google has not confirmed the turn yet; it may still start. Read GET /agent/chats/{chatId} before sending it again",
      "code": 504,
      "chatId": "c-u12345-email:[email protected]:f166200a-ea22-461a-bc68-47ff6d3ee500-chat:8bcfbc1d-6c51-409c-8a2e-1870cbbe6e76-bot:google-flow",
      "turn": 1
    }
    
  • 596 Session Error

    The account’s Google session is no longer valid. Delete the account with DELETE /accounts/email and add it again by following Setup Google Flow.

    {
      "error": "Google Flow account [email protected] Session expired on 2026-10-16T20:00:00.000Z",
      "code": 596
    }
    
Model
{ // TypeScript, all fields are optional
  chatId: string        // c-u<user>-email:<email>-project:<projectId>-chat:<id>-bot:google-flow
  email: string         // the account the chat runs on
  turn: number          // 1 for a new chat
  status: 'running' | 'completed' | 'waiting_approval' | 'failed'  // almost always running
  error?: string        // errors only
  code?: number         // errors only
  reason?: string       // CAPTCHA_FAILED | UNREADABLE_ANSWER | GOOGLE_ERROR | AGENT_QUOTA, on errors after the request reached Google
  retryAfter?: string   // 429 only
}
Callback

When the turn ends, the API sends one POST with a JSON body to replyUrl. Videos usually finish a minute or two after the turn, so they arrive with status queued. Get their links from GET /agent/chats/chatId or the stream’s media events.

{
  "chatId": "c-u12345-email:[email protected]:f166200a-ea22-461a-bc68-47ff6d3ee500-chat:2a0f1973-d554-4fbc-aa6b-0c372edf182e-bot:google-flow",
  "email": "[email protected]",
  "turn": 2,
  "status": "completed",
  "replyRef": "my-ref-42",
  "messages": [
    {
      "id": "2:b3f9cea0-19f1-4fbb-a207-f3a9cc8c58f9",
      "turn": 2,
      "items": [
        {
          "kind": "tool_result",
          "tool": "generate_video_from_text",
          "result": { "status": "queued", "media_id": "97aa051d-419f-40fd-a200-f5593d997822", "display_name": "Paper boat floating on pond" }
        }
      ]
    },
    {
      "id": "2:847ad05d-6709-45a0-b75d-b15ea1f5efba",
      "turn": 2,
      "items": [
        { "kind": "text", "text": "Your video of a paper boat on a calm pond has been scheduled. Feel free to check back in a few minutes!" }
      ]
    }
  ],
  "media": [
    {
      "referenceId": "user:12345-email:6a6f...-video:97aa051d-419f-40fd-a200-f5593d997822",
      "mediaId": "97aa051d-419f-40fd-a200-f5593d997822",
      "type": "video",
      "status": "queued",
      "tool": "generate_video_from_text",
      "model": "veo_3_1_t2v_lite",
      "displayName": "Paper boat floating on pond"
    }
  ]
}
  • status is completed, waiting_approval (the agent asks before it spends credits, see pendingApproval) or failed (see error).
  • messages are the agent’s messages of this turn, the same objects as the stream’s message events.
  • media lists what the turn made, the same objects as the stream’s media events.
  • pendingApproval is there only while the agent waits for an approval: { turn, cost, images, videos, total }.
  • error is there only on a failed turn: { code, message, httpStatus }, see Turn errors.
  • replyRef is your own replyRef, when you sent one.
Examples
  • curl -X POST "https://api.useapi.net/v1/google-flow/agent/chats" \
         --max-time 150 \
         -H "Content-Type: application/json" \
         -H "Authorization: Bearer YOUR_API_TOKEN" \
         -d '{
           "message": "Make one image of a lighthouse at sunset in a watercolor style.",
           "email": "[email protected]"
         }'
    
  • const token = 'YOUR_API_TOKEN'
    const response = await fetch('https://api.useapi.net/v1/google-flow/agent/chats', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'Authorization': `Bearer ${token}`
      },
      body: JSON.stringify({
        message: 'Make one image of a lighthouse at sunset in a watercolor style.',
        email: '[email protected]'
      }),
      signal: AbortSignal.timeout(150_000)
    })
    const result = await response.json()
    console.log(response.status, result.chatId)
    
  • import requests
    token = 'YOUR_API_TOKEN'
    r = requests.post(
        'https://api.useapi.net/v1/google-flow/agent/chats',
        headers={'Authorization': f'Bearer {token}'},
        json={
            'message': 'Make one image of a lighthouse at sunset in a watercolor style.',
            'email': '[email protected]',
        },
        timeout=150,
    )
    print(r.status_code, r.json().get('chatId'))
    
Try It

The form waits until Google accepts the turn, which can take up to about 100 seconds. Copy the chatId into GET /agent/chats/chatId/stream to watch the agent work.