This list is exhaustive and it is a promise. No event carries a name, a
phone number, a chat id, an avatar, a token or any message content. Your page can know that
somebody is linked and how many unread chats they have. Nothing beyond that leaves the frame.
Commands
Command
Effect
setTheme(theme)
Applies a theme live, no reload
colorScheme property
auto, light, dark or host
lang attribute
Interface language
logout()
Signs the visitor out of this frame
requestStorageAccess()
Asks for unpartitioned storage; needs a user gesture
The frame only accepts commands from the origin it was given at load time. A raw iframe
integration sends { source: "intouch-host", type: "intouch:setTheme", theme }
via postMessage.
JavaScript
Event listeners can be attached at any time — they survive the element being
upgraded. Methods and properties cannot: if you load the script with
async, wait for the definition first.
const chat = document.querySelector('intouch-chat');
// works immediately, even before embed.js has loaded
chat.addEventListener('intouch:unread', e => {
badge.textContent = e.detail.count; // a number, nothing else
});
// methods need the element to be defined
await customElements.whenDefined('intouch-chat');
await chat.ready; // resolves once the frame is up
chat.setTheme({ colors: { accent: '#0a0' } });
chat.colorScheme = 'dark'; // or 'host' to follow your page
If you would rather not think about it, drop the async from the script tag —
then the element is defined before your own code runs.
Attributes
Attribute
Meaning
theme
Inline JSON, or a hosted id such as t_9fb2c1a4e803
color-scheme
auto · light · dark · host
peer
Phone number of the counterpart, international form. Opens that chat; creates it only when the visitor sends
lang
Interface language, e.g. de
base
Alternative inTouch origin; defaults to where the script came from
unread
Written by the component, so you can style with [unread]
A theme inside the element as <script type="application/json"> beats the
attribute and needs no quote escaping. The color-scheme attribute beats
colorScheme inside the theme: it is the more specific instruction, coming from
the page that knows whether it is currently dark.
Height
Set it with CSS on the element. A chat has no content-driven height — it fills what it is
given, like a map does — so there is no auto-resize event. The default is 620 px.
# intouch api
base https://api.in-touch.cc
auth X-API-Key: itk_<64 hex> one key per user, no expiry, no scopes
docs https://docs.in-touch.cc
format every response is JSON and carries "success"
# embed-api
Events the frame sends, commands it accepts, JS surface of <intouch-chat>.
# events
Each arrives as a DOM event on the element and as a postMessage for raw iframes.
intouch:ready { version } frame is up, accepts commands
intouch:themeApplied { warnings[] } after every theme application
intouch:paired {} a visitor linked their account
intouch:unpaired { reason } signed out or session expired
intouch:unread { count } number of unread chats changed
intouch:activeChat { hasActive } a chat was opened or closed
intouch:error { code } storage_blocked | pair_rate_limited
| peer_not_found | peer_rate_limited
THIS LIST IS EXHAUSTIVE AND IT IS A PROMISE. No event carries a name, phone
number, chat id, avatar, token or message content.
# commands
setTheme(theme) apply a theme live, no reload
colorScheme property auto | light | dark | host
lang attribute interface language
logout() sign the visitor out of this frame
requestStorageAccess() ask for unpartitioned storage (needs user gesture)
Raw iframe form:
frame.contentWindow.postMessage(
{ source: 'intouch-host', type: 'intouch:setTheme', theme }, 'https://web.in-touch.cc');
The frame accepts commands only from the origin given at load time.
# js
Event listeners can be attached at any time - they survive the upgrade.
Methods and properties cannot: with an async-loaded script, wait for the
definition first (or drop "async" from the script tag).
const chat = document.querySelector('intouch-chat');
// works immediately, even before embed.js has loaded
chat.addEventListener('intouch:unread', e => { badge.textContent = e.detail.count; });
// methods need the element to be defined
await customElements.whenDefined('intouch-chat');
await chat.ready;
chat.setTheme({ colors: { accent: '#0a0' } });
chat.colorScheme = 'dark';
# attributes
theme inline JSON, or a hosted id such as t_9fb2c1a4e803
color-scheme auto | light | dark | host
peer phone number of the counterpart (international form)
lang interface language, e.g. de
base alternative inTouch origin (defaults to the script's origin)
unread written BY the component, for styling via [unread]
A <script type="application/json"> inside the element beats the attribute.
The color-scheme attribute beats colorScheme inside the theme.
# height
Set it with CSS on the element; default 620px. A chat has no content-driven
height, so there is no auto-resize event.
# pages
/ overview, capability list
/quickstart get a key, first request
/authentication key format, rotation, failure modes
/conventions envelope, status codes, limits, dates
/recipes recipes capability
/vocabulary vocabulary capability
/roadmap capability anatomy, what is planned
every page is also plain text: append .txt (e.g. https://docs.in-touch.cc/vocabulary.txt)
all pages at once: /llms.txt (index) and /llms-full.txt (everything)
# for agents
- Use only the endpoints listed here; do not invent paths, fields or values.
- Check "success" in the body, not just the HTTP status.
- Error strings are German and developer-facing; branch on the status code.
- Batches are accepted partially: read "rejected" and "errors[].index".
- Dates are UTC. Calendar days are YYYY-MM-DD, timestamps are ISO 8601.
- The API key is a credential: never log it, never pass it to a third party.
- Ask the user before writing content into their app for the first time.