Getting started
Widgets (embed on your site)
Add a white-label AI chat, image, speech, music or video widget to your website with one script tag, locked to your domains and spend limits.
Widgets put a white-label AI interface on your own website with one script tag: chat, image, speech, music or video, powered by any model in the catalog. Visitors do not need an API key. Requests are charged to your USD balance at the model's normal price.
Create a widget
- Open Widgets and choose New widget (or design one first, without an account, on the widgets page).
- Pick a type and a model, then set the title, colors, theme, corner radius, texts and placement. Chat widgets also take private instructions and a response length cap.
- The preview runs your unsaved settings for real, so you can test a model or instructions before saving. Preview requests are charged to your balance.
- Save, then copy the embed code.
Embed code
<script src="https://api14.com/widget.js" data-widget="YOUR_WIDGET_ID" async></script>
Put the tag inside <body> where the widget should appear. Options:
| Attribute | Effect |
|---|---|
data-widget | Required. The widget id from the dashboard. |
data-target | CSS selector of an element to render into, for example #support. Without it the widget renders right before the script tag. |
data-height | Height of an inline widget, for example 520px. Defaults: 480px for chat, 420px for other types. |
The widget renders in an isolated Shadow DOM, so your page styles do not leak in and the widget does not change your page. With the Floating button placement it opens from a button in the bottom corner instead.
Allowed sites
A widget only answers requests from the sites you list under Settings, Widget sites. One domain per line; a domain also covers its subdomains (example.com covers www.example.com). Add a port to allow only that port, for example localhost:3000 for local testing. The dashboard preview always works.
A page on any other site gets 403 site_not_allowed and the widget does not render (the browser console shows one line explaining why).
The check uses the browser's Origin header. Browsers cannot change it, but tools outside a browser can, so treat the site list as a restriction, not a secret. The spend controls below are what cap the cost.
Spend controls
Because a widget is public, its cost is capped by limits only you can change:
| Control | Where | Effect |
|---|---|---|
| Daily spend limit for this widget | Widget editor | When the widget has spent this much today (UTC), it stops until the next day: 429 widget_daily_limit. |
| Daily spend limit for all widgets | Settings, Widget controls | One cap across every widget on the account. |
| Requests per visitor per day | Settings, Widget controls | Counted per visitor IP, for each widget. Default 100: 429 visitor_daily_limit. |
| Requests per visitor per minute | Fixed | 10 per minute per visitor: 429 rate_limited. |
| Widget rate | Your plan | All visitors of one widget together share your plan's requests per minute. |
Your balance is the final limit: at $0 every widget returns 402 insufficient_balance until you add funds.
Health and alerts
The widget list shows when each widget was last used, today's spend and requests, and the last error when a widget is failing for a reason you can fix: empty balance, a removed model, a reached spend limit or a site missing from the list. With Email me when a widget fails on (Settings, Widget controls) you get at most one email per widget per day.
Usage shows widget requests with the widget name and the site they came from; group by By widget or By site to compare them.
What visitors see
- Chat answers stream in and support basic formatting (paragraphs, lists, bold, italic, code and links). The conversation stays while the visitor moves between pages in the same tab.
- A Stop button ends a long answer; after an error a Try again link resends the message.
- Images, audio and video come with a Download link. Video is generated as a background job and appears when it is ready, usually within a few minutes.
- Visitors never see your instructions, your balance or the model's raw error. They see your error message (or a neutral default) and the cause is shown to you in the dashboard.
- Texts you leave empty use defaults in your account language.