> For the complete documentation index, see [llms.txt](https://ask-clio.gitbook.io/ask-clio/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://ask-clio.gitbook.io/ask-clio/adding-context-and-custom-workflows/ask-clioworkflows-+-context-website-integration-guide.md).

# Ask ClioWorkflows + Context —Website Integration Guide

## &#x20;<a href="#ask-clio-workflows-context-website-integration-guide" id="ask-clio-workflows-context-website-integration-guide"></a>

### Overview <a href="#overview" id="overview"></a>

Once the Ask Clio widget is on your page, two features let your page steer it:

* **Context**: your page tells Clio what the user is viewing (a quote page, a selected account). Nothing opens. When the user later asks *"Should I buy this?"*, Clio knows "this" is AAPL.
* **Workflows**: your page starts a ready-made conversation, such as an account update at login or a "Upload Financial Statement" button. Your staff write the instructions in Middle Office; your page only sends data.

Both use what your integration already has: the SDK session token (`SESSION_TOKEN` below) and the `clio` handle returned by `attachClioSDK`. Everything here runs on production, **app.askclio.ai**.

### Step 1 — Send context <a href="#step-1-send-context" id="step-1-send-context"></a>

Call this from your page whenever what the user is looking at changes. It uses the same session token; no chat opens.

```
function setClioContext(context, textContext) {
  return fetch("https://app.askclio.ai/api/sdk/context/", {
    method: "PUT",
    headers: {
      Authorization: "session " + SESSION_TOKEN,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({ context: context, text_context: textContext }),
  });
}

function clearClioContext() {
  return fetch("https://app.askclio.ai/api/sdk/context/", {
    method: "DELETE",
    headers: { Authorization: "session " + SESSION_TOKEN },
  });
}

// On the Apple quote page:
setClioContext({
  page_key: "markets.quote",
  page_label: "Apple Quote",
  attributes: { symbol: "AAPL", account_type: "brokerage" },
});
```

Rules that matter:

* **Each call replaces the whole context.** Keys you leave out are gone, so always send everything that is still true.
* **It expires 30 minutes after the last call.** Send it on page load and again whenever the page or selection changes.
* **Clear it** when the user leaves a page whose context no longer applies.
* **It is data, not instructions.** Clio reads it as background facts; to tell Clio what to do, use a workflow.
* **Limits:** context up to 8 KB, 50 keys, 3 levels deep; `text_context` up to 4,000 characters. Over a limit is refused, never cut.
* **Rate limit:** 60 calls a minute per session. Past that you get a `429` with `Retry-After`.

**Try it from the dashboard first.** In **Workflows → Context API → Test the SDK**, click **Create Session**, then **Set context**, **Get current** or **Clear**. This works only on that staff test session: a real visitor's context can only come from your page, and the dashboard shows it read-only under **Recent Context Events**.

### Step 2 — Start a workflow <a href="#step-2-start-a-workflow" id="step-2-start-a-workflow"></a>

**Configure it once in Middle Office.** In the dashboard, go to **Workflows → Conversation Workflows → New workflow** and set:

| Field               | Example                                           | Notes                                        |
| ------------------- | ------------------------------------------------- | -------------------------------------------- |
| Slug                | `login_account_update`                            | What your page calls; can never change       |
| Prompt              | Give a short account update and invite questions. | Clio's instructions; never shown to the user |
| Opening message     | Welcome back!                                     | First message the user sees                  |
| Launch behavior     | Open chat                                         | How the chat appears (table below)           |
| Expected fields     | `account_number`, string, required                | Checked on every start                       |
| Attachments enabled | Off                                               | Turn on to accept files                      |
| Follow-up chips     | What changed this week?                           | Up to 5, shown after the first answer        |

**Call it from your page:**

```
clio.startWorkflow("login_account_update", {
  context: { account_number: "12345678" },
  // text_context: "optional free text",
  // files: fileInput.files,   // documents or images to attach
})
  .then(function (launch) {
    console.log("Started chat", launch.chat_id);
  })
  .catch(function (err) {
    console.warn("Refused", err.status, err.message, err.body);
  });
```

Every start creates a **new chat**. The promise resolves once the chat exists and rejects if it was refused, in which case nothing was created.

| Launch behavior            | What the user sees                                                                           |
| -------------------------- | -------------------------------------------------------------------------------------------- |
| Open chat                  | The chat opens immediately                                                                   |
| Open minimized             | The chat stays closed; a label with the workflow's user-facing label appears on the launcher |
| Open after document upload | The chat opens once the attached documents have been read                                    |
| Start silently             | Nothing until the user opens the chat; the conversation is waiting there                     |

**Files:** PDF, DOCX, DOC, XLSX, XLS, CSV, TXT, PNG, JPG, JPEG or GIF, up to 5 per start, only for workflows with attachments enabled. To know when the documents are read and the answer starts, use `clio.on("workflowReady", function (e) { … })`.

### Expected fields, such as account\_number <a href="#expected-fields-such-as-accountnumber" id="expected-fields-such-as-accountnumber"></a>

An expected field is a piece of data a workflow needs from your page at launch. `account_number` is only an example; you define your own per workflow in Middle Office.

**Why a workflow needs it.** A prompt like *"Give a short account update"* can't say which account. Your page knows (the user just signed in to 12345678), so it sends it in `context`. Clio receives the prompt plus `account_number: 12345678` as data and answers about that account.

**Why mark it required.** A launch without it is a bug in your code. With **Required** on, Clio refuses that launch with a `400` and creates no chat, so your developer sees it the first time they test, not a user in a confused conversation. The type check does the same for a wrong type, such as `12345678` instead of `"12345678"`.

**What it doesn't do: fetch the account's data.** Your tools read real balances and positions from the session's `tools_input`, which your backend sets when it creates the session.

|         | `account_number` in context                        | `tools_input`                             |
| ------- | -------------------------------------------------- | ----------------------------------------- |
| Set by  | Your page, at launch                               | Your backend, when creating the session   |
| Read by | The assistant, as background data                  | Your tools only                           |
| Purpose | Tells Clio which account the conversation is about | Lets tools fetch that account's real data |

For a real account update, send both: `account_number` so Clio knows what the conversation is about, and the account id in `tools_input` so its tools can fetch the numbers.

### Errors <a href="#errors" id="errors"></a>

Go by the status code. On some hosts a `404` comes back as an HTML page instead of JSON; the status is still right.

| Status                                  | Meaning                                                                                 | What your page should do                                             |
| --------------------------------------- | --------------------------------------------------------------------------------------- | -------------------------------------------------------------------- |
| `401`                                   | Session token missing or expired (24 h)                                                 | Get a new token from your backend, then `clio.refreshSession(token)` |
| `403`                                   | Not a valid session for your firm                                                       | Check you send the end user's session token                          |
| `404` on start                          | Unknown slug, or the workflow is switched off                                           | Check the slug and that it is enabled in Middle Office               |
| `400` "required by workflow"            | A required expected field is missing                                                    | Integration bug: send the field                                      |
| `400` "Expected string, got number."    | Wrong type for an expected field                                                        | Send the declared type, e.g. `"123"` not `123`                       |
| `400` on attachments                    | Files not allowed, unknown file, wrong type, or none sent to an "after upload" workflow | Fix the files you send                                               |
| `400` `RateLimitExceededException`      | Your firm's plan has no requests left                                                   | Contact Ask Clio                                                     |
| `429` `UserDailyLimitExceededException` | This user's daily allowance is used up                                                  | Show `err.body.message` to the user as-is                            |
| `429` "Request was throttled"           | Over 60 context calls a minute                                                          | Wait `Retry-After` seconds; send context less often                  |

For `startWorkflow`, these arrive as `err.status`, `err.body` (the original response body) and `err.message`.

### Verify it works <a href="#verify-it-works" id="verify-it-works"></a>

Run through this before going live.

**Context**

* On a page that sends context, check what Clio sees: `fetch("https://app.askclio.ai/api/sdk/context/", { headers: { Authorization: "session " + SESSION_TOKEN } }).then(r => r.json()).then(console.log)` prints `active: true` and your context.
* Open a **new chat** and ask *"Should I buy this?"*: the answer is about the symbol on the page.
* Move to another page: the context is replaced (or cleared) and the next new chat follows it.

**Workflows**

* `startWorkflow` with valid data: a new chat opens the way the launch behavior says, with your opening message, the answer, then the follow-up chips.
* Start it once **without** a required field: the promise rejects with `400`, no chat appears, and your page logs it where a developer will see it.
* If the workflow takes files: a start with a PDF shows the answer after the document is read.
* The user can keep chatting normally after the first answer.

**In the dashboard**

* **Workflows → Context API → Recent Context Events** lists your context sets, clears and workflow launches.
* **Open chat** on a launch row shows the conversation in Chat History, with a **Launched by workflow** box holding the instructions and data Clio received.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://ask-clio.gitbook.io/ask-clio/adding-context-and-custom-workflows/ask-clioworkflows-+-context-website-integration-guide.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
