# Texa AI in your website and app

One script tag or an app component: a support chat for visitors that works in the customer's account once they sign in.


Put Texa AI in your own website and app. To a visitor who hasn't signed in it answers questions
from your knowledge. Once they sign in, the same chat knows who they are and works in their
account through your systems: it looks things up, makes changes with their yes, sends them
files, takes them to the right page and fills in forms. Your team sees every chat in Texa Desk
and takes over when it's needed.

You never share your code with Texa. You give it four things, all set up in Texa Desk under
Texa AI:

1. One script tag (or our app component) and a site key: visitors can chat at once.
2. One route on your server that says who is signed in.
3. What Texa AI may do in your systems: your API, your own server, MCP, or the Texa Relay.
4. The pages Texa AI may open, and any steps your page can do for the customer.

## 1. Visitors: one script tag

In Texa Desk, **Developers → Website and app**, make a site key, and add your websites under
**API keys → Websites your widget runs on** (live keys answer only there; the sandbox answers
anywhere). Then add this to every page:

```html
<script src="https://api.texadesk.com/widget.js" async
        data-site-key="pk_live_..."
        data-session-url="/texa/session"
        data-title="Help" data-color="#144AA7"></script>
```

A site key is safe in a page: it only opens visitor chats, from your websites, 20 an hour per
address. A visitor is never treated as verified, and an action you keep for signed-in customers
is refused for them: Texa AI asks them to sign in.

## 2. Signed-in customers: your server says who they are

`data-session-url` is a route on **your** server. When someone is signed in, it makes a session
with your secret key and returns it; when nobody is, it answers 401 and the widget stays a
visitor's. Your key never reaches the page.

<!-- tabs -->
```js
// Node (Express) with @texadesk/sdk
app.post("/texa/session", requireSignIn, async (req, res) => {
  const s = await texa.widgetSession(`user-${req.user.id}`, {
    first_name: req.user.firstName, name: req.user.fullName,
    email: req.user.email, phone: req.user.phone,
    customer_token: req.user.apiToken,          // optional: see step 3
  });
  res.json(s);
});
```

```python
# Python (FastAPI) with texa
@app.post("/texa/session")
def texa_session(user = Depends(signed_in_or_401)):
    return texa.widget_session(f"user-{user.id}", first_name=user.first_name,
                               name=user.full_name, email=user.email)
```

```php
// PHP (Laravel) with texa/texa-php
Route::post('/texa/session', fn () => auth()->check()
    ? $texa->widgetSession('user-' . auth()->id(), ['name' => auth()->user()->name])
    : response()->json(['error' => 'not signed in'], 401));
```
<!-- /tabs -->

When a visitor signs in on a new page, the widget notices and the same chat carries on as them.
In a single-page app, call `TexaWidget.signedIn()` after your sign-in, and
`TexaWidget.signedOut()` after sign-out.

**Signed in counts as verified.** With **Sign-in counts as verified** on (Developers → Website
and app), Texa AI treats a customer your server signed in as verified, so they aren't asked for
a one-time code. Leave it off if you want a code anyway (a bank moving money, say).

## 3. Acting as the customer

Pass the customer's own token for your API as `customer_token` when you make their session.
Then, in **Actions → Connectors → Your own system**, choose the sign-in **The signed-in
customer's own token**: Texa sends it, in the header you name, on that customer's actions
only. Your API decides what that person may see and change, exactly as for your own app.

The token is sealed, never logged, never shown to Texa AI, and gone when the session ends. If
it has ended, the action fails and Texa AI asks the customer to sign in again.

If your own server runs actions instead (the `conversation.action_request` webhook), each
request says who asks: `data.customer = {"ref": "user-1842", "signed_in": true}`.

## 4. What Texa AI may do

Connect your system in **Actions**:

- **Your API's OpenAPI file:** every operation becomes a draft action to review and save.
- **No OpenAPI file?** Give the address of your API's documentation page: Texa AI drafts the
  actions from it, and you review and save each one.
- **Your MCP server**, **your own server** (a signed webhook), or **the Texa Relay** inside your
  network.

For each action, under **In your website or app chat**:

- **Who can use it:** anyone, or signed-in customers only.
- **Show the customer:** the file (a receipt, a statement: give the result that holds its
  link and its name), or a list as a spreadsheet. The customer gets it as a document in the chat.

Texa AI uses an action only in a step of a procedure you approved, and asks the customer's yes
before anything that changes something.

## 5. Pages and steps on your page

**Pages Texa AI can open** (Developers → Website and app): name the pages customers ask for,
such as *My documents* or *Payments*, or read them from your sitemap. When a customer asks where
something is, Texa AI takes them there. By default the page loads; to use your own router:

```js
window.TexaWidget.onOpenPage((url, page) => router.push(url));
```

Texa AI opens a page only from a step of an approved procedure: on the same page, **Add the
procedure** saves a draft of your procedures with the step "Show the customer a page", for you
to approve under **Procedures**.

**Screen actions** are steps your page does for the customer: filling in a form, opening a
dialog. Add an action on the connector **Our website or app (screen actions)**, and handle it
in your page:

```js
window.TexaWidget.on("fill_delivery_address", async ({ street, city }) => {
  form.street.value = street;
  form.city.value = city;
  return { filled: true };        // the action's results, for Texa AI
});
```

The page has 30 seconds to answer; otherwise Texa AI is told it didn't, and says so. The script
loads `async`: call these after the `texa:ready` event, or set them before it loads with
`window.TexaWidgetSettings = { handlers: {...}, onOpenPage: fn }`.

## 6. In your app

React Native and Expo, with `@texadesk/react-native`:

```tsx
<TexaChat
  siteKey="pk_live_..."
  getSession={async () => (user ? await api.post("/texa/session") : null)}
  signedIn={!!user}
  actions={{ fill_delivery_address: async (inputs) => ({ filled: true }) }}
  onOpenPage={(url, page) => navigation.navigate(page)}
  onPickFile={pickDocument}              // your picker: { uri, name, type }
/>
```

Flutter, with `texa_flutter` (coming soon: it isn't on pub.dev yet):

```dart
TexaChat(
  siteKey: 'pk_live_...',
  getSession: () async => user == null ? null : WidgetSession.fromJson(await api.texaSession()),
  signedIn: user != null,
  actions: {'fill_delivery_address': (inputs) async => {'filled': true}},
  onOpenPage: (url, page) => Navigator.pushNamed(context, url),
)
```

Both components are also clients without a screen (`TexaWidgetClient`), for your own design.
The routes they call are in the [API reference](/api-reference/introduction), under widgets.

## 7. Files, documents and the typing preview

- Customers send photos, PDFs, Word documents and recordings with the paper clip (10 MB at most).
  Texa AI reads them.
- Documents Texa AI sends show as document messages; a spreadsheet downloads as a CSV.
- While a chat is shown in Texa Desk, your team sees what the customer is typing, with a line
  telling the customer so. The widget masks it before it leaves the page: any run of six or more
  digits, and whatever follows *pin*, *otp*, *code*, *cvv* or *password*. Your own client must
  do the same before `POST .../typing`.

## 8. Your team

With **Every chat in Texa Desk** on (the default), each chat shows in the **App conversations**
inbox from its first message, waiting with Texa AI, with the customer's name, email, phone and
city. When Texa AI hands over, or doesn't answer within 2 minutes, the same conversation opens
for your team; their replies reach the customer in the chat.

## Before you go live

- Your secret key stays on your server; only the session token and the site key reach a page.
- Your websites are listed under **API keys**.
- Each action that touches an account is kept for signed-in customers.
- Try it all with a sandbox key and the sandbox site key first: nothing reaches a real customer.
