Skip to content

Widget API Documentation

Everything you need to integrate the NexonTech chat widget into your application.

Overview

The Widget API lets you initialize chat conversations and exchange messages with your AI agent programmatically. All endpoints accept and return JSON. CORS is fully open, so you can call these endpoints from any domain.

Base URL: https://nexontech.org/api/widget

Quick Start

Get a conversation running in two API calls:

1. Initialize a conversation

POST /api/widget/init
Content-Type: application/json

{
  "key": "wk_your_widget_key"
}

2. Send a message

POST /api/widget/chat
Content-Type: application/json

{
  "key": "wk_your_widget_key",
  "conversation_id": "conv_id_from_step_1",
  "text": "Hello, I need help!"
}

Authentication

Every widget request identifies itself with your widget key, sent in the request body. Keys start with wk_ and are tied to one agent. Treat the key as a public identifier, not a secret: it ships inside the embed snippet on your own page, so anyone viewing your site can read it. These endpoints carry no cookies or Authorization header by design and answer any origin. The key says which agent to answer as — it does not prove who is asking, so never rely on it to protect anything.

Where to find your key

  1. Go to Dashboard > Agents
  2. Select or create an agent
  3. Copy the key from the Embed Code section

Initialize Conversation

POST/api/widget/init

Creates a new conversation and returns the conversation ID. Call this once per chat session.

Request Body

FieldTypeRequiredDescription
keystringYesYour widget API key (starts with wk_)
visitor_idstringNoOptional visitor identifier for tracking returning users
page_urlstringNoURL of the page where the chat was started

Response 200 OK

{
  "conversation_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "visitor_id": "v_abc123",
  "chatbot_name": "Support Bot",
  "config": {}
}
FieldTypeDescription
conversation_idstringUnique conversation identifier — use this in all subsequent chat requests
visitor_idstringVisitor ID (generated if not provided in the request)
chatbot_namestringDisplay name of the agent
configobjectAgent configuration metadata

Send Message

POST/api/widget/chat

Sends a user message and returns the AI agent's response. Messages are persisted and visible in your dashboard.

Request Body

FieldTypeRequiredDescription
keystringYesYour widget API key
conversation_idstringYesConversation ID from the init response
textstringYesUser message (max 2,000 characters)
visitor_idstringNoVisitor identifier
langstringNoLanguage code: en, ro, or ru (default: en)

Response 200 OK

{
  "response": "Hi! I'd be happy to help. What can I do for you today?",
  "user_reply_options": ["Check order status", "Talk to a human", "Browse products"]
}
FieldTypeDescription
responsestringThe AI agent's reply text
user_reply_optionsstring[]Optional quick-reply suggestions (may be absent)

When a human has taken over 200 OK

{
  "handoff": "human",
  "wait": true
}
FieldTypeDescription
handoffstringAlways the string "human". Present only while an operator is handling this conversation.
waitbooleantrue — stop expecting AI replies and poll for the operator's messages instead.

If an operator has taken over the conversation, this endpoint returns a different 200 body — no response text at all. Your message is still stored, but the AI does not answer it. Handle this shape or your integration will read an empty reply as a failure. The operator's replies arrive via GET /api/widget/poll, which returns only human-sent messages after a cursor; poll it every few seconds while wait is true.

Note: The user_reply_options array is optional and may not be present in every response. When provided, you can display these as quick-reply buttons.

Rate Limiting

All widget endpoints are rate-limited to 30 requests per minute per IP address, counted in a fixed 60-second window across every widget route combined. Exceeding it returns 429 with no limit_reached field; the window clears on its own, so waiting a few seconds is the whole fix. This is separate from the account's conversation allowance, which also returns 429 but carries limit_reached: true and is not cleared by waiting — see Error Codes.

Error Codes

All errors return a JSON object with an error field describing the issue.

StatusDescription
400 Bad RequestMissing or invalid required fields in the request body.
403 ForbiddenInvalid or inactive widget key, or invalid conversation.
429 Too Many RequestsTwo conditions share this code — read the body. No limit_reached field means the per-IP rate limit: wait and retry. limit_reached: true means the account itself is blocked, with reason "quota" (monthly conversation allowance used up) or reason "spend_cap" (metered overage budget reached). Retrying clears neither.
502 Bad GatewayThe AI agent backend is temporarily unavailable.
504 Gateway TimeoutThe request timed out. Try again.

Error response format

{
  "error": "Invalid or inactive widget key"
}

Embed Snippet

The easiest way to add the chat widget to your website is with our drop-in script tag. No API calls needed — it handles everything automatically.

<script src="https://nexontech.org/widget.js" data-key="wk_your_widget_key"></script>

Replace wk_your_widget_key with your actual key from the dashboard. The script loads asynchronously and won't block your page.