Overview

Quick Start

Annotate a class, push it, embed an iframe. You'll have a live conversational settings surface in under five minutes. This guide uses Java + Maven. Step 1 covers the Maven setup; the rest is language-independent.


Before you start

You'll need:

  • A confiqure.ai workspace. Sign in if you don't have one yet — the workspace is created on first login.
  • A workspace API key (cqai_…). Generate one in Settings.
  • Node.js 18+ on your machine for the CLI.

1. Add the annotation library

Add the annotation artifact to your pom.xml. It's published on Maven Central — no extra repository entry needed.

pom.xml — dependency
<dependency>
  <groupId>ai.confiqure</groupId>
  <artifactId>confiqure-annotation-java</artifactId>
  <version>3.0.0</version>
</dependency>

The processor injects a confiqureKey field and its accessors into every object class (@Confiqure.Setting, @Confiqure.List, …) at compile time using internal javac APIs. Add the following compiler plugin configuration so Maven exposes those APIs to the forked compiler process:

pom.xml — compiler plugin
<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-compiler-plugin</artifactId>
  <configuration>
    <fork>true</fork>
    <compilerArgs>
      <arg>-J--add-exports=jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED</arg>
      <arg>-J--add-exports=jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED</arg>
      <arg>-J--add-exports=jdk.compiler/com.sun.tools.javac.processing=ALL-UNNAMED</arg>
      <arg>-J--add-exports=jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED</arg>
      <arg>-J--add-exports=jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED</arg>
      <arg>-J--add-opens=jdk.compiler/com.sun.tools.javac.processing=ALL-UNNAMED</arg>
    </compilerArgs>
  </configuration>
</plugin>

<fork>true</fork> is required — the -J prefix passes flags to the forked compiler JVM, not to javac itself. Gradle users: add the same -J--add-exports entries to compileJava.options.forkOptions.jvmArgs.

2. Annotate a configuration class

Annotate the class your end-users should be able to configure — @Confiqure.Setting for one record per organization, @Confiqure.List for many (see @Confiqure). Write a plain-language comment above each field — the AI reads those comments to know what to ask.

NotificationPreferences.java
@Confiqure.Setting(end = "/notifications")
public class NotificationPreferences {

    // Which channels should receive alerts?
    private List<Channel> channels;

    // How often should digest emails be sent?
    private Frequency digestFrequency;

    // What is the minimum severity to trigger an alert?
    private Severity minSeverity;
}

To hear back when a user finishes (step 7), also mark one controller method as your callback endpoint — its route is discovered automatically when you push:

ConfiqureCallbackController.java
@Confiqure.DefaultCallbackHook
@PostMapping("/api/confiqure/callback")
public ResponseEntity<Void> confiqureCallback(@RequestBody JsonNode event) {
    // read event.get("event") — see step 7
    return ResponseEntity.ok().build();
}

end is the endpoint your users will configure through the chat. The callback URL is your app's base URL (set once in Dashboard settings) plus this discovered route.

3. Install the CLI and authenticate

The CLI scans your repo for annotated classes, diffs them against your workspace, and pushes the changes.

Terminal
$ npm install -g @confiqure/cli
$ confiqure login
?  Workspace key   abcdef
?  API token       cqai_••••••••••
✓  Credentials saved ~/.confiqure/credentials

Then initialize the project. This creates a confiqure.config.json with sensible scan paths and ignore rules.

Terminal
$ confiqure init -y
✓  Wrote confiqure.config.json

4. Push your schema

Commit your changes first — push refuses a dirty working tree by default so the version on the server always matches a real commit.

Terminal
$ git add . && git commit -m "add notification config"
$ confiqure push

Pushed to sandbox (sb-abcdef): 1/1 accepted, 0 rejected.
✓  NotificationPreferences ready (2.1s)

Push targets your sandbox workspace — try the conversation there first, then promote with confiqure push --production (or push and promote in one step with --live). Need to push before committing? Use --allow-dirty. Running in CI? Skip the readiness poll with --no-watch.

5. Mint an embed token from your backend

The iframe needs a short-lived token that ties this chat session to one of your end-users. Mint it server-side using your workspace API key — never expose cqai_… to the browser. Send the attachments block on every mint: without it the widget shows no attach button, no paste and no ctrl+v.

Server
POST https://api.confiqure.ai/api/{workspaceKey}/embed-tokens
Authorization: Bearer cqai_••••••••••
Content-Type:  application/json

{
  "endUserHandle": "user_42",
  "attachments": { "enabled": true, "allowedTypes": ["image/png", "image/jpeg"], "camera": true },
  "ttlSeconds":    3600
}

→ 200 OK
{
  "token":     "eyJhbGciOi…",
  "jti":       "01HXYZ…",
  "expiresAt": "2026-05-13T18:00:00Z"
}

6. Embed the chat

Hand the minted token to the @confiqure/embed loader — it frames the chat and wires lifecycle events back to your page. Install from npm or drop in the script tag.

settings.html
<div id="chat-panel"></div>
<script src="https://confiqure.ai/embed.js"></script>
<script>
  confiqure.init({
    target: '#chat-panel',
    token,  // minted by YOUR server in step 5
  })
</script>

7. Receive the callback

When the user finishes, confiqure POSTs onComplete to the hook method from step 2. The payload carries the finalized instances' confiqureKeys — not the values. Fetch each key over the data API, deserialize into your class, and provision. Set your app's base URL once in Dashboard settings so the events reach you.

Your callback endpoint
// POST /api/confiqure/callback
{
  "event":           "onComplete",
  "workspaceKey":    "abcdef",
  "configEnd":       "/notifications",
  "endUserHandle":   "user_42",
  "conversationId":  10247,
  "confiqureKeys":   ["7299ac44b18b"],   // finalized instances — GET each, read data
  "timestamp":       "2026-05-13T17:42:11.401"
}

Other lifecycle events (onStart, session closes, deletions) arrive at the same endpoint — branch on event. Full contract: Callbacks.


Where to next

Last updated June 2026