API v2

Ask Optiverse

Ask the Optiverse Agent from your own code, continue sessions, stream progress, and cancel a running answer.

POST /v2/agent/ask sends a message to the full Optiverse Agent, the same agent you use in the app. It can search and analyze your meetings, work on your boards, and act through the integrations you have connected. Use it when a task needs reasoning across several steps. For a single lookup, the direct Meetings and Boards operations are faster and free.

The agent acts with your permissions, including your connected integrations. It may make changes in external systems that are hard to reverse, for example sending a message or updating a CRM record.

Ask a Question

POST /v2/agent/ask

FieldTypeRequiredDescription
messagestringYesYour request, up to 32,000 characters. Markdown is supported.
sessionIdstring (UUID)NoContinue an earlier session. Omit it to start a new private session.
curl -X POST "https://developer.optiverse.ai/api/v2/agent/ask" \
  -H "Authorization: Bearer optiuser_v1_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{ "message": "What did we agree with Acme in last week'\''s meetings?" }'
{
  "data": {
    "answer": "In the two Acme meetings last week, you agreed to...",
    "sessionId": "6c1f5b0e-4a51-4c4e-9a43-0d7e2b8f1a27"
  }
}

To ask a follow-up in the same thread, send the returned sessionId with your next message. A session started over the API can also be continued from an MCP client, and the reverse.

Answers can take from a few seconds to several minutes, depending on how much work the agent does. Set your HTTP client timeout to at least 10 minutes.

Stream Progress

Send Accept: text/event-stream to receive progress while the agent works. The response is a Server-Sent Events stream with four event types:

EventDataWhen
session{ "sessionId": "..." }Once, first, when the agent starts; the session this answer belongs to
progress{ "message": "Searching meetings…" }Each time the agent starts a step
result{ "data": { "answer": "...", "sessionId": "..." } }Once, when the answer is ready
errorThe standard error envelopeOnce, if the turn fails after the stream opened
curl -N -X POST "https://developer.optiverse.ai/api/v2/agent/ask" \
  -H "Authorization: Bearer optiuser_v1_your_key_here" \
  -H "Content-Type: application/json" \
  -H "Accept: text/event-stream" \
  -d '{ "message": "Summarize open tasks on my Launch board" }'
event: session
data: {"sessionId":"6c1f5b0e-..."}

event: progress
data: {"message":"Reading board Launch"}

event: result
data: {"data":{"answer":"There are 7 open tasks...","sessionId":"6c1f5b0e-..."}}

Lines starting with : are keep-alive comments; ignore them. An invalid key, invalid input or a rate limit is returned as a normal JSON error response, before the stream opens. Every later error, including conflict, not_found, insufficient_credits and cancelled, arrives as an error event in the stream.

Disconnects and Cancellation

Closing the connection does not stop the agent. The answer is still saved to the session, and you can read it later with Get session messages. To stop a running answer, call Cancel. For a new session, take the sessionId from the session event. JSON clients receive it in the final response, or in error.details.sessionId if a started turn times out, loses its internal connection, or fails.

These failures return retryable: false because actions may already have happened or may still be running. Read the existing session or cancel it before deciding on a new request. Resending the original message is a new turn and can repeat actions. If your own connection closes before any response, use List sessions to locate the recent session instead of automatically replaying the request.

Errors

CodeStatusWhen
conflict409The session is still answering a previous message. Wait for it, or cancel it.
insufficient_credits402Your plan has no credits left.
not_found404The sessionId does not exist or belongs to someone else.
rate_limited429More than 10 asks in a minute.
cancelled400The answer was stopped with Cancel while you were waiting for it.
timeout504The agent took too long to answer. Use error.details.sessionId to inspect or cancel the existing session.
upstream_unavailable503The internal connection was interrupted. After a turn starts, inspect the existing session instead of automatically retrying.

Each message uses one credit, the same as asking in the app.

List Sessions

GET /v2/agent/sessions

Sessions started over the API or MCP, newest first. Chats you start in the app are not included.

ParameterTypeDefaultDescription
limitinteger201 to 100
offsetinteger0Number of sessions to skip
{
  "data": {
    "sessions": [
      {
        "sessionId": "6c1f5b0e-4a51-4c4e-9a43-0d7e2b8f1a27",
        "title": "Acme agreements last week",
        "source": "api",
        "createdAt": "2026-10-14T08:12:40.000Z",
        "updatedAt": "2026-10-14T08:13:55.000Z"
      }
    ]
  },
  "pagination": { "limit": 20, "offset": 0, "hasMore": false, "nextOffset": null, "total": 1 }
}

source is api or mcp, depending on where the session started.

Get Session Messages

GET /v2/agent/sessions/{sessionId}/messages

The messages in one session, oldest first.

ParameterTypeDefaultDescription
limitinteger501 to 100
offsetinteger0Number of messages to skip
{
  "data": {
    "session": { "sessionId": "6c1f5b0e-...", "title": "Acme agreements last week", "source": "api", "createdAt": "...", "updatedAt": "..." },
    "messages": [
      {
        "messageId": "0b8d2c1a-...",
        "createdAt": "2026-10-14T08:12:40.000Z",
        "message": "What did we agree with Acme in last week's meetings?",
        "answer": "In the two Acme meetings last week, you agreed to...",
        "completed": true
      }
    ]
  },
  "pagination": { "limit": 50, "offset": 0, "hasMore": false, "nextOffset": null, "total": 1 }
}

While the agent is still working, completed is false and answer may be null.

Cancel a Running Answer

POST /v2/agent/sessions/{sessionId}/cancel

Stops the answer the session is currently working on.

{ "data": { "sessionId": "6c1f5b0e-...", "cancelled": true } }

cancelled is false when nothing was running.