asssistive

Overview

The three ways to bring Assistive into your product, how to choose between them, and the conventions the Public API shares.

Assistive is an operational helpdesk: a small team receives customer messages, turns them into trackable tickets, assigns the work, replies, and keeps a record.

There are three ways to bring it into your product. The first two are about talking to your customers; the third is about giving your agents the answers.

Choosing your path

Install the chat widget if you want chat on your website. You embed a snippet and configure it in the dashboard — that's it. Visitor identity, file attachments, and handoff to a human are all handled for you. You write no API code. The only code you might write is optional: signing an identity token so your logged-in users are recognized.

Use the Public API if you want to build the interface yourself — a chat screen inside a native mobile app, a support panel in your product, or a help center rendered by your own site — and you're calling from your own backend.

Add a Context Source if the answers your agents need live in your systems — shipment status, subscription tier, account balance. You build a read endpoint on your server, we call it, and the data appears on the ticket.

The first two are the same engine underneath

A conversation started in the widget and one started through the Public API are the same object. They land in the same agent inbox and follow the same routing rules. Only the client-facing edges differ.

So it isn't either/or. You can run the widget on your marketing site, a Public API integration in your mobile app, and Context Sources feeding both — one inbox, one set of agents.

Chat widgetPublic APIContext Sources
What it isA drop-in productAn API you callAn endpoint we call
Who calls whomOur widget calls usYou call usWe call you
You buildNothingThe whole interfaceAn HTTP endpoint on your server
Code you writeNone (identity token is optional)Your backend and your clientYour endpoint + signature verification
It servesYour customersYour customersYour agents

Context Sources run the other way round

Worth registering before you read on: with the widget and the Public API, you are the client and we are the server. With Context Sources, that inverts — we are the client and you are the server.

So the security problem inverts too. Instead of proving who you are to us with a key we issued, you verify a signature we send to satisfy yourself that an inbound request really came from Assistive.

What neither path gives you

All three are deliberately narrow. None of them can read or write tickets, staff, teams, reports, notes, canned replies, SLA, or the audit trail. Those are dashboard-only — they answer to a staff session, not to any key you can hold, and there is no integration path to them by design. (A Context Source puts data onto a ticket, but it can't read one.)

Also worth knowing before you plan around them: there are no webhooks, no streaming, no SDKs, and no sandbox environment. Clients poll, and a Context Source lookup only ever happens because an agent asked for it. None of these are hiding behind a flag — they don't exist today.

Base URL and versioning

Every Public API endpoint lives under /api/v1:

{BASE_URL}/api/v1/...
EnvironmentBase URL
Productionhttps://api.useassistive.com
Local developmenthttp://localhost:8080

Examples throughout these docs write it as {BASE_URL}.

Note that the API and the dashboard are separate hosts — the dashboard lives at agent.useassistive.com. Point your integration at the API host; a request to the dashboard host won't reach these endpoints.

We bump the version group rather than break an existing one, so /api/v1 paths and response shapes are stable.

Credentials

Three credentials matter, and confusing them is the most common integration mistake. Here they are side by side:

CredentialPrefixWho holds itWhat it authorizes
Publishable keypk_…Your serverStarting a conversation; reading the help center
Visitor tokenvt_…The end user's deviceReading and posting on one conversation
Widget secret keywsk_…Your serverSigning widget identity tokens. Never sent — it signs

Two rules follow from that table, and they're the whole security model:

  1. pk_ and wsk_ never leave your server. Despite the name, a publishable key can start conversations on your behalf and shares one organization-wide rate budget — treat it as semi-trusted, not as something to embed.
  2. vt_ is the only credential that may reach a user's device. It's scoped to a single conversation, so a leaked one can't read or post to any other conversation, and can't start new ones. That narrow scope is exactly what makes it safe to hand out.

There's a fourth key you'll see but never really handle: the widget public key (wpk_…), which sits in your embed snippet. It ships in your page, so it is not a secret — the origin allow-list is what protects the widget, not that key.

Publishable keys are minted in the dashboard — see Public API authentication. The widget's two keys live in your widget settings — see Installation.

The response envelope

Every Public API response — success or failure — uses the same envelope:

{
  "success": true,
  "request_id": "6d7979ce52075b24979cd5b415319339",
  "data": { "...": "the payload" },
  "meta": { "page": 1, "per_page": 20, "total": 42, "total_pages": 3 }
}
  • success — always present. Check this, not just the HTTP status.
  • request_id — a correlation ID for this request. Log it, and quote it when you report a problem; it's the fastest way for support to find what happened.
  • data — the payload. Omitted on error.
  • meta — pagination only. Present on GET /public/articles and nowhere else.
  • error — present only on failure.

A failure looks like this:

{
  "success": false,
  "request_id": "6d7979ce52075b24979cd5b415319339",
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "the request contains invalid fields",
    "details": [
      { "field": "message", "message": "message is required" }
    ]
  }
}

error.details is a list of {field, message} pairs, present on validation failures. The field names match the JSON field names you sent, so you can map them straight back onto your form.

Full status codes, and what to actually do about each: see Errors.

Where to go next

On this page