ELAV8.ai Widget runtime API
Public embed API keyed by public_key
Public embed API keyed by public_key
Every API here is available over the APIs.io API and to AI agents over MCP.
One button, every client — Claude, Cursor, VS Code and the rest.
https://apis.io/mcp
find_apisBrowse and filter every API in the catalog.get_api_artifactsOne API's artifacts, grouped by type.get_openapiThe primary OpenAPI for this API.find_similar_apisAPIs that look like this one.apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.resolveTurn a domain, URL or GitHub org into the provider it belongs to.find_cohortsEvery scored population of providers in the catalog.curl "https://apis.io/api/v1/apis/elav8-ai:elav8-ai-widget-runtime-api"
curl "https://apis.io/api/v1/apis?limit=25"
Calls without X-API-Key need no key. Calls with it need a paid plan — get a key.
Free tier, no form to fill in. Signing in shares your email address with us — we store it to create your key and to recognise you if you sign in with another provider. See our Privacy Policy and Terms.
A second provider on the same verified email joins the account you already have.
openapi: 3.2.0
info:
title: FALA by Elav8 public Widget runtime API
version: 1.0.0
description: 'Public, unauthenticated FALA (Elevate Follow-Up by Elav8) surface: widget runtime, health, branding, and agent discovery. Dashboard, admin, billing mutation, and Shopify-internal routes are not part of this specification.
Errors: every 4xx/5xx body is the `Error` object (`detail` is a human-readable message, or a list of field errors on 422). Rate-limited requests answer 429 with a `Retry-After` header in seconds.
Versioning: this is version 1 of the public API. Changes within 1.x are additive only — new operations, optional fields, new enum values — because embed snippets already on customer sites call these routes. A breaking change ships as a new major version alongside the old one; an operation scheduled for removal is marked `deprecated: true` here and answers with `Deprecation` and `Sunset` headers at least 90 days before it is removed.'
contact:
name: FALA by Elav8
url: https://fala.elav8.ai/developers
x-api-versioning:
strategy: major-version
current: '1'
deprecation: 'deprecated: true + Deprecation/Sunset headers, at least 90 days notice'
header: API-Version
request-header: API-Version
sunset-header: Sunset
deprecation-header: Deprecation
x-rate-limits:
headers:
- RateLimit-Policy
- RateLimit
- RateLimit-Limit
- RateLimit-Remaining
- RateLimit-Reset
on-429: Retry-After (seconds)
servers:
- url: https://fala.elav8.ai
description: Production
tags:
- name: Widget runtime
description: Public embed API keyed by public_key
paths:
/widget.js:
get:
tags:
- Widget runtime
operationId: getWidgetLoader
summary: Embeddable FALA widget loader
responses:
'200':
description: JavaScript loader
content:
application/javascript:
schema:
type: string
contentMediaType: application/javascript
description: The loader script; it fetches the widget bundle and the key's published config.
headers:
API-Version:
$ref: '#/components/headers/API-Version'
Deprecation:
$ref: '#/components/headers/Deprecation'
Sunset:
$ref: '#/components/headers/Sunset'
'500':
description: Unexpected server error; safe to retry with backoff
headers:
API-Version:
$ref: '#/components/headers/API-Version'
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
default:
description: Unexpected server error; safe to retry with backoff
headers:
API-Version:
$ref: '#/components/headers/API-Version'
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'400':
description: The API-Version request header names a version this server does not support
headers:
API-Version:
$ref: '#/components/headers/API-Version'
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
parameters:
- $ref: '#/components/parameters/ApiVersion'
/api/w/{public_key}/config:
get:
tags:
- Widget runtime
operationId: getWidgetConfig
summary: Public widget appearance and capabilities
parameters:
- name: public_key
in: path
required: true
schema:
type: string
description: Widget public key from the embed snippet
- $ref: '#/components/parameters/ApiVersion'
responses:
'200':
description: Widget config snapshot
content:
application/json:
schema:
$ref: '#/components/schemas/WidgetConfig'
headers:
API-Version:
$ref: '#/components/headers/API-Version'
RateLimit-Policy:
$ref: '#/components/headers/RateLimit-Policy'
RateLimit:
$ref: '#/components/headers/RateLimit'
RateLimit-Limit:
$ref: '#/components/headers/RateLimit-Limit'
RateLimit-Remaining:
$ref: '#/components/headers/RateLimit-Remaining'
RateLimit-Reset:
$ref: '#/components/headers/RateLimit-Reset'
Deprecation:
$ref: '#/components/headers/Deprecation'
Sunset:
$ref: '#/components/headers/Sunset'
'403':
description: 'Refused: the page''s host is outside the widget''s domain lock, or the widget is not switched on yet. `detail` says which and where the owner fixes it.'
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'404':
description: Unknown widget or resource
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'429':
description: Rate limited
headers:
Retry-After:
description: Seconds until the client may retry
schema:
type: integer
minimum: 1
RateLimit-Policy:
$ref: '#/components/headers/RateLimit-Policy'
RateLimit:
$ref: '#/components/headers/RateLimit'
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'500':
description: Unexpected server error; safe to retry with backoff
headers:
API-Version:
$ref: '#/components/headers/API-Version'
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
default:
description: Unexpected server error; safe to retry with backoff
headers:
API-Version:
$ref: '#/components/headers/API-Version'
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'400':
description: The API-Version request header names a version this server does not support
headers:
API-Version:
$ref: '#/components/headers/API-Version'
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
/api/w/chat:
post:
tags:
- Widget runtime
operationId: postWidgetChat
summary: Stream a text reply from the published agent
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/ChatRequest'
responses:
'200':
description: Server-sent events stream of tokens and cards
content:
text/event-stream:
schema:
type: string
contentMediaType: text/event-stream
description: Server-sent events. Each `data:` line is a JSON object carrying a reply delta, a card, or the final message; the stream ends when the reply is complete.
headers:
API-Version:
$ref: '#/components/headers/API-Version'
RateLimit-Policy:
$ref: '#/components/headers/RateLimit-Policy'
RateLimit:
$ref: '#/components/headers/RateLimit'
RateLimit-Limit:
$ref: '#/components/headers/RateLimit-Limit'
RateLimit-Remaining:
$ref: '#/components/headers/RateLimit-Remaining'
RateLimit-Reset:
$ref: '#/components/headers/RateLimit-Reset'
Deprecation:
$ref: '#/components/headers/Deprecation'
Sunset:
$ref: '#/components/headers/Sunset'
'403':
description: 'Refused: the page''s host is outside the widget''s domain lock, or the widget is not switched on yet. `detail` says which and where the owner fixes it.'
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'404':
description: Unknown widget or resource
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'422':
description: The request body failed validation
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'429':
description: Rate limited
headers:
Retry-After:
description: Seconds until the client may retry
schema:
type: integer
minimum: 1
RateLimit-Policy:
$ref: '#/components/headers/RateLimit-Policy'
RateLimit:
$ref: '#/components/headers/RateLimit'
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'500':
description: Unexpected server error; safe to retry with backoff
headers:
API-Version:
$ref: '#/components/headers/API-Version'
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
default:
description: Unexpected server error; safe to retry with backoff
headers:
API-Version:
$ref: '#/components/headers/API-Version'
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'400':
description: The API-Version request header names a version this server does not support
headers:
API-Version:
$ref: '#/components/headers/API-Version'
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
parameters:
- $ref: '#/components/parameters/ApiVersion'
/api/w/lead:
post:
tags:
- Widget runtime
operationId: postWidgetLead
summary: Capture a visitor lead
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/LeadCapture'
responses:
'200':
description: Lead accepted
content:
application/json:
schema:
$ref: '#/components/schemas/LeadAccepted'
headers:
API-Version:
$ref: '#/components/headers/API-Version'
RateLimit-Policy:
$ref: '#/components/headers/RateLimit-Policy'
RateLimit:
$ref: '#/components/headers/RateLimit'
RateLimit-Limit:
$ref: '#/components/headers/RateLimit-Limit'
RateLimit-Remaining:
$ref: '#/components/headers/RateLimit-Remaining'
RateLimit-Reset:
$ref: '#/components/headers/RateLimit-Reset'
Deprecation:
$ref: '#/components/headers/Deprecation'
Sunset:
$ref: '#/components/headers/Sunset'
'403':
description: 'Refused: the page''s host is outside the widget''s domain lock, or the widget is not switched on yet. `detail` says which and where the owner fixes it.'
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'404':
description: Unknown widget or resource
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'422':
description: The request body failed validation
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'429':
description: Rate limited
headers:
Retry-After:
description: Seconds until the client may retry
schema:
type: integer
minimum: 1
RateLimit-Policy:
$ref: '#/components/headers/RateLimit-Policy'
RateLimit:
$ref: '#/components/headers/RateLimit'
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'500':
description: Unexpected server error; safe to retry with backoff
headers:
API-Version:
$ref: '#/components/headers/API-Version'
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
default:
description: Unexpected server error; safe to retry with backoff
headers:
API-Version:
$ref: '#/components/headers/API-Version'
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'400':
description: The API-Version request header names a version this server does not support
headers:
API-Version:
$ref: '#/components/headers/API-Version'
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
parameters:
- $ref: '#/components/parameters/ApiVersion'
/api/w/{public_key}/voice-token:
post:
tags:
- Widget runtime
operationId: postWidgetVoiceToken
summary: Mint an ephemeral live-voice token
parameters:
- name: public_key
in: path
required: true
schema:
type: string
description: Widget public key from the embed snippet
- $ref: '#/components/parameters/ApiVersion'
responses:
'200':
description: Short-lived voice credentials
content:
application/json:
schema:
$ref: '#/components/schemas/VoiceToken'
headers:
API-Version:
$ref: '#/components/headers/API-Version'
RateLimit-Policy:
$ref: '#/components/headers/RateLimit-Policy'
RateLimit:
$ref: '#/components/headers/RateLimit'
RateLimit-Limit:
$ref: '#/components/headers/RateLimit-Limit'
RateLimit-Remaining:
$ref: '#/components/headers/RateLimit-Remaining'
RateLimit-Reset:
$ref: '#/components/headers/RateLimit-Reset'
Deprecation:
$ref: '#/components/headers/Deprecation'
Sunset:
$ref: '#/components/headers/Sunset'
'403':
description: 'Refused: the page''s host is outside the widget''s domain lock, or the widget is not switched on yet. `detail` says which and where the owner fixes it.'
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'404':
description: Unknown widget or resource
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'429':
description: Rate limited
headers:
Retry-After:
description: Seconds until the client may retry
schema:
type: integer
minimum: 1
RateLimit-Policy:
$ref: '#/components/headers/RateLimit-Policy'
RateLimit:
$ref: '#/components/headers/RateLimit'
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'500':
description: Unexpected server error; safe to retry with backoff
headers:
API-Version:
$ref: '#/components/headers/API-Version'
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
default:
description: Unexpected server error; safe to retry with backoff
headers:
API-Version:
$ref: '#/components/headers/API-Version'
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'400':
description: The API-Version request header names a version this server does not support
headers:
API-Version:
$ref: '#/components/headers/API-Version'
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
components:
headers:
RateLimit-Policy:
description: 'IETF RateLimit-Policy: "<bucket>";q=<requests>;w=<window seconds>.'
schema:
type: string
API-Version:
description: Major version of the public API that answered (see the versioning policy).
schema:
type: string
enum:
- '1'
RateLimit:
description: 'IETF RateLimit: "<bucket>";r=<remaining>;t=<seconds until reset>.'
schema:
type: string
RateLimit-Reset:
description: Seconds until the window resets.
schema:
type: integer
Sunset:
description: 'RFC 8594: the HTTP-date after which a deprecated operation is removed.'
schema:
type: string
Deprecation:
description: 'RFC 9745: present on an operation scheduled for removal.'
schema:
type: string
RateLimit-Remaining:
description: Requests left in this window.
schema:
type: integer
RateLimit-Limit:
description: Requests allowed per window.
schema:
type: integer
schemas:
VoiceToken:
type: object
description: Ephemeral credentials for the server-chosen realtime voice engine.
additionalProperties: true
required:
- provider
- token
- conversationId
properties:
provider:
type: string
enum:
- grok
- gemini
model:
type: string
token:
type: string
greeting:
type: string
conversationId:
type: string
audio:
type: object
additionalProperties: true
failover:
type: array
items:
type: string
connectTimeoutMs:
type: integer
prefetchMaxAgeMs:
type: integer
WidgetConfig:
type: object
description: 'The published widget snapshot the embed renders (also served from the CDN). A widget whose install terms are not yet on record answers {publicKey, notActivated: true, reason: ''install_terms''}.'
additionalProperties: true
required:
- publicKey
properties:
publicKey:
type: string
notActivated:
type: boolean
reason:
type: string
LeadCapture:
type: object
required:
- public_key
properties:
public_key:
type: string
conversation_id:
type: string
name:
type: string
email:
type: string
phone:
type: string
notes:
type: string
LeadAccepted:
type: object
required:
- success
- leadId
properties:
success:
type: boolean
leadId:
type: string
Error:
type: object
required:
- detail
properties:
detail:
description: Human-readable message, or a list of field errors (422)
oneOf:
- type: string
- type: array
items:
type: object
properties:
loc:
type: array
items:
type:
- string
- integer
msg:
type: string
type:
type: string
ChatRequest:
type: object
required:
- public_key
- message
properties:
public_key:
type: string
message:
type: string
maxLength: 8000
conversation_id:
type: string
visitor_id:
type: string
parameters:
ApiVersion:
name: API-Version
in: header
required: false
description: Major version of the public API the client expects. Omit for the current version; any unsupported value answers 400.
schema:
type: string
enum:
- '1'