Create data collection
Endpoint: POST /data-collections
Description
Creates a data collection. Optional dataset_ids attaches your non-proprietary datasets that are not already in another collection; linked runs for those datasets move to this collection too. Optional custom_run_ids attaches custom runs (runs without a dataset) you can access that are not already in another collection. Optional trace_ids attaches traces you can access that are not already in another collection.
Sharing rules
The new collection is always owned by you (your account is the individual owner). Sharing isn't accepted directly on this endpoint — the collection's visibility is derived from the datasets, custom runs, and traces you attach, from an optional project_id, or from a project-scoped API key. Collections created here are never org-only (org-only resources have no individual owner and can only be produced through admin flows).
- A project-scoped API key always org-shares the collection and assigns it to the key's project. Any
project_idin the body must match the key's project (or be omitted). Attached datasets, runs, and traces must be unassigned or already belong to the key's project; a resource assigned to a different project returns403. See Introduction — API key scoping. - No
dataset_ids,custom_run_ids, ortrace_ids(or all selected resources are private) → the collection is created private (org_id = null, no project), unless a project-scoped key applies (above). - Every selected dataset, custom run, and trace is already shared with your organization → the collection is created shared with that same
org_id. You must also supplyproject_id; the collection and attached members inherit that project. Attached traces, and the spans on those traces, receive the sameorg_id. - Mixed selection (private + org-shared resources) on a project-scoped key → your own private datasets, runs, and traces in the selection are auto-promoted to your organization, so the whole selection becomes org-visible and the collection is created shared. If any selected resources you don't own can't be promoted (they stay private), the request fails with
400("This selection mixes organization-visible datasets, custom runs, or traces with private resources that are not yours or cannot be shared with your organization automatically."). This path also requiresproject_id; the project is assigned to the collection and to the promoted members. - A private key (including an org member's private key) or a solo account has no organization scope. Attaching any resource that is already org-shared returns
400("You cannot include organization-visible resources unless you belong to an organization.").
Sending project_id alone on an otherwise private collection (no org-visible attached resources) auto-shares the collection with your organization and assigns it to that project when your key is project-scoped. On a private key, project_id is ignored: the collection stays private and the value is not stored.
Parameters
- Body —
application/json:
{
"name": "string",
"dataset_ids": "integer[] | null",
"custom_run_ids": "integer[] | null",
"trace_ids": "integer[] | null",
"project_id": "integer | null"
}
name
- Required. Surrounding whitespace is trimmed. Max 255 characters. A longer value returns
422.
dataset_ids, custom_run_ids, trace_ids, and project_id must be JSON integers. A digit string ("74"), a whole-number float (1.0), or a boolean (true / false) returns 422 before lookup. Omit a field or send null to leave it unset.
custom_run_ids
- Optional list of custom run ids (runs with no
dataset_id) you can access. - Each run must not already belong to another data collection.
- Dataset runs cannot be attached here — they follow their dataset’s collection membership.
trace_ids
- Optional list of trace row ids (from
GET /traces) you can access. Omitted ornull= no traces attached. - Each trace must not already belong to another data collection.
- Attached traces are filed into the new collection (
data_collection_idset).
project_id
- Required when the collection ends up org-shared after create (see sharing rules above), including auto-promotion from a mixed resource selection. Pass a project id your organization owns;
GET /organizations/meexposesdefault_project_idas a convenient starting point. - On an otherwise private collection, a project-scoped key may send it alone to auto-share with your organization and assign the collection to that project. It must match the key's project.
- On a private key, the field is ignored.
- Omit or pass
nullwhen the collection stays private.
Error responses
401— Authentication failed.403— API key scoping violation (project_idin the body conflicts with a project-scoped key, attached resource already assigned to a different project).422— Invalid body, including anamelonger than 255 characters.dataset_ids,custom_run_ids,trace_ids, andproject_idmust be JSON integers. A digit string ("74"), a whole-number float (1.0), or a boolean (true/false) is rejected before lookup. The validation error is"Input should be a valid integer". For a list field, the error location includes the index (["body", "dataset_ids", 0]). An integer id that does not exist still returns the404"do not exist" response. JSONnulland omitting an optional id are still accepted.400— Emptyname("Data collection name cannot be empty."); duplicate name for your account ("A data collection with this name already exists for your account.") or organization ("A data collection with this name is already shared with your organization."); datasets, custom runs, or traces already filed in another collection ("Datasets with IDs: […] are already used in another data collection.", and the same sentence for custom runs and traces); org-visible resources selected with a key that has no organization scope ("You cannot include organization-visible resources unless you belong to an organization."); mixed selection where non-owner private resources cannot be auto-promoted ("This selection mixes organization-visible datasets, custom runs, or traces with private resources that are not yours or cannot be shared with your organization automatically."); org-shared create withoutproject_id("project_id is required when sharing a resource with your organization.").404— Referenced dataset, custom run, or trace ids not found or not accessible. Proprietary datasets and runs that are not custom use the same not-found responses:"Datasets with IDs: […] do not exist.","Custom runs with IDs: […] do not exist.","Traces with IDs: […] do not exist."500— Server error creating the collection.
Responses
201— collection object with the same JSON shape as one element ofitemsfrom Get data collections (paginated list). Nestedruns[].api_key_idmay benullper that shape. Nestedtraces[]entries include identity and filing fields only (no observability rollups).
Example response (201)
{
"id": 14,
"user": { "id": 7, "email": "analyst@acme.com" },
"name": "My bundle",
"org_id": null,
"project_id": null,
"permissions": {
"can_edit": true,
"can_delete": true,
"can_share": false,
"can_assign_project": false,
"can_move_collection": true
},
"author_email": "analyst@acme.com",
"datasets": [
{
"id": 1,
"name": "Support QA - March",
"description": "March support QA prompts",
"user": { "id": 7, "email": "analyst@acme.com" },
"org_id": null,
"data_collection_id": 14,
"project_id": null,
"permissions": {
"can_edit": true,
"can_delete": true,
"can_share": false,
"can_assign_project": false,
"can_move_collection": true
},
"author_email": "analyst@acme.com",
"created_at": "2026-03-30T10:00:00Z",
"updated_at": "2026-03-30T10:00:00Z"
},
{
"id": 2,
"name": "Support QA - April",
"description": "April support QA prompts",
"user": { "id": 7, "email": "analyst@acme.com" },
"org_id": null,
"data_collection_id": 14,
"project_id": null,
"permissions": {
"can_edit": true,
"can_delete": true,
"can_share": false,
"can_assign_project": false,
"can_move_collection": true
},
"author_email": "analyst@acme.com",
"created_at": "2026-03-31T10:00:00Z",
"updated_at": "2026-03-31T10:00:00Z"
}
],
"runs": [],
"traces": [],
"created_at": "2026-04-01T09:20:00Z",
"updated_at": "2026-04-01T09:20:00Z"
}
curl
curl -X POST "https://api.aegisevals.ai/api/v1/data-collections" \
-H "Authorization: Bearer sk_00000000000000000000000000000000" \
-H "Content-Type: application/json" \
-d '{"name":"My bundle","dataset_ids":[1,2],"custom_run_ids":[992]}'
Attach org-shared datasets (requires project_id):
curl -X POST "https://api.aegisevals.ai/api/v1/data-collections" \
-H "Authorization: Bearer sk_00000000000000000000000000000000" \
-H "Content-Type: application/json" \
-d '{"name":"Team bundle","dataset_ids":[1,2],"project_id":5}'