API docs
API reference

Sources

Connect the systems you already run and keep a training file current from them.

A source connects a system you already run to Nucleus and keeps one training file current from it. Connect the source, map its records onto the chat format, set how often it refreshes, and every refresh writes a new file you can train and evaluate on without exporting anything by hand.

A source starts in connecting while its credentials are checked and its first records are read, then settles at ready or error. Each refresh runs running and then succeeded or failed. The file a refresh writes goes through the same line-by-line validation every upload does, validating and then ready or error, so a bad export is caught before it reaches a fine-tuning job. The source's file_id always names the latest ready version. Poll Retrieve a source after connecting and after a refresh.

type is the catalogue slug of the system you are connecting, for example salesforce, postgresql, rest or csv. The catalogue of 95 sources is on the Data connectors page of the Nucleus AI website.

Create a source

POST/v1/sourcesscope: train

Connects a source. The response comes back in connecting: credentials are checked and the first refresh is scheduled in the background, so poll Retrieve a source until the source reaches ready or error.

Body parameters

typestringrequired

The catalogue slug of the system to connect, for example salesforce, postgresql, rest or csv.

namestringrequired

Names the source, so you can tell your connections apart later.

credentialsobjectrequired

How to sign in, which depends on the type. A database takes a connection_string. A REST source takes a base_url and an api_key. A SaaS system that signs in with OAuth takes a connection_id, minted in the dashboard when you authorise the connection. Credentials are stored encrypted and are never returned by the API.

mappingobjectrequired

A template over the record's fields, mapping them onto the chat format. system, user and assistant each take a string with {{ field }} placeholders that are filled from the record. An optional filter expression selects which records are used.

refreshstringdefault: manual

How often the source refreshes: hourly, daily, weekly or manual. A manual source refreshes only when you call Refresh a source.

purposestring

What the files it writes are for: fine-tune, evaluation or retrieval. This is the purpose the written file carries.

project_idstring

Attach the source to a project. Keys bound to a different project cannot read it.

Connecting is not idempotent: retrying a timed-out request can create a duplicate source. Send an Idempotency-Key header if your client retries automatically. See Errors and retries.

curl https://api.nucleus-ai.io/v1/sources \
  -H "Authorization: Bearer $NUCLEUS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "salesforce",
    "name": "Support cases",
    "credentials": { "connection_id": "conn_5Ht9w" },
    "mapping": {
      "system": "You are a support agent for Acme.",
      "user": "{{ subject }}\n\n{{ description }}",
      "assistant": "{{ resolution }}",
      "filter": "status == '\''closed'\''"
    },
    "refresh": "daily",
    "purpose": "fine-tune",
    "project_id": "proj_1a2b"
  }'
201 Created
{
  "id": "src_7kQ2m",
  "type": "salesforce",
  "name": "Support cases",
  "status": "connecting",
  "purpose": "fine-tune",
  "project_id": "proj_1a2b",
  "refresh": "daily",
  "file_id": null,
  "rows": null
}

List sources

GET/v1/sourcesscope: read

Returns your connected sources, newest first, so you can see what is connected, what is still connecting and what has failed across the account. See Pagination for how limit, offset and the cursor object behave across list endpoints.

Query parameters

typestring

Filter to one catalogue slug, for example postgresql.

statusstring

Filter to one status: connecting, ready or error.

project_idstring

Only sources in this project.

limitinteger

Maximum number of sources to return.

offsetinteger

Number of sources to skip from the start of the list.

curl "https://api.nucleus-ai.io/v1/sources?status=ready" \
  -H "Authorization: Bearer $NUCLEUS_API_KEY"
200 OK
{
  "data": [
    {
      "id": "src_7kQ2m",
      "type": "salesforce",
      "name": "Support cases",
      "status": "ready",
      "file_id": "file_9fQ2x",
      "rows": 8412
    }
  ],
  "cursor": { "offset": 0, "total_count": 4 }
}

Retrieve a source

GET/v1/sources/{source_id}scope: read

Returns one source, including its mapping, its schedule and the file it currently writes to. This is the endpoint to poll after connecting and after a refresh.

file_id names the latest ready file written from this source: pass it straight to a fine-tuning job as the training_file. rows is the number of records that file holds. last_refreshed_at and next_refresh_at report where the source sits in its schedule.

Path parameters

source_idstringrequired

ID of the source, from the create response.

curl https://api.nucleus-ai.io/v1/sources/src_7kQ2m \
  -H "Authorization: Bearer $NUCLEUS_API_KEY"
200 OK
{
  "id": "src_7kQ2m",
  "type": "salesforce",
  "name": "Support cases",
  "status": "ready",
  "purpose": "fine-tune",
  "project_id": "proj_1a2b",
  "mapping": {
    "system": "You are a support agent for Acme.",
    "user": "{{ subject }}\n\n{{ description }}",
    "assistant": "{{ resolution }}",
    "filter": "status == 'closed'"
  },
  "refresh": "daily",
  "file_id": "file_9fQ2x",
  "rows": 8412,
  "last_refreshed_at": "2026-09-07T04:00:12Z",
  "next_refresh_at": "2026-09-08T04:00:00Z"
}

Update a source

PATCH/v1/sources/{source_id}scope: train

Changes the mapping or the schedule of a connected source. Send only the fields you are changing. A new mapping takes effect on the next refresh, so files already written are left alone and file_id keeps naming the latest ready one until that refresh completes.

Path parameters

source_idstringrequired

ID of the source to update.

Body parameters

mappingobject

A replacement template over the record's fields: system, user, assistant and an optional filter.

refreshstring

A new schedule: hourly, daily, weekly or manual.

curl -X PATCH https://api.nucleus-ai.io/v1/sources/src_7kQ2m \
  -H "Authorization: Bearer $NUCLEUS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "refresh": "hourly" }'
200 OK
{
  "id": "src_7kQ2m",
  "status": "ready",
  "refresh": "hourly",
  "file_id": "file_9fQ2x",
  "next_refresh_at": "2026-09-07T05:00:00Z"
}

Refresh a source

POST/v1/sources/{source_id}/refreshscope: train

Runs a refresh now, without waiting for the schedule. Use it after changing a mapping, or to pull a system that is set to manual.

The refresh runs asynchronously and returns 202 Accepted with the refresh record. It reports running while it reads the records and writes the file, then succeeded or failed. The file it writes starts in validating, so follow it through List refreshes or Retrieve a dataset.

Path parameters

source_idstringrequired

ID of the source to refresh.

curl -X POST https://api.nucleus-ai.io/v1/sources/src_7kQ2m/refresh \
  -H "Authorization: Bearer $NUCLEUS_API_KEY"
202 Accepted
{
  "id": "ref_3Wm8t",
  "source_id": "src_7kQ2m",
  "status": "running",
  "file_id": null,
  "started_at": "2026-09-07T11:22:41Z"
}

List refreshes

GET/v1/sources/{source_id}/refreshesscope: read

Returns the source's refresh history, newest first. Each entry carries the file it wrote, how many rows reached that file and how many lines were rejected, with the line number and reason for each rejection. This is where you see a mapping that has drifted from the records: a rejected count that climbs is a field that stopped arriving.

See Pagination for how limit, offset and the cursor object behave across list endpoints.

Path parameters

source_idstringrequired

ID of the source.

Query parameters

limitinteger

Maximum number of refreshes to return.

offsetinteger

Number of refreshes to skip from the start of the list.

curl https://api.nucleus-ai.io/v1/sources/src_7kQ2m/refreshes \
  -H "Authorization: Bearer $NUCLEUS_API_KEY"
200 OK
{
  "data": [
    {
      "id": "ref_3Wm8t",
      "status": "succeeded",
      "file_id": "file_9fQ2x",
      "rows": 8412,
      "rejected": 2,
      "rejections": [{ "line": 812, "reason": "assistant message empty" }]
    },
    {
      "id": "ref_2Vk4s",
      "status": "succeeded",
      "file_id": "file_8dP1w",
      "rows": 8237,
      "rejected": 0,
      "rejections": []
    }
  ],
  "cursor": { "offset": 0, "total_count": 12 }
}

Disconnect a source

DELETE/v1/sources/{source_id}scope: train

Disconnects a source and discards its stored credentials. No further refresh runs and the schedule stops.

The files already written stay in Files and can still be trained on, until you delete them there. Disconnecting is therefore about stopping the connection, and Delete a dataset is what honours a data-erasure request.

Path parameters

source_idstringrequired

ID of the source to disconnect.

curl -X DELETE https://api.nucleus-ai.io/v1/sources/src_7kQ2m \
  -H "Authorization: Bearer $NUCLEUS_API_KEY"
204 No Content
(empty body)
Sources | Nucleus AI API