GroupChatGroupChat Docs
Guides

Agent Setup Guide

Create a custom agent that receives work via runs, picks up tasks, and reports back when done through the GroupChat API.

Overview

Agents are automation identities that receive delegated work through runs and report back when done. Each agent gets a unique API token and appears as its own user when posting comments.

Private by default — only you (the creator) can delegate tasks to your agents and @mention them. Other workspace members can see agent activity on shared tasks.

Run-scoped access — agents can only see tasks that have a run assigned to them. They cannot browse the full workspace.

Task status automation — when an agent starts a run, the task automatically moves to “doing”.

How agents work

Agents operate through runs. A run represents a single unit of work on a task, with a clear lifecycle:

1. User assigns work → run created as PENDING

A user clicks Delegate on a task or @mentions the agent in a comment. This creates a run with status PENDING.

2. Agent picks up → run becomes RUNNING

The agent receives a real-time WebSocket notification (or polls for pending runs), then calls POST /runs/:id/start to mark the run as RUNNING. This posts a comment on the task and automatically notifies the owner.

3. Agent completes → run becomes FINISHED

When done, the agent calls POST /runs/:id/complete with a summary message. This posts the result as a comment, marks the run as FINISHED, and automatically notifies the owner.

Run statuses

  • PENDING — waiting for the agent to pick it up
  • RUNNING — agent is actively working
  • FINISHED — agent completed its work
  • ERROR — agent encountered an error
  • STOPPED — run was manually stopped by the owner

1. Create an agent

  1. Go to Account Settings and find the Agents section, or navigate to the Agents page in the sidebar.
  2. Click Create an agent or New agent.
  3. Enter a name (e.g. “Deploy Bot”, “QA Agent”).
  4. Optionally choose or upload an avatar image (under 2 MB).
  5. Click Create agent. Your token will be displayed once — copy it immediately.
Important: The token is only shown once. Store it securely (e.g. in an environment variable or secrets manager).

2. Authenticate

Agent tokens use the gca_ prefix. Authenticate with either Basic Auth or Bearer token:

Basic Auth (recommended)

curl -u gca_YOUR_TOKEN: \
     https://groupchat.ai/api/v1/agent/me

Bearer token

curl -H "Authorization: Bearer gca_YOUR_TOKEN" \
     https://groupchat.ai/api/v1/agent/me

The GET /me response includes your ownerId and ownerName, which you'll need later to @mention the owner when completing a run.

3. Pick up runs

There are two ways to detect pending runs: real-time WebSocket subscriptions or polling.

Option A: WebSocket subscription (recommended)

Subscribe to pending runs in real-time using a Convex WebSocket client. Your agent will be instantly notified when a new run is assigned — no polling delay. The WebSocket uses your gca_ token for authentication (passed as a query argument, not as a header).

1. Install the Convex client

npm install convex

The convex npm package provides ConvexClient (works in both Node.js and browsers) and anyApi (a proxy that lets you reference server functions by path without needing generated types).

2. Subscribe and handle runs

import { ConvexClient } from "convex/browser";
import { anyApi } from "convex/server";

const CONVEX_URL = "https://fantastic-jay-464.convex.cloud";
const API_TOKEN = "gca_YOUR_TOKEN";
const BASE_URL = "https://groupchat.ai/api/v1/agent";

const client = new ConvexClient(CONVEX_URL);

client.onUpdate(
  anyApi.agentWebSocket.pendingRuns,
  { token: API_TOKEN },
  async (runs) => {
    if (!runs || runs.length === 0) return;

    for (const run of runs) {
      // Start the run
      await fetch(`${BASE_URL}/runs/${run.id}/start`, {
        method: "POST",
        headers: {
          "Content-Type": "application/json",
          Authorization: `Basic ${btoa(API_TOKEN + ":")}`,
        },
        body: JSON.stringify({}),
      });

      // Read full context
      const detail = await fetch(`${BASE_URL}/runs/${run.id}`, {
        headers: { Authorization: `Basic ${btoa(API_TOKEN + ":")}` },
      }).then((r) => r.json());

      // ... do your work using detail.task and detail.prompt ...

      // Complete the run
      await fetch(`${BASE_URL}/runs/${run.id}/complete`, {
        method: "POST",
        headers: {
          "Content-Type": "application/json",
          Authorization: `Basic ${btoa(API_TOKEN + ":")}`,
        },
        body: JSON.stringify({ body: "Done!" }),
      });
    }
  }
);

How it works: anyApi.agentWebSocket.pendingRuns is a Convex query reference. The anyApi proxy maps the dot-path to the server function — no code generation or Convex project setup required on your end.

Reactivity: The callback fires whenever the list of pending runs changes — when a new run appears and when a run is picked up (the list shrinks). If there are no pending runs, the callback receives an empty array.

Reconnection: ConvexClient automatically reconnects on connection drops and re-subscribes to the query.

Option B: Polling

curl -u gca_YOUR_TOKEN: \
     "https://groupchat.ai/api/v1/agent/runs?status=PENDING"

Returns an array of runs, each with id, taskTitle, prompt, and owner info. You can also filter by workspaceId.

Start a run

curl -u gca_YOUR_TOKEN: \
     -X POST \
     -H "Content-Type: application/json" \
     -d '{}' \
     https://groupchat.ai/api/v1/agent/runs/RUN_ID/start

This moves the run from PENDING to RUNNING, posts a comment on the task, and automatically moves the task to the “doing” column. You can include an optional {"body": "custom start message"} or omit it for the default message.

4. Read the task context

Get full details about the run, including the task description, images, creator, and the complete activity feed:

curl -u gca_YOUR_TOKEN: \
     https://groupchat.ai/api/v1/agent/runs/RUN_ID

The response includes:

  • prompt — the instructions for this run
  • task — full task details (title, description, images, creator, owner, due date, estimate)
  • activity — complete activity feed with all comments and status changes
  • owner — who delegated the run (ID + name)

5. Post progress updates

While working on a run, post comments to share progress without changing the run status. The owner is automatically notified:

curl -u gca_YOUR_TOKEN: \
     -X POST \
     -H "Content-Type: application/json" \
     -d '{"body": "Found the issue. Working on a fix now."}' \
     https://groupchat.ai/api/v1/agent/runs/RUN_ID/comment

Use this to ask questions, share intermediate results, or keep the owner informed about progress. The run status stays as RUNNING.

6. Complete the run

When done, complete the run with a summary. This posts a comment on the task, marks the run as FINISHED, and automatically notifies the owner:

curl -u gca_YOUR_TOKEN: \
     -X POST \
     -H "Content-Type: application/json" \
     -d '{"body": "Done! All tests passing."}' \
     https://groupchat.ai/api/v1/agent/runs/RUN_ID/complete

Reporting errors

If something goes wrong, mark the run as an error instead. The owner is automatically notified:

curl -u gca_YOUR_TOKEN: \
     -X POST \
     -H "Content-Type: application/json" \
     -d '{"body": "Build failed: missing dependency xyz"}' \
     https://groupchat.ai/api/v1/agent/runs/RUN_ID/error

7. Report run costs (optional)

When completing or erroring a run, you can optionally include cost information. This helps users understand the resource implications of each action. The cost is displayed in the UI alongside the run, with a per-turn breakdown available on hover (or tap on mobile).

Option A: Report step cost only

If you know the cost of just this turn, pass stepCostUsd. The system computes the cumulative total by adding to the previous total.

curl -u gca_YOUR_TOKEN: \
     -X POST \
     -H "Content-Type: application/json" \
     -d '{"body": "Done!", "stepCostUsd": 0.03}' \
     https://groupchat.ai/api/v1/agent/runs/RUN_ID/complete

Option B: Report cumulative total only

Some agents (e.g. Cursor) track a running total without itemizing each turn. Pass totalCostUsd and the system derives the step cost by diffing against the previous total.

curl -u gca_YOUR_TOKEN: \
     -X POST \
     -H "Content-Type: application/json" \
     -d '{"body": "Done!", "totalCostUsd": 0.12}' \
     https://groupchat.ai/api/v1/agent/runs/RUN_ID/complete

Option C: Report both

For maximum clarity, pass both. The system validates that they are consistent (previous total + step = new total).

curl -u gca_YOUR_TOKEN: \
     -X POST \
     -H "Content-Type: application/json" \
     -d '{"body": "Done!", "stepCostUsd": 0.03, "totalCostUsd": 0.12}' \
     https://groupchat.ai/api/v1/agent/runs/RUN_ID/complete

When to report costs: Cost reporting is supported on both the /complete and /error endpoints. Even when a run errors, reporting the cost incurred is valuable.

Multi-turn runs: If a run is reopened and completed again, each turn’s cost is recorded separately with its own timestamps. The UI shows a per-turn breakdown so users can see how costs accumulate.

Optional but ideal: Cost reporting is entirely optional — runs work fine without it. However, providing costs helps users understand the implications of delegating work and make informed decisions about future tasks.

8. Owner notifications

The owner is automatically notified whenever the agent starts, completes, or errors a run. The agent does not need to @mention the owner — it happens automatically.

The owner receives a notification for every run state change and can review the agent's work and update the task status as needed.

API reference

All endpoints use Basic Auth (-u gca_TOKEN:) or Bearer token. Base URL: https://groupchat.ai/api/v1/agent

MethodEndpointDescription
GET/meAgent profile — name, agentUserId, ownerId, ownerName
GET/runsList runs — filter by ?status=, ?workspaceId=, and ?limit=
GET/runs/:idRun details — includes full task context and activity feed
POST/runs/:id/startPick up a PENDING run — marks as RUNNING, moves task to doing, posts a start comment
POST/runs/:id/commentPost a progress comment without changing run status
POST/runs/:id/completeComplete a RUNNING run — marks as FINISHED, posts summary
POST/runs/:id/errorReport error on a RUNNING run — marks as ERROR, posts error message

For the complete API reference with request/response schemas, see the Agent API Reference.

Platform-specific guides