Outcome sources
Turn the results your systems already record into the cases a model is scored against.
An outcome source connects a system of record and keeps an evaluation file current from it. Where a source maps records onto the chat format to train on, an outcome source names the two fields that make a scored case: the field holding the case and the field holding the result your business already wrote down for it. Point it at the CRM, the ticketing queue or the ERP where the answer lives, and every refresh writes a fresh set of cases with their real outcomes.
That is what turns a score into a business measure. The model is not being judged against a public benchmark; it is being judged against what actually happened, on the same records your team is already accountable for.
Reference it from a benchmark and every evaluation scores against the current rows, so a model can be re-scored as new records arrive and the result compared with every release before it.
An outcome 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, and the file it writes goes through the same validation every upload
does. The source's file_id always names the latest ready version.
type is the catalogue slug of the system you are connecting, the same catalogue the
training sources draw on, for example salesforce, zendesk or
postgresql. The catalogue of 95 sources is on the Data connectors page of the Nucleus AI
website.
Create an outcome source
/v1/outcome-sourcesscope: trainConnects a system of record and schedules its first read. Connecting is not idempotent:
retrying a timed-out request can create a duplicate. Send an Idempotency-Key header if your
client retries automatically. See Errors and retries.
Body parameters
typestringrequiredThe catalogue slug of the system, for example zendesk.
credentialsobjectrequiredThe connection details for that system, in the shape its catalogue entry documents.
case_fieldstringrequiredThe field holding the case the model is asked about, for example the body of a ticket.
outcome_fieldstringrequiredThe field holding the result the system recorded, for example the queue a ticket was routed to or whether it closed inside its SLA. This is what the model's answer is scored against.
filterstringAn expression selecting which records are used, so closed records or one product line can be scored on their own.
refreshstringdefault: manualHow often the source refreshes: hourly, daily, weekly or manual. A manual source
refreshes only when you call Refresh an outcome source.
project_idstringAttach the source to a project. Keys bound to a different project cannot read it.
curl https://api.nucleus-ai.io/v1/outcome-sources \
-H "Authorization: Bearer $NUCLEUS_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"type": "zendesk",
"credentials": { "subdomain": "acme", "api_token": "..." },
"case_field": "description",
"outcome_field": "assignee_group",
"filter": "status == \"closed\"",
"refresh": "daily"
}'{
"id": "osrc_2Km",
"type": "zendesk",
"status": "connecting",
"case_field": "description",
"outcome_field": "assignee_group",
"refresh": "daily",
"file_id": null,
"cases": null,
"created_at": "2026-09-08T09:04:00Z"
}List outcome sources
/v1/outcome-sourcesscope: readReturns your connected outcome sources, newest first. See Pagination for how
limit, offset and the cursor object behave across list endpoints.
Query parameters
typestringFilter to one catalogue slug, for example zendesk.
statusstringFilter to one status: connecting, ready or error.
project_idstringOnly sources in this project.
limitintegerMaximum number of sources to return.
offsetintegerNumber of sources to skip from the start of the list.
curl "https://api.nucleus-ai.io/v1/outcome-sources?status=ready" \
-H "Authorization: Bearer $NUCLEUS_API_KEY"{
"outcome_sources": [
{
"id": "osrc_2Km",
"type": "zendesk",
"status": "ready",
"cases": 1200,
"refresh": "daily",
"refreshed_at": "2026-09-08T04:00:00Z"
}
]
}Retrieve an outcome source
/v1/outcome-sources/{outcome_source_id}scope: readReturns one outcome source, including its field mapping, its schedule and the file it
currently writes to. Poll it after connecting and after a refresh; status and the last
refresh record report where it sits in its schedule.
Path parameters
outcome_source_idstringrequiredID of the outcome source.
curl https://api.nucleus-ai.io/v1/outcome-sources/osrc_2Km \
-H "Authorization: Bearer $NUCLEUS_API_KEY"{
"id": "osrc_2Km",
"type": "zendesk",
"status": "ready",
"case_field": "description",
"outcome_field": "assignee_group",
"filter": "status == \"closed\"",
"refresh": "daily",
"file_id": "file_4kEv1",
"cases": 1200,
"refreshed_at": "2026-09-08T04:00:00Z",
"created_at": "2026-09-08T09:04:00Z"
}Update an outcome source
/v1/outcome-sources/{outcome_source_id}scope: trainChanges the field mapping, the filter or the schedule. Send only the fields you are changing.
A change to case_field, outcome_field or filter takes effect on the next refresh, so
call Refresh an outcome source if you want it applied now.
Path parameters
outcome_source_idstringrequiredID of the outcome source.
Body parameters
case_fieldstringA new field to read the case from.
outcome_fieldstringA new field to read the recorded result from.
filterstringA new expression selecting which records are used.
refreshstringA new schedule: hourly, daily, weekly or manual.
curl -X PATCH https://api.nucleus-ai.io/v1/outcome-sources/osrc_2Km \
-H "Authorization: Bearer $NUCLEUS_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "refresh": "hourly" }'{
"id": "osrc_2Km",
"type": "zendesk",
"status": "ready",
"refresh": "hourly",
"refreshed_at": "2026-09-08T04:00:00Z"
}Refresh an outcome source
/v1/outcome-sources/{outcome_source_id}/refreshscope: trainReads the system now, without waiting for the schedule. Use it after changing a mapping, or
to pick up records written since the last run. The refresh runs asynchronously and returns
202 Accepted with the refresh record.
Path parameters
outcome_source_idstringrequiredID of the outcome source.
curl -X POST https://api.nucleus-ai.io/v1/outcome-sources/osrc_2Km/refresh \
-H "Authorization: Bearer $NUCLEUS_API_KEY"{
"id": "osrf_8Vt",
"outcome_source": "osrc_2Km",
"status": "running",
"started_at": "2026-09-08T10:15:00Z"
}Disconnect an outcome source
/v1/outcome-sources/{outcome_source_id}scope: trainDisconnects the system and stops the schedule. The files it has already written are kept and any benchmark built on them keeps working; the set simply stops updating.
Path parameters
outcome_source_idstringrequiredID of the outcome source.
curl -X DELETE https://api.nucleus-ai.io/v1/outcome-sources/osrc_2Km \
-H "Authorization: Bearer $NUCLEUS_API_KEY"{
"id": "osrc_2Km",
"deleted": true
}