---
title: "Append Datapoints to a Dataset"
method: POST
path: "/api/v1/data-collection/datasets/{dataset_id}/datapoints"
tags: ["aiTaskBuilder"]
---

# Append Datapoints to a Dataset

`POST /api/v1/data-collection/datasets/{dataset_id}/datapoints`

Synchronously appends one or more JSONL records to an existing **V4 dataset**. Unlike the
file-upload flow, this endpoint processes the whole payload within the request and returns the
accepted/rejected counts directly — there is no async import job to poll.

**Request body:** JSONL — one JSON object per line — sent with a JSONL content type
(e.g. `application/x-ndjson`). Blank lines are skipped. CSV is not supported on this endpoint.

Each record is validated against the dataset's current schema. Valid records are persisted as
datapoints and sort after every existing datapoint. Records that are malformed or violate the
schema are rejected individually and reported in `errors` — they do not fail the whole request.
Re-appending an identical record is idempotent (counted as accepted, not written twice).

**Limits and preconditions:**
- At most 1000 records per request. Larger imports should use the file-upload flow.
- The dataset must be V4 and have a schema defined.
- Rejected with `409 Conflict` while a dataset import or a schema migration is in progress.

If the dataset is attached to any batches with `auto_sync_enabled`, a sync is triggered
automatically for the newly written datapoints.

## Path parameters

- `dataset_id` string, uuid, required

## Headers

- `Authorization` string, required

## Request body

- string

## Response `200`

Append processed. Returns per-request accepted/rejected counts. A `200` is returned even
when some (or all) records were rejected — inspect `rejected` and `errors`.

- DatasetAppendResult — Result of a synchronous append to a V4 dataset (`POST /datasets/{dataset_id}/datapoints`). `accepted` counts records that passed validation (newly written plus idempotent duplicates); `rejected` counts records that failed parsing or schema validation, each detailed in `errors`.
  - `accepted` integer, required — Number of records that passed validation (newly written or idempotent duplicates).
  - `rejected` integer, required — Number of records rejected. Equal to the length of `errors`.
  - `errors` DatasetAppendError[], required — Record-level rejections. Empty when every record was accepted.
    - `record_index` integer, required — One-based index of the rejected non-blank JSONL record in the append request body.
    - `field` string, required — The schema field key that caused the rejection. The special value `_raw` indicates a whole-record parse failure (for example malformed JSON) rather than a field-level error.
    - `reason` string, required — Human-readable description of why the record was rejected.

## Other responses

- `400` — Bad request — missing body, CSV payload, empty JSONL, too many records, a non-V4 dataset, or a dataset with no schema.
- `403` — Forbidden — the user does not have access to the dataset's workspace.
- `404` — Dataset not found
- `409` — Conflict — a dataset import or a schema migration is in progress. Retry once it completes.

---

[API](https://skmtc.net/prolific/apis/api-reference.md) · [All operations](https://skmtc.net/prolific/apis/api-reference/llms.txt) · [OpenAPI document](https://skmtc-service-staging.skmtc.workers.dev/v1/apis/prolific/api-reference/versions/dc6f073a9827/schema)
