Skip to content

Bring context they already have

Your users have history: transcripts from another assistant, and whatever your own product already stored about them. Both can land in the profile before the first message, so the first turn is already informed.

There are two calls, and they are for different moments.

CallThe momentShape
profile.import(text)A user hands you a chunk to keep, such as a pasted exportOne user, returns the stored memory
configure.importProfiles({ mode, users })You are integrating and already have usersMany users, returns a job you poll

Set up the client

Server-side, with your secret key.

ts
import { Configure } from "configure";

export const configure = new Configure({
  apiKey: process.env.CONFIGURE_API_KEY,   // sk_..., server only
  agent: process.env.CONFIGURE_AGENT,      // your agent handle
});

export const profileFor = (userId: string) => configure.profile({ externalId: userId });

One chunk, from one user

When someone pastes a transcript, an export, or a long note, do not split it into remember() calls. Send the whole thing and let Configure distill it.

ts
const result = await profileFor(user.id).import(pastedText);
// { saved: true, box: "work", distilled: true, memory: { id, text, ... } }

Configure rewrites the chunk into durable facts and files them into a box it picks, so box in the response is where it landed rather than something you chose. Pass box yourself when you want it somewhere specific. The response carries memory.id, which is the id forget() needs.

Use this instead of many remember() calls whenever the content is longer than a sentence or covers more than one topic.

Every user you already have

When you add Configure to a product with existing users, backfill them. Each user arrives with their profile already synthesized, so the first turn after they connect is informed rather than empty.

ts
const job = await configure.importProfiles({
  mode: "backfill",
  idempotencyKey: `backfill-${batchId}`,
  users: [
    {
      externalId: user.id,
      profile: {
        summary: "Runs a small logistics company in Rotterdam.",
        preferences: ["Prefers metric units"],
      },
      conversations: [
        { id: thread.id, messages: [
          { role: "user", content: "We ship pallets to Hamburg twice a week." },
          { role: "assistant", content: "Noted, twice weekly to Hamburg." },
        ]},
      ],
    },
  ],
});
// { id: "imp_...", status: "queued", accepted_profiles: 1, quota: { imported_profiles: { used, limit, remaining } } }

mode is backfill. externalId is the same id you use everywhere else, so a user you backfill today is the user who links tomorrow. Give each batch an idempotencyKey: sending the same body twice returns the same job rather than importing anyone twice, which makes a retry after a timeout safe.

Read quota.imported_profiles on the response. It reports used, limit and remaining for your account, so a large migration should check it between batches rather than discovering the ceiling mid-run.

The job finishes after the call returns

importProfiles() returns as soon as the work is accepted, with status: "queued". The distillation happens afterwards, and a small batch is usually done within seconds.

ts
const res = await fetch(`https://api.configure.dev/v1/import/jobs/${job.id}`, {
  headers: { "X-API-Key": process.env.CONFIGURE_API_KEY, "X-Agent": process.env.CONFIGURE_AGENT },
});
const status = await res.json();
// { status: "completed", processed_profile_count: 1, imported_memory_count: 3, failed_profile_count: 0 }

status moves through queued, processing, then completed, failed or cancelled. Poll it over HTTP: the published SDK starts a job but does not expose a method to read one back.

Do not block a user on a job. Backfill runs when you integrate, not while someone waits, and everything else about the profile works while it runs. Check failed_profile_count when the job completes, since a job can finish with some users imported and others not.

What it does not do

Importing does not link anyone. A backfilled profile is developer-scoped memory keyed by your externalId, exactly like a user who has not connected yet. Connecting is still the step that gives you their wider profile and their apps, and it is still the user's decision. See Quickstart for that flow.

Personalization infrastructure for agents