> ## Documentation Index
> Fetch the complete documentation index at: https://docs.landfall.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Datalinks.api

# datalinks.api package

### *class* datalinks.api.DataLinksAPI(config=None)

Bases: `object`

Class for interfacing with the DataLinks API.

Provides methods for ingesting data, managing namespaces, and querying data
from DataLinks. Designed to interact with a configurable
backend, providing flexibility for deployment environments.

* **Variables:**
  **config** – Configuration object containing API key, host, index, namespace,
  and object name.

#### ingest(data, inference\_steps=None, entity\_resolution=None, batch\_size=0, max\_attempts=3, curate=None, data\_description=None, schema\_definition=None, additional\_instructions=None)

Ingests data into the namespace by batching the given data and performing multiple retries
in case of failures. This function sends data in chunks (batches), to be processed through configured
inference steps, and to resolve entities based on the provided configuration. If a batch fails, it
is retried up to a maximum number of attempts.

* **Parameters:**
  * **data** (`List`\[`Dict`\[`str`, `Any`]]) – List of dictionaries, where each dictionary represents a data block to be ingested.
  * **inference\_steps** ([`Pipeline`](datalinks#datalinks.pipeline.Pipeline) | `None`) – Pipeline of inference steps to be applied for processing the data. If None the data will be ingested as is.
  * **entity\_resolution** ([`MatchTypeConfig`](datalinks#datalinks.links.MatchTypeConfig) | `None`) – Configuration specifying how entity resolution is to be performed.
  * **batch\_size** – Number of data blocks to be included in each batch. Defaults to the size of the
    entire dataset if not provided.
  * **max\_attempts** – Maximum number of retry attempts for failed batches. Defaults to the
    provided constant MAX\_INGEST\_ATTEMPTS.
  * **curate** (*Optional* \*\[\**bool* *]*) – If `True`, automatically curate ontology links after ingestion.
  * **data\_description** (*Optional* \*\[\**str* *]*) – Free-text description of the dataset to guide the AI during ingestion.
  * **schema\_definition** (*Optional* \*\[\**Dict* \*\[\**str* *,* *str* *]* *]*) – Field-name-to-description mapping to guide the AI in structuring extracted data.
  * **additional\_instructions** (*Optional* \*\[\**str* *]*) – Additional free-text instructions to guide the AI during ingestion.
* **Return type:**
  [`IngestionResult`](#datalinks.api.datalinks.IngestionResult)
* **Returns:**
  An IngestionResult object containing lists of successfully ingested data blocks and
  data blocks that failed to be ingested.

#### create\_space(is\_private=None, data\_description=None, schema\_definition=None)

Creates a new space. This function sends a POST request to create a namespace.
Information about the namespace creation will be logged, including the HTTP
status code and response reason. A space that already exists is left alone
and reported as success.

#### Versionchanged

Changed in version 1.2.13: `is_private` is ignored. Public datasets have been removed; every
space is private and access is granted per user with
[`share_dataset_access()`](#datalinks.api.DataLinksAPI.share_dataset_access) / [`share_namespace_access()`](#datalinks.api.DataLinksAPI.share_namespace_access).

* **Parameters:**
  * **is\_private** (*Optional* \*\[\**bool* *]*) – Ignored; see the note above.
  * **data\_description** (*Optional* \*\[\**str* *]*) – Free-text description of the dataset (max 10,000 chars).
  * **schema\_definition** (*Optional* \*\[\**Dict* \*\[\**str* *,* *str* *]* *]*) – Field-name-to-description mapping to guide the AI in structuring data.
* **Return type:**
  `None`
* **Returns:**
  None
* **Raises:**
  **HTTPError** – If the HTTP request fails due to connectivity issues or
  server-side problems.

#### update\_infer\_definition(data\_description=None, schema\_definition=None)

Update the saved inference definition for the configured dataset.

The inference definition is used automatically on future ingest calls to guide
field extraction and normalization.

* **Parameters:**
  * **data\_description** (*Optional* \*\[\**str* *]*) – Free-text description of the dataset (max 10,000 chars).
  * **schema\_definition** (*Optional* \*\[\**Dict* \*\[\**str* *,* *str* *]* *]*) – Field-name-to-description mapping to guide the AI in
    structuring extracted data.
* **Raises:**
  [**DataLinksRequestError**](#datalinks.api.DataLinksRequestError) – If the HTTP request fails.
* **Return type:**
  `None`

#### infer\_dataset\_description(sample, model=None, provider=None, current\_description=None, current\_schema=None)

Ask an agent to infer a data description and field schema from sampled data.

* **Parameters:**
  * **sample** (*Dataset*) – A sample of data rows to analyse.
  * **model** (*Optional* \*\[\**str* *]*) – LLM model name.
  * **provider** (*Optional* \*\[\**str* *]*) – LLM provider (e.g. `"openai"`, `"ollama"`).
  * **current\_description** (*Optional* \*\[\**str* *]*) – Existing description to refine.
  * **current\_schema** (*Optional* \*\[\**Dict* \*\[\**str* *,* *str* *]* *]*) – Existing field schema to refine (field → description mapping).
* **Returns:**
  Inferred `dataDescription` and `fieldDefinition`.
* **Return type:**
  Dict
* **Raises:**
  [**DataLinksRequestError**](#datalinks.api.DataLinksRequestError) – If the HTTP request fails.

#### update\_sort\_order(order)

Update the display order of columns for the configured dataset.

* **Parameters:**
  **order** (*List* \*\[\**str* *]*) – Ordered list of all column names in the desired sequence.
* **Raises:**
  [**DataLinksRequestError**](#datalinks.api.DataLinksRequestError) – If the HTTP request fails.
* **Return type:**
  `None`

#### prepare\_multipart\_upload(filename, size)

Initiate a multipart upload and receive presigned URLs for each part.

Use this for large files. Upload each part directly to its presigned URL,
then call [`finish_multipart_upload()`](#datalinks.api.DataLinksAPI.finish_multipart_upload) with the returned ETags.

* **Parameters:**
  * **filename** (*str*) – Name of the file being uploaded.
  * **size** (*int*) – File size in bytes.
* **Returns:**
  Response containing `uploadId`, `key`, and presigned part URLs.
* **Return type:**
  Dict
* **Raises:**
  [**DataLinksRequestError**](#datalinks.api.DataLinksRequestError) – If the HTTP request fails.

#### finish\_multipart\_upload(upload\_id, key, parts, name=None, inference\_steps=None, entity\_resolution=None)

Complete a multipart upload after all parts have been uploaded.

* **Parameters:**
  * **upload\_id** (*str*) – Upload ID from [`prepare_multipart_upload()`](#datalinks.api.DataLinksAPI.prepare_multipart_upload).
  * **key** (*str*) – S3 object key from [`prepare_multipart_upload()`](#datalinks.api.DataLinksAPI.prepare_multipart_upload).
  * **parts** (*List* \*\[\**Dict* \*\[\**str* *,* *Any* *]* *]*) – List of completed parts, each with `partNumber` (int) and
    `etag` (str) returned by S3.
  * **name** (*Optional* \*\[\**str* *]*) – Optional label for the ingestion (e.g. original filename).
  * **inference\_steps** (*Optional* *\[*[*Pipeline*](datalinks#datalinks.pipeline.Pipeline) *]*) – Pipeline of inference steps to apply to the uploaded
    file during ingestion. If `None` the file is ingested as is.
  * **entity\_resolution** (*Optional* *\[*[*MatchTypeConfig*](datalinks#datalinks.links.MatchTypeConfig) *]*) – Configuration specifying how entity resolution is to
    be performed on the uploaded file.
* **Returns:**
  Ingestion result from the server.
* **Return type:**
  Dict
* **Raises:**
  [**DataLinksRequestError**](#datalinks.api.DataLinksRequestError) – If the HTTP request fails.

#### abort\_multipart\_upload(upload\_id, key)

Abort a multipart upload and clean up partial data.

* **Parameters:**
  * **upload\_id** (*str*) – Upload ID from [`prepare_multipart_upload()`](#datalinks.api.DataLinksAPI.prepare_multipart_upload).
  * **key** (*str*) – S3 object key from [`prepare_multipart_upload()`](#datalinks.api.DataLinksAPI.prepare_multipart_upload).
* **Raises:**
  [**DataLinksRequestError**](#datalinks.api.DataLinksRequestError) – If the HTTP request fails.
* **Return type:**
  `None`

#### list\_ingestions(page\_size=25)

List ingestion attempts for the configured dataset, most recent first.

* **Parameters:**
  **page\_size** (*int*) – Number of records to return (1-100, default 25).
* **Return type:**
  `Optional`\[`List`\[[`ListIngestionsResponseDataItem`](datalinks#datalinks.models.ListIngestionsResponseDataItem)]]
* **Returns:**
  Ingestion attempts, or None on failure.

#### wait\_for\_ingestion(ingestion\_id, poll\_interval=5, timeout=1200)

Poll until the given ingestion reaches a terminal status.

Polls [`list_ingestions()`](#datalinks.api.DataLinksAPI.list_ingestions) every *poll\_interval* seconds until the
ingestion with *ingestion\_id* is no longer in a pending/processing
state, or until *timeout* seconds have elapsed.

* **Parameters:**
  * **ingestion\_id** (*str*) – Ingestion ID returned by [`finish_multipart_upload()`](#datalinks.api.DataLinksAPI.finish_multipart_upload).
  * **poll\_interval** (*int*) – Seconds between polls (default 5).
  * **timeout** (*int*) – Maximum seconds to wait before raising (default 600).
* **Return type:**
  [`ListIngestionsResponseDataItem`](datalinks#datalinks.models.ListIngestionsResponseDataItem)
* **Returns:**
  The final ingestion record.
* **Raises:**
  * **TimeoutError** – If *timeout* is exceeded before a terminal status.
  * [**DataLinksRequestError**](#datalinks.api.DataLinksRequestError) – If polling requests fail.

#### get\_dataset\_info()

Retrieve metadata for the configured dataset.

* **Return type:**
  `Optional`\[[`DatasetResponse`](datalinks#datalinks.models.DatasetResponse)]
* **Returns:**
  The dataset and its metadata, or None on failure.

#### delete\_dataset()

Permanently delete the configured dataset, including all data, links, and metadata.

This action is irreversible (balefire).

* **Raises:**
  [**DataLinksRequestError**](#datalinks.api.DataLinksRequestError) – If the HTTP request fails.
* **Return type:**
  `None`

#### rename\_dataset(new\_name)

Rename the configured dataset.

* **Parameters:**
  **new\_name** (*str*) – The new dataset name.
* **Raises:**
  [**DataLinksRequestError**](#datalinks.api.DataLinksRequestError) – If the HTTP request fails.
* **Return type:**
  `None`

#### clear\_dataset()

Remove all data and links from the configured dataset.

The dataset itself (metadata, schema) is preserved. This action is irreversible.

* **Raises:**
  [**DataLinksRequestError**](#datalinks.api.DataLinksRequestError) – If the HTTP request fails.
* **Return type:**
  `None`

#### add\_link(from\_namespace, from\_dataset, from\_column, to\_namespace, to\_dataset, to\_column, match\_type, options=None)

Create a manual link between two dataset columns.

* **Parameters:**
  * **from\_namespace** (`str`) – Source namespace.
  * **from\_dataset** (`str`) – Source dataset name.
  * **from\_column** (`str`) – Source column name.
  * **to\_namespace** (`str`) – Target namespace.
  * **to\_dataset** (`str`) – Target dataset name.
  * **to\_column** (`str`) – Target column name.
  * **match\_type** (`str`) – Match type — `"ExactMatch"` or `"GeoMatch"`.
  * **options** (`Optional`\[`Dict`\[`str`, `Any`]]) – Optional match configuration (e.g. `minDistinct`, `distance`).
* **Returns:**
  True if the link was successfully created, False if already exists. None if failure.
* **Return type:**
  bool
* **Raises:**
  [**DataLinksRequestError**](#datalinks.api.DataLinksRequestError) – If the HTTP request fails.

#### preview\_links(data, entity\_resolution=None)

Preview what recalculating links would produce without saving changes.

* **Parameters:**
  * **data** (*Dataset*) – Array of ontology data objects (e.g. from [`query_data()`](#datalinks.api.DataLinksAPI.query_data)).
  * **entity\_resolution** (*Optional* *\[*[*MatchTypeConfig*](datalinks#datalinks.links.MatchTypeConfig) *]*) – Optional link matching configuration.
* **Return type:**
  `Optional`\[`List`\[[`ApiLink`](datalinks#datalinks.models.ApiLink)]]
* **Returns:**
  The previewed links, or None on failure.
* **Raises:**
  [**DataLinksRequestError**](#datalinks.api.DataLinksRequestError) – If the HTTP request fails.

#### rebuild\_links(data, entity\_resolution=None)

Recalculate links for the configured dataset based on current data.

* **Parameters:**
  * **data** (*Dataset*) – Array of ontology data objects (e.g. from [`query_data()`](#datalinks.api.DataLinksAPI.query_data)).
  * **entity\_resolution** (*Optional* *\[*[*MatchTypeConfig*](datalinks#datalinks.links.MatchTypeConfig) *]*) – Optional link matching configuration.
* **Return type:**
  `Optional`\[`List`\[[`ApiLink`](datalinks#datalinks.models.ApiLink)]]
* **Returns:**
  The rebuilt links, or None on failure.
* **Raises:**
  [**DataLinksRequestError**](#datalinks.api.DataLinksRequestError) – If the HTTP request fails.

#### load\_links()

Retrieve active and suggested links for the configured dataset.

* **Return type:**
  `Optional`\[`List`\[[`ApiLink`](datalinks#datalinks.models.ApiLink)]]
* **Returns:**
  The links, or None on failure.

#### list\_datasets(namespace=None)

Retrieves the list of datasets for the user, optionally filtered by a specific namespace.

* **Parameters:**
  **namespace** (*Optional* \*\[\**AnyStr* *]*) – Optional namespace to filter the datasets by.
  If provided, only datasets associated with the given
  namespace will be returned. If not provided, all datasets are
  retrieved.
* **Return type:**
  `Optional`\[`List`\[[`ApiDatasetDescription`](datalinks#datalinks.models.ApiDatasetDescription)]]
* **Returns:**
  The datasets, or None on failure.

#### query\_data(query=None, is\_natural\_language=False, model=None, provider=None, include\_metadata=False, explain=False, , username='self')

Queries data from a specified data source and processes the response.

The method allows querying with a specific query string or with a wildcard
(“\*”) for all data. The response from the query can be filtered to exclude
metadata fields if include\_metadata is set to False. Metadata fields are
identified by key names starting with an underscore.

* **Parameters:**
  * **query** (*str*) – The query string to use for fetching data. Defaults to “\*”,
    which retrieves all data.
  * **is\_natural\_language** (*bool*) – If True, the query is treated as a natural language query.
  * **model** (*str*) – The model name to use for inference.
  * **provider** (*str*) – The provider of the LLM model (ollama, openai, etc)
  * **include\_metadata** (*bool*) – Specifies whether to include metadata fields in
    the returned data. Defaults to False.
  * **explain** (*bool*) – If True, request an explanation of how the query was resolved.
  * **username** (*str*) – Owner of the namespace being queried.
* **Returns:**
  A list of records represented as dictionaries, or None if the query
  fails or an exception occurs during the request.
* **Return type:**
  List\[Dict] | None
* **Raises:**
  [**DataLinksRequestError**](#datalinks.api.DataLinksRequestError) – If a transport-level error occurs.

#### ask(query, model=None, provider=None, helper\_prompt=None, , username='self', stage\_models=None, conversation\_id=None, web\_search=None)

Talk to your data with natural language using the DataLinks AutoRAG agent.

Streams the agent’s reasoning and final answer as Server-Sent Events. Events are
yielded in order: one `plan` event, one or more `step` events, then either an
`answer` event or an `error` event.

* **Parameters:**
  * **query** (*str*) – The natural language question to answer.
  * **model** (*str*) – The model name to use for inference.
  * **provider** (*str*) – The LLM provider (e.g. `openai`, `ollama`).
  * **helper\_prompt** (*str*) – Optional custom system prompt.
  * **stage\_models** (*Optional* \*\[\**Dict* \*\[\**str* *,* *Dict* \*\[\**str* *,* *str* *]* *]* *]*) – Per-stage model overrides, keyed by stage (`plan`,
    `query`, `answer`), each mapping to a dict with optional `model`
    and `provider`. An override wins over the run-wide
    `model`/`provider` *as a whole*: a stage that sets only `model`
    does not inherit the run-wide `provider` but falls back to the
    deployment default, so set both fields or neither.
  * **conversation\_id** (*Optional* \*\[\**str* *]*) – Existing conversation to continue. Omit to start a new
    one; its id arrives on the `run-started` event.
  * **web\_search** (*Optional* \*\[\**bool* *]*) – Pass False to disable web search. `True` is
    equivalent to omitting it — there is no way to force-enable a
    deployment that has web search switched off.
  * **username** (*str*) – Owner of the namespace being queried.
* **Returns:**
  An iterator of [`AskEvent`](#datalinks.api.AskEvent) objects, also exposing the
  streaming response once it is open.
* **Return type:**
  [AskStream](#datalinks.api.AskStream)
* **Raises:**
  [**DataLinksRequestError**](#datalinks.api.DataLinksRequestError) – If the HTTP request fails.

#### Versionchanged

Changed in version 1.2.15: Returns [`AskStream`](#datalinks.api.AskStream) rather than a bare iterator.

#### preview\_ingest(data, inference\_steps=None)

Process data through the ingestion pipeline without saving it to a dataset.

* **Parameters:**
  * **data** (*Dataset*) – List of data records to preview.
  * **inference\_steps** (*Optional* *\[*[*Pipeline*](datalinks#datalinks.pipeline.Pipeline) *]*) – Optional pipeline of inference steps to apply.
* **Return type:**
  `Optional`\[`List`\[`Dict`\[`str`, `Any`]]]
* **Returns:**
  The processed preview records, or None on failure.
* **Raises:**
  [**DataLinksRequestError**](#datalinks.api.DataLinksRequestError) – If the HTTP request fails.

#### infer\_schema(sample, model=None, provider=None, current\_schema=None)

Ask an agent to infer a field type schema from sampled data.

* **Parameters:**
  * **sample** (*Dataset*) – A sample of data rows to analyse.
  * **model** (*Optional* \*\[\**str* *]*) – LLM model name.
  * **provider** (*Optional* \*\[\**str* *]*) – LLM provider (e.g. `"openai"`, `"ollama"`).
  * **current\_schema** (*Optional* \*\[\**Dict* \*\[\**str* *,* *str* *]* *]*) – Existing field schema to refine (field → description mapping).
* **Return type:**
  `Optional`\[[`InferredSchemaResponse`](datalinks#datalinks.models.InferredSchemaResponse)]
* **Returns:**
  The inferred schema, mapping field names to their types, or None
  on failure.
* **Raises:**
  [**DataLinksRequestError**](#datalinks.api.DataLinksRequestError) – If the HTTP request fails.

#### retry\_ingestion(ingestion\_id)

Retry a failed ingestion by creating a new ingestion record from the original.

* **Parameters:**
  **ingestion\_id** (*str*) – The ID of the ingestion to retry.
* **Return type:**
  `Optional`\[[`CreatedIngestionTrackingResponse`](datalinks#datalinks.models.CreatedIngestionTrackingResponse)]
* **Returns:**
  The new ingestion record, whose `id` is a `UUID`; or None on
  failure.
* **Raises:**
  [**DataLinksRequestError**](#datalinks.api.DataLinksRequestError) – If the HTTP request fails.

#### mark\_ingestion\_seen(ingestion\_id)

Mark an ingestion as seen, updating its `seenAt` timestamp.

* **Parameters:**
  **ingestion\_id** (*str*) – The ID of the ingestion to mark as seen.
* **Raises:**
  [**DataLinksRequestError**](#datalinks.api.DataLinksRequestError) – If the HTTP request fails.
* **Return type:**
  `None`

#### autorag(query, model=None, provider=None, helper\_prompt=None, , username='self', stage\_models=None, conversation\_id=None, web\_search=None)

Answer a natural language question using the AutoRAG agent (non-streaming).

Returns the final answer and all intermediate steps once the agent completes.
For incremental streaming results, use [`ask()`](#datalinks.api.DataLinksAPI.ask) instead.

* **Parameters:**
  * **query** (*str*) – The natural language question to answer.
  * **model** (*Optional* \*\[\**str* *]*) – LLM model name.
  * **provider** (*Optional* \*\[\**str* *]*) – LLM provider (e.g. `"openai"`, `"ollama"`).
  * **helper\_prompt** (*Optional* \*\[\**str* *]*) – Optional custom system prompt.
  * **stage\_models** (*Optional* \*\[\**Dict* \*\[\**str* *,* *Dict* \*\[\**str* *,* *str* *]* *]* *]*) – Per-stage model overrides, keyed by stage (`plan`,
    `query`, `answer`), each mapping to a dict with optional `model`
    and `provider`. An override wins over the run-wide
    `model`/`provider` *as a whole*: a stage that sets only `model`
    does not inherit the run-wide `provider` but falls back to the
    deployment default, so set both fields or neither.
  * **conversation\_id** (*Optional* \*\[\**str* *]*) – Existing conversation to continue. Omit to start a new one.
  * **web\_search** (*Optional* \*\[\**bool* *]*) – Pass False to disable web search. `True` is
    equivalent to omitting it — there is no way to force-enable a
    deployment that has web search switched off.
  * **username** (*str*) – Owner of the namespace being queried.
* **Returns:**
  Dict with `response` (str) and `steps` (list) keys, also
  carrying the response `headers`.
* **Return type:**
  [AutoRagResult](#datalinks.api.AutoRagResult)
* **Raises:**
  [**DataLinksRequestError**](#datalinks.api.DataLinksRequestError) – If the request fails, the server answers
  non-2xx, or the body is not a JSON object.

#### Versionchanged

Changed in version 1.2.15: Raises on failure instead of returning `None`, and returns
[`AutoRagResult`](#datalinks.api.AutoRagResult) rather than a plain dict.

#### request\_cleaning(prompts, output\_namespace, output\_dataset\_name)

Request a cleaning job for the configured dataset.

* **Parameters:**
  * **prompts** (*List* \*\[\**str* *]*) – 1–10 prompts describing each cleaning step in order.
  * **output\_namespace** (*str*) – Target namespace for the cleaned dataset.
  * **output\_dataset\_name** (*str*) – Name for the cleaned dataset (must be unused in target namespace).
* **Returns:**
  The `cleaningTaskId` UUID string, or None on failure.
* **Return type:**
  Optional\[str]
* **Raises:**
  [**DataLinksRequestError**](#datalinks.api.DataLinksRequestError) – If the HTTP request fails.

#### get\_cleaning\_code(cleaning\_task\_id)

Retrieve code files generated by the cleaning agent for a task.

* **Parameters:**
  **cleaning\_task\_id** (*str*) – UUID of the cleaning task.
* **Returns:**
  List of dicts with `name` and `content` keys, or None on failure.
* **Return type:**
  Optional\[List\[Dict]]
* **Raises:**
  [**DataLinksRequestError**](#datalinks.api.DataLinksRequestError) – If the HTTP request fails.

#### get\_ontology()

Load the ontology (active links) for the configured dataset.

* **Return type:**
  `Optional`\[`List`\[[`ApiLink`](datalinks#datalinks.models.ApiLink)]]
* **Returns:**
  The active links, or None if no ontology exists or the request fails.
* **Raises:**
  [**DataLinksRequestError**](#datalinks.api.DataLinksRequestError) – If the HTTP request fails.

#### save\_ontology(add=None, remove=None)

Save (update) the ontology for the configured dataset.

* **Parameters:**
  * **add** (`Optional`\[`Sequence`\[`Union`\[[`ApiLink`](datalinks#datalinks.models.ApiLink), `Mapping`\[`str`, `Any`]]]]) – Links to add, as returned by [`get_ontology()`](#datalinks.api.DataLinksAPI.get_ontology) or as dicts.
  * **remove** (`Optional`\[`Sequence`\[`Union`\[[`ApiLink`](datalinks#datalinks.models.ApiLink), `Mapping`\[`str`, `Any`]]]]) – Links to remove, in the same form as `add`.
* **Raises:**
  [**DataLinksRequestError**](#datalinks.api.DataLinksRequestError) – If the HTTP request fails.
* **Return type:**
  `None`

#### curate\_links(namespace=None, dataset=None, model=None, provider=None, activate=False)

Run the OntologyCurator agent to analyse computed links and optionally activate them.

When `activate=False` (default), the curated links are returned without being saved.
When `activate=True`, the curated links are added to the ontology.

* **Parameters:**
  * **namespace** (*Optional* \*\[\**str* *]*) – Namespace to curate. Defaults to the configured namespace.
  * **dataset** (*Optional* \*\[\**str* *]*) – Dataset to curate. If omitted, all datasets in the namespace are curated.
  * **model** (*Optional* \*\[\**str* *]*) – LLM model name.
  * **provider** (*Optional* \*\[\**str* *]*) – LLM provider (e.g. `"openai"`, `"anthropic"`).
  * **activate** (*bool*) – If `True`, add curated links to the ontology.
* **Return type:**
  `Optional`\[[`CurateLinkResponse`](datalinks#datalinks.models.CurateLinkResponse)]
* **Returns:**
  The curation outcome — `datasets_processed`, `total_selected`,
  and `curated_links` when `activate` is `False`; or None on failure.
* **Raises:**
  [**DataLinksRequestError**](#datalinks.api.DataLinksRequestError) – If the HTTP request fails.

#### rename\_namespace(new\_name)

Rename the configured namespace.

* **Parameters:**
  **new\_name** (*str*) – The new namespace name.
* **Raises:**
  [**DataLinksRequestError**](#datalinks.api.DataLinksRequestError) – If the HTTP request fails.
* **Return type:**
  `None`

#### list\_namespaces(user='self')

Retrieve namespaces for a user.

* **Parameters:**
  **user** (*str*) – Username or `"self"` for the current user.
* **Return type:**
  `Optional`\[`List`\[[`ApiNamespace`](datalinks#datalinks.models.ApiNamespace)]]
* **Returns:**
  The namespaces, or None on failure.
* **Raises:**
  [**DataLinksRequestError**](#datalinks.api.DataLinksRequestError) – If the HTTP request fails.

#### list\_all\_datasets\_schema()

Retrieve all datasets visible to the authenticated user (schema endpoint).

* **Return type:**
  `Optional`\[`List`\[[`ApiDatasetDescription`](datalinks#datalinks.models.ApiDatasetDescription)]]
* **Returns:**
  The datasets, or None on failure.
* **Raises:**
  [**DataLinksRequestError**](#datalinks.api.DataLinksRequestError) – If the HTTP request fails.

#### list\_datasets\_in\_namespace\_schema(namespace=None, user='self')

Retrieve datasets within a specific namespace (schema endpoint).

* **Parameters:**
  * **namespace** (*Optional* \*\[\**str* *]*) – Namespace to list. Defaults to the configured namespace.
  * **user** (*str*) – Username or `"self"` for the current user.
* **Return type:**
  `Optional`\[`List`\[[`ApiDatasetDescription`](datalinks#datalinks.models.ApiDatasetDescription)]]
* **Returns:**
  The datasets, or None on failure.
* **Raises:**
  [**DataLinksRequestError**](#datalinks.api.DataLinksRequestError) – If the HTTP request fails.

#### get\_current\_user()

Resolve the identity of the user owning the configured API key.

* **Return type:**
  `Optional`\[[`CurrentUserResponse`](datalinks#datalinks.models.CurrentUserResponse)]
* **Returns:**
  The user’s `id` and `username`, plus nullable `name` and
  `email`; or None on failure.

#### list\_tokens()

List all API tokens for the authenticated user.

* **Return type:**
  `Optional`\[`List`\[[`UserToken`](datalinks#datalinks.models.UserToken)]]
* **Returns:**
  The tokens, or None on failure — including the 403 a restricted
  token gets, since it may not manage API tokens.

#### add\_token(name, expires\_at=None, access\_restricted\_to=None)

Create a new API token for the authenticated user.

* **Parameters:**
  * **name** (*str*) – Display name for the token.
  * **expires\_at** (*Optional* \*\[\**str* *]*) – Optional expiry timestamp (ISO 8601 string).
  * **access\_restricted\_to** (`Optional`\[`Sequence`\[`Union`\[[`TokenPermissionEntry`](datalinks#datalinks.models.TokenPermissionEntry), `Mapping`\[`str`, `Any`]]]]) – Permission entries restricting access, as returned
    by [`list_token_permissions()`](#datalinks.api.DataLinksAPI.list_token_permissions) or as dicts with `username`,
    `namespace` and optionally `dataset`.
* **Return type:**
  `Optional`\[[`UserToken`](datalinks#datalinks.models.UserToken)]
* **Returns:**
  The created token, including the `token` secret, or None on failure.
* **Raises:**
  [**DataLinksRequestError**](#datalinks.api.DataLinksRequestError) – If the HTTP request fails.

#### delete\_token(token\_id)

Delete an API token.

* **Parameters:**
  **token\_id** (*str*) – ID of the token to delete.
* **Raises:**
  [**DataLinksRequestError**](#datalinks.api.DataLinksRequestError) – If the HTTP request fails.
* **Return type:**
  `None`

#### list\_token\_permissions(token\_id)

List permissions assigned to a token.

* **Parameters:**
  **token\_id** (*str*) – ID of the token.
* **Return type:**
  `Optional`\[[`TokenPermissionsResponse`](datalinks#datalinks.models.TokenPermissionsResponse)]
* **Returns:**
  The token’s permissions, or None on failure.
* **Raises:**
  [**DataLinksRequestError**](#datalinks.api.DataLinksRequestError) – If the HTTP request fails.

#### get\_usage\_history(on\_or\_after=None, before=None, page\_size=25, page\_cursor=None)

Retrieve historical usage data for the authenticated user.

* **Parameters:**
  * **on\_or\_after** (*Optional* \*\[\**str* *]*) – Return records on or after this ISO 8601 timestamp.
  * **before** (*Optional* \*\[\**str* *]*) – Return records before this ISO 8601 timestamp.
  * **page\_size** (*int*) – Number of records per page (default 25).
  * **page\_cursor** (`Union`\[[`UserUsageHistoryCursor`](datalinks#datalinks.models.UserUsageHistoryCursor), `Mapping`\[`str`, `Any`], `None`]) – `meta.page_cursor` from a previous response.
* **Return type:**
  `Optional`\[[`UserUsageHistoryResponse`](datalinks#datalinks.models.UserUsageHistoryResponse)]
* **Returns:**
  The usage history page, or None on failure.
* **Raises:**
  [**DataLinksRequestError**](#datalinks.api.DataLinksRequestError) – If the HTTP request fails.

#### get\_usage\_by\_day(on\_or\_after=None, before=None, timezone='UTC')

Retrieve usage data aggregated by day for the authenticated user.

* **Parameters:**
  * **on\_or\_after** (*Optional* \*\[\**str* *]*) – Return records on or after this ISO 8601 timestamp.
  * **before** (*Optional* \*\[\**str* *]*) – Return records before this ISO 8601 timestamp.
  * **timezone** (*str*) – Timezone for date aggregation (e.g. `"America/New_York"`). Defaults to UTC.
* **Return type:**
  `Optional`\[[`UserUsageByDayResponse`](datalinks#datalinks.models.UserUsageByDayResponse)]
* **Returns:**
  The daily usage, in `.data` and `.meta`; or None on failure.
* **Raises:**
  [**DataLinksRequestError**](#datalinks.api.DataLinksRequestError) – If the HTTP request fails.

#### get\_agent\_run\_status(run\_id)

Get the current status of an agent run.

* **Parameters:**
  **run\_id** (*str*) – UUID of the agent run.
* **Return type:**
  `Optional`\[[`AgentRunStatusResponse`](datalinks#datalinks.models.AgentRunStatusResponse)]
* **Returns:**
  The run’s `run_id`, `agent_kind`, `question`, `status`
  (`running`/`completed`/`failed`/`expired`), `can_resume`,
  and optionally `last_node_id`, `error_message`, `result`; or
  None on failure.
* **Raises:**
  [**DataLinksRequestError**](#datalinks.api.DataLinksRequestError) – If the HTTP request fails.

#### delete\_agent\_run(run\_id)

Permanently delete an agent run and its resume checkpoint.

* **Parameters:**
  **run\_id** (*str*) – UUID of the agent run.
* **Raises:**
  [**DataLinksRequestError**](#datalinks.api.DataLinksRequestError) – If the HTTP request fails (e.g. 404 when
  the run does not exist or is not owned by the caller).
* **Return type:**
  `None`

#### submit\_agent\_run\_feedback(run\_id, , thumbs\_up, comment=None)

Rate the answer a completed agent run produced.

Resubmitting replaces the previous rating for the same run.

* **Parameters:**
  * **run\_id** (*str*) – UUID of the agent run.
  * **thumbs\_up** (*bool*) – True for a thumbs up, False for a thumbs down.
  * **comment** (*Optional* \*\[\**str* *]*) – Optional free-text comment accompanying the rating.
* **Raises:**
  [**DataLinksRequestError**](#datalinks.api.DataLinksRequestError) – If the HTTP request fails (e.g. 404 when the
  run does not exist or is not owned by the caller, 422 when it has not
  completed).
* **Return type:**
  `None`

#### resume\_agent\_run(run\_id)

Resume a previously paused or crashed agent run, streaming its events.

The first event is `run-started`, followed by the same domain events as
[`ask()`](#datalinks.api.DataLinksAPI.ask) (e.g. `plan`, `step`, `answer`). Runs that cannot be
streamed arrive as a single synthetic event instead:

> * `completed` / `expired` (HTTP 410) — yielded as an
>   `AskEvent(type="terminal", data=<body>)` whose data carries the
>   original question and, for completed runs, the rendered result.
> * `failed` (HTTP 422) — yielded as an `AskEvent` of type
>   `"terminal"`.
> * no checkpoint to resume from (HTTP 409) — yielded as an
>   `AskEvent(type="no-checkpoint", data=<body>)`. The run is untouched
>   and still in progress; poll [`get_agent_run_status()`](#datalinks.api.DataLinksAPI.get_agent_run_status) for its
>   eventual outcome.
> * not-found / not-owned (HTTP 404) — raises `DataLinksRequestError`.

* **Parameters:**
  **run\_id** (*str*) – UUID of the agent run to resume.
* **Returns:**
  An iterator of [`AskEvent`](#datalinks.api.AskEvent) objects.
* **Return type:**
  Iterator\[[AskEvent](#datalinks.api.AskEvent)]
* **Raises:**
  [**DataLinksRequestError**](#datalinks.api.DataLinksRequestError) – On 404 or transport-level failure.

#### share\_dataset\_access(username, role)

Grant another user access to the configured dataset.

Since public datasets were removed, this is how you give someone else
access. Re-sharing with a different role replaces the existing grant.

* **Parameters:**
  * **username** (*str*) – User to grant access to.
  * **role** (*str*) – `"viewer"` (read-only) or `"editor"` (read and write).
* **Raises:**
  * **ValueError** – If `role` is not a valid access level.
  * [**DataLinksRequestError**](#datalinks.api.DataLinksRequestError) – If the HTTP request fails (e.g. 403 when
    the caller does not own the dataset).
* **Return type:**
  `None`

#### revoke\_dataset\_access(username, role)

Remove a user’s access to the configured dataset.

* **Parameters:**
  * **username** (*str*) – User whose access is being removed.
  * **role** (*str*) – The granted access level to remove.
* **Raises:**
  * **ValueError** – If `role` is not a valid access level.
  * [**DataLinksRequestError**](#datalinks.api.DataLinksRequestError) – If the HTTP request fails.
* **Return type:**
  `None`

#### list\_dataset\_shares()

List the per-user grants on the configured dataset.

* **Return type:**
  `Optional`\[`List`\[[`AccessGrant`](datalinks#datalinks.models.AccessGrant)]]
* **Returns:**
  The grants, each with `username` and `role`; or None on failure.

#### share\_namespace\_access(username, role)

Grant another user access to the configured namespace.

The grant cascades to every dataset in the namespace.

* **Parameters:**
  * **username** (*str*) – User to grant access to.
  * **role** (*str*) – `"viewer"` (read-only) or `"editor"` (read and write).
* **Raises:**
  * **ValueError** – If `role` is not a valid access level.
  * [**DataLinksRequestError**](#datalinks.api.DataLinksRequestError) – If the HTTP request fails.
* **Return type:**
  `None`

#### revoke\_namespace\_access(username, role)

Remove a user’s access to the configured namespace.

* **Parameters:**
  * **username** (*str*) – User whose access is being removed.
  * **role** (*str*) – The granted access level to remove.
* **Raises:**
  * **ValueError** – If `role` is not a valid access level.
  * [**DataLinksRequestError**](#datalinks.api.DataLinksRequestError) – If the HTTP request fails.
* **Return type:**
  `None`

#### list\_namespace\_shares()

List the per-user grants on the configured namespace.

* **Return type:**
  `Optional`\[`List`\[[`AccessGrant`](datalinks#datalinks.models.AccessGrant)]]
* **Returns:**
  The grants, each with `username` and `role`; or None on failure.

#### list\_conversations(username='self', namespace=None)

List the caller’s conversations within a namespace (most-recently-updated first).

* **Parameters:**
  * **username** (*str*) – Owner username. Defaults to `"self"`.
  * **namespace** (*Optional* \*\[\**str* *]*) – Namespace to list within. Defaults to the configured namespace.
* **Return type:**
  `Optional`\[[`ConversationListResponse`](datalinks#datalinks.models.ConversationListResponse)]
* **Returns:**
  The summaries, in `.conversations`; or None on failure.
* **Raises:**
  [**DataLinksRequestError**](#datalinks.api.DataLinksRequestError) – If the HTTP request fails.

#### get\_conversation(conversation\_id)

Get a conversation and its turns (oldest first).

* **Parameters:**
  **conversation\_id** (*str*) – UUID of the conversation.
* **Return type:**
  `Optional`\[[`ConversationDetailResponse`](datalinks#datalinks.models.ConversationDetailResponse)]
* **Returns:**
  The conversation’s `id`, `title` and `turns` (each turn has
  `run_id`, `question`, `status`, and optionally `result`); or
  None on failure.
* **Raises:**
  [**DataLinksRequestError**](#datalinks.api.DataLinksRequestError) – If the HTTP request fails.

### *class* datalinks.api.AsyncDataLinksAPI(config=None)

Bases: `object`

Async counterpart of [`DataLinksAPI`](#datalinks.api.DataLinksAPI).

Method signatures mirror the sync facade — same parameter names, defaults,
and return types. Every networked method is `async def`. The streaming
`ask` method returns an [`AsyncAskStream`](#datalinks.api.AsyncAskStream) instead of an
[`AskStream`](#datalinks.api.datalinks.AskStream).

Use `async with` for guaranteed cleanup of the underlying
`httpx.AsyncClient`, or call [`aclose()`](#datalinks.api.AsyncDataLinksAPI.aclose) manually:

```default theme={null}
async with AsyncDataLinksAPI() as api:
    datasets = await api.list_datasets()
```

#### *async* aclose()

Close the underlying `httpx.AsyncClient`.

* **Return type:**
  `None`

#### *async* ingest(data, inference\_steps=None, entity\_resolution=None, batch\_size=0, max\_attempts=3, curate=None, data\_description=None, schema\_definition=None, additional\_instructions=None)

Async variant of [`DataLinksAPI.ingest()`](#datalinks.api.DataLinksAPI.ingest).

Same batching + retry semantics as the sync facade.

* **Return type:**
  [`IngestionResult`](#datalinks.api.datalinks.IngestionResult)

#### create\_space(is\_private=None, data\_description=None, schema\_definition=None)

Create a new space (see [`DataLinksAPI.create_space()`](#datalinks.api.DataLinksAPI.create_space)).

Deliberately not an `async def`: the body of a coroutine runs on
whoever resumes it, so under `asyncio.gather` the deprecation warning
below would be filed against `asyncio/events.py` instead of the
caller. Warning here, at call time, keeps the attribution right.

* **Return type:**
  `Coroutine`\[`Any`, `Any`, `None`]

#### *async* update\_infer\_definition(data\_description=None, schema\_definition=None)

* **Return type:**
  `None`

#### *async* infer\_dataset\_description(sample, model=None, provider=None, current\_description=None, current\_schema=None)

* **Return type:**
  `Dict`

#### *async* update\_sort\_order(order)

* **Return type:**
  `None`

#### *async* prepare\_multipart\_upload(filename, size)

* **Return type:**
  `Dict`

#### *async* finish\_multipart\_upload(upload\_id, key, parts, name=None, inference\_steps=None, entity\_resolution=None)

* **Return type:**
  `Dict`

#### *async* abort\_multipart\_upload(upload\_id, key)

* **Return type:**
  `None`

#### *async* list\_ingestions(page\_size=25)

* **Return type:**
  `Optional`\[`List`\[[`ListIngestionsResponseDataItem`](datalinks#datalinks.models.ListIngestionsResponseDataItem)]]

#### *async* wait\_for\_ingestion(ingestion\_id, poll\_interval=5, timeout=1200)

Async variant of [`DataLinksAPI.wait_for_ingestion()`](#datalinks.api.DataLinksAPI.wait_for_ingestion).

Polls via [`list_ingestions()`](#datalinks.api.AsyncDataLinksAPI.list_ingestions), awaiting `asyncio.sleep` between
ticks instead of blocking the event loop with `time.sleep`.

* **Return type:**
  [`ListIngestionsResponseDataItem`](datalinks#datalinks.models.ListIngestionsResponseDataItem)

#### *async* get\_dataset\_info()

* **Return type:**
  `Optional`\[[`DatasetResponse`](datalinks#datalinks.models.DatasetResponse)]

#### *async* delete\_dataset()

* **Return type:**
  `None`

#### *async* rename\_dataset(new\_name)

* **Return type:**
  `None`

#### *async* rename\_namespace(new\_name)

* **Return type:**
  `None`

#### *async* clear\_dataset()

* **Return type:**
  `None`

#### *async* add\_link(from\_namespace, from\_dataset, from\_column, to\_namespace, to\_dataset, to\_column, match\_type, options=None)

* **Return type:**
  `Optional`\[`bool`]

#### *async* preview\_links(data, entity\_resolution=None)

* **Return type:**
  `Optional`\[`List`\[[`ApiLink`](datalinks#datalinks.models.ApiLink)]]

#### *async* rebuild\_links(data, entity\_resolution=None)

* **Return type:**
  `Optional`\[`List`\[[`ApiLink`](datalinks#datalinks.models.ApiLink)]]

#### *async* load\_links()

* **Return type:**
  `Optional`\[`List`\[[`ApiLink`](datalinks#datalinks.models.ApiLink)]]

#### *async* list\_datasets(namespace=None)

* **Return type:**
  `Optional`\[`List`\[[`ApiDatasetDescription`](datalinks#datalinks.models.ApiDatasetDescription)]]

#### *async* list\_namespaces(user='self')

* **Return type:**
  `Optional`\[`List`\[[`ApiNamespace`](datalinks#datalinks.models.ApiNamespace)]]

#### *async* list\_all\_datasets\_schema()

* **Return type:**
  `Optional`\[`List`\[[`ApiDatasetDescription`](datalinks#datalinks.models.ApiDatasetDescription)]]

#### *async* list\_datasets\_in\_namespace\_schema(namespace=None, user='self')

* **Return type:**
  `Optional`\[`List`\[[`ApiDatasetDescription`](datalinks#datalinks.models.ApiDatasetDescription)]]

#### *async* query\_data(query=None, is\_natural\_language=False, model=None, provider=None, include\_metadata=False, explain=False, , username='self')

Query the configured dataset (see [`DataLinksAPI.query_data()`](#datalinks.api.DataLinksAPI.query_data)).

* **Return type:**
  `Optional`\[`List`\[`Dict`\[`str`, `Any`]]]

#### *async* autorag(query, model=None, provider=None, helper\_prompt=None, , username='self', stage\_models=None, conversation\_id=None, web\_search=None)

Answer a question with the AutoRAG agent (see [`DataLinksAPI.autorag()`](#datalinks.api.DataLinksAPI.autorag)).

* **Return type:**
  [`AutoRagResult`](#datalinks.api.datalinks.AutoRagResult)

#### ask(query, model=None, provider=None, helper\_prompt=None, , username='self', stage\_models=None, conversation\_id=None, web\_search=None)

Async SSE stream of [`DataLinksAPI.ask()`](#datalinks.api.DataLinksAPI.ask) events.

Yields [`AskEvent`](#datalinks.api.AskEvent) objects until the server closes the stream, and
exposes the response headers once the stream is open (see [`AsyncAskStream`](#datalinks.api.AsyncAskStream)).

* **Return type:**
  [`AsyncAskStream`](#datalinks.api.async_datalinks.AsyncAskStream)

#### *async* preview\_ingest(data, inference\_steps=None)

* **Return type:**
  `Optional`\[`List`\[`Dict`\[`str`, `Any`]]]

#### *async* infer\_schema(sample, model=None, provider=None, current\_schema=None)

* **Return type:**
  `Optional`\[[`InferredSchemaResponse`](datalinks#datalinks.models.InferredSchemaResponse)]

#### *async* retry\_ingestion(ingestion\_id)

* **Return type:**
  `Optional`\[[`CreatedIngestionTrackingResponse`](datalinks#datalinks.models.CreatedIngestionTrackingResponse)]

#### *async* mark\_ingestion\_seen(ingestion\_id)

* **Return type:**
  `None`

#### *async* request\_cleaning(prompts, output\_namespace, output\_dataset\_name)

* **Return type:**
  `Optional`\[`str`]

#### *async* get\_cleaning\_code(cleaning\_task\_id)

* **Return type:**
  `Optional`\[`List`\[`Dict`]]

#### *async* get\_ontology()

* **Return type:**
  `Optional`\[`List`\[[`ApiLink`](datalinks#datalinks.models.ApiLink)]]

#### *async* save\_ontology(add=None, remove=None)

* **Return type:**
  `None`

#### *async* curate\_links(namespace=None, dataset=None, model=None, provider=None, activate=False)

* **Return type:**
  `Optional`\[[`CurateLinkResponse`](datalinks#datalinks.models.CurateLinkResponse)]

#### *async* get\_current\_user()

Resolve the current user’s identity (see [`DataLinksAPI.get_current_user()`](#datalinks.api.DataLinksAPI.get_current_user)).

* **Return type:**
  `Optional`\[[`CurrentUserResponse`](datalinks#datalinks.models.CurrentUserResponse)]

#### *async* list\_tokens()

* **Return type:**
  `Optional`\[`List`\[[`UserToken`](datalinks#datalinks.models.UserToken)]]

#### *async* add\_token(name, expires\_at=None, access\_restricted\_to=None)

* **Return type:**
  `Optional`\[[`UserToken`](datalinks#datalinks.models.UserToken)]

#### *async* delete\_token(token\_id)

* **Return type:**
  `None`

#### *async* list\_token\_permissions(token\_id)

* **Return type:**
  `Optional`\[[`TokenPermissionsResponse`](datalinks#datalinks.models.TokenPermissionsResponse)]

#### *async* get\_usage\_history(on\_or\_after=None, before=None, page\_size=25, page\_cursor=None)

* **Return type:**
  `Optional`\[[`UserUsageHistoryResponse`](datalinks#datalinks.models.UserUsageHistoryResponse)]

#### *async* get\_usage\_by\_day(on\_or\_after=None, before=None, timezone='UTC')

* **Return type:**
  `Optional`\[[`UserUsageByDayResponse`](datalinks#datalinks.models.UserUsageByDayResponse)]

#### *async* get\_agent\_run\_status(run\_id)

Get the current status of an agent run (see [`DataLinksAPI.get_agent_run_status()`](#datalinks.api.DataLinksAPI.get_agent_run_status)).

* **Return type:**
  `Optional`\[[`AgentRunStatusResponse`](datalinks#datalinks.models.AgentRunStatusResponse)]

#### *async* delete\_agent\_run(run\_id)

Permanently delete an agent run and its resume checkpoint (see [`DataLinksAPI.delete_agent_run()`](#datalinks.api.DataLinksAPI.delete_agent_run)).

* **Return type:**
  `None`

#### *async* submit\_agent\_run\_feedback(run\_id, , thumbs\_up, comment=None)

Rate a completed agent run (see [`DataLinksAPI.submit_agent_run_feedback()`](#datalinks.api.DataLinksAPI.submit_agent_run_feedback)).

* **Return type:**
  `None`

#### *async* resume\_agent\_run(run\_id)

Resume an agent run, streaming its events (see [`DataLinksAPI.resume_agent_run()`](#datalinks.api.DataLinksAPI.resume_agent_run)).

* **Return type:**
  `AsyncIterator`\[[`AskEvent`](#datalinks.api.datalinks.AskEvent)]

#### *async* share\_dataset\_access(username, role)

Grant a user access to the dataset (see [`DataLinksAPI.share_dataset_access()`](#datalinks.api.DataLinksAPI.share_dataset_access)).

* **Return type:**
  `None`

#### *async* revoke\_dataset\_access(username, role)

Remove a user’s dataset access (see [`DataLinksAPI.revoke_dataset_access()`](#datalinks.api.DataLinksAPI.revoke_dataset_access)).

* **Return type:**
  `None`

#### *async* list\_dataset\_shares()

List grants on the dataset (see [`DataLinksAPI.list_dataset_shares()`](#datalinks.api.DataLinksAPI.list_dataset_shares)).

* **Return type:**
  `Optional`\[`List`\[[`AccessGrant`](datalinks#datalinks.models.AccessGrant)]]

#### *async* share\_namespace\_access(username, role)

Grant a user access to the namespace (see [`DataLinksAPI.share_namespace_access()`](#datalinks.api.DataLinksAPI.share_namespace_access)).

* **Return type:**
  `None`

#### *async* revoke\_namespace\_access(username, role)

Remove a user’s namespace access (see [`DataLinksAPI.revoke_namespace_access()`](#datalinks.api.DataLinksAPI.revoke_namespace_access)).

* **Return type:**
  `None`

#### *async* list\_namespace\_shares()

List grants on the namespace (see [`DataLinksAPI.list_namespace_shares()`](#datalinks.api.DataLinksAPI.list_namespace_shares)).

* **Return type:**
  `Optional`\[`List`\[[`AccessGrant`](datalinks#datalinks.models.AccessGrant)]]

#### *async* list\_conversations(username='self', namespace=None)

List the caller’s conversations within a namespace (see [`DataLinksAPI.list_conversations()`](#datalinks.api.DataLinksAPI.list_conversations)).

* **Return type:**
  `Optional`\[[`ConversationListResponse`](datalinks#datalinks.models.ConversationListResponse)]

#### *async* get\_conversation(conversation\_id)

Get a conversation and its turns (see [`DataLinksAPI.get_conversation()`](#datalinks.api.DataLinksAPI.get_conversation)).

* **Return type:**
  `Optional`\[[`ConversationDetailResponse`](datalinks#datalinks.models.ConversationDetailResponse)]

### *exception* datalinks.api.DataLinksRequestError(endpoint, e, reason=None)

Bases: `Exception`

### *class* datalinks.api.DLConfig(host, apikey, namespace, objectname)

Bases: `object`

DLConfig class is a configuration container for managing the required settings
to interact with DataLinks. It loads configuration values from environment
variables to provide flexibility across different environments.

This class is designed to simplify the initialization and storage of connection
and namespace details required to communicate with DataLinks.

* **Variables:**
  * **host** – The host URL for the data layer connection.
  * **apikey** – The API key for authentication with the data layer.
  * **namespace** – The namespace for organizing data in the data layer.
  * **objectname** – The name of the object associated with the configuration.
    Defaults to an empty string.

#### host *: str*

#### apikey *: str*

#### namespace *: str*

#### objectname *: str*

#### *classmethod* from\_env(load\_dotenv=True)

### *class* datalinks.api.AskEvent(type, data)

Bases: `object`

Represents a single SSE event from the /query/ask streaming endpoint.

Server-sent types are `plan`, `step`, `answer`, `error`, the
lifecycle signals `planningStarted`, `stepStarted`, `queryExecuting`
and `answerStarted`, and — when resuming — `run-started`. Two further
types are synthesised by the SDK when the server answers a resume with a
one-off body instead of a stream: `terminal` and `no-checkpoint` (see
[`DataLinksAPI.resume_agent_run()`](#datalinks.api.DataLinksAPI.resume_agent_run)). Both vocabularies share this one
field, so match on the types you expect rather than assuming the list is
closed — the server may add lifecycle events without an SDK release.

* **Variables:**
  * **type** – Event type.
  * **data** – Parsed JSON payload for the event.

#### type *: str*

#### data *: Dict\[str, Any]*

### *class* datalinks.api.AskStream(open\_events)

Bases: `object`

The [`DataLinksAPI.ask()`](#datalinks.api.DataLinksAPI.ask) event stream, plus the response carrying it.

Iterate it exactly as before to get [`AskEvent`](#datalinks.api.AskEvent) objects. `headers`
and `status_code` are `None` until the first event arrives — nothing is
sent until iteration starts, so there is no response to read them off before
then.

Only the headers and status are exposed, not the response itself: its body
is consumed by the event loop, so reading `.text` off it would raise.

Close it when abandoning a stream early, or use it as a context manager:

```default theme={null}
with api.ask("...") as stream:
    for event in stream:
        if event.type == "answer":
            break
```

#### close()

Release the connection, whether or not the stream was exhausted.

* **Return type:**
  `None`

#### *property* headers *: Headers | None*

Response headers once the stream is open, else `None`.

#### *property* status\_code *: int | None*

HTTP status once the stream is open, else `None`.

### *class* datalinks.api.AsyncAskStream(open\_events)

Bases: `object`

Async counterpart of [`AskStream`](#datalinks.api.datalinks.AskStream).

Iterated with `async for`; released with `aclose()` or `async with`.

#### *async* aclose()

Release the connection, whether or not the stream was exhausted.

* **Return type:**
  `None`

#### *property* headers *: Headers | None*

Response headers once the stream is open, else `None`.

#### *property* status\_code *: int | None*

HTTP status once the stream is open, else `None`.

### *class* datalinks.api.AutoRagResult(data, http\_response)

Bases: `Dict`\[`str`, `Any`]

The AutoRAG answer body, plus the response it arrived in.

A `dict` subclass rather than a wrapper, so `result["response"]` and
`result["steps"]` keep working unchanged. The attribute is
`http_response`, not `response`, because `result["response"]` is
already the answer text.

* **Variables:**
  **http\_response** – The raw `httpx.Response`, already fully read.

#### *property* headers *: Headers*

Response headers.

#### *property* status\_code *: int*

HTTP status of the response — always 2xx, since anything else raised.

### *class* datalinks.api.IngestionResult(successful, failed)

Bases: `object`

Represents the result of a data ingestion process into DataLinks.

This class is a data structure used to store the results of a data ingestion
operation. It separates the successfully ingested items from the failed ones,
enabling users to track and handle both cases effectively.

* **Variables:**
  * **successful** – A list of records successfully ingested. Each record is
    represented as a dictionary.
  * **failed** – A list of records that failed ingestion. Each record is
    represented as a dictionary.

#### successful *: List\[Dict\[str, Any]]*

#### failed *: List\[Dict\[str, Any]]*

### *class* datalinks.api.IngestProxyAPI(config=None)

Bases: `object`

Client for the DataLinks ingestion proxy (auto-modelling) service.

Wraps the `POST /api/pipeline`, `GET /api/pipeline/{runId}/stream`,
`GET /api/pipeline/{runId}/trace`, and `POST /api/pipeline/{runId}/hook`
endpoints.

* **Variables:**
  **config** – Proxy configuration.

#### run\_pipeline(, data=None, data\_url=None, data\_blob\_url=None, namespace=None, user\_prompt=None, model=True, ingest=True, ontology=True, max\_eval\_retries=3, max\_rows\_for\_modeling=20, max\_sample\_rows=10, enable\_human\_in\_the\_loop=False, predefined\_schema=None, explosion\_helper\_prompt=None, coalescence\_helper\_prompt=None, llm=None, datalinks\_inference\_settings=None)

Start a full pipeline run (auto-modelling + ingest).

Exactly one of *data*, *data\_url*, or *data\_blob\_url* must be provided.

Returns a [`PipelineRun`](#datalinks.api.PipelineRun) whose `run_id` attribute is the workflow
run identifier and which can be iterated to receive NDJSON progress events.

* **Parameters:**
  * **data** (`Optional`\[`List`\[`Dict`\[`str`, `Any`]]]) – Inline JSON array of row objects.
  * **data\_url** (`Optional`\[`str`]) – Remote URL returning a JSON array (fetched by the pipeline).
  * **data\_blob\_url** (`Optional`\[`str`]) – Pre-uploaded Vercel Blob URL.
  * **namespace** (`Optional`\[`str`]) – Target namespace; defaults to `config.namespace`.
  * **user\_prompt** (`Optional`\[`str`]) – Domain goals; inferred from data when omitted.
  * **model** (`bool`) – Run the model phase (default True).
  * **ingest** (`bool`) – Run the ingest phase (default True).
  * **ontology** (`bool`) – Run namespace curation after ingest (default True).
  * **max\_eval\_retries** (`int`) – Max modelling iterations (default 3).
  * **max\_rows\_for\_modeling** (`int`) – Rows sent to the LLM for schema modelling (default 20).
  * **max\_sample\_rows** (`int`) – Sample rows generated for preview (default 10).
  * **enable\_human\_in\_the\_loop** (`bool`) – Surface clarification + schema review hooks (default False).
  * **predefined\_schema** (`Optional`\[`Dict`\[`str`, `Any`]]) – Skip model phase when provided.
  * **explosion\_helper\_prompt** (`Optional`\[`str`]) – Extra context injected into the explode step.
  * **coalescence\_helper\_prompt** (`Optional`\[`str`]) – Extra context injected into the coalesce step.
  * **llm** (`Optional`\[`Dict`\[`str`, `Any`]]) – LLM configuration dict with optional keys: `provider`, `model`,
    `explosionTemperature`, `coalescenceTemperature`, `evaluationTemperature`,
    `ontologyTemperature`.
  * **datalinks\_inference\_settings** (`Optional`\[`Dict`\[`str`, `Any`]]) – DataLinks inference settings dict with optional keys:
    `provider`, `model`, `ontologyCurationProvider`, `ontologyCurationModel`.
* **Return type:**
  [`PipelineRun`](#datalinks.api.ingest_proxy.PipelineRun)
* **Returns:**
  A [`PipelineRun`](#datalinks.api.PipelineRun) instance.
* **Raises:**
  [**DataLinksRequestError**](#datalinks.api.DataLinksRequestError) – If the HTTP request fails.

#### stream\_pipeline(run\_id, start\_index=0)

Stream progress events for an existing pipeline run.

* **Parameters:**
  * **run\_id** (`str`) – Workflow run identifier returned by [`run_pipeline()`](#datalinks.api.IngestProxyAPI.run_pipeline).
  * **start\_index** (`int`) – Resume from this event index (default 0).  Pass the
    number of events already received to skip replaying them on reconnect.
* **Return type:**
  `Iterator`\[`Dict`\[`str`, `Any`]]
* **Returns:**
  An iterator of NDJSON event dicts.
* **Raises:**
  [**DataLinksRequestError**](#datalinks.api.DataLinksRequestError) – If the HTTP request fails.

#### get\_pipeline\_trace(run\_id)

Download the full trace for a completed pipeline run.

* **Parameters:**
  **run\_id** (`str`) – Workflow run identifier.
* **Return type:**
  `Optional`\[`Dict`\[`str`, `Any`]]
* **Returns:**
  Dict with LLM calls, token usage, and step durations, or None on failure.
* **Raises:**
  [**DataLinksRequestError**](#datalinks.api.DataLinksRequestError) – If the HTTP request fails.

#### resume\_pipeline\_hook(run\_id, payload)

Resume a human-in-the-loop hook (clarification, schema review, or token refresh).

* **Parameters:**
  * **run\_id** (`str`) – Workflow run identifier.
  * **payload** (`Dict`\[`str`, `Any`]) – Hook response payload.
* **Return type:**
  `Optional`\[`Dict`\[`str`, `Any`]]
* **Returns:**
  Response dict, or None on failure.
* **Raises:**
  [**DataLinksRequestError**](#datalinks.api.DataLinksRequestError) – If the HTTP request fails.

### *class* datalinks.api.IngestProxyConfig(host, datalinks\_token, datalinks\_username, namespace)

Bases: `object`

Configuration for the DataLinks ingestion proxy (auto-modelling) service.

* **Variables:**
  * **host** – Base URL of the ingestion proxy (e.g. `http://localhost:3003`).
  * **datalinks\_token** – DataLinks JWT token sent as `Authorization: Bearer` (`DL_API_KEY`).
  * **datalinks\_username** – DataLinks username included in the request body (`DL_USERNAME`).
  * **namespace** – Default target namespace (`DL_NAMESPACE`).

#### host *: str*

#### datalinks\_token *: str*

#### datalinks\_username *: str*

#### namespace *: str*

#### *classmethod* from\_env(load\_dotenv=True)

* **Return type:**
  [`IngestProxyConfig`](#datalinks.api.ingest_proxy.IngestProxyConfig)

### *class* datalinks.api.PipelineRun(run\_id, stream\_fn)

Bases: `object`

Wraps a pipeline run with automatic stream reconnection.

Provides the workflow `run_id` (from the `x-workflow-run-id` response
header) and an iterable interface over the NDJSON progress events.

The iterator reconnects transparently on connection drops, resuming from
the last received event via the `startIndex` query parameter.  Iteration
ends only when an explicit `complete` or `error` event is received.

Usage:

```default theme={null}
run = proxy.run_pipeline(data=[...])
print(run.run_id)
for event in run:
    print(event)
```

Can also be used as a context manager:

```default theme={null}
with proxy.run_pipeline(data=[...]) as run:
    for event in run:
        process(event)
```

#### close()

* **Return type:**
  `None`

## Submodules

## datalinks.api.async\_datalinks module

Async sibling of [`datalinks.api.DataLinksAPI`](#datalinks.api.DataLinksAPI).

`AsyncDataLinksAPI` exposes the same surface as `DataLinksAPI` but every
remote-call method is an `async def` that dispatches through the underlying
`httpx.AsyncClient`. The two facades share one `DataLinksClient` and the
same request bodies, so spec drift is caught uniformly.

Use this when you need concurrency — e.g. fanning out queries, embedding the
SDK in an async web service. For one-shot scripts, prefer `DataLinksAPI`.

### *class* datalinks.api.async\_datalinks.AsyncAskStream(open\_events)

Bases: `object`

Async counterpart of [`AskStream`](#datalinks.api.datalinks.AskStream).

Iterated with `async for`; released with `aclose()` or `async with`.

#### *async* aclose()

Release the connection, whether or not the stream was exhausted.

* **Return type:**
  `None`

#### *property* headers *: Headers | None*

Response headers once the stream is open, else `None`.

#### *property* status\_code *: int | None*

HTTP status once the stream is open, else `None`.

### *class* datalinks.api.async\_datalinks.AsyncDataLinksAPI(config=None)

Bases: `object`

Async counterpart of `DataLinksAPI`.

Method signatures mirror the sync facade — same parameter names, defaults,
and return types. Every networked method is `async def`. The streaming
`ask` method returns an [`AsyncAskStream`](#datalinks.api.async_datalinks.AsyncAskStream) instead of an
[`AskStream`](#datalinks.api.datalinks.AskStream).

Use `async with` for guaranteed cleanup of the underlying
`httpx.AsyncClient`, or call [`aclose()`](#datalinks.api.async_datalinks.AsyncDataLinksAPI.aclose) manually:

```default theme={null}
async with AsyncDataLinksAPI() as api:
    datasets = await api.list_datasets()
```

#### *async* aclose()

Close the underlying `httpx.AsyncClient`.

* **Return type:**
  `None`

#### *async* ingest(data, inference\_steps=None, entity\_resolution=None, batch\_size=0, max\_attempts=3, curate=None, data\_description=None, schema\_definition=None, additional\_instructions=None)

Async variant of `DataLinksAPI.ingest()`.

Same batching + retry semantics as the sync facade.

* **Return type:**
  [`IngestionResult`](#datalinks.api.datalinks.IngestionResult)

#### create\_space(is\_private=None, data\_description=None, schema\_definition=None)

Create a new space (see `DataLinksAPI.create_space()`).

Deliberately not an `async def`: the body of a coroutine runs on
whoever resumes it, so under `asyncio.gather` the deprecation warning
below would be filed against `asyncio/events.py` instead of the
caller. Warning here, at call time, keeps the attribution right.

* **Return type:**
  `Coroutine`\[`Any`, `Any`, `None`]

#### *async* update\_infer\_definition(data\_description=None, schema\_definition=None)

* **Return type:**
  `None`

#### *async* infer\_dataset\_description(sample, model=None, provider=None, current\_description=None, current\_schema=None)

* **Return type:**
  `Dict`

#### *async* update\_sort\_order(order)

* **Return type:**
  `None`

#### *async* prepare\_multipart\_upload(filename, size)

* **Return type:**
  `Dict`

#### *async* finish\_multipart\_upload(upload\_id, key, parts, name=None, inference\_steps=None, entity\_resolution=None)

* **Return type:**
  `Dict`

#### *async* abort\_multipart\_upload(upload\_id, key)

* **Return type:**
  `None`

#### *async* list\_ingestions(page\_size=25)

* **Return type:**
  `Optional`\[`List`\[[`ListIngestionsResponseDataItem`](datalinks#datalinks.models.ListIngestionsResponseDataItem)]]

#### *async* wait\_for\_ingestion(ingestion\_id, poll\_interval=5, timeout=1200)

Async variant of `DataLinksAPI.wait_for_ingestion()`.

Polls via [`list_ingestions()`](#datalinks.api.async_datalinks.AsyncDataLinksAPI.list_ingestions), awaiting `asyncio.sleep` between
ticks instead of blocking the event loop with `time.sleep`.

* **Return type:**
  [`ListIngestionsResponseDataItem`](datalinks#datalinks.models.ListIngestionsResponseDataItem)

#### *async* get\_dataset\_info()

* **Return type:**
  `Optional`\[[`DatasetResponse`](datalinks#datalinks.models.DatasetResponse)]

#### *async* delete\_dataset()

* **Return type:**
  `None`

#### *async* rename\_dataset(new\_name)

* **Return type:**
  `None`

#### *async* rename\_namespace(new\_name)

* **Return type:**
  `None`

#### *async* clear\_dataset()

* **Return type:**
  `None`

#### *async* add\_link(from\_namespace, from\_dataset, from\_column, to\_namespace, to\_dataset, to\_column, match\_type, options=None)

* **Return type:**
  `Optional`\[`bool`]

#### *async* preview\_links(data, entity\_resolution=None)

* **Return type:**
  `Optional`\[`List`\[[`ApiLink`](datalinks#datalinks.models.ApiLink)]]

#### *async* rebuild\_links(data, entity\_resolution=None)

* **Return type:**
  `Optional`\[`List`\[[`ApiLink`](datalinks#datalinks.models.ApiLink)]]

#### *async* load\_links()

* **Return type:**
  `Optional`\[`List`\[[`ApiLink`](datalinks#datalinks.models.ApiLink)]]

#### *async* list\_datasets(namespace=None)

* **Return type:**
  `Optional`\[`List`\[[`ApiDatasetDescription`](datalinks#datalinks.models.ApiDatasetDescription)]]

#### *async* list\_namespaces(user='self')

* **Return type:**
  `Optional`\[`List`\[[`ApiNamespace`](datalinks#datalinks.models.ApiNamespace)]]

#### *async* list\_all\_datasets\_schema()

* **Return type:**
  `Optional`\[`List`\[[`ApiDatasetDescription`](datalinks#datalinks.models.ApiDatasetDescription)]]

#### *async* list\_datasets\_in\_namespace\_schema(namespace=None, user='self')

* **Return type:**
  `Optional`\[`List`\[[`ApiDatasetDescription`](datalinks#datalinks.models.ApiDatasetDescription)]]

#### *async* query\_data(query=None, is\_natural\_language=False, model=None, provider=None, include\_metadata=False, explain=False, , username='self')

Query the configured dataset (see `DataLinksAPI.query_data()`).

* **Return type:**
  `Optional`\[`List`\[`Dict`\[`str`, `Any`]]]

#### *async* autorag(query, model=None, provider=None, helper\_prompt=None, , username='self', stage\_models=None, conversation\_id=None, web\_search=None)

Answer a question with the AutoRAG agent (see `DataLinksAPI.autorag()`).

* **Return type:**
  [`AutoRagResult`](#datalinks.api.datalinks.AutoRagResult)

#### ask(query, model=None, provider=None, helper\_prompt=None, , username='self', stage\_models=None, conversation\_id=None, web\_search=None)

Async SSE stream of `DataLinksAPI.ask()` events.

Yields `AskEvent` objects until the server closes the stream, and
exposes the response headers once the stream is open (see [`AsyncAskStream`](#datalinks.api.async_datalinks.AsyncAskStream)).

* **Return type:**
  [`AsyncAskStream`](#datalinks.api.async_datalinks.AsyncAskStream)

#### *async* preview\_ingest(data, inference\_steps=None)

* **Return type:**
  `Optional`\[`List`\[`Dict`\[`str`, `Any`]]]

#### *async* infer\_schema(sample, model=None, provider=None, current\_schema=None)

* **Return type:**
  `Optional`\[[`InferredSchemaResponse`](datalinks#datalinks.models.InferredSchemaResponse)]

#### *async* retry\_ingestion(ingestion\_id)

* **Return type:**
  `Optional`\[[`CreatedIngestionTrackingResponse`](datalinks#datalinks.models.CreatedIngestionTrackingResponse)]

#### *async* mark\_ingestion\_seen(ingestion\_id)

* **Return type:**
  `None`

#### *async* request\_cleaning(prompts, output\_namespace, output\_dataset\_name)

* **Return type:**
  `Optional`\[`str`]

#### *async* get\_cleaning\_code(cleaning\_task\_id)

* **Return type:**
  `Optional`\[`List`\[`Dict`]]

#### *async* get\_ontology()

* **Return type:**
  `Optional`\[`List`\[[`ApiLink`](datalinks#datalinks.models.ApiLink)]]

#### *async* save\_ontology(add=None, remove=None)

* **Return type:**
  `None`

#### *async* curate\_links(namespace=None, dataset=None, model=None, provider=None, activate=False)

* **Return type:**
  `Optional`\[[`CurateLinkResponse`](datalinks#datalinks.models.CurateLinkResponse)]

#### *async* get\_current\_user()

Resolve the current user’s identity (see `DataLinksAPI.get_current_user()`).

* **Return type:**
  `Optional`\[[`CurrentUserResponse`](datalinks#datalinks.models.CurrentUserResponse)]

#### *async* list\_tokens()

* **Return type:**
  `Optional`\[`List`\[[`UserToken`](datalinks#datalinks.models.UserToken)]]

#### *async* add\_token(name, expires\_at=None, access\_restricted\_to=None)

* **Return type:**
  `Optional`\[[`UserToken`](datalinks#datalinks.models.UserToken)]

#### *async* delete\_token(token\_id)

* **Return type:**
  `None`

#### *async* list\_token\_permissions(token\_id)

* **Return type:**
  `Optional`\[[`TokenPermissionsResponse`](datalinks#datalinks.models.TokenPermissionsResponse)]

#### *async* get\_usage\_history(on\_or\_after=None, before=None, page\_size=25, page\_cursor=None)

* **Return type:**
  `Optional`\[[`UserUsageHistoryResponse`](datalinks#datalinks.models.UserUsageHistoryResponse)]

#### *async* get\_usage\_by\_day(on\_or\_after=None, before=None, timezone='UTC')

* **Return type:**
  `Optional`\[[`UserUsageByDayResponse`](datalinks#datalinks.models.UserUsageByDayResponse)]

#### *async* get\_agent\_run\_status(run\_id)

Get the current status of an agent run (see `DataLinksAPI.get_agent_run_status()`).

* **Return type:**
  `Optional`\[[`AgentRunStatusResponse`](datalinks#datalinks.models.AgentRunStatusResponse)]

#### *async* delete\_agent\_run(run\_id)

Permanently delete an agent run and its resume checkpoint (see `DataLinksAPI.delete_agent_run()`).

* **Return type:**
  `None`

#### *async* submit\_agent\_run\_feedback(run\_id, , thumbs\_up, comment=None)

Rate a completed agent run (see `DataLinksAPI.submit_agent_run_feedback()`).

* **Return type:**
  `None`

#### *async* resume\_agent\_run(run\_id)

Resume an agent run, streaming its events (see `DataLinksAPI.resume_agent_run()`).

* **Return type:**
  `AsyncIterator`\[[`AskEvent`](#datalinks.api.datalinks.AskEvent)]

#### *async* share\_dataset\_access(username, role)

Grant a user access to the dataset (see `DataLinksAPI.share_dataset_access()`).

* **Return type:**
  `None`

#### *async* revoke\_dataset\_access(username, role)

Remove a user’s dataset access (see `DataLinksAPI.revoke_dataset_access()`).

* **Return type:**
  `None`

#### *async* list\_dataset\_shares()

List grants on the dataset (see `DataLinksAPI.list_dataset_shares()`).

* **Return type:**
  `Optional`\[`List`\[[`AccessGrant`](datalinks#datalinks.models.AccessGrant)]]

#### *async* share\_namespace\_access(username, role)

Grant a user access to the namespace (see `DataLinksAPI.share_namespace_access()`).

* **Return type:**
  `None`

#### *async* revoke\_namespace\_access(username, role)

Remove a user’s namespace access (see `DataLinksAPI.revoke_namespace_access()`).

* **Return type:**
  `None`

#### *async* list\_namespace\_shares()

List grants on the namespace (see `DataLinksAPI.list_namespace_shares()`).

* **Return type:**
  `Optional`\[`List`\[[`AccessGrant`](datalinks#datalinks.models.AccessGrant)]]

#### *async* list\_conversations(username='self', namespace=None)

List the caller’s conversations within a namespace (see `DataLinksAPI.list_conversations()`).

* **Return type:**
  `Optional`\[[`ConversationListResponse`](datalinks#datalinks.models.ConversationListResponse)]

#### *async* get\_conversation(conversation\_id)

Get a conversation and its turns (see `DataLinksAPI.get_conversation()`).

* **Return type:**
  `Optional`\[[`ConversationDetailResponse`](datalinks#datalinks.models.ConversationDetailResponse)]

## datalinks.api.datalinks module

### *class* datalinks.api.datalinks.DLConfig(host, apikey, namespace, objectname)

Bases: `object`

DLConfig class is a configuration container for managing the required settings
to interact with DataLinks. It loads configuration values from environment
variables to provide flexibility across different environments.

This class is designed to simplify the initialization and storage of connection
and namespace details required to communicate with DataLinks.

* **Variables:**
  * **host** – The host URL for the data layer connection.
  * **apikey** – The API key for authentication with the data layer.
  * **namespace** – The namespace for organizing data in the data layer.
  * **objectname** – The name of the object associated with the configuration.
    Defaults to an empty string.

#### host *: str*

#### apikey *: str*

#### namespace *: str*

#### objectname *: str*

#### *classmethod* from\_env(load\_dotenv=True)

### *class* datalinks.api.datalinks.AskEvent(type, data)

Bases: `object`

Represents a single SSE event from the /query/ask streaming endpoint.

Server-sent types are `plan`, `step`, `answer`, `error`, the
lifecycle signals `planningStarted`, `stepStarted`, `queryExecuting`
and `answerStarted`, and — when resuming — `run-started`. Two further
types are synthesised by the SDK when the server answers a resume with a
one-off body instead of a stream: `terminal` and `no-checkpoint` (see
[`DataLinksAPI.resume_agent_run()`](#datalinks.api.datalinks.DataLinksAPI.resume_agent_run)). Both vocabularies share this one
field, so match on the types you expect rather than assuming the list is
closed — the server may add lifecycle events without an SDK release.

* **Variables:**
  * **type** – Event type.
  * **data** – Parsed JSON payload for the event.

#### type *: str*

#### data *: Dict\[str, Any]*

### *class* datalinks.api.datalinks.AskStream(open\_events)

Bases: `object`

The [`DataLinksAPI.ask()`](#datalinks.api.datalinks.DataLinksAPI.ask) event stream, plus the response carrying it.

Iterate it exactly as before to get [`AskEvent`](#datalinks.api.datalinks.AskEvent) objects. `headers`
and `status_code` are `None` until the first event arrives — nothing is
sent until iteration starts, so there is no response to read them off before
then.

Only the headers and status are exposed, not the response itself: its body
is consumed by the event loop, so reading `.text` off it would raise.

Close it when abandoning a stream early, or use it as a context manager:

```default theme={null}
with api.ask("...") as stream:
    for event in stream:
        if event.type == "answer":
            break
```

#### close()

Release the connection, whether or not the stream was exhausted.

* **Return type:**
  `None`

#### *property* headers *: Headers | None*

Response headers once the stream is open, else `None`.

#### *property* status\_code *: int | None*

HTTP status once the stream is open, else `None`.

### *class* datalinks.api.datalinks.AutoRagResult(data, http\_response)

Bases: `Dict`\[`str`, `Any`]

The AutoRAG answer body, plus the response it arrived in.

A `dict` subclass rather than a wrapper, so `result["response"]` and
`result["steps"]` keep working unchanged. The attribute is
`http_response`, not `response`, because `result["response"]` is
already the answer text.

* **Variables:**
  **http\_response** – The raw `httpx.Response`, already fully read.

#### *property* headers *: Headers*

Response headers.

#### *property* status\_code *: int*

HTTP status of the response — always 2xx, since anything else raised.

### *class* datalinks.api.datalinks.IngestionResult(successful, failed)

Bases: `object`

Represents the result of a data ingestion process into DataLinks.

This class is a data structure used to store the results of a data ingestion
operation. It separates the successfully ingested items from the failed ones,
enabling users to track and handle both cases effectively.

* **Variables:**
  * **successful** – A list of records successfully ingested. Each record is
    represented as a dictionary.
  * **failed** – A list of records that failed ingestion. Each record is
    represented as a dictionary.

#### successful *: List\[Dict\[str, Any]]*

#### failed *: List\[Dict\[str, Any]]*

### *class* datalinks.api.datalinks.DataLinksAPI(config=None)

Bases: `object`

Class for interfacing with the DataLinks API.

Provides methods for ingesting data, managing namespaces, and querying data
from DataLinks. Designed to interact with a configurable
backend, providing flexibility for deployment environments.

* **Variables:**
  **config** – Configuration object containing API key, host, index, namespace,
  and object name.

#### config *: [DLConfig](#datalinks.api.datalinks.DLConfig)*

#### ingest(data, inference\_steps=None, entity\_resolution=None, batch\_size=0, max\_attempts=3, curate=None, data\_description=None, schema\_definition=None, additional\_instructions=None)

Ingests data into the namespace by batching the given data and performing multiple retries
in case of failures. This function sends data in chunks (batches), to be processed through configured
inference steps, and to resolve entities based on the provided configuration. If a batch fails, it
is retried up to a maximum number of attempts.

* **Parameters:**
  * **data** (`List`\[`Dict`\[`str`, `Any`]]) – List of dictionaries, where each dictionary represents a data block to be ingested.
  * **inference\_steps** ([`Pipeline`](datalinks#datalinks.pipeline.Pipeline) | `None`) – Pipeline of inference steps to be applied for processing the data. If None the data will be ingested as is.
  * **entity\_resolution** ([`MatchTypeConfig`](datalinks#datalinks.links.MatchTypeConfig) | `None`) – Configuration specifying how entity resolution is to be performed.
  * **batch\_size** – Number of data blocks to be included in each batch. Defaults to the size of the
    entire dataset if not provided.
  * **max\_attempts** – Maximum number of retry attempts for failed batches. Defaults to the
    provided constant MAX\_INGEST\_ATTEMPTS.
  * **curate** (*Optional* \*\[\**bool* *]*) – If `True`, automatically curate ontology links after ingestion.
  * **data\_description** (*Optional* \*\[\**str* *]*) – Free-text description of the dataset to guide the AI during ingestion.
  * **schema\_definition** (*Optional* \*\[\**Dict* \*\[\**str* *,* *str* *]* *]*) – Field-name-to-description mapping to guide the AI in structuring extracted data.
  * **additional\_instructions** (*Optional* \*\[\**str* *]*) – Additional free-text instructions to guide the AI during ingestion.
* **Return type:**
  [`IngestionResult`](#datalinks.api.datalinks.IngestionResult)
* **Returns:**
  An IngestionResult object containing lists of successfully ingested data blocks and
  data blocks that failed to be ingested.

#### create\_space(is\_private=None, data\_description=None, schema\_definition=None)

Creates a new space. This function sends a POST request to create a namespace.
Information about the namespace creation will be logged, including the HTTP
status code and response reason. A space that already exists is left alone
and reported as success.

#### Versionchanged

Changed in version 1.2.13: `is_private` is ignored. Public datasets have been removed; every
space is private and access is granted per user with
[`share_dataset_access()`](#datalinks.api.datalinks.DataLinksAPI.share_dataset_access) / [`share_namespace_access()`](#datalinks.api.datalinks.DataLinksAPI.share_namespace_access).

* **Parameters:**
  * **is\_private** (*Optional* \*\[\**bool* *]*) – Ignored; see the note above.
  * **data\_description** (*Optional* \*\[\**str* *]*) – Free-text description of the dataset (max 10,000 chars).
  * **schema\_definition** (*Optional* \*\[\**Dict* \*\[\**str* *,* *str* *]* *]*) – Field-name-to-description mapping to guide the AI in structuring data.
* **Return type:**
  `None`
* **Returns:**
  None
* **Raises:**
  **HTTPError** – If the HTTP request fails due to connectivity issues or
  server-side problems.

#### update\_infer\_definition(data\_description=None, schema\_definition=None)

Update the saved inference definition for the configured dataset.

The inference definition is used automatically on future ingest calls to guide
field extraction and normalization.

* **Parameters:**
  * **data\_description** (*Optional* \*\[\**str* *]*) – Free-text description of the dataset (max 10,000 chars).
  * **schema\_definition** (*Optional* \*\[\**Dict* \*\[\**str* *,* *str* *]* *]*) – Field-name-to-description mapping to guide the AI in
    structuring extracted data.
* **Raises:**
  [**DataLinksRequestError**](#datalinks.api.DataLinksRequestError) – If the HTTP request fails.
* **Return type:**
  `None`

#### infer\_dataset\_description(sample, model=None, provider=None, current\_description=None, current\_schema=None)

Ask an agent to infer a data description and field schema from sampled data.

* **Parameters:**
  * **sample** (*Dataset*) – A sample of data rows to analyse.
  * **model** (*Optional* \*\[\**str* *]*) – LLM model name.
  * **provider** (*Optional* \*\[\**str* *]*) – LLM provider (e.g. `"openai"`, `"ollama"`).
  * **current\_description** (*Optional* \*\[\**str* *]*) – Existing description to refine.
  * **current\_schema** (*Optional* \*\[\**Dict* \*\[\**str* *,* *str* *]* *]*) – Existing field schema to refine (field → description mapping).
* **Returns:**
  Inferred `dataDescription` and `fieldDefinition`.
* **Return type:**
  Dict
* **Raises:**
  [**DataLinksRequestError**](#datalinks.api.DataLinksRequestError) – If the HTTP request fails.

#### update\_sort\_order(order)

Update the display order of columns for the configured dataset.

* **Parameters:**
  **order** (*List* \*\[\**str* *]*) – Ordered list of all column names in the desired sequence.
* **Raises:**
  [**DataLinksRequestError**](#datalinks.api.DataLinksRequestError) – If the HTTP request fails.
* **Return type:**
  `None`

#### prepare\_multipart\_upload(filename, size)

Initiate a multipart upload and receive presigned URLs for each part.

Use this for large files. Upload each part directly to its presigned URL,
then call [`finish_multipart_upload()`](#datalinks.api.datalinks.DataLinksAPI.finish_multipart_upload) with the returned ETags.

* **Parameters:**
  * **filename** (*str*) – Name of the file being uploaded.
  * **size** (*int*) – File size in bytes.
* **Returns:**
  Response containing `uploadId`, `key`, and presigned part URLs.
* **Return type:**
  Dict
* **Raises:**
  [**DataLinksRequestError**](#datalinks.api.DataLinksRequestError) – If the HTTP request fails.

#### finish\_multipart\_upload(upload\_id, key, parts, name=None, inference\_steps=None, entity\_resolution=None)

Complete a multipart upload after all parts have been uploaded.

* **Parameters:**
  * **upload\_id** (*str*) – Upload ID from [`prepare_multipart_upload()`](#datalinks.api.datalinks.DataLinksAPI.prepare_multipart_upload).
  * **key** (*str*) – S3 object key from [`prepare_multipart_upload()`](#datalinks.api.datalinks.DataLinksAPI.prepare_multipart_upload).
  * **parts** (*List* \*\[\**Dict* \*\[\**str* *,* *Any* *]* *]*) – List of completed parts, each with `partNumber` (int) and
    `etag` (str) returned by S3.
  * **name** (*Optional* \*\[\**str* *]*) – Optional label for the ingestion (e.g. original filename).
  * **inference\_steps** (*Optional* *\[*[*Pipeline*](datalinks#datalinks.pipeline.Pipeline) *]*) – Pipeline of inference steps to apply to the uploaded
    file during ingestion. If `None` the file is ingested as is.
  * **entity\_resolution** (*Optional* *\[*[*MatchTypeConfig*](datalinks#datalinks.links.MatchTypeConfig) *]*) – Configuration specifying how entity resolution is to
    be performed on the uploaded file.
* **Returns:**
  Ingestion result from the server.
* **Return type:**
  Dict
* **Raises:**
  [**DataLinksRequestError**](#datalinks.api.DataLinksRequestError) – If the HTTP request fails.

#### abort\_multipart\_upload(upload\_id, key)

Abort a multipart upload and clean up partial data.

* **Parameters:**
  * **upload\_id** (*str*) – Upload ID from [`prepare_multipart_upload()`](#datalinks.api.datalinks.DataLinksAPI.prepare_multipart_upload).
  * **key** (*str*) – S3 object key from [`prepare_multipart_upload()`](#datalinks.api.datalinks.DataLinksAPI.prepare_multipart_upload).
* **Raises:**
  [**DataLinksRequestError**](#datalinks.api.DataLinksRequestError) – If the HTTP request fails.
* **Return type:**
  `None`

#### list\_ingestions(page\_size=25)

List ingestion attempts for the configured dataset, most recent first.

* **Parameters:**
  **page\_size** (*int*) – Number of records to return (1-100, default 25).
* **Return type:**
  `Optional`\[`List`\[[`ListIngestionsResponseDataItem`](datalinks#datalinks.models.ListIngestionsResponseDataItem)]]
* **Returns:**
  Ingestion attempts, or None on failure.

#### wait\_for\_ingestion(ingestion\_id, poll\_interval=5, timeout=1200)

Poll until the given ingestion reaches a terminal status.

Polls [`list_ingestions()`](#datalinks.api.datalinks.DataLinksAPI.list_ingestions) every *poll\_interval* seconds until the
ingestion with *ingestion\_id* is no longer in a pending/processing
state, or until *timeout* seconds have elapsed.

* **Parameters:**
  * **ingestion\_id** (*str*) – Ingestion ID returned by [`finish_multipart_upload()`](#datalinks.api.datalinks.DataLinksAPI.finish_multipart_upload).
  * **poll\_interval** (*int*) – Seconds between polls (default 5).
  * **timeout** (*int*) – Maximum seconds to wait before raising (default 600).
* **Return type:**
  [`ListIngestionsResponseDataItem`](datalinks#datalinks.models.ListIngestionsResponseDataItem)
* **Returns:**
  The final ingestion record.
* **Raises:**
  * **TimeoutError** – If *timeout* is exceeded before a terminal status.
  * [**DataLinksRequestError**](#datalinks.api.DataLinksRequestError) – If polling requests fail.

#### get\_dataset\_info()

Retrieve metadata for the configured dataset.

* **Return type:**
  `Optional`\[[`DatasetResponse`](datalinks#datalinks.models.DatasetResponse)]
* **Returns:**
  The dataset and its metadata, or None on failure.

#### delete\_dataset()

Permanently delete the configured dataset, including all data, links, and metadata.

This action is irreversible (balefire).

* **Raises:**
  [**DataLinksRequestError**](#datalinks.api.DataLinksRequestError) – If the HTTP request fails.
* **Return type:**
  `None`

#### rename\_dataset(new\_name)

Rename the configured dataset.

* **Parameters:**
  **new\_name** (*str*) – The new dataset name.
* **Raises:**
  [**DataLinksRequestError**](#datalinks.api.DataLinksRequestError) – If the HTTP request fails.
* **Return type:**
  `None`

#### clear\_dataset()

Remove all data and links from the configured dataset.

The dataset itself (metadata, schema) is preserved. This action is irreversible.

* **Raises:**
  [**DataLinksRequestError**](#datalinks.api.DataLinksRequestError) – If the HTTP request fails.
* **Return type:**
  `None`

#### add\_link(from\_namespace, from\_dataset, from\_column, to\_namespace, to\_dataset, to\_column, match\_type, options=None)

Create a manual link between two dataset columns.

* **Parameters:**
  * **from\_namespace** (`str`) – Source namespace.
  * **from\_dataset** (`str`) – Source dataset name.
  * **from\_column** (`str`) – Source column name.
  * **to\_namespace** (`str`) – Target namespace.
  * **to\_dataset** (`str`) – Target dataset name.
  * **to\_column** (`str`) – Target column name.
  * **match\_type** (`str`) – Match type — `"ExactMatch"` or `"GeoMatch"`.
  * **options** (`Optional`\[`Dict`\[`str`, `Any`]]) – Optional match configuration (e.g. `minDistinct`, `distance`).
* **Returns:**
  True if the link was successfully created, False if already exists. None if failure.
* **Return type:**
  bool
* **Raises:**
  [**DataLinksRequestError**](#datalinks.api.DataLinksRequestError) – If the HTTP request fails.

#### preview\_links(data, entity\_resolution=None)

Preview what recalculating links would produce without saving changes.

* **Parameters:**
  * **data** (*Dataset*) – Array of ontology data objects (e.g. from [`query_data()`](#datalinks.api.datalinks.DataLinksAPI.query_data)).
  * **entity\_resolution** (*Optional* *\[*[*MatchTypeConfig*](datalinks#datalinks.links.MatchTypeConfig) *]*) – Optional link matching configuration.
* **Return type:**
  `Optional`\[`List`\[[`ApiLink`](datalinks#datalinks.models.ApiLink)]]
* **Returns:**
  The previewed links, or None on failure.
* **Raises:**
  [**DataLinksRequestError**](#datalinks.api.DataLinksRequestError) – If the HTTP request fails.

#### rebuild\_links(data, entity\_resolution=None)

Recalculate links for the configured dataset based on current data.

* **Parameters:**
  * **data** (*Dataset*) – Array of ontology data objects (e.g. from [`query_data()`](#datalinks.api.datalinks.DataLinksAPI.query_data)).
  * **entity\_resolution** (*Optional* *\[*[*MatchTypeConfig*](datalinks#datalinks.links.MatchTypeConfig) *]*) – Optional link matching configuration.
* **Return type:**
  `Optional`\[`List`\[[`ApiLink`](datalinks#datalinks.models.ApiLink)]]
* **Returns:**
  The rebuilt links, or None on failure.
* **Raises:**
  [**DataLinksRequestError**](#datalinks.api.DataLinksRequestError) – If the HTTP request fails.

#### load\_links()

Retrieve active and suggested links for the configured dataset.

* **Return type:**
  `Optional`\[`List`\[[`ApiLink`](datalinks#datalinks.models.ApiLink)]]
* **Returns:**
  The links, or None on failure.

#### list\_datasets(namespace=None)

Retrieves the list of datasets for the user, optionally filtered by a specific namespace.

* **Parameters:**
  **namespace** (*Optional* \*\[\**AnyStr* *]*) – Optional namespace to filter the datasets by.
  If provided, only datasets associated with the given
  namespace will be returned. If not provided, all datasets are
  retrieved.
* **Return type:**
  `Optional`\[`List`\[[`ApiDatasetDescription`](datalinks#datalinks.models.ApiDatasetDescription)]]
* **Returns:**
  The datasets, or None on failure.

#### query\_data(query=None, is\_natural\_language=False, model=None, provider=None, include\_metadata=False, explain=False, , username='self')

Queries data from a specified data source and processes the response.

The method allows querying with a specific query string or with a wildcard
(“\*”) for all data. The response from the query can be filtered to exclude
metadata fields if include\_metadata is set to False. Metadata fields are
identified by key names starting with an underscore.

* **Parameters:**
  * **query** (*str*) – The query string to use for fetching data. Defaults to “\*”,
    which retrieves all data.
  * **is\_natural\_language** (*bool*) – If True, the query is treated as a natural language query.
  * **model** (*str*) – The model name to use for inference.
  * **provider** (*str*) – The provider of the LLM model (ollama, openai, etc)
  * **include\_metadata** (*bool*) – Specifies whether to include metadata fields in
    the returned data. Defaults to False.
  * **explain** (*bool*) – If True, request an explanation of how the query was resolved.
  * **username** (*str*) – Owner of the namespace being queried.
* **Returns:**
  A list of records represented as dictionaries, or None if the query
  fails or an exception occurs during the request.
* **Return type:**
  List\[Dict] | None
* **Raises:**
  [**DataLinksRequestError**](#datalinks.api.DataLinksRequestError) – If a transport-level error occurs.

#### ask(query, model=None, provider=None, helper\_prompt=None, , username='self', stage\_models=None, conversation\_id=None, web\_search=None)

Talk to your data with natural language using the DataLinks AutoRAG agent.

Streams the agent’s reasoning and final answer as Server-Sent Events. Events are
yielded in order: one `plan` event, one or more `step` events, then either an
`answer` event or an `error` event.

* **Parameters:**
  * **query** (*str*) – The natural language question to answer.
  * **model** (*str*) – The model name to use for inference.
  * **provider** (*str*) – The LLM provider (e.g. `openai`, `ollama`).
  * **helper\_prompt** (*str*) – Optional custom system prompt.
  * **stage\_models** (*Optional* \*\[\**Dict* \*\[\**str* *,* *Dict* \*\[\**str* *,* *str* *]* *]* *]*) – Per-stage model overrides, keyed by stage (`plan`,
    `query`, `answer`), each mapping to a dict with optional `model`
    and `provider`. An override wins over the run-wide
    `model`/`provider` *as a whole*: a stage that sets only `model`
    does not inherit the run-wide `provider` but falls back to the
    deployment default, so set both fields or neither.
  * **conversation\_id** (*Optional* \*\[\**str* *]*) – Existing conversation to continue. Omit to start a new
    one; its id arrives on the `run-started` event.
  * **web\_search** (*Optional* \*\[\**bool* *]*) – Pass False to disable web search. `True` is
    equivalent to omitting it — there is no way to force-enable a
    deployment that has web search switched off.
  * **username** (*str*) – Owner of the namespace being queried.
* **Returns:**
  An iterator of [`AskEvent`](#datalinks.api.datalinks.AskEvent) objects, also exposing the
  streaming response once it is open.
* **Return type:**
  [AskStream](#datalinks.api.datalinks.AskStream)
* **Raises:**
  [**DataLinksRequestError**](#datalinks.api.DataLinksRequestError) – If the HTTP request fails.

#### Versionchanged

Changed in version 1.2.15: Returns [`AskStream`](#datalinks.api.datalinks.AskStream) rather than a bare iterator.

#### preview\_ingest(data, inference\_steps=None)

Process data through the ingestion pipeline without saving it to a dataset.

* **Parameters:**
  * **data** (*Dataset*) – List of data records to preview.
  * **inference\_steps** (*Optional* *\[*[*Pipeline*](datalinks#datalinks.pipeline.Pipeline) *]*) – Optional pipeline of inference steps to apply.
* **Return type:**
  `Optional`\[`List`\[`Dict`\[`str`, `Any`]]]
* **Returns:**
  The processed preview records, or None on failure.
* **Raises:**
  [**DataLinksRequestError**](#datalinks.api.DataLinksRequestError) – If the HTTP request fails.

#### infer\_schema(sample, model=None, provider=None, current\_schema=None)

Ask an agent to infer a field type schema from sampled data.

* **Parameters:**
  * **sample** (*Dataset*) – A sample of data rows to analyse.
  * **model** (*Optional* \*\[\**str* *]*) – LLM model name.
  * **provider** (*Optional* \*\[\**str* *]*) – LLM provider (e.g. `"openai"`, `"ollama"`).
  * **current\_schema** (*Optional* \*\[\**Dict* \*\[\**str* *,* *str* *]* *]*) – Existing field schema to refine (field → description mapping).
* **Return type:**
  `Optional`\[[`InferredSchemaResponse`](datalinks#datalinks.models.InferredSchemaResponse)]
* **Returns:**
  The inferred schema, mapping field names to their types, or None
  on failure.
* **Raises:**
  [**DataLinksRequestError**](#datalinks.api.DataLinksRequestError) – If the HTTP request fails.

#### retry\_ingestion(ingestion\_id)

Retry a failed ingestion by creating a new ingestion record from the original.

* **Parameters:**
  **ingestion\_id** (*str*) – The ID of the ingestion to retry.
* **Return type:**
  `Optional`\[[`CreatedIngestionTrackingResponse`](datalinks#datalinks.models.CreatedIngestionTrackingResponse)]
* **Returns:**
  The new ingestion record, whose `id` is a `UUID`; or None on
  failure.
* **Raises:**
  [**DataLinksRequestError**](#datalinks.api.DataLinksRequestError) – If the HTTP request fails.

#### mark\_ingestion\_seen(ingestion\_id)

Mark an ingestion as seen, updating its `seenAt` timestamp.

* **Parameters:**
  **ingestion\_id** (*str*) – The ID of the ingestion to mark as seen.
* **Raises:**
  [**DataLinksRequestError**](#datalinks.api.DataLinksRequestError) – If the HTTP request fails.
* **Return type:**
  `None`

#### autorag(query, model=None, provider=None, helper\_prompt=None, , username='self', stage\_models=None, conversation\_id=None, web\_search=None)

Answer a natural language question using the AutoRAG agent (non-streaming).

Returns the final answer and all intermediate steps once the agent completes.
For incremental streaming results, use [`ask()`](#datalinks.api.datalinks.DataLinksAPI.ask) instead.

* **Parameters:**
  * **query** (*str*) – The natural language question to answer.
  * **model** (*Optional* \*\[\**str* *]*) – LLM model name.
  * **provider** (*Optional* \*\[\**str* *]*) – LLM provider (e.g. `"openai"`, `"ollama"`).
  * **helper\_prompt** (*Optional* \*\[\**str* *]*) – Optional custom system prompt.
  * **stage\_models** (*Optional* \*\[\**Dict* \*\[\**str* *,* *Dict* \*\[\**str* *,* *str* *]* *]* *]*) – Per-stage model overrides, keyed by stage (`plan`,
    `query`, `answer`), each mapping to a dict with optional `model`
    and `provider`. An override wins over the run-wide
    `model`/`provider` *as a whole*: a stage that sets only `model`
    does not inherit the run-wide `provider` but falls back to the
    deployment default, so set both fields or neither.
  * **conversation\_id** (*Optional* \*\[\**str* *]*) – Existing conversation to continue. Omit to start a new one.
  * **web\_search** (*Optional* \*\[\**bool* *]*) – Pass False to disable web search. `True` is
    equivalent to omitting it — there is no way to force-enable a
    deployment that has web search switched off.
  * **username** (*str*) – Owner of the namespace being queried.
* **Returns:**
  Dict with `response` (str) and `steps` (list) keys, also
  carrying the response `headers`.
* **Return type:**
  [AutoRagResult](#datalinks.api.datalinks.AutoRagResult)
* **Raises:**
  [**DataLinksRequestError**](#datalinks.api.DataLinksRequestError) – If the request fails, the server answers
  non-2xx, or the body is not a JSON object.

#### Versionchanged

Changed in version 1.2.15: Raises on failure instead of returning `None`, and returns
[`AutoRagResult`](#datalinks.api.datalinks.AutoRagResult) rather than a plain dict.

#### request\_cleaning(prompts, output\_namespace, output\_dataset\_name)

Request a cleaning job for the configured dataset.

* **Parameters:**
  * **prompts** (*List* \*\[\**str* *]*) – 1–10 prompts describing each cleaning step in order.
  * **output\_namespace** (*str*) – Target namespace for the cleaned dataset.
  * **output\_dataset\_name** (*str*) – Name for the cleaned dataset (must be unused in target namespace).
* **Returns:**
  The `cleaningTaskId` UUID string, or None on failure.
* **Return type:**
  Optional\[str]
* **Raises:**
  [**DataLinksRequestError**](#datalinks.api.DataLinksRequestError) – If the HTTP request fails.

#### get\_cleaning\_code(cleaning\_task\_id)

Retrieve code files generated by the cleaning agent for a task.

* **Parameters:**
  **cleaning\_task\_id** (*str*) – UUID of the cleaning task.
* **Returns:**
  List of dicts with `name` and `content` keys, or None on failure.
* **Return type:**
  Optional\[List\[Dict]]
* **Raises:**
  [**DataLinksRequestError**](#datalinks.api.DataLinksRequestError) – If the HTTP request fails.

#### get\_ontology()

Load the ontology (active links) for the configured dataset.

* **Return type:**
  `Optional`\[`List`\[[`ApiLink`](datalinks#datalinks.models.ApiLink)]]
* **Returns:**
  The active links, or None if no ontology exists or the request fails.
* **Raises:**
  [**DataLinksRequestError**](#datalinks.api.DataLinksRequestError) – If the HTTP request fails.

#### save\_ontology(add=None, remove=None)

Save (update) the ontology for the configured dataset.

* **Parameters:**
  * **add** (`Optional`\[`Sequence`\[`Union`\[[`ApiLink`](datalinks#datalinks.models.ApiLink), `Mapping`\[`str`, `Any`]]]]) – Links to add, as returned by [`get_ontology()`](#datalinks.api.datalinks.DataLinksAPI.get_ontology) or as dicts.
  * **remove** (`Optional`\[`Sequence`\[`Union`\[[`ApiLink`](datalinks#datalinks.models.ApiLink), `Mapping`\[`str`, `Any`]]]]) – Links to remove, in the same form as `add`.
* **Raises:**
  [**DataLinksRequestError**](#datalinks.api.DataLinksRequestError) – If the HTTP request fails.
* **Return type:**
  `None`

#### curate\_links(namespace=None, dataset=None, model=None, provider=None, activate=False)

Run the OntologyCurator agent to analyse computed links and optionally activate them.

When `activate=False` (default), the curated links are returned without being saved.
When `activate=True`, the curated links are added to the ontology.

* **Parameters:**
  * **namespace** (*Optional* \*\[\**str* *]*) – Namespace to curate. Defaults to the configured namespace.
  * **dataset** (*Optional* \*\[\**str* *]*) – Dataset to curate. If omitted, all datasets in the namespace are curated.
  * **model** (*Optional* \*\[\**str* *]*) – LLM model name.
  * **provider** (*Optional* \*\[\**str* *]*) – LLM provider (e.g. `"openai"`, `"anthropic"`).
  * **activate** (*bool*) – If `True`, add curated links to the ontology.
* **Return type:**
  `Optional`\[[`CurateLinkResponse`](datalinks#datalinks.models.CurateLinkResponse)]
* **Returns:**
  The curation outcome — `datasets_processed`, `total_selected`,
  and `curated_links` when `activate` is `False`; or None on failure.
* **Raises:**
  [**DataLinksRequestError**](#datalinks.api.DataLinksRequestError) – If the HTTP request fails.

#### rename\_namespace(new\_name)

Rename the configured namespace.

* **Parameters:**
  **new\_name** (*str*) – The new namespace name.
* **Raises:**
  [**DataLinksRequestError**](#datalinks.api.DataLinksRequestError) – If the HTTP request fails.
* **Return type:**
  `None`

#### list\_namespaces(user='self')

Retrieve namespaces for a user.

* **Parameters:**
  **user** (*str*) – Username or `"self"` for the current user.
* **Return type:**
  `Optional`\[`List`\[[`ApiNamespace`](datalinks#datalinks.models.ApiNamespace)]]
* **Returns:**
  The namespaces, or None on failure.
* **Raises:**
  [**DataLinksRequestError**](#datalinks.api.DataLinksRequestError) – If the HTTP request fails.

#### list\_all\_datasets\_schema()

Retrieve all datasets visible to the authenticated user (schema endpoint).

* **Return type:**
  `Optional`\[`List`\[[`ApiDatasetDescription`](datalinks#datalinks.models.ApiDatasetDescription)]]
* **Returns:**
  The datasets, or None on failure.
* **Raises:**
  [**DataLinksRequestError**](#datalinks.api.DataLinksRequestError) – If the HTTP request fails.

#### list\_datasets\_in\_namespace\_schema(namespace=None, user='self')

Retrieve datasets within a specific namespace (schema endpoint).

* **Parameters:**
  * **namespace** (*Optional* \*\[\**str* *]*) – Namespace to list. Defaults to the configured namespace.
  * **user** (*str*) – Username or `"self"` for the current user.
* **Return type:**
  `Optional`\[`List`\[[`ApiDatasetDescription`](datalinks#datalinks.models.ApiDatasetDescription)]]
* **Returns:**
  The datasets, or None on failure.
* **Raises:**
  [**DataLinksRequestError**](#datalinks.api.DataLinksRequestError) – If the HTTP request fails.

#### get\_current\_user()

Resolve the identity of the user owning the configured API key.

* **Return type:**
  `Optional`\[[`CurrentUserResponse`](datalinks#datalinks.models.CurrentUserResponse)]
* **Returns:**
  The user’s `id` and `username`, plus nullable `name` and
  `email`; or None on failure.

#### list\_tokens()

List all API tokens for the authenticated user.

* **Return type:**
  `Optional`\[`List`\[[`UserToken`](datalinks#datalinks.models.UserToken)]]
* **Returns:**
  The tokens, or None on failure — including the 403 a restricted
  token gets, since it may not manage API tokens.

#### add\_token(name, expires\_at=None, access\_restricted\_to=None)

Create a new API token for the authenticated user.

* **Parameters:**
  * **name** (*str*) – Display name for the token.
  * **expires\_at** (*Optional* \*\[\**str* *]*) – Optional expiry timestamp (ISO 8601 string).
  * **access\_restricted\_to** (`Optional`\[`Sequence`\[`Union`\[[`TokenPermissionEntry`](datalinks#datalinks.models.TokenPermissionEntry), `Mapping`\[`str`, `Any`]]]]) – Permission entries restricting access, as returned
    by [`list_token_permissions()`](#datalinks.api.datalinks.DataLinksAPI.list_token_permissions) or as dicts with `username`,
    `namespace` and optionally `dataset`.
* **Return type:**
  `Optional`\[[`UserToken`](datalinks#datalinks.models.UserToken)]
* **Returns:**
  The created token, including the `token` secret, or None on failure.
* **Raises:**
  [**DataLinksRequestError**](#datalinks.api.DataLinksRequestError) – If the HTTP request fails.

#### delete\_token(token\_id)

Delete an API token.

* **Parameters:**
  **token\_id** (*str*) – ID of the token to delete.
* **Raises:**
  [**DataLinksRequestError**](#datalinks.api.DataLinksRequestError) – If the HTTP request fails.
* **Return type:**
  `None`

#### list\_token\_permissions(token\_id)

List permissions assigned to a token.

* **Parameters:**
  **token\_id** (*str*) – ID of the token.
* **Return type:**
  `Optional`\[[`TokenPermissionsResponse`](datalinks#datalinks.models.TokenPermissionsResponse)]
* **Returns:**
  The token’s permissions, or None on failure.
* **Raises:**
  [**DataLinksRequestError**](#datalinks.api.DataLinksRequestError) – If the HTTP request fails.

#### get\_usage\_history(on\_or\_after=None, before=None, page\_size=25, page\_cursor=None)

Retrieve historical usage data for the authenticated user.

* **Parameters:**
  * **on\_or\_after** (*Optional* \*\[\**str* *]*) – Return records on or after this ISO 8601 timestamp.
  * **before** (*Optional* \*\[\**str* *]*) – Return records before this ISO 8601 timestamp.
  * **page\_size** (*int*) – Number of records per page (default 25).
  * **page\_cursor** (`Union`\[[`UserUsageHistoryCursor`](datalinks#datalinks.models.UserUsageHistoryCursor), `Mapping`\[`str`, `Any`], `None`]) – `meta.page_cursor` from a previous response.
* **Return type:**
  `Optional`\[[`UserUsageHistoryResponse`](datalinks#datalinks.models.UserUsageHistoryResponse)]
* **Returns:**
  The usage history page, or None on failure.
* **Raises:**
  [**DataLinksRequestError**](#datalinks.api.DataLinksRequestError) – If the HTTP request fails.

#### get\_usage\_by\_day(on\_or\_after=None, before=None, timezone='UTC')

Retrieve usage data aggregated by day for the authenticated user.

* **Parameters:**
  * **on\_or\_after** (*Optional* \*\[\**str* *]*) – Return records on or after this ISO 8601 timestamp.
  * **before** (*Optional* \*\[\**str* *]*) – Return records before this ISO 8601 timestamp.
  * **timezone** (*str*) – Timezone for date aggregation (e.g. `"America/New_York"`). Defaults to UTC.
* **Return type:**
  `Optional`\[[`UserUsageByDayResponse`](datalinks#datalinks.models.UserUsageByDayResponse)]
* **Returns:**
  The daily usage, in `.data` and `.meta`; or None on failure.
* **Raises:**
  [**DataLinksRequestError**](#datalinks.api.DataLinksRequestError) – If the HTTP request fails.

#### get\_agent\_run\_status(run\_id)

Get the current status of an agent run.

* **Parameters:**
  **run\_id** (*str*) – UUID of the agent run.
* **Return type:**
  `Optional`\[[`AgentRunStatusResponse`](datalinks#datalinks.models.AgentRunStatusResponse)]
* **Returns:**
  The run’s `run_id`, `agent_kind`, `question`, `status`
  (`running`/`completed`/`failed`/`expired`), `can_resume`,
  and optionally `last_node_id`, `error_message`, `result`; or
  None on failure.
* **Raises:**
  [**DataLinksRequestError**](#datalinks.api.DataLinksRequestError) – If the HTTP request fails.

#### delete\_agent\_run(run\_id)

Permanently delete an agent run and its resume checkpoint.

* **Parameters:**
  **run\_id** (*str*) – UUID of the agent run.
* **Raises:**
  [**DataLinksRequestError**](#datalinks.api.DataLinksRequestError) – If the HTTP request fails (e.g. 404 when
  the run does not exist or is not owned by the caller).
* **Return type:**
  `None`

#### submit\_agent\_run\_feedback(run\_id, , thumbs\_up, comment=None)

Rate the answer a completed agent run produced.

Resubmitting replaces the previous rating for the same run.

* **Parameters:**
  * **run\_id** (*str*) – UUID of the agent run.
  * **thumbs\_up** (*bool*) – True for a thumbs up, False for a thumbs down.
  * **comment** (*Optional* \*\[\**str* *]*) – Optional free-text comment accompanying the rating.
* **Raises:**
  [**DataLinksRequestError**](#datalinks.api.DataLinksRequestError) – If the HTTP request fails (e.g. 404 when the
  run does not exist or is not owned by the caller, 422 when it has not
  completed).
* **Return type:**
  `None`

#### resume\_agent\_run(run\_id)

Resume a previously paused or crashed agent run, streaming its events.

The first event is `run-started`, followed by the same domain events as
[`ask()`](#datalinks.api.datalinks.DataLinksAPI.ask) (e.g. `plan`, `step`, `answer`). Runs that cannot be
streamed arrive as a single synthetic event instead:

> * `completed` / `expired` (HTTP 410) — yielded as an
>   `AskEvent(type="terminal", data=<body>)` whose data carries the
>   original question and, for completed runs, the rendered result.
> * `failed` (HTTP 422) — yielded as an `AskEvent` of type
>   `"terminal"`.
> * no checkpoint to resume from (HTTP 409) — yielded as an
>   `AskEvent(type="no-checkpoint", data=<body>)`. The run is untouched
>   and still in progress; poll [`get_agent_run_status()`](#datalinks.api.datalinks.DataLinksAPI.get_agent_run_status) for its
>   eventual outcome.
> * not-found / not-owned (HTTP 404) — raises `DataLinksRequestError`.

* **Parameters:**
  **run\_id** (*str*) – UUID of the agent run to resume.
* **Returns:**
  An iterator of [`AskEvent`](#datalinks.api.datalinks.AskEvent) objects.
* **Return type:**
  Iterator\[[AskEvent](#datalinks.api.datalinks.AskEvent)]
* **Raises:**
  [**DataLinksRequestError**](#datalinks.api.DataLinksRequestError) – On 404 or transport-level failure.

#### share\_dataset\_access(username, role)

Grant another user access to the configured dataset.

Since public datasets were removed, this is how you give someone else
access. Re-sharing with a different role replaces the existing grant.

* **Parameters:**
  * **username** (*str*) – User to grant access to.
  * **role** (*str*) – `"viewer"` (read-only) or `"editor"` (read and write).
* **Raises:**
  * **ValueError** – If `role` is not a valid access level.
  * [**DataLinksRequestError**](#datalinks.api.DataLinksRequestError) – If the HTTP request fails (e.g. 403 when
    the caller does not own the dataset).
* **Return type:**
  `None`

#### revoke\_dataset\_access(username, role)

Remove a user’s access to the configured dataset.

* **Parameters:**
  * **username** (*str*) – User whose access is being removed.
  * **role** (*str*) – The granted access level to remove.
* **Raises:**
  * **ValueError** – If `role` is not a valid access level.
  * [**DataLinksRequestError**](#datalinks.api.DataLinksRequestError) – If the HTTP request fails.
* **Return type:**
  `None`

#### list\_dataset\_shares()

List the per-user grants on the configured dataset.

* **Return type:**
  `Optional`\[`List`\[[`AccessGrant`](datalinks#datalinks.models.AccessGrant)]]
* **Returns:**
  The grants, each with `username` and `role`; or None on failure.

#### share\_namespace\_access(username, role)

Grant another user access to the configured namespace.

The grant cascades to every dataset in the namespace.

* **Parameters:**
  * **username** (*str*) – User to grant access to.
  * **role** (*str*) – `"viewer"` (read-only) or `"editor"` (read and write).
* **Raises:**
  * **ValueError** – If `role` is not a valid access level.
  * [**DataLinksRequestError**](#datalinks.api.DataLinksRequestError) – If the HTTP request fails.
* **Return type:**
  `None`

#### revoke\_namespace\_access(username, role)

Remove a user’s access to the configured namespace.

* **Parameters:**
  * **username** (*str*) – User whose access is being removed.
  * **role** (*str*) – The granted access level to remove.
* **Raises:**
  * **ValueError** – If `role` is not a valid access level.
  * [**DataLinksRequestError**](#datalinks.api.DataLinksRequestError) – If the HTTP request fails.
* **Return type:**
  `None`

#### list\_namespace\_shares()

List the per-user grants on the configured namespace.

* **Return type:**
  `Optional`\[`List`\[[`AccessGrant`](datalinks#datalinks.models.AccessGrant)]]
* **Returns:**
  The grants, each with `username` and `role`; or None on failure.

#### list\_conversations(username='self', namespace=None)

List the caller’s conversations within a namespace (most-recently-updated first).

* **Parameters:**
  * **username** (*str*) – Owner username. Defaults to `"self"`.
  * **namespace** (*Optional* \*\[\**str* *]*) – Namespace to list within. Defaults to the configured namespace.
* **Return type:**
  `Optional`\[[`ConversationListResponse`](datalinks#datalinks.models.ConversationListResponse)]
* **Returns:**
  The summaries, in `.conversations`; or None on failure.
* **Raises:**
  [**DataLinksRequestError**](#datalinks.api.DataLinksRequestError) – If the HTTP request fails.

#### get\_conversation(conversation\_id)

Get a conversation and its turns (oldest first).

* **Parameters:**
  **conversation\_id** (*str*) – UUID of the conversation.
* **Return type:**
  `Optional`\[[`ConversationDetailResponse`](datalinks#datalinks.models.ConversationDetailResponse)]
* **Returns:**
  The conversation’s `id`, `title` and `turns` (each turn has
  `run_id`, `question`, `status`, and optionally `result`); or
  None on failure.
* **Raises:**
  [**DataLinksRequestError**](#datalinks.api.DataLinksRequestError) – If the HTTP request fails.

## datalinks.api.ingest\_proxy module

### *class* datalinks.api.ingest\_proxy.IngestProxyConfig(host, datalinks\_token, datalinks\_username, namespace)

Bases: `object`

Configuration for the DataLinks ingestion proxy (auto-modelling) service.

* **Variables:**
  * **host** – Base URL of the ingestion proxy (e.g. `http://localhost:3003`).
  * **datalinks\_token** – DataLinks JWT token sent as `Authorization: Bearer` (`DL_API_KEY`).
  * **datalinks\_username** – DataLinks username included in the request body (`DL_USERNAME`).
  * **namespace** – Default target namespace (`DL_NAMESPACE`).

#### host *: str*

#### datalinks\_token *: str*

#### datalinks\_username *: str*

#### namespace *: str*

#### *classmethod* from\_env(load\_dotenv=True)

* **Return type:**
  [`IngestProxyConfig`](#datalinks.api.ingest_proxy.IngestProxyConfig)

### *class* datalinks.api.ingest\_proxy.PipelineRun(run\_id, stream\_fn)

Bases: `object`

Wraps a pipeline run with automatic stream reconnection.

Provides the workflow `run_id` (from the `x-workflow-run-id` response
header) and an iterable interface over the NDJSON progress events.

The iterator reconnects transparently on connection drops, resuming from
the last received event via the `startIndex` query parameter.  Iteration
ends only when an explicit `complete` or `error` event is received.

Usage:

```default theme={null}
run = proxy.run_pipeline(data=[...])
print(run.run_id)
for event in run:
    print(event)
```

Can also be used as a context manager:

```default theme={null}
with proxy.run_pipeline(data=[...]) as run:
    for event in run:
        process(event)
```

#### close()

* **Return type:**
  `None`

### *class* datalinks.api.ingest\_proxy.IngestProxyAPI(config=None)

Bases: `object`

Client for the DataLinks ingestion proxy (auto-modelling) service.

Wraps the `POST /api/pipeline`, `GET /api/pipeline/{runId}/stream`,
`GET /api/pipeline/{runId}/trace`, and `POST /api/pipeline/{runId}/hook`
endpoints.

* **Variables:**
  **config** – Proxy configuration.

#### config *: [IngestProxyConfig](#datalinks.api.ingest_proxy.IngestProxyConfig)*

#### run\_pipeline(, data=None, data\_url=None, data\_blob\_url=None, namespace=None, user\_prompt=None, model=True, ingest=True, ontology=True, max\_eval\_retries=3, max\_rows\_for\_modeling=20, max\_sample\_rows=10, enable\_human\_in\_the\_loop=False, predefined\_schema=None, explosion\_helper\_prompt=None, coalescence\_helper\_prompt=None, llm=None, datalinks\_inference\_settings=None)

Start a full pipeline run (auto-modelling + ingest).

Exactly one of *data*, *data\_url*, or *data\_blob\_url* must be provided.

Returns a [`PipelineRun`](#datalinks.api.ingest_proxy.PipelineRun) whose `run_id` attribute is the workflow
run identifier and which can be iterated to receive NDJSON progress events.

* **Parameters:**
  * **data** (`Optional`\[`List`\[`Dict`\[`str`, `Any`]]]) – Inline JSON array of row objects.
  * **data\_url** (`Optional`\[`str`]) – Remote URL returning a JSON array (fetched by the pipeline).
  * **data\_blob\_url** (`Optional`\[`str`]) – Pre-uploaded Vercel Blob URL.
  * **namespace** (`Optional`\[`str`]) – Target namespace; defaults to `config.namespace`.
  * **user\_prompt** (`Optional`\[`str`]) – Domain goals; inferred from data when omitted.
  * **model** (`bool`) – Run the model phase (default True).
  * **ingest** (`bool`) – Run the ingest phase (default True).
  * **ontology** (`bool`) – Run namespace curation after ingest (default True).
  * **max\_eval\_retries** (`int`) – Max modelling iterations (default 3).
  * **max\_rows\_for\_modeling** (`int`) – Rows sent to the LLM for schema modelling (default 20).
  * **max\_sample\_rows** (`int`) – Sample rows generated for preview (default 10).
  * **enable\_human\_in\_the\_loop** (`bool`) – Surface clarification + schema review hooks (default False).
  * **predefined\_schema** (`Optional`\[`Dict`\[`str`, `Any`]]) – Skip model phase when provided.
  * **explosion\_helper\_prompt** (`Optional`\[`str`]) – Extra context injected into the explode step.
  * **coalescence\_helper\_prompt** (`Optional`\[`str`]) – Extra context injected into the coalesce step.
  * **llm** (`Optional`\[`Dict`\[`str`, `Any`]]) – LLM configuration dict with optional keys: `provider`, `model`,
    `explosionTemperature`, `coalescenceTemperature`, `evaluationTemperature`,
    `ontologyTemperature`.
  * **datalinks\_inference\_settings** (`Optional`\[`Dict`\[`str`, `Any`]]) – DataLinks inference settings dict with optional keys:
    `provider`, `model`, `ontologyCurationProvider`, `ontologyCurationModel`.
* **Return type:**
  [`PipelineRun`](#datalinks.api.ingest_proxy.PipelineRun)
* **Returns:**
  A [`PipelineRun`](#datalinks.api.ingest_proxy.PipelineRun) instance.
* **Raises:**
  [**DataLinksRequestError**](#datalinks.api.DataLinksRequestError) – If the HTTP request fails.

#### stream\_pipeline(run\_id, start\_index=0)

Stream progress events for an existing pipeline run.

* **Parameters:**
  * **run\_id** (`str`) – Workflow run identifier returned by [`run_pipeline()`](#datalinks.api.ingest_proxy.IngestProxyAPI.run_pipeline).
  * **start\_index** (`int`) – Resume from this event index (default 0).  Pass the
    number of events already received to skip replaying them on reconnect.
* **Return type:**
  `Iterator`\[`Dict`\[`str`, `Any`]]
* **Returns:**
  An iterator of NDJSON event dicts.
* **Raises:**
  [**DataLinksRequestError**](#datalinks.api.DataLinksRequestError) – If the HTTP request fails.

#### get\_pipeline\_trace(run\_id)

Download the full trace for a completed pipeline run.

* **Parameters:**
  **run\_id** (`str`) – Workflow run identifier.
* **Return type:**
  `Optional`\[`Dict`\[`str`, `Any`]]
* **Returns:**
  Dict with LLM calls, token usage, and step durations, or None on failure.
* **Raises:**
  [**DataLinksRequestError**](#datalinks.api.DataLinksRequestError) – If the HTTP request fails.

#### resume\_pipeline\_hook(run\_id, payload)

Resume a human-in-the-loop hook (clarification, schema review, or token refresh).

* **Parameters:**
  * **run\_id** (`str`) – Workflow run identifier.
  * **payload** (`Dict`\[`str`, `Any`]) – Hook response payload.
* **Return type:**
  `Optional`\[`Dict`\[`str`, `Any`]]
* **Returns:**
  Response dict, or None on failure.
* **Raises:**
  [**DataLinksRequestError**](#datalinks.api.DataLinksRequestError) – If the HTTP request fails.
