Connector Templates
A connector is the code that pulls data out of a source system and into the workspace's graph. Curiosity ships templates for the common shapes (file system, SQL, REST API, popular SaaS apps) so you can start from a working skeleton instead of a blank file.
For the overall architecture see Connectors. For idempotent design see Schema design. For the SDK API see C# SDK and Python SDK.
Where to get the templates
Templates live in the workspace itself. To download:
- Sign into your workspace.
- Go to API integrations.
- Click + New connector → pick a template.
- Choose C# or Python at the bottom right of the dialog.
- The workspace generates a starter project (zip), pre-filled with the right SDK reference, an ingestion token, and a stub
Mainthat prints the connection check.
If you can't see API integrations, you don't have admin permissions on this workspace.
Available templates
| Template | Source shape | Languages | Notes |
|---|---|---|---|
| File system | Local or network share | C#, Python | Walks a directory, uploads files; OCR/STT run automatically. |
| SQL database | PostgreSQL, MySQL, SQL Server | C#, Python | Uses incremental cursor (updated_at > ?) to fetch only changes. |
| REST API | JSON-over-HTTP | C#, Python | Generic skeleton with pagination + retry. Customize for each API. |
| Slack | Conversations, channels, users | C# | Maps messages to Message nodes with Channel/User edges. |
| Jira | Issues, projects, comments | C# | Issue key is the stable graph key. |
| ServiceNow | Tickets, KB articles, CMDB | C# | Carries CMDB CIs as device nodes. |
| Confluence | Spaces, pages, comments | C# | Uses the version number for incremental updates. |
| SharePoint | Sites, lists, files | C# | Mirrors site permissions onto the file nodes via RestrictAccessTo*. |
| Email (PST/MBOX) | Mail archives | C# | Built on Curiosity.Library.FileSync.PstIngest. |
| CSV / Excel | Tabular files | Python | One row → one node, with column → property mapping. |
The exact list available depends on your workspace version. Check the API integrations page.
Hello connector — C#
The smallest possible C# connector. Connect, ensure schema, write one node, commit.
using Curiosity.Library;
[Node]
public class Note
{
[Key] public string Id { get; set; }
[Property] public string Title { get; set; }
[Property] public string Body { get; set; }
[Timestamp] public DateTimeOffset CreatedAt { get; set; }
}
class Program
{
static async Task Main()
{
using var graph = Graph.Connect(
endpoint: "https://workspace.example.com",
token: Environment.GetEnvironmentVariable("CURIOSITY_TOKEN")!,
connectorName: "hello-connector");
await graph.CreateNodeSchemaAsync<Note>(overwrite: false);
graph.AddOrUpdate(new Note
{
Id = "note-0001",
Title = "Hello from C#",
Body = "This is my first connector.",
CreatedAt = DateTimeOffset.UtcNow,
});
await graph.CommitPendingAsync();
}
}
Run with CURIOSITY_TOKEN=… dotnet run. The note appears in the workspace immediately.
Hello connector — Python
import os
from curiosity import Graph
with Graph.connect(endpoint="https://workspace.example.com",
token=os.environ["CURIOSITY_TOKEN"],
connector_name="hello-connector") as g:
g.add_or_update_by_key(
node_type="Note",
key="note-0001",
content={
"Title": "Hello from Python",
"Body": "This is my first connector.",
"CreatedAt": "2026-01-01T00:00:00Z",
},
)
g.commit_pending()
Install with pip install curiosity. Run with CURIOSITY_TOKEN=… python hello.py.
Customizing a template
The templates put scaffolding in three places — change each one as your source dictates:
- Source-side fetch. Inside the
FetchPage(...)/Fetch(...)helper. Replace with your client library. - Mapping. A
MapToGraph(...)function turns a source record into one or moreAddOrUpdate(...)andLink(...)calls. Keep this pure (no I/O) so you can unit test it. - Loop driver. The outer loop reads a cursor (last-updated timestamp, last-seen page token) and asks the source for changes. Persist the cursor between runs.
Configure ACLs at ingest time
If the source has permissions, mirror them — don't try to bolt them on later.
var team = await graph.CreateTeamAsync("Engineering");
graph.RestrictAccessToTeam(noteNode, team);
See Access control model.
Incremental sync pattern
var lastSync = await ReadCheckpointAsync(); // your own persistence
var page = 0;
while (true)
{
var batch = await source.FetchChangedAsync(since: lastSync, page: page++, pageSize: 500);
if (batch.Count == 0) break;
foreach (var record in batch)
MapToGraph(graph, record);
await graph.CommitPendingAsync();
lastSync = batch.Max(r => r.UpdatedAt);
await WriteCheckpointAsync(lastSync);
}
The checkpoint must survive process restarts — write it to disk, S3, or a workspace node, not just memory.
Best practices
- Stable keys. Always use a source-side stable identifier. Never use a generated UUID for the graph key.
- Idempotency. Re-running the connector should be a no-op for unchanged records.
TryAdd/AddOrUpdateare the building blocks. - Auto-commit cost. For high-volume jobs, set
SetAutoCommitCost(everyNodes: 10_000)so the local queue doesn't grow unbounded. - Pause indexing for backfills.
PauseIndexing("backfill")before a large initial load andResumeIndexing("backfill")after — the workspace will rebuild once instead of many small times. - Token scopes. Connector tokens should be scoped tightly — write-only on the relevant types, no admin. See Token scopes.
- Dry-run mode. Use
.WithDryRun(true)during development so you can iterate without polluting the graph.
Contributing back
If you build a connector for a system not in the template list, consider opening a PR against the workspace repository (or a parallel "community connectors" repo if your organization maintains one). A well-shaped template:
- Pure mapping function with unit tests.
- Cursor-driven loop with checkpointing.
- ACL handling visible in the template, even if commented out.
- A README that lists required environment variables.
Where to go next
- Connectors — overall architecture.
- Ingestion pipelines — orchestration around the connector.
- Pipeline orchestration — Airflow / GitHub Actions / cron patterns.
- C# SDK · Python SDK.