v1.0

Build with Nuria

Embed live chat, surveys, and forms on your website. Connect via webhooks, authenticate with SSO, and integrate through our REST API.

Quick Start

Get the Nuria widget running on your website in under 5 minutes.

  1. Create your account
    Sign up at app.nuria.run and create your workspace.
  2. Add a Web Chat channel
    Go to Settings → Channels → Add Channel → Web Chat. Configure your welcome message, colors, and operating hours.
  3. Copy the embed code
    After saving the channel, copy the script tag provided in the installation panel.
  4. Paste on your site
    Add the script before the closing </body> tag on every page where you want the widget.
<!-- Nuria Widget -->
<script src="https://widget.nuria.run/loader.js" ws="YOUR_WORKSPACE_ID"></script>
Your Workspace ID is found in Settings → Workspace → General. It looks like 09005ea904334c3fb61e2a8302a5f798.

Widget Installation

Multiple ways to add Nuria to your website or application.

HTML / Script Tag

The simplest method. Add the loader script before the closing </body> tag:

<script src="https://widget.nuria.run/loader.js" ws="YOUR_WORKSPACE_ID"></script>

Attributes

AttributeRequiredDescription
wsYesWorkspace ID. Determines which channels and rules to load.
kbNoKnowledge base ID. Scopes the chat to a specific KB.

WordPress

Paste the same script tag into one of these locations:

  • A Custom HTML block in your page/post editor
  • Your theme's footer.php file, before </body>
  • A Google Tag Manager Custom HTML tag
  • A plugin like Insert Headers and Footers

React / Next.js

Load the script dynamically in a useEffect hook:

Reactimport { useEffect } from 'react';

function App() {
  useEffect(() => {
    const script = document.createElement('script');
    script.src = 'https://widget.nuria.run/loader.js';
    script.setAttribute('ws', 'YOUR_WORKSPACE_ID');
    document.body.appendChild(script);

    return () => {
      script.remove();
    };
  }, []);

  return <div>My App</div>;
}

For Next.js App Router, use the script in a Client Component or via next/script:

Next.jsimport Script from 'next/script';

export default function RootLayout({ children }) {
  return (
    <html>
      <body>
        {children}
        <Script
          src="https://widget.nuria.run/loader.js"
          strategy="afterInteractive"
          ws="YOUR_WORKSPACE_ID"
        />
      </body>
    </html>
  );
}

Vue.js

Inject the script in your App.vue or main layout component:

Vue 3<script setup>
import { onMounted, onUnmounted } from 'vue';

let script;

onMounted(() => {
  script = document.createElement('script');
  script.src = 'https://widget.nuria.run/loader.js';
  script.setAttribute('ws', 'YOUR_WORKSPACE_ID');
  document.body.appendChild(script);
});

onUnmounted(() => {
  script?.remove();
});
</script>

Display Rules

Channels support server-configured display rules evaluated client-side. Configure these in the Nuria dashboard, not via the JavaScript API.

RuleOptionsExample
WhereURL include/exclude patterns with wildcard/pricing*
WhenDelay, scroll depth, exit intent, min visitsShow after 10 seconds
WhoDevice type, identified vs anonymous, custom propsDesktop only, plan = pro

JavaScript API

Once the loader runs, it exposes a global window.Nuria object. Use it to control the widget, identify visitors, and listen for events.

Nuria.isReady

booleantrue after the workspace config has been fetched, display rules evaluated, and active channels rendered.

if (window.Nuria.isReady) {
  window.Nuria.chat.open();
}

Nuria.identify(user)

Identify the current visitor. This re-evaluates display rules and associates the conversation with a contact record.

window.Nuria.identify({
  email: 'maria@acme.com',
  name: 'Maria Silva',
  phone: '+5511999999999',
  // Custom properties (used in display rules and agent context)
  plan: 'enterprise',
  company: 'Acme Corp',
});
FieldTypeDescription
emailstringContact email for matching.
namestringDisplay name.
phonestringPhone number (E.164 recommended).
*anyAdditional key-value pairs stored as custom data.

Nuria.chat

Controls for the chat channel.

// Open / close / toggle the chat panel
window.Nuria.chat.open();
window.Nuria.chat.close();
window.Nuria.chat.toggle();

// Send a message programmatically
window.Nuria.chat.sendMessage('I need help with my order');

// Listen for incoming messages
window.Nuria.chat.onMessage((msg) => {
  console.log('New message:', msg);
});
MethodDescription
open()Open the chat panel.
close()Close the chat panel.
toggle()Toggle open/closed.
sendMessage(text)Send a plain-text message as the visitor.
onMessage(callback)Shorthand for Nuria.on('message:received', cb).

Nuria.survey

Controls for the survey channel.

window.Nuria.survey.show();
window.Nuria.survey.hide();
MethodDescription
show()Display the survey overlay.
hide()Dismiss the survey overlay.

Nuria.form

Controls for the form channel.

window.Nuria.form.show();
window.Nuria.form.hide();
MethodDescription
show()Display the form overlay.
hide()Dismiss the form overlay.

Events

Subscribe to widget events with Nuria.on(event, callback).

window.Nuria.on('ready', () => {
  console.log('Widget loaded');
});
EventCallback ArgumentsDescription
ready(none)Widget finished initializing.
channel:showchannelId, typeA channel (chat/survey/form) became visible.
channel:hidechannelId, typeA channel was hidden.
message:receivedmessageA new message arrived in the chat.
survey:submittedresponseVisitor submitted a survey response.
identifyuseridentify() was called.
page:changeurlSPA navigation detected.

Examples

Open chat on button click

<button onclick="window.Nuria.chat.open()">Talk to us</button>

Identify visitor after login

window.Nuria.on('ready', () => {
  const user = getCurrentUser();
  window.Nuria.identify({
    email: user.email,
    name: user.name,
    plan: user.subscription,
  });
});

Open chat with a pre-filled message

function askAboutPricing() {
  window.Nuria.chat.open();
  window.Nuria.chat.sendMessage('I would like to know about pricing');
}

Track messages in analytics

window.Nuria.on('message:received', (msg) => {
  gtag('event', 'nuria_message_received', {
    event_category: 'chat',
  });
});

Show survey after 60 seconds

window.Nuria.on('ready', () => {
  setTimeout(() => {
    window.Nuria.survey.show();
  }, 60000);
});

Custom trigger for the form

<a href="#" onclick="event.preventDefault(); window.Nuria.form.show();">
  Open contact form
</a>

Webhook Events

Receive real-time HTTP POST notifications when events occur in your Nuria workspace.

Setup

Configure your webhook endpoint in Settings → Developers → Webhooks. Each webhook receives a JSON payload with a signature header for verification.

Your endpoint must respond with a 2xx status within 10 seconds. Failed deliveries are retried with exponential backoff (3 attempts).

HMAC Verification

Every webhook includes a X-Nuria-Signature header containing an HMAC-SHA256 signature of the raw request body. Verify it using your webhook secret:

Node.jsimport crypto from 'crypto';

function verifyWebhook(body, signature, secret) {
  const expected = crypto
    .createHmac('sha256', secret)
    .update(body)
    .digest('hex');

  return crypto.timingSafeEqual(
    Buffer.from(signature),
    Buffer.from(expected)
  );
}

// Express example
app.post('/webhooks/nuria', (req, res) => {
  const signature = req.headers['x-nuria-signature'];
  const rawBody = req.body; // raw string/buffer

  if (!verifyWebhook(rawBody, signature, process.env.NURIA_WEBHOOK_SECRET)) {
    return res.status(401).send('Invalid signature');
  }

  const event = JSON.parse(rawBody);
  console.log('Event:', event.type);
  res.status(200).send('OK');
});

Event Reference

EventDescriptionKey Payload Fields
conversation.created A new conversation was started. conversation_id, channel, contact
conversation.resolved A conversation was marked as resolved. conversation_id, resolved_by, duration
message.created A new message was sent (by visitor or agent). message_id, conversation_id, sender, content
agent.assigned An agent was assigned to a conversation. conversation_id, agent_id, agent_name
csat.submitted A customer satisfaction rating was submitted. conversation_id, score, comment
contact.created A new contact was created. contact_id, email, name
contact.updated A contact's information was updated. contact_id, changes
ticket.created A helpdesk ticket was created. ticket_id, subject, priority, requester
ticket.resolved A helpdesk ticket was resolved. ticket_id, resolved_by

Example Payload

{
  "id": "evt_01JQXYZ...",
  "type": "message.created",
  "workspace_id": "09005ea9...",
  "created_at": "2026-03-22T14:30:00Z",
  "data": {
    "message_id": "msg_01JQXYZ...",
    "conversation_id": "conv_01JQXYZ...",
    "sender": {
      "type": "contact",
      "id": "ct_01JQXYZ...",
      "name": "Maria Silva"
    },
    "content": "I need help with my subscription",
    "channel": "web_chat"
  }
}

SSO Setup

Enable Single Sign-On for your workspace using OIDC or SAML 2.0. Available on Pro and Enterprise plans.

OpenID Connect (OIDC)

Supports Okta, Azure AD, Google Workspace, Auth0, and any OIDC-compliant provider.

  1. Create an application in your IdP
    Set the redirect URI to https://auth.api.nuria.run/sso/oidc/callback
  2. Collect your credentials
    You will need the Client ID, Client Secret, and the Issuer URL (e.g., https://login.microsoftonline.com/{tenant}/v2.0).
  3. Configure in Nuria
    Go to Settings → Security → SSO. Select OIDC, paste your credentials, and save.
  4. Test the connection
    Click Test SSO to verify. A successful test will show the authenticated user's email and name.

Provider-Specific Notes

ProviderIssuer URLNotes
Okta https://{domain}.okta.com Use "Web Application" type. Enable openid, profile, email scopes.
Azure AD https://login.microsoftonline.com/{tenant}/v2.0 Register app in "App registrations". Add User.Read permission.
Google Workspace https://accounts.google.com Create OAuth2 credentials in Google Cloud Console.
Auth0 https://{domain}.auth0.com/ Create a "Regular Web Application".

SAML 2.0

For enterprise identity providers that require SAML (e.g., ADFS, Ping Identity).

  1. Download Nuria's SP metadata
    Available at https://auth.api.nuria.run/sso/saml/metadata
  2. Register Nuria in your IdP
    Import the SP metadata or manually configure:
    ACS URL: https://auth.api.nuria.run/sso/saml/acs
    Entity ID: https://auth.api.nuria.run
    Name ID: emailAddress
  3. Upload IdP metadata to Nuria
    Go to Settings → Security → SSO. Select SAML 2.0 and upload your IdP metadata XML.
  4. Map attributes
    Ensure these SAML attributes are included in assertions:
Nuria FieldSAML Attribute
Emailhttp://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress
First Namehttp://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname
Last Namehttp://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname
SSO users are auto-provisioned on first login. Their role defaults to Member. Admins can adjust roles in Settings → Team.

REST API

The Nuria REST API lets you programmatically manage contacts, conversations, tickets, and more. Base URL: https://api.nuria.run

Explore the full API interactively at api.nuria.run/docs (Swagger UI with OpenAPI spec).

Authentication

All API requests require authentication via one of these methods:

JWT Bearer Token

Obtain a token via the login endpoint or SSO flow. Include it in the Authorization header:

curl -X GET https://api.nuria.run/contacts \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiJ9..." \
  -H "Content-Type: application/json"

API Key

Create API keys in Settings → Developers → API Keys. Keys can be scoped to specific permissions (e.g., contacts:read, tickets:write).

curl -X GET https://api.nuria.run/contacts \
  -H "X-API-Key: nuria_sk_live_..." \
  -H "Content-Type: application/json"

Standard Headers

HeaderDescription
x-nuria-request-idUnique request ID (auto-generated if not provided).
x-nuria-tenant-idWorkspace ID (resolved from auth token).

Rate Limits

Rate limits are enforced per-token with different tiers based on the endpoint:

TierFreeEssentialProEnterprise
Auth10/min20/min50/min250/min
API100/min200/min500/min2,500/min
Upload20/min40/min100/min500/min
Search30/min60/min150/min750/min

Rate limit status is returned in response headers:

X-RateLimit-Plan: pro
X-RateLimit-Limit: 500
X-RateLimit-Remaining: 487

Key Endpoints

Contacts

GET /contacts List contacts (paginated)
POST /contacts Create a contact
GET /contacts/:id Get contact by ID
PATCH /contacts/:id Update a contact
DELETE /contacts/:id Delete a contact

Conversations

GET /inbox/conversations List conversations
GET /inbox/conversations/:id Get conversation details
POST /inbox/conversations/:id/messages Send a message
POST /inbox/conversations/:id/resolve Resolve conversation
POST /inbox/conversations/:id/assign Assign to agent

Helpdesk

GET /helpdesk/tickets List tickets
POST /helpdesk/tickets Create a ticket
GET /helpdesk/tickets/:id Get ticket details
PATCH /helpdesk/tickets/:id Update ticket

Scheduling

GET /scheduling/availability Check available slots
POST /scheduling/appointments Book an appointment
DELETE /scheduling/appointments/:id Cancel appointment

AI Agents

GET /ai/agents List AI agents
POST /ai/conversations Start AI conversation
POST /ai/conversations/:id/messages Send message to AI agent
This is not the complete API reference. Visit api.nuria.run/docs for the full OpenAPI specification with request/response schemas.