Skip to main content

Quickstart

This walks through the whole path once: a project and its secret, an end user and their token, a session with a first message, and its reply streaming back. Every call is plain HTTPS with JSON, so any language works; the examples use curl, JavaScript and Python.

1. Create a project and a secret​

Sign in to the console with your Google account and create a project. The console shows the project's first secret once, right after you create the project: copy it into your backend's secret store. You can create more secrets, and revoke any of them, on the project's Keys page.

The console's project page also shows the API base URL to call. The examples below read both from the environment:

export NEWEYES_API_BASE="https://…" # the API base URL from the console
export NEWEYES_PROJECT_SECRET="…" # the secret you just copied
warning

A project secret acts for your whole project. Keep it on your servers: never put it in an app, a web page, or a code repository.

2. Create an end user and issue a token​

Your backend creates one end user per user of your product, and keeps the returned id with its own record of that user. Every call creates a new user, so call it once per user. Ask for the user's first token in the same call with issue_token:

curl -s "$NEWEYES_API_BASE/v1/users" -X POST \
-H "Authorization: Bearer $NEWEYES_PROJECT_SECRET" \
-H "Content-Type: application/json" \
-d '{"issue_token": true}' \
| jq -r '.id, .token.token' # the user's id, then its token string
{
"object": "user",
"id": "4f6d…",
"is_active": true,
"created_at": "2026-10-19T08:00:00Z",
"token": { "object": "token", "token": "…", "token_type": "bearer", "expires_at": "2026-10-19T09:00:00Z" }
}

The token string is the answer's token.token: it is what the user's app sends, as Authorization: Bearer <token>.

A token lasts an hour unless you ask for another lifetime (expires_in, from 60 seconds to 24 hours). When it runs out, issue the user a new one:

curl -s "$NEWEYES_API_BASE/v1/users/$USER_ID/tokens" -X POST \
-H "Authorization: Bearer $NEWEYES_PROJECT_SECRET" \
-H "Content-Type: application/json" \
-d '{"expires_in": 3600}'
{ "object": "token", "token": "…", "token_type": "bearer", "expires_at": "2026-10-19T10:00:00Z" }

Hand the token string to your app. From here on, every call is made as that user, with the token; the examples read it from the environment:

export NEWEYES_USER_TOKEN="…" # the token string: token.token in the answer above

3. Start a session with a first message​

A session is one conversation. Create it with the user's first message, and pick the form its replies take: markdown for formatted text, or a2ui (the default) for UI data your app renders.

curl -s "$NEWEYES_API_BASE/v1/sessions" -X POST \
-H "Authorization: Bearer $NEWEYES_USER_TOKEN" \
-H "Content-Type: application/json" \
-d '{"output_format": "markdown", "text": "Plan a two-day trip to Kyoto in spring."}'
{
"object": "session",
"id": "9c1e…",
"type": "text",
"status": "queued",
"output_format": "markdown",
"task_id": "exec-…",
"last_event_id": "0",
"created_at": "2026-10-19T08:01:00Z"
}

The message started a task: the assistant's answer, named by task_id. last_event_id says where the task begins on the session's event stream.

4. Stream the reply​

Open the session's event stream with Last-Event-ID set to that last_event_id. The stream sends the task from its first frame: the reply text as it is written (text.delta), the steps the assistant takes (task.progress), and one end frame (task.completed, task.failed or task.stopped) whose text is the whole reply.

curl -N "$NEWEYES_API_BASE/v1/sessions/$SESSION_ID/events" \
-H "Authorization: Bearer $NEWEYES_USER_TOKEN" \
-H "Last-Event-ID: 0"

A frame looks like this on the wire:

id: 1760860860123-0:1
event: text.delta
data: {"task_id": "exec-…", "delta": "Day one: start early at Fushimi Inari"}

You can also ask for the task on the request itself: send the next message with "stream": true, and the response is that task's own frames, ending with its end frame. See Event streams.

5. Read the conversation​

The reply is also kept in the session's message list, so your app can show the conversation later without replaying the stream:

curl -s "$NEWEYES_API_BASE/v1/sessions/$SESSION_ID/messages" \
-H "Authorization: Bearer $NEWEYES_USER_TOKEN"

Next steps​

  • Sessions and messages — later messages, attachments, stopping a task, and deleting a session.
  • Event streams — every frame, resuming after a dropped connection, and heartbeats.
  • Errors — how a refused call answers, and how to branch on it.