Create dataset
Endpoint: POST /datasets
Description
Creates a custom dataset from a CSV file. The server parses the file and stores records. Default selected metrics (default_selected_metrics: metric shortname → { threshold?, metric_args? }) are optional: omit them to store none. A later dataset run may send its own selected_metrics, or omit that field to reuse this stored default. You can also set name, description, and data_collection_id — the collection id must be one you can access (same rules as listing collections: yours or shared with your organization).
Sharing rules
The new dataset is always owned by you (your account is the individual owner). Sharing isn't accepted directly on this endpoint — visibility is derived from the data collection (if any), from an optional project_id, or from a project-scoped API key. Datasets created here are never org-only (org-only resources have no individual owner and can only be produced through admin flows).
- Without
data_collection_id:- Private (
org_id = null, no project) when you use a private API key and omitproject_id. - Org-shared and assigned to a project when you use a project-scoped API key (the key's project is applied and the dataset is org-shared automatically). A private key cannot org-share via
project_idalone. See Introduction — API key scoping.
- Private (
- With
data_collection_id:- The collection is loaded via claim semantics. When claimable, the dataset is created shared or private according to the collection's
org_idand inherits the collection's project (not a separate project assignment). You must still be a member of that organization when the collection is org-shared. Unassigned collections can be claimed into the key's project; a collection already assigned to a different project returns403. - The linked collection is private → the dataset is created private (no project until the collection or dataset is shared later).
- The collection is loaded via claim semantics. When claimable, the dataset is created shared or private according to the collection's
Parameters
- Body —
multipart/form-data:
{
"file": "binary (.csv file)",
"default_selected_metrics": "string | null (JSON: see shape below)",
"column_mappings": "string | null (JSON: Aegis field → CSV column name)",
"name": "string | null",
"description": "string | null",
"data_collection_id": "integer | null",
"project_id": "integer | null"
}
descriptionis optional. Max 255 characters. Surrounding whitespace is trimmed; blank or whitespace-only values are stored asnull. A longer value returns422.nameis the stored dataset label (for exampleMy evaluation set). The.csvcheck uses the uploaded file's own filename, case-insensitively. Any other extension returns400(Only CSV files are supported. Please upload a file with .csv extension.). A missing filename is the same400.
project_id
- Optional. On a private key, sending
project_idalone does not org-share the dataset (private keys have personal visibility only). Use a project-scoped key to create org-shared datasets. - On a project-scoped key, must match the key's project when provided; omit to use the key's project (standalone creates are org-shared automatically).
- Cannot be set on a dataset that will live inside a data collection — assign the collection instead.
default_selected_metrics is an optional JSON-encoded string. Omit it, pass null, or pass {} to store no metrics. When present and non-empty, it is a map keyed by metric shortname ("ans_corr"), where each value is an object:
{
"<metric_shortname>": {
"threshold": "integer (0–100) | null",
"metric_args": "object | null"
}
}
thresholdis optional. When present it must be an integer between0and100. Omit it (or sendnull) to use that metric's catalog default threshold at evaluation time.metric_argsis optional (nullor omitted means "use the metric's defaults"). Keys are argument names declared by the metric and values should match the argument's declared type. Only the shape is checked here (metric_argsmust be an object): an unknown argument name (for example a typo likemin_cout) is stored but ignored when the run evaluates, and a missing required argument or wrong-typed value surfaces later as an evaluation withis_success: falseand the reason inexplanation.- Keys are metric shortnames. Metric ids return
400. Unknown shortnames return400.GETreturns the same shortname keys. - A later
POST /runs/datasetmay omitselected_metricsto reuse thisdefault_selected_metricsmap, or send a different map for that run only (the dataset default is unchanged).
column_mappings is an optional JSON-encoded string. Decoded, it maps each Aegis field to the matching CSV column header:
{
"prompt": "question",
"input": "user_input",
"context": "background",
"output": "model_answer",
"golden_answer": "expected_answer",
"external_id": "upstream_row_id"
}
- Keys must be Aegis field names:
external_id,prompt,input,context,output,golden_answer. Include only the fields you want to import. - Values are the exact CSV column names (case-insensitive match against the file header).
- Each CSV column can be mapped to only one field. Comparison is case-insensitive, so
questionandQuestionare the same column. Two fields that share a column return400(Each CSV column can be mapped to only one field. 'question' is mapped to input, output.). - Omit
column_mappings(or passnull) to auto-detect columns whose headers already match Aegis field names (includingexternal_id). - The CSV must still include at least one of
prompt,input,context,output, orgolden_answer. Anexternal_idcolumn alone is not enough to create a dataset.
Error responses
401— Authentication failed.403— API key scoping violation (project_idconflicts with a project-scoped key, collection/dataset project mismatch, scoped key on a personal resource).422— Missing required form parts or invalid multipart fields.400— File name does not end in.csv, invalid CSV, empty file, bad encoding, invaliddefault_selected_metrics/column_mappings(includingInvalid default_selected_metrics format. Must be valid JSON.;default_selected_metrics must be a JSON object mapping metric shortnames to {threshold, metric_args} objects.; two fields mapped to the same CSV column —Each CSV column can be mapped to only one field. '<column>' is mapped to <fields>.); metric id used as a map key (Invalid metric key '<id>'. Use a metric shortname, not a metric id.); unknown or inactive metric shortnames (The following metrics do not exist: …,The following metrics are not active: …); invalid thresholds ormetric_args; duplicate metric keys; agentic metrics that score a trace or span (These metrics score a trace or a span and cannot be used on a dataset or custom run: <shortnames>.); duplicate dataset name for your account or organization. This endpoint always creates a custom dataset, so proprietary-dataset errors do not apply.404— Dataset type not found; or data collection not found or not claimable fordata_collection_id.500— Server error.
Responses
201— dataset object with the same JSON shape as Get dataset by id. The example is a private dataset you own, created with a private API key, socan_shareis false. On create,runsandevaluationsare usually empty arrays until you start a dataset run; nesteduser_idandapi_key_idfields are typically populated when present, but may benullper that shape.
Example response (201)
{
"id": 42,
"user": { "id": 7, "email": "analyst@acme.com" },
"dataset_type_id": 2,
"author_email": "analyst@acme.com",
"name": "My evaluation set",
"description": "Evaluation prompts for support QA",
"default_selected_metrics": {
"ans_corr": { "threshold": 70, "metric_args": null },
"faith": { "threshold": 80, "metric_args": { "ignore_extra_keys": true } }
},
"structure": ["external_id", "prompt", "output", "golden_answer"],
"column_mappings": {
"external_id": "row_id",
"prompt": "question",
"output": "model_answer",
"golden_answer": "expected_answer"
},
"data_collection_id": null,
"org_id": null,
"project_id": null,
"permissions": {
"can_edit": true,
"can_delete": true,
"can_share": false,
"can_assign_project": false,
"can_move_collection": true
},
"created_at": "2026-04-02T12:00:00Z",
"updated_at": "2026-04-02T12:00:00Z",
"extra_columns": [],
"dataset_type": {
"id": 2,
"name": "CUSTOM",
"label": "Custom",
"description": null
},
"records": [
{
"id": 1001,
"user_id": 7,
"dataset_id": 42,
"external_id": "row-42",
"prompt": "What is the refund policy?",
"input": null,
"context": null,
"output": "Refunds are available within 30 days.",
"golden_answer": "30-day refund window.",
"extra_values": {},
"created_at": "2026-04-02T12:00:00Z",
"updated_at": "2026-04-02T12:00:00Z"
}
],
"runs": [],
"evaluations": [],
"last_run_id": null
}
curl
curl -X POST "https://api.aegisevals.ai/api/v1/datasets" \
-H "Authorization: Bearer sk_00000000000000000000000000000000" \
-F "file=@/path/to/data.csv" \
-F 'default_selected_metrics={"ans_corr":{"threshold":70,"metric_args":null},"faith":{"threshold":80,"metric_args":{"ignore_extra_keys":true}}}' \
-F 'column_mappings={"external_id":"row_id","prompt":"question","output":"model_answer","golden_answer":"expected_answer"}' \
-F 'name=My evaluation set' \
-F 'description=Evaluation prompts for support QA'