The sales agent answers in the widget on your own websiteAll articles

The sales agent answers in the widget on your own website

Enquiries arrive at night and at weekends. This case shows how a widget answers them without any browser script ever seeing your API key.

Published: 2026-09-12Reading time: 5 mintapinomahub API & workflows
API & processesAPIMarketplacesPricing & valuationLogistics & inventory

Many enquiries about a used part are the same three questions: does it fit my vehicle, what does shipping cost, what condition is it in. They arrive in the evening and at weekends, and whoever waits until Monday buys elsewhere. A form captures the question but does not answer it.

The sales agent answers in the widget on your own websiteInput: a visitor opens the widget; it authenticates with a channel key, never your API key 1. Set up the widget (GET /web/channel): title, greeting, accentColor, locale and maxMessageChars for the surface 2. Start the conversation (POST /web/conversations): conversationId plus the first reply, with needsHuman and owner 3. Keep answering (POST /web/conversations/{conversationId}/messages): One reply per turn with seq; the same clientMessageId returns the stored reply 4. Close the conversation (POST /web/conversations/{conversationId}/close): A closed conversation that stays traceable in the inbox Output: enquiries answered around the clock, handed to a human where appropriate needsHuman is not a failure but the agent’s built-in boundary. Ignoring it trades away trust.The sales agent answers in the widget on your own websiteInput: a visitor opens the widget; it authenticates with a channel key, never your API key01Set up the widgetGET /web/channeltitle, greeting, accentColor, locale and maxMessageChars for the surface02Start the conversationPOST /web/conversationsconversationId plus the first reply, with needsHuman and owner03Keep answeringPOST /web/conversations/{conversationId}/messagesOne reply per turn with seq; the same clientMessageId returns the stored reply04Close the conversationPOST /web/conversations/{conversationId}/closeA closed conversation that stays traceable in the inboxOutput: enquiries answered around the clock, handed to a human where appropriateneedsHuman is not a failure but the agent’s built-in boundary. Ignoring it trades away trust.
Four calls of the browser gateway. needsHuman and owner say in every reply who is responsible.

The website channel is built as a browser gateway, not as a Hub call with a hidden credential: the widget authenticates with a channel key that can be rotated at any time. Your API key stays on the server, where it belongs.

SurfaceRoles
Sales agentParts trading, Vehicle trading, Platform and marketplace

What this case requires

  • A configured profile. The agent answers according to its instruction; without a profile there is no tone, no rules and no permissions.
  • A website channel with allowed origins. allowedOrigins defines which addresses the widget may speak from — that is the protection against misuse of the channel key. When setting up the widget and when starting a conversation, the Origin of the request must be one of these origins; otherwise the gateway answers with origin_not_allowed.
  • The visitor token. GET /web/channel issues it; the gateway expects it back in the X-Agent-Visitor header.
  • Somewhere for handovers to land. needsHuman without an inbox is a warning nobody reads.

The sequence

The table names the responsible call per stage and what exists afterwards. The reasoning for why a stage cannot be skipped follows below it.

The call chain of this use case
StageCallWhat exists afterwards
Set up the widgetGET /web/channeltitle, greeting, accentColor, locale and maxMessageChars for the surface
Start the conversationPOST /web/conversationsconversationId plus the first reply, with needsHuman and owner
Keep answeringPOST /web/conversations/{conversationId}/messagesOne reply per turn with seq; the same clientMessageId returns the stored reply
Close the conversationPOST /web/conversations/{conversationId}/closeA closed conversation that stays traceable in the inbox

Why each stage is needed

  1. Set up the widget. GET /web/channel returns title, greeting, accentColor, locale, pollIntervalSeconds and maxMessageChars. The surface is therefore not hard-wired in the script but loaded from the channel — changing the greeting needs no new page build.
  2. Start the conversation. POST /web/conversations accepts the first message and immediately performs the first turn. Back come conversationId, seq and the reply, plus needsHuman and owner. A second call for the first reply would be avoidable waiting.
  3. Keep answering. POST /web/conversations/{conversationId}/messages performs every further turn. The clientMessageId matters more than it looks: if a message is sent again with the same clientMessageId, the call returns the stored reply instead of running again.
  4. Close the conversation. POST /web/conversations/{conversationId}/close ends it. Closed does not mean deleted — the history stays traceable in the inbox, and that is exactly what you need in a complaint.
Start a conversation from the widget
curl -X POST \
  -H 'X-Agent-Channel-Key: <KANALSCHLUESSEL>' \
  -H 'X-Agent-Visitor: <BESUCHERTOKEN>' \
  -H 'Content-Type: application/json' \
  -d '{"message":"Passt der Scheinwerfer an einen Golf 7 Facelift?","clientMessageId":"m-1"}' \
  'https://api.tapinomahub.com/agent/api/index.php/web/conversations'

What you end up with

In the end the website answers the recurring questions itself and passes the rest, with their history, to a colleague. The visitor does not wait until Monday, and the colleague does not start from zero.

Where to find this in the documentation

The binding field lists, error codes and sample responses live in this surface’s OpenAPI contract at docs.tapinomahub.com (tapinoma-agent). All use cases arranged by surface and role: overview of the use cases.

Frequently asked

Does my API key end up in the browser?

No. The widget authenticates with a channel key valid only for that channel, and it can be rotated. The API key stays server-side.

What if a stranger copies the channel key?

That is what the allowed origins and the ability to rotate the channel key are for. On top of that, turns per visitor and conversations per hour can be capped.

Can I change the greeting without rebuilding the page?

Yes. The widget loads title, greeting and accent colour from the channel. A change to the channel takes effect on the next load.