# Add Chat to Your App

Source: https://docs.generalaugment.com/guides/add-chat-to-your-app/
Description: Call General Augment from your app backend with the Responses-compatible API.

General Augment is the agent backend for your app. Your product keeps the user interface,
auth, billing, and source of truth. General Augment runs the managed agent turn with memory,
tools, identity resolution, usage tracking, and observability.

Integration shape
**One backend call per user message.**
Your UI talks to your own app backend. Your backend attaches the signed-in user id, calls General Augment, then returns assistant text to the client.

POST
`https://api.generalaugment.com/v1/responses`

> Note:

Never call General Augment directly from browser or mobile client code. Put the project
scoped API key in your backend environment and expose your own app endpoint to the UI.

> Note:

`/v1/responses` accepts a project-scoped API key as `Authorization: Bearer ...`.
If you use an unscoped admin key for testing, also send `X-Project-ID`; production app
chat should use a project-scoped key.

## Request Path

Your chat UI
Your app backend
General Augment
Managed agent runtime

Use one stable `user` value per signed-in app user. That lets General Augment attach memory,
tool approvals, usage, and future channel identity links to the same person.

Use `model: "simple"`, `"balanced"`, or `"complex"` as a tier selector instead of
hardcoding provider model names. Operators can update the provider model behind each
project tier without app code changes. If you prefer OpenAI-style effort hints, use
current Responses `reasoning.effort`: `low` maps to `simple`, `medium` to
`balanced`, and `high` or `xhigh` to `complex`. The legacy top-level
`reasoning_effort` alias remains accepted for existing clients.

## Integration Steps

1. Create or open a project in the General Augment dashboard.

2. Generate a project-scoped API key and store it as `GENERAL_AUGMENT_PROJECT_API_KEY`.

3. Add a backend route in your app that accepts a user message and calls `/v1/responses`.

4. Pass your signed-in app user id as `user`.

5. Render the returned `output_text` in your existing chat UI.

## Backend Route Contract

Expose a small route in your own app. The browser or mobile client should only know about
your route, not the General Augment project-scoped key.

Client to backend
**`message`**
The latest user message.

Backend to General Augment
**`userId`**
Use your signed-in app user id.

Backend to General Augment
**`metadata.source`**
Set a stable source such as `app-chat`, `support-chat`, or `mobile-chat`.

General Augment to backend
**`response.id`**
Store in logs for debugging, audit, and support.

Backend to client
**`output_text`**
Render this in your chat UI.

## Backend Example

During app backend tests, set `GENAUG_API_BASE_URL=http://127.0.0.1:8787` and point
this same client path at the [local mock server](/guides/local-testing/). The mock
returns deterministic Responses and memory fixtures without live model calls or
provider credentials.

If your app already owns user OAuth for actions such as Gmail or Calendar, keep those
side effects in your backend. Ask General Augment for a summary, draft, or structured
action proposal, show your own confirmation UI, then execute with app-held credentials.
Delegate tools later only after General Augment credentials, identity links, allowlists,
and approval UX are connected.

```ts
type ChatInput = {
  userId: string;
  message: string;
};

export async function generalAugmentChat({ userId, message }: ChatInput) {
  const baseUrl = process.env.GENAUG_API_BASE_URL ?? "https://api.generalaugment.com";

  const response = await fetch(`${baseUrl}/v1/responses`, {
    method: "POST",
    headers: {
      Authorization: `Bearer ${process.env.GENERAL_AUGMENT_PROJECT_API_KEY}`,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      model: "balanced",
      user: userId,
      input: message,
      metadata: {
        source: "app-chat",
      },
      stream: false,
    }),
  });

  if (!response.ok) {
    if (response.status === 429) {
      const retryAfter = response.headers.get("Retry-After");
      throw new Error(`General Augment rate limited this user; retry after ${retryAfter ?? "the reset window"}.`);
    }
    if (response.status === 402) {
      throw new Error("General Augment budget or usage limit reached for this project.");
    }
    throw new Error(await response.text());
  }

  const payload = await response.json();
  return extractOutputText(payload);
}

function extractOutputText(payload: any): string {
  return (
    payload.output
      ?.flatMap((item: any) => item.content ?? [])
      ?.find((part: any) => part.type === "output_text")
      ?.text ?? ""
  );
}
```

```python

def general_augment_chat(user_id: str, message: str) -> str:
    base_url = os.getenv("GENAUG_API_BASE_URL", "https://api.generalaugment.com")
    response = httpx.post(
        f"{base_url}/v1/responses",
        headers={
            "Authorization": f"Bearer {os.environ['GENERAL_AUGMENT_PROJECT_API_KEY']}",
            "Content-Type": "application/json",
        },
        json={
            "model": "balanced",
            "user": user_id,
            "input": message,
            "metadata": {"source": "app-chat"},
            "stream": False,
        },
        timeout=30,
    )
    if response.status_code == 429:
        raise RuntimeError(
            f"General Augment rate limited this user; retry after {response.headers.get('Retry-After', 'the reset window')}"
        )
    if response.status_code == 402:
        raise RuntimeError("General Augment budget or usage limit reached for this project")
    response.raise_for_status()
    payload = response.json()
    return extract_output_text(payload)

def extract_output_text(payload: dict) -> str:
    for item in payload.get("output", []):
        if item.get("type") != "message":
            continue
        for part in item.get("content", []):
            if part.get("type") == "output_text":
                return part.get("text", "")
    return ""
```

## What To Send

### user

A stable app user id, such as your database user id. Avoid email addresses when a durable
opaque id is available.

### input

The latest user message, or a typed Responses-style input array when you need richer
conversation context.

### metadata

App-specific routing and diagnostics, such as `source`, `workspace_id`, `plan`, or
`environment`.

### previous_response_id

Optional continuity when your app wants to resume from a specific stored response.

Use the same opaque app user id for explicit memory APIs:

```ts
await fetch(`${baseUrl}/api/v1/agent/memory/store`, {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.GENERAL_AUGMENT_PROJECT_API_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    user_id: "app-user-123",
    fact: "User prefers weekly summaries on Mondays",
    fact_type: "preference",
    source: "settings",
  }),
});
```

That value is the join key between `/v1/responses`, durable memory, approvals, traces,
and future channel identity links. Regression coverage verifies memory context is
scoped per external app user before model dispatch; launch validation should still
include explicit memory store/search/profile checks.

## Response Shape

General Augment returns a Responses-compatible object. For a normal text reply, read the
first `output_text` part from the `output` list.

```json
{
  "id": "resp_abc123",
  "object": "response",
  "status": "completed",
  "output": [
    {
      "type": "message",
      "content": [
        {
          "type": "output_text",
          "text": "Here is the plan..."
        }
      ]
    }
  ]
}
```

For debugging and reconciliation, store response `id`,
`metadata.general_augment_trace_id`, top-level `model`,
`metadata.general_augment_model`, `usage.input_tokens`, `usage.output_tokens`,
`usage.total_tokens`, and `metadata.general_augment_cost_usd` when present.

## Production Checklist

**Secrets**Store `GENERAL_AUGMENT_PROJECT_API_KEY` in your backend secret manager.
**Identity**Pass a stable `user` id for every signed-in user.
**Limits**Add your own app rate limits before forwarding requests.
**Tools**Keep tool credentials in General Augment credentials, not prompts.
**Metadata**Send useful `metadata.source` values for analytics and debugging.
**Logs**Log the returned response `id` in your app request logs.
**Verification**Run `genaug smoke`, `genaug verify`, and `genaug onboarding verify --json` before launch.
**Backoff**Handle `402` and `429` without tight retry loops.

## Next

- [Local testing] - Run offline contract tests against a local Responses and memory mock.
- [Connect your API] - Generate governed tools from an OpenAPI spec.
- [Identity linking] - Map channel users back to your app users.
- [Security model] - Review tenant, credential, and tool execution boundaries.
