ARCY AI
BETA
Reference

Configuration

All ARCYProvider props and what they control.

ARCYProvider is the root component that connects your app to ARCY. Wrap your root layout with it and pass your publishable key plus any identity props you have available.

Supported insights

ARCY's dashboard insights each need specific traits to activate. See Trait requirements for the full mapping of which insight needs which trait, on which prop.

Props

publicKey (required)

ts
publicKey: string

Your ARCY publishable key. Safe to include in client-side code. Get it from app.arcyai.com under Settings > API Keys.

Store it in your env file and pass it via process.env or import.meta.env:

Add to .env.local:

bash
NEXT_PUBLIC_ARCY_PUBLISHABLE_KEY=pk_live_...
tsx
publicKey={(process.env.NEXT_PUBLIC_ARCY_PUBLISHABLE_KEY || process.env.NEXT_PUBLIC_ARCY_TEST_PUBLISHABLE_KEY)!}

Falls back to NEXT_PUBLIC_ARCY_TEST_PUBLISHABLE_KEY when the live key isn't set, so a .env.local holding only test keys (the convention for local dev, see Quickstart) still resolves. Vite and CRA need the same value duplicated under VITE_ARCY_PUBLISHABLE_KEY/REACT_APP_ARCY_PUBLISHABLE_KEY instead, since neither framework exposes NEXT_PUBLIC_-prefixed vars to the browser.

showWidget

ts
showWidget?: boolean

Whether ARCY renders its built-in widget UI (Launcher, Panel, Overlay, ChatBar, InterventionPrompt, CopilotTooltip). Defaults to true. Set to false to hide the widget on a page (for example a sign-in screen) while the session, tracking, and detection engine keeps running unchanged underneath.

uiLanguage

ts
uiLanguage?: "en" | "tr"

Sets the widget's UI language. Defaults to "en". Setting "tr" translates all built-in widget chrome (buttons, labels, confirmations, toasts, coachmarks) to Turkish, and sets the default (non-overridden) values of customization.content's greetingMessage, assistantName, and chatPlaceholder. An explicit content override always wins over the uiLanguage default for that field. See Customization for how uiLanguage and content interact.

uiLanguage also sets the AI's default response language for Chat, Copilot, and Autopilot. The model may still answer in the end user's own language when their query is unambiguously written in the other supported language (English or Turkish), so a Turkish-configured widget doesn't force an English-speaking user into Turkish replies. Brand terms (ARCY, Chat, Copilot, Autopilot) are never translated, in either the widget UI or AI responses.

Only English and Turkish are supported today. This is a code-level prop set once in your ARCYProvider JSX, there's no dashboard control for it yet. Changing it takes effect on the widget's next session bootstrap, not mid-session.

tsx
<ARCYProvider publicKey={(process.env.NEXT_PUBLIC_ARCY_PUBLISHABLE_KEY || process.env.NEXT_PUBLIC_ARCY_TEST_PUBLISHABLE_KEY)!} uiLanguage="tr">
  {children}
</ARCYProvider>

userTraits

ts
userTraits?: {
  userId?: string            // Your auth system's user ID for the currently logged-in user
  email?: string
  name?: string
  plan?: string
  planValue?: number         // Monthly plan value, in planCurrency. Drives revenue insights
  planCurrency?: PlanCurrency // ISO 4217 code planValue is in. Defaults to USD
  role?: string
  signupDate?: string | Date // When this user signed up. Renamed from createdAt.
  persona?: string           // Job-function classification, used for segmentation. Distinct from role.
  region?: string            // Geography, used for segmentation
  billingCycle?: number      // Billing cadence in days
  renewalDate?: string | Date // Next auto-renewal date (B2C)
  // Extra data about this user
  seatCount?: number         // Active seats/licenses this user holds
  [key: string]: string | number | boolean | null | undefined | Date
}

Traits used for segmentation and revenue tracking. All fields are optional. More traits give ARCY more signal for behavioral analysis.

userId is the one trait ARCY extracts specially (pulled into the session bootstrap payload to tie behavioral signals to this user in your dashboard); every other trait stays opaque pass-through data. Omit it (don't pass null) when no user is signed in. There is no separate root-level userId prop — pass it here, nested under userTraits.

The user's role within your app (e.g. "admin", "viewer") also lives here. Used in the dashboard to segment sessions by role.

The planValue field is the monthly value of this user, denominated in planCurrency. When provided, it activates Revenue at risk and Recoverable now in the Console. See Revenue Tracking for the full setup and the B2C vs. B2B guidance.

planCurrency is the ISO 4217 code that planValue is expressed in. That account's own figures still render when it's omitted (assumed USD), but the account is excluded from the portfolio-wide Revenue at risk / Recoverable now totals rather than silently counted as USD there. Set it explicitly on every account you want counted. Supported values: USD, EUR, GBP, JPY, CNY, AUD, CAD, CHF, INR, TRY. ARCY never converts between currencies, so keep planValue in a single currency per user.

plan alone (without planValue) does not activate Revenue at risk. plan is a display label; planValue is the number ARCY sums.

createdAt was renamed to signupDate to avoid ambiguity with a database row's creation timestamp. featureDepth was removed entirely (it never worked correctly server-side); there is no replacement.

The seatCount field is additional account-sizing data ARCY uses for segmentation.

Every dashboard insight declares which of the traits above it needs, and whether they're required or optional. See Trait requirements for the full mapping. ARCYProvider reads this same mapping to print a console warning in development when a required trait for an active insight is missing, naming the exact prop path to add.

organizationTraits

ts
organizationTraits?: {
  organizationId?: string    // Your auth system's organization or workspace ID
  name?: string
  plan?: string
  planValue?: number         // Monthly plan value, in planCurrency (the account MRR)
  planCurrency?: PlanCurrency // ISO 4217 code planValue is in. Defaults to USD
  signupDate?: string | Date // When this organization signed up
  contractEndDate?: string | Date // Fixed-term contract end date (B2B)
  billingCycle?: number      // Billing cadence in days
  region?: string            // Geography, used for segmentation
  // Extra data about this organization
  companySize?: "1-10" | "11-50" | "51-200" | "201-500" | "500+"
  industry?: string
  seatCount?: number         // Active seats/licenses under this org
  integrationCount?: number  // Integrations connected by this org
  [key: string]: string | number | boolean | null | undefined
}

Account-level traits for segmentation and revenue tracking, for B2B SaaS products.

organizationId is the one trait ARCY extracts specially (pulled into the session bootstrap payload to link this user to an account in your dashboard); every other trait stays opaque pass-through data. There is no separate root-level organizationId prop — pass it here, nested under organizationTraits.

For B2B products, set planValue on organizationTraits to track account-level MRR. It powers Revenue at risk and Recoverable now in the Console. See Revenue Tracking.

Set planCurrency on organizationTraits to control the currency the account's MRR renders in, and to include this account in the portfolio-wide revenue totals (an account with planValue but no planCurrency renders its own MRR as USD but is excluded from those totals). It accepts the same ISO 4217 codes listed for userTraits.planCurrency above.

If you bill per seat, aggregate your own seat-level pricing into a single organizationTraits.planValue before passing it. ARCY does not sum userTraits.planValue across an organization's members into an account figure.

renewalDate (on userTraits, B2C) and contractEndDate (on organizationTraits, B2B) are deliberately separate fields for different renewal semantics, not the same date with two names.

The companySize and industry fields describe your account's firmographics, and seatCount and integrationCount describe its size and integration footprint. ARCY uses all four for segmentation.

There is no metadata prop. Both userTraits and organizationTraits have an open index signature, so any extra data you want ARCY to have goes directly on whichever one it actually describes — user-scoped data on userTraits, org-scoped data on organizationTraits. Attribute it to the right subject rather than passing it as unattributed metadata.

tsx
<ARCYProvider
  publicKey="pk_..."
  userTraits={{ userId }}
  organizationTraits={{
    organizationId: orgId,
    name: "Acme Corp",
    plan: "enterprise",
    companySize: "51-200",
    industry: "FinTech",
    seatCount: 120,
    integrationCount: 8,
  }}
>
  {children}
</ARCYProvider>

flowAbandonThresholdMs

ts
flowAbandonThresholdMs?: number

How long (in milliseconds) ARCY waits before marking an in-progress guided flow as abandoned. Defaults to 300000 (5 minutes). Increase this for flows with long natural pauses between steps, such as multi-step configuration wizards.

Full example

tsx
"use client"
import { ARCYProvider } from "@arcyai/sdk/react"
import "@arcyai/sdk/styles"

interface ArcyWrapperProps {
  userId?: string | null
  userEmail?: string | null
  userPlan?: string | null
  organizationId?: string | null
  children: React.ReactNode
}

export function ArcyWrapper({
  userId,
  userEmail,
  userPlan,
  organizationId,
  children,
}: ArcyWrapperProps) {
  return (
    <ARCYProvider
      publicKey={(process.env.NEXT_PUBLIC_ARCY_PUBLISHABLE_KEY || process.env.NEXT_PUBLIC_ARCY_TEST_PUBLISHABLE_KEY)!}
      userTraits={{
        userId: userId ?? undefined,
        email: userEmail ?? undefined,
        plan: userPlan ?? undefined,
      }}
      organizationTraits={{ organizationId: organizationId ?? undefined }}
    >
      {children}
    </ARCYProvider>
  )
}

How ARCYProvider receives identity

Pass userTraits={{ userId, ...other traits }} directly as a prop. The values should come from your auth system, read server-side (for Next.js App Router) or from a client auth hook (for Pages Router or client-only setups).

Read identity server-side and pass it as props to a client wrapper:

app/layout.tsx
import { auth } from "@clerk/nextjs/server"
import { ArcyWrapper } from "@/components/arcy-wrapper"

export default async function RootLayout({ children }: { children: React.ReactNode }) {
  const { userId } = await auth()
  return (
    <html lang="en">
      <body>
        <ArcyWrapper userId={userId}>{children}</ArcyWrapper>
      </body>
    </html>
  )
}

Read identity from a client auth hook inside the wrapper:

tsx
import { useUser } from "@clerk/clerk-react"
import { ARCYProvider } from "@arcyai/sdk/react"

function ArcyWrapper({ children }: { children: React.ReactNode }) {
  const { user } = useUser()
  return (
    <ARCYProvider
      publicKey={(process.env.NEXT_PUBLIC_ARCY_PUBLISHABLE_KEY || process.env.NEXT_PUBLIC_ARCY_TEST_PUBLISHABLE_KEY)!}
      userTraits={
        user?.primaryEmailAddress
          ? { userId: user?.id ?? undefined, email: user.primaryEmailAddress.emailAddress }
          : undefined
      }
    >
      {children}
    </ARCYProvider>
  )
}

See CLI commands for the full .arcy/ setup flow across all auth libraries.

On this page