---
title: "Sample records before importing them"
method: POST
path: "/table-sources/preview/"
tags: ["table-sources"]
---

# Sample records before importing them

`POST /table-sources/preview/`

## Request

- Base URL: `https://api.getoneprofile.ai` (the document declares no server; this is the origin it was published from)
- URL: `https://api.getoneprofile.ai/table-sources/preview/`
- Auth: one of:
  - API key in header `X-API-Key`
  - HTTP bearer

Fetch a page of records and report what is in them: the fields they carry, example values, and which identifier rows would be matched on across refreshes.

NOTHING is created here. Review it, then POST to the create endpoint.

`fields` merges what the sampled records actually contained with what the provider says a record of this type can carry, so a field every sampled record happens to leave empty is still offered.

## Request body

- TableSourcePreviewRequestSchema: What to sample.
  - `integration_id` string, uuid, required: The connected integration to sample.
  - `record_type` string, required: Which object to sample.

## Response `200`

Successful Response

- TableSourcePreviewResponseSchema: A sample of the records an import would bring in, and the fields inside them. Nothing is created here: no table, no column, no row. Review it, then POST to the create endpoint to build the table.
  - `fields` SourceFieldSchema[], required: Sampled and declared fields.
    - `declared` boolean, required: True when the provider lists this field in its own schema. A declared field with no sample value is one every sampled record left empty, still promotable.
    - `label` string, required: Humanized name, for a column header.
    - `path` string, required: Dotted path into the object; ready for a formula.
    - `property_type` 'string' | 'integer' | 'float' | 'boolean' | 'datetime' | 'date' | 'list' | 'dict', required: Type of a property. Used while creating/updating/deleting properties.
    - `sample_value` string, nullable, required: An example from the sampled records.
  - `identity_field` string, nullable, required: The recommended key of the record's ids to match rows on across refreshes: one the tool sets itself where it says which those are. Null means the provider returned nothing usable, and the import cannot proceed.
  - `identity_field_choices` string[], required: Every id key rows could be matched on: present on all sampled records, and no two records share a value.
  - `identity_field_options` IdentityFieldOptionSchema[], required: Every id key the sample carries, usable or not, with how many records have it, whether values repeat, and whether people can edit it.
    - `editable` boolean, nullable, required: True when people can edit this field in the tool, so an edited record comes back as a new row; false when the tool sets it and it never changes; null when the tool does not say.
    - `field` string, required: The key, as the tool names it. Send it as identity_field.
    - `filled` integer, required: How many sampled records carry a value for it.
    - `label` string, required: The key's name for a person to read, e.g. 'Record ID'.
    - `problem` 'missing' | 'shared' | 'inexact', required: Why a key cannot match rows. ``MISSING`` and ``SHARED`` are facts about values: some records (or rows) have none, or two different ones hold the same. ``INEXACT`` is about how a value is stored: only text and whole numbers come back out of a row's stored record exactly as the provider sends them, and re-keying stored rows on anything else would match nothing on the next refresh.
    - `sampled` integer, required: How many records were sampled.
    - `unique` boolean, required: Whether no two different sampled records share a value.
  - `integration_id` string, uuid, required
  - `integration_type` string, required
  - `record_type` string, required
  - `sample_records` object[], required: The sampled records themselves.
  - `suggested_display_paths` string[], required: Fields the create step would give their own column.
  - `supports_incremental` boolean, required: Whether the provider can return only records changed since a given time. When false every refresh re-lists everything.

## Other responses

- `401`: Unauthorized
- `403`: Forbidden
- `404`: Integration not found
- `422`: Invalid request made to the API.
- `500`: Internal server error.
- `502`: Bad gateway error.
- `503`: Service unavailable.

---

[API](https://skmtc.dev/getoneprofile/apis/api-reference-oneprofile.md) · [All operations](https://skmtc.dev/getoneprofile/apis/api-reference-oneprofile/llms.txt) · [OpenAPI document](https://skmtc.dev/getoneprofile/apis/api-reference-oneprofile/revisions/4a6bd71e3f02?raw)
