1. From the dashboard
Data → Import Data connects to LangSmith, Langfuse (Cloud and self-hosted, including older deployments), Phoenix, Braintrust, PostHog, and Mastra directly: paste the provider’s API credentials, preview the recent conversations, and import the ones you pick. The import runs in the background: you can leave the page, and progress (with a Cancel button and per-conversation failures) shows at the top of Import Data. Credentials are encrypted for the length of the import and deleted when it finishes; self-hosted deployments need a public https URL. Or upload a CSV / JSONL / JSON file of conversations: OpenAI-style{"messages": [...]} lines, input/output exchange rows, or role+content CSV columns are detected automatically.
Imported conversations are labeled by source (“LangSmith”, “PostHog”, “File import”, and so on) rather than by an API key: pick that label in the API key filter on the Data pages, or as a data source in the training wizard, to work with just the imported data. No API key is created for an import.
2. Or from the shell
The LangSmith importer imports the 20 most recent conversations by default. Pass--list first to see what would be imported. Both importers also take --base-url when your traces should go to a platform host other than the default https://platform.belvedir.ai:
--list previews here as well; --limit caps how many conversations import):
3. Or from Python
List conversations, pick, and import. Conversations are LangSmith traces grouped by theirsession_id / conversation_id / thread_id metadata (traces without any are imported individually):
import_conversations looks for the ids within the most recent conversations (its limit, default 20): if you picked ids from a deeper list_conversations(limit=...) call, pass the same limit to import_conversations or it raises LangSmithImportError for the older ones. FileImporter(path) in belvedir.importers.files works the same way, except that import_conversations(belvedir_api_key=..., limit=...) takes no ids and imports the whole file; both importers accept belvedir_base_url=. Scripts written against the old belvedir_loop import paths: see Migrating from Fractal.
What to expect
Imported traffic from the shell or Python is attributed to the API key you pass, like live traffic; filter by it on the Data pages (dashboard imports carry their source label instead). Full message history, tool calls (an assistant turn that only calls tools is kept as[tool_call] name(arguments)), token counts, and errors are preserved, so failure signals, usage graphs, and optimization treat imported sessions like live ones. Tasks appear once the imported session goes quiet; see How it works.
Dashboard imports skip spans the project already holds, so importing a conversation twice, or resuming an interrupted import, doesn’t double it. The shell and Python importers post through the ingest API, which has no such check, so import a conversation once from there.